[BIP-XXX] Permissions Policy Update Request #5 (ETH Mainnet)

PR with payload

https://github.com/BalancerMaxis/multisig-ops/pull/1449

Abstract

This proposal seeks BalancerDAO’s approval for updates, new actions, and strategies related to the permissions policy governing the karpatkey-managed treasury on Mainnet. These changes are part of a broader effort to optimise the treasury, with the goal of enhancing its performance, flexibility, and diversification.

The proposed new permissions focus on strategies involving Aave’s GHO, Sky’s USDS, Origin’s oETH, and Stakewise’s osETH.

Motivation

Effective treasury management strategies need to be adjusted based on market conditions and protocol updates, such as migrations and the introduction of new pools. Protocols and pools that were once considered immature and unsuitable for the BalancerDAO’s risk appetite can become more viable as they prove their reliability over time. This proposal aims to integrate these new strategies into the existing Permissions Policy.

Changes to the Permissions Policy

This proposal outlines the following modifications to the permissions policy:

  1. GHO Carry Trade
  • Deposit, sDAI, USDS, wstETH, osETH and WBTC on Aave v3 and allow it to be used as collateral.
  • Borrow GHO
  • Stake GHO in the Staking Module on Aave v3
  • Claim AAVE rewards
  • Claim GHO Merit rewards
  • Swap GHO <> USDT, USDC, in Balancer.
  • Swap stkGHO-GHO in Cow and Maverick
  1. Sky’s USDS
  • Deposit and Withdraw USDS in Spark
  • Swap sUSDS <> USDS in Cow
  • Swap USDS for Stablecoins in Cow
  1. osETH in Stakewise v3
  • Stake (and unstake) ETH on Stakewise v3.
  1. oETH in Origin
  • Mint oETH in vault
  • Redeem WETH via ARM and vault
  • Swap oETH for ETH and LSTs (same policy as with other LSTs) in Cow
  • Back up swap permissions in Curve
  • Provide liquidity in oETH-ETH pool in Curve
  • Stake LP token in Curve and Convex
  • Claim rewards, unstake and withdraw oETH-ETH in Curve and Convex.

Zodiac Roles Modifier Permissions Policy

Permissions page:

https://roles.gnosisguild.org/permissions/eth/6WhgTGie6QoelTwqaE6z8h0MqZa6UOkyZcwJif5sig

Permissions diff page:

https://roles.gnosisguild.org/eth:0x13c61a25DB73e7a94a244bD2205aDba8b4a60F4a/roles/MANAGER/diff/6WhgTGie6QoelTwqaE6z8h0MqZa6UOkyZcwJif5sig

review summary

