[BIP XXX] Permissions Update Request #9

TL;DR

not mentioned in the proposal but found in the payload:

  • pendle
  • silo
  • sablier
  • cctp
  • sky psm
  • makerdao psm
  • polygon staking revokes
  • lido withdrawal revokes
  • old xdai bridge revokes
  • dai and gno bridging

discrepancies:

  • you mention unwinding balancer 80bal20weth positions but also add permissions to join those pools
  • gyd is not revoked, only sgyd
  • not only stkaave delegation is revoked, also aave
  • swapping pairs are more complex than how you describe it
  • also bridge dai and gno, plus cctp arb1 bridge

furthermore some minor comments, mostly unnecessary transactions, but no security concerns (except for maybe usr swapping, which has been depegged)

TX 0: USDC Allowance

now correctly sets a usdc allowance of 100_000usdc to kpk every 90 days. used in tx 18

setAllowance(USDC_KPK-FEES, bal=100000000000, period=90d)

TX 1-13, 182-188: Revokes

as stated previously, i dont think there is a need to revoke permissions unless there is a security concern. however, i understand it was easier to keep these in the payload for now:

  • revoke delegate permissions for aave and stkaave
  • revoke withdrawal permissions for unsteth
  • revoke sgyd permissions to deposit and redeem
  • revoke susds permissions to deposit
  • revoke xdai foreign bridge permissions (replaced by newer one; see tx 177-181)
AAVE.delegate
AAVE.delegateByType
stkAAVE.delegate
stkAAVE.delegateByType
unstETH.requestWithdrawalsWithPermit
unstETH.requestWithdrawalsWstETHWithPermit
sGYD.[TARGET]
sGYD.deposit
sGYD.redeem
sUSDS.deposit
XDaiForeignBridge.[TARGET]
XDaiForeignBridge.relayTokens
XDaiForeignBridge.executeSignatures

revoke permissions to manage pol delegation

POL.[TARGET]
POL.approve
DelegateRegistry.[TARGET]
DelegateRegistry.setDelegation
DelegateRegistry.clearDelegation
dPOLa2.[TARGET]
dPOLa2.buyVoucherPOL

TX 14, 189: Metadata

n/a; metadata

_post_(removeAnnotations)
_post_(addAnnotations)

TX 15: WETH

approve weth for bridging, gearbox, morpho, compound, aave umbrella, balancer vault and cow relayer

WETH.approve(OR(SwapRouter02, ForeignOmnibridge, kpkWETH, cWETHv3, stkwaEthWETH.v1, Vault, kpk_ETH_PrimeV2, UNI-V3-POS, GPv2VaultRelayer, UmbrellaBatchHelper), *)

TX 16, 44-53, 158-159: Compound

scope the rewards claim to only the relevant reward markets, and not all of them (why i dont know, unscoped should be fine):

CometRewards.claim(OR(cUSDTv3, cUSDSv3, cWETHv3, cUSDCv3), AVATAR, *)

supply and withdraw from usds/usdt/weth compound markets:

cUSDSv3.[TARGET]
cUSDSv3.supply(USDS, *)
cUSDSv3.withdraw(USDS, *)
cUSDTv3.[TARGET]
cUSDTv3.supply(USDT, *)
cUSDTv3.withdraw(USDT, *)
cWETHv3.[TARGET]
cWETHv3.supply(WETH, *)
cWETHv3.withdraw(WETH, *)
cWETHv3.allow(MainnetBulker, *)

eth<>weth helper for cwethv3

MainnetBulker.[TARGET]
MainnetBulker.invoke(EVERY(...), EVERY(...)) [Send]

TX 17-21: Stablecoin Approvals

  • approve usdc and usdt for spark, spark savings, kpk vault, (batch) aave umbrella, gnosis bridge
  • approve usds for compound and gnosis bridge
  • allow transfer of usdc to kpk within allowance defined in tx 0
  • stake usds into susds
USDC.approve(OR(spUSDC, kpk_USDC_PrimeV2, PSMVariant1Actions, SwapRouter02, stkwaEthUSDC.v1, PoolInstance, ForeignOmnibridge, UsdsPsmWrapper, Vault, Pool, cUSDCv3, GPv2VaultRelayer, UmbrellaBatchHelper, PSMVariant1Actions), *)
USDC.transfer(kpk-fees-safe, <=USDC_KPK-FEES)
USDT.approve(OR(cUSDTv3, SwapRouter02, ForeignOmnibridge, stkwaEthUSDT.v1, Vault, Pool, GPv2VaultRelayer, UmbrellaBatchHelper, spUSDT), *)
USDS.approve(OR(cUSDSv3, PoolInstance, BridgeRouter, UsdsPsmWrapper, sUSDS, GPv2VaultRelayer, MigrationActions), *)
sUSDS.deposit(*, AVATAR, *)