permissions added:

  • stkgho
    • approve(maverick_router_v2)
    • approve(cow_relayer)
    • redeem(AVATAR)
    • cooldown()
    • claimRewards(AVATAR,*)
    • stake(AVATAR, *)
  • wbtc.approve(aave_pool_v3)
  • cow_order_signer
    • signOrder:
      • stkgho, gho → stkgho, gho
      • usds → dai, usdc, susds, usdt
      • oeth → wsteth, reth, steth, weth, eth
      • gho, dai, sdai, usdc, usdt, gyd → gho, dai, sdai, usdc, usdt, gyd
      • always with AVATAR as destination and fee < 200bips
  • curve_gauge_ethoeth
    • withdraw(*, *)
    • getReward(AVATAR, *)
    • stake(*)
    • withdrawAndUnwrap(*, *)
  • oeth_vault
    • claimWithdrawals(*)
    • requestWithdrawal(*)
    • claimWithdrawal(*)
  • angle_distributor.claim([AVATAR], *, *, *)
  • gho.approve
    • stkgho
    • maverick_router_v2
    • aave_pool_v3
    • balancer_vault
    • cow_relayer
  • gnosis_xdai_bridge
    • relayTokens(AVATAR, *)
    • executeSignatures:
      • recipient: AVATAR
      • amount: *
      • txHash: *
      • contractAddress: gnosis_xdai_bridge
  • gnosis_amb_bridge
    • safeExecuteSignaturesWithGasLimit
      • msgId: 00050000a7823d6f1e31569f51861e345b30c6bebf70ebe7xxxxxxxxxxxxxxxx
      • sender: gnosis_xdai_bridge (gno:0xca3e2a662d6dd1703c939c8ace2e268d88ad0951)
      • executor: 0x88ad09518695c6c3712ac10a214be5109a655671
      • dataType: 128
      • chainIds: [100, 1]
      • data: handleNativeTokens(gno, AVATAR, *)
  • curve_zap
    • deposit_and_stake
      • deposit: curve_pool_ethoeth
      • lp_token: curve_pool_ethoeth
      • gauge: curve_gauge_ethoeth
      • n_coins: 2
      • coins: [eth, oeth]
      • use_dynarray: 0
  • maverick_router_v2
    • inputSingleWithTickLimit(AVATAR, maverick_pool_ghostkgho, *, *, *, *)
  • gno.approve(gnosis_omni_bridge, *)
  • dai.approve
    • gnosis_xdai_bridge
    • sdai
    • dai_sdai_migrator
  • oeth_redeemer
    • swapExactTokensForTokens(oeth, eth, *, *, AVATAR)
  • wsteth.approve(aave_pool_v3)
  • sdai
    • approve
      • aave_pool_v3
      • balancer_vault
      • cow_relayer
    • deposit(*, AVATAR)
    • withdraw(*, AVATAR, AVATAR)
    • redeem(*, AVATAR, AVATAR)
  • oeth.approve
    • curve_zap
    • oeth_redeemer
    • curve_pool_ethoeth
    • cow_relayer
  • aave_pool_v3
    • repay(gho, *, *, AVATAR)
    • setUserUseReserveAsCollateral
      • wbtc
      • wsteth
      • sdai
      • usds
      • oseth
    • supply (AVATAR)
      • wbtc
      • wsteth
      • sdai
      • usds
      • oseth
    • withdraw (AVATAR)
      • wbtc
      • wsteth
      • sdai
      • usds
      • oseth
    • swapBorrowRateMode(gho, *)
    • borrow(gho, *, *, *, AVATAR)
  • gnosis_omni_bridge.relayTokens(gno, AVATAR, *)
  • curve_pool_ethoeth
    • approve
      • curve_gauge_ethoeth
      • convex_booster
    • add*liquidity(*, *)
    • remove_liquidity_one_coin(*, *, *)
    • exchange(*, *, *, *)
    • remove_liquidity(*, *)
    • remove_liquidity_imbalance(*, *)
  • oeth_zapper.deposit(*)
  • usdc.approve(balancer_vault)
  • susds
    • approve(cow_relayer)
    • deposit(*, AVATAR)
    • withdraw(*, AVATAR, AVATAR)
    • redeem(*, AVATAR, AVATAR)
  • stakewise: genesis vault (StakeWise | Vault)
    • burnOsTokens(*)
    • updateStateAndDeposit(AVATAR, *, *, *)
    • updateState(*)
    • mintOsTokens(AVATAR, *, *)
    • claimExitedAssets(*, *, *)
    • enterExitQueue(*, AVATAR)
    • deposit(AVATAR, *)
  • balancer_vault.swap (always with sender and receiver as AVATAR)
    • ghousdcusdt: usdc OR usdt → gho
    • ghousdcusdt: gho → usdc OR usdt
    • sdaigyd: sdai OR gyd → sdai OR gyd
    • sdaigyd(2): sdai OR gyd → sdai OR gyd
    • ghogyd: gho OR gyd → gho OR gyd
    • usdcgyd: usdc OR gyd → usdc OR gyd
    • usdtgyd: usdt OR gyd → usdt OR gyd
  • convex_ethoeth.approve(convex_gauge_ethoeth)
  • curve_gauge_ethoeth
    • withdraw(*)
    • deposit(*)
    • claim_rewards()
  • curve_minter.mint(curve_gauge_ethoeth)
  • usdt.approve(balancer_vault)
  • usds.approve
    • aave_pool_v3
    • susds
    • cow_relayer
    • dai_sdai_migrator
  • gyd.approve
    • balancer_vault
    • cow_relayer
  • sgyd
    • deposit(*, AVATAR)
    • redeem(*, AVATAR, AVATAR)
  • oseth.approve(aave_pool_v3)
  • covex_booster
    • deposit(ethoeth, *, *)
    • withdraw(ethoeth, *)
    • depositAll(ethoeth, *)
  • dai_sdai_migrator
    • migrateDAIToSUSDS(AVATAR, *)
    • downgradeUSDSToDAI(AVATAR, *)
    • migrateDAIToUSDS(AVATAR, *)