TX 22: OETH

opt in to oeth rebasing; doesnt pose a problem for safe contracts

OETH.rebaseOptIn()

TX 23: Merkl

allow claiming of rewards via merkl. not sure why this needs to be scoped; what is the security concern here?

Distributor.claim(OR(..., ..., ..., ..., ...), *, *, *)

TX 24-26: Bridging

allow bridging of wbtc, gno, weth, usdt and usdc

ForeignOmnibridge.relayTokens(OR(WBTC, GNO, WETH, USDT), AVATAR, *)
ForeignOmnibridge.relayTokensAndCall(USDC, 0x0392a2f5, *, ...)
ForeignAMB.safeExecuteSignaturesWithAutoGasLimit(OR(AND(0x), AND(0x), AND(0x), AND(0x), AND(0x)), *)

TX 27-31

new approvals here are:

  • gho: (batch) aave umbrella
  • dai: redundant!
  • sdai: redundant!
  • wbtc: bridge
  • wsteth: kpk gearbox vault
GHO.approve(OR(stkGHO, stkGHO.v1, PoolInstance, Vault, GPv2VaultRelayer, UmbrellaBatchHelper), *)
DAI.approve(OR(DsrManager, SwapRouter02, sDAI, PoolInstance, BridgeRouter, GPv2VaultRelayer, MigrationActions), *)
sDAI.approve(OR(PSMVariant1Actions, PoolInstance, Vault, GPv2VaultRelayer), *)
WBTC.approve(OR(SwapRouter02, PoolInstance, ForeignOmnibridge, UNI-V3-POS, GPv2VaultRelayer), *)
wstETH.approve(OR(SwapRouter02, PoolInstance, unstETH, kpkwstETH, Vault, GPv2VaultRelayer), *)

TX 32-33, 54-71, 75-92: CoW Swap

allow signing of the following swapping pairs:

  • gho staking/unstaking via swap: stkgho<>gho
  • dust liquidations: fjo, mta, gtc > usdc, weth
  • oeth exit: oeth > wsteth, reth, steth, weth, eth
  • bal token rebalance: aethbal, abal, weth, anybal > aethbal, abal, weth, anybal, eth
  • main rebalance: wbtc, swise, stkaave, syrup, dai, wsteth, aave, usdc, reth, steth, comp, weth, usdt, cow > wbtc, dai, wsteth, usdc, reth, steth, weth, usdt
  • stablecoin rebalance: usda, stusd, steur, wstusr, eura, eurc, gho, usde, usr, dai, sdai, susde, usdc, susds, aetheurc, usdt, usds, gyd <> usda, stusd, steur, wstusr, eura, eurc, gho, usde, usr, dai, sdai, susde, usdc, susds, aetheurc, usdt, gyd

looks like you missed usds as a buy token, or was this by design? i guess there is always the psm as a fallback

CowswapOrderSigner.signOrder([...], *, [...])

approve cow relayer:

GYD.approve(OR(Vault, GPv2VaultRelayer), *)
COW.[TARGET]
COW.approve(GPv2VaultRelayer, *)
SYRUP.[TARGET]
SYRUP.approve(GPv2VaultRelayer, *)
aEthEURC.[TARGET]
aEthEURC.approve(GPv2VaultRelayer, *)
EURA.[TARGET]
EURA.approve(GPv2VaultRelayer, *)
EURC.[TARGET]
EURC.approve(OR(kpk_EURC_YieldV2, GPv2VaultRelayer), *)
stEUR.[TARGET]
stEUR.approve(GPv2VaultRelayer, *)
stUSD.[TARGET]
stUSD.approve(GPv2VaultRelayer, *)
USR.[TARGET]
USR.approve(GPv2VaultRelayer, *)
sUSDe.[TARGET]
sUSDe.approve(GPv2VaultRelayer, *)
USDA.[TARGET]
USDA.approve(GPv2VaultRelayer, *)
USDe.[TARGET]
USDe.approve(OR(PendleRouterV4, sUSDe, GPv2VaultRelayer), *)
wstUSR.[TARGET]
wstUSR.approve(GPv2VaultRelayer, *)
FJO.[TARGET]
FJO.approve(GPv2VaultRelayer, *)
GTC.[TARGET]
GTC.approve(GPv2VaultRelayer, *)
MTA.[TARGET]
MTA.approve(GPv2VaultRelayer, *)
aBAL.[TARGET]
aBAL.approve(GPv2VaultRelayer, *)
aEthBAL.[TARGET]
aEthBAL.approve(GPv2VaultRelayer, *)
anyBAL.[TARGET]
anyBAL.approve(GPv2VaultRelayer, *)