permissions that were scoped that now become unscoped

  • cow_order_signer
    • unsignOrder(*)

permissions removed

  • uniswap_nft
    • refundETH()
    • unwrapWETH9()
    • sweepToken()

notes

  • maverick_pool_ghostkgho is unverified on etherscan (Maverick, Contract Address 0x9f274d28fedce05153f9c810b8070277eaf8c031 | Etherscan)
  • why scope cow swap orders so granularly? eg why make it explicit that usds should be swappable to dai but not the other way around? i do not see the added value of this
  • why scope the tokens for every balancer pool?
  • why scope curve minter?
  • why remove permissions already granted, such as the uniswap eth methods?
  • for the amb bridge; expected value at shift 76 is 0101806401, which for me translates to:
    • srcChainIdLength: 01 == 1
    • dstChainIdLength: 01 == 1
    • dataType: 80 == 128
    • sourceChainId: 64 == 100
    • destinationChainId: 01 == 1
    • do i understand correctly these are thus payloads to bridge from gnosis chain to mainnet? should it not be the other way around? or is this the claiming of a bridge initiated on the gnosis chain side?

resources

to be able to continue doing proper reviews, without it costing us too much time, i suggest that going forward the zodiac roles ui is updated to at least have:

  • proper decoding for all function selectors
  • the option to use an (external) address book for labelling addresses (for example the same way the avatar is labelled as AVATAR). a tooltip or something like that could then show the original hex data

Hey @Gosuto !

We greatly appreciate the effort involved in auditing these payloads. We recognise that they are intricate and require substantial time to evaluate thoroughly.

As for your concerns:

  1. Unverified Maverick contract on Etherscan.
    1. The deployer of this contract is aavechan.eth, who are a recognized member of the Aave community. However, we will do our best to reach out to them and have the contract verified.
  2. Why scope tokens allowed to swap on CoW and Balancer.
    2. We could remove restrictions on which tokens can be sold or purchased. However, this approach ensures the DAO has complete certainty that the managed treasury will never be exposed to undesired or illiquid assets.
  3. Why scope curve minter?
    3. oETH / ETH is the only Curve pool we have allowlisted thus far for the managed treasury. Providing transparency on the actions we, as Asset Managers, are authorised to execute—and being able to easily identify the available actions for each gauge when more are introduced—is simply a matter of structure.
  4. Why remove permissions already granted.
    4. Permissions are removed to streamline the payload, ensuring it reflects only the currently active permissions. As market conditions shift, contracts are upgraded, or the DAO decides to abandon a strategy, permissions are updated accordingly to simplify execution and auditing.
    5. We’ve disabled native ETH deposits in Uniswap V3 Positions to avoid complications that the Zodiac Pilot was facing, WETH deposits remain available and avoids these issues.
  5. You are correct, the Arbitrary Message Bridge (AMB) is indeed a contract that allows receiving assets from Gnosis Chain on Mainnet. As this proposal was launched at the same time as the PUR#6 [BIP 732] we thought it was prudent to add this functionality in both chains. You can read more about AMB contracts here.

wonderful, lets see if that contract can still get verified. the rest of your comments make sense.

any feedback on my proposed changes for the zodiac roles ui?

1 Like