TX 34-35, 38-41: Balancer

join (why?) and exit 80bal20weth pools:

Vault.joinPool(OR(0x5c6ee304399d..., 0xc5c91aea7551...), AVATAR, AVATAR, *) [Send]
Vault.exitPool(OR(0x5c6ee304399d..., 0xc5c91aea7551...), AVATAR, AVATAR, *)
B-80BAL-20WETH.[TARGET]
B-80BAL-20WETH.approve(Vault, *)
BAL.[TARGET]
BAL.approve(Vault, *)

TX 36-37: AAVE V3

aave v3 reward claiming:

RewardsController.[TARGET]
RewardsController.claimRewards(*, *, AVATAR, *)

TX 42-43: CCTP

receive cctp messages from arb1 to eth; usdc burning from treasury on arb1 that result in minting of usdc on eth treasury

MessageTransmitterV2.[TARGET]
MessageTransmitterV2.receiveMessage(AND(...), *)

TX 72-74: Ethena

stake and unstake (s)usde

sUSDe.deposit(*, AVATAR)
sUSDe.cooldownShares(*)
sUSDe.unstake(AVATAR)

TX 93-104: Morpho

deposit, withdraw and redeem from eth, eurc and usdc kpk vaults:

kpk_ETH_PrimeV2.[TARGET]
kpk_ETH_PrimeV2.deposit(*, AVATAR)
kpk_ETH_PrimeV2.withdraw(*, AVATAR, AVATAR)
kpk_ETH_PrimeV2.redeem(*, AVATAR, AVATAR)
kpk_EURC_YieldV2.[TARGET]
kpk_EURC_YieldV2.deposit(*, AVATAR)
kpk_EURC_YieldV2.withdraw(*, AVATAR, AVATAR)
kpk_EURC_YieldV2.redeem(*, AVATAR, AVATAR)
kpk_USDC_PrimeV2.[TARGET]
kpk_USDC_PrimeV2.deposit(*, AVATAR)
kpk_USDC_PrimeV2.withdraw(*, AVATAR, AVATAR)
kpk_USDC_PrimeV2.redeem(*, AVATAR, AVATAR)

TX 160-167: Gearbox

kpkWETH.[TARGET]
kpkWETH.deposit(*, AVATAR)
kpkWETH.depositWithReferral(*, AVATAR, *)
kpkWETH.redeem(*, AVATAR, AVATAR)
kpkwstETH.[TARGET]
kpkwstETH.deposit(*, AVATAR)
kpkwstETH.depositWithReferral(*, AVATAR, *)
kpkwstETH.redeem(*, AVATAR, AVATAR)

TX 105-111, 116-119, 127-132: Spark

supply and withdraw from usdc and usdt markets:

Pool.[TARGET]
Pool.supply(OR(USDC, USDT), *, AVATAR, *)
Pool.withdraw(OR(USDC, USDT), *, AVATAR)
Pool.setUserUseReserveAsCollateral(OR(USDC, USDT), *)

spark reward claiming (fork of aave v3, so same pattern as tx 36-37)

RewardsController.[TARGET]
RewardsController.claimRewards(*, *, AVATAR, *)
RewardsController.claimAllRewards(*, AVATAR)

deposit/withdraw/redeem spark savings usdc:

spUSDC.[TARGET]
spUSDC.deposit(*, AVATAR, *)
spUSDC.withdraw(*, AVATAR, AVATAR)
spUSDC.redeem(*, AVATAR, AVATAR)

not clear why susdc needs approval? i think you confuse it for susds or usdc here

sUSDC.[TARGET]
sUSDC.approve(PSMVariant1Actions, *)

deposit/withdraw/redeem spark savings usdt:

spUSDT.[TARGET]
spUSDT.deposit(*, AVATAR, *)
spUSDT.withdraw(*, AVATAR, AVATAR)
spUSDT.redeem(*, AVATAR, AVATAR)

TX 112-115: MakerDAO PSM

makerdao psm routing (usdc <> dai <> sdai)

PSMVariant1Actions.[TARGET]
PSMVariant1Actions.swapAndDeposit(AVATAR, *, *)
PSMVariant1Actions.withdrawAndSwap(AVATAR, *, *)
PSMVariant1Actions.redeemAndSwap(AVATAR, *, *)

TX 120-126: Sky PSM

sky psm wrapper (usdc<>usds):

UsdsPsmWrapper.[TARGET]
UsdsPsmWrapper.sellGem(AVATAR, *)
UsdsPsmWrapper.buyGem(AVATAR, *)

sky psm routing (usdc <> usds <> susds)

PSMVariant1Actions.[TARGET]
PSMVariant1Actions.swapAndDeposit(AVATAR, *, *)
PSMVariant1Actions.withdrawAndSwap(AVATAR, *, *)
PSMVariant1Actions.redeemAndSwap(AVATAR, *, *)

TX 133-153: AAVE Umbrella

stake and unstake usdc, usdt, weth and gho into aave umbrella

UmbrellaBatchHelper.[TARGET]
UmbrellaBatchHelper.deposit(OR(MATCH(0x), MATCH(0x), MATCH(0x), MATCH(0x)))
UmbrellaBatchHelper.redeem(OR(MATCH(0x), MATCH(0x), MATCH(0x), MATCH(0x)))
stkGHO.v1.[TARGET]
stkGHO.v1.deposit(*, AVATAR)
stkGHO.v1.cooldown()
stkGHO.v1.redeem(*, AVATAR, AVATAR)
stkwaEthUSDC.v1.[TARGET]
stkwaEthUSDC.v1.deposit(*, AVATAR)
stkwaEthUSDC.v1.cooldown()
stkwaEthUSDC.v1.redeem(*, AVATAR, AVATAR)
stkwaEthUSDT.v1.[TARGET]
stkwaEthUSDT.v1.deposit(*, AVATAR)
stkwaEthUSDT.v1.cooldown()
stkwaEthUSDT.v1.redeem(*, AVATAR, AVATAR)
stkwaEthWETH.v1.[TARGET]
stkwaEthWETH.v1.deposit(*, AVATAR)
stkwaEthWETH.v1.cooldown()
stkwaEthWETH.v1.redeem(*, AVATAR, AVATAR)
RewardsController.[TARGET]
RewardsController.claimSelectedRewards(*, *, AVATAR)

TX 154-157: CoW AMM

unwind weth/usdc and bal/eth positions on cow amm

BCoW-50WETH-50USDC.[TARGET]
BCoW-50WETH-50USDC.exitPool(*, *)
BCoW-50BAL-50ETH.[TARGET]
BCoW-50BAL-50ETH.exitPool(*, *)

TX 168-169: Sablier

withdraw sablier streams:

SAB-V2-LOCKUP-DYN.[TARGET]
SAB-V2-LOCKUP-DYN.withdraw(*, AVATAR, *)

TX 170-171: Silo

withdraw from bal silo

SiloRouterV2.[TARGET]
SiloRouterV2.execute((MATCH))

TX 172-176: Pendle

this particular PENDLE-LPT appears expired already (1770249600; 2026-02-05)

PendleRouterV4.[TARGET]
PendleRouterV4.swapExactTokenForPt(AVATAR, PENDLE-LPT, *, *, (USDe, *, USDe, 0x0, MATCH), (0x0, *, ..., ...))
PendleRouterV4.swapExactPtForToken(AVATAR, PENDLE-LPT, *, (USDe, *, USDe, 0x0, MATCH), (0x0, *, ..., ...))
PENDLE-LPT.[TARGET]
PENDLE-LPT.approve(PendleRouterV4, *)

TX 177-181: Gnosis Chain Bridge

bridge weth, dai or usds to gnosis and receive inbound bridge messages from gnosis

BridgeRouter.[TARGET]
BridgeRouter.relayTokens(OR(DAI, USDS), AVATAR, *)
BridgeRouter.executeSignatures([recipient=AVATAR, bridge=XDaiForeignBridge], *)
WETHOmnibridgeRouter.[TARGET]
WETHOmnibridgeRouter.wrapAndRelayTokens(AVATAR) [Send]