Introduce ProtocolFeesWithdrawer


The recent issue involving double-entrypoint tokens, which includes SNX and sBTC, saw those tokens being transferred out of the Vault into the ProtocolFeeCollector. The multisig in charge of managing protocol fees renounced the permission to withdraw them, meaning these user funds are now solely controlled by the Balancer Governance multisig. Until the situation is resolved however, regular protocol fee withdrawal and distribution (including revenue for veBAL holders) is halted.

This proposal provides a mechanism to continue with protocol fee distribution while keeping SNX and sBTC from LPs safe.


We’ve developed a contract called ProtocolFeesWithdrawer, which forwards requests to withdraw tokens to the ProtocolFeesCollector, as long as the tokens are not included in a ‘denylist’ of tokens that cannot be withdrawn. This list can be updated by Balancer Governance.

By granting permission to the ProtocolFeesWithdrawer to withdraw from Collector, and to the original Safe to initiate withdrawals on the Withdrawer, the multisig will regain the ability to manage protocol fees, but will be unable to withdraw any SNX or sBTC.

I propose we make the Withdrawer part of our permanent infrastructure, since it adds very little overhead and allows for measures like this one to be taken. This is not the first instance we’ve seen of tokens incorrectly landing in the ProtocolFeeCollector, and we might want to make use of these capabilities again in the future.

Execution details

Call grantRolesToMany on the Authorizer, with:

  • roles: [0xb2b6e48fa160a7c887d9d7a68b6a9bb9d47d4953d33e07f3a39e175d75e97796, 0x826ac7ce861f2a54e071e6c724653757fdd1259804eb1ca7f040aa1cd09923fe]
  • accounts: [0x5ef4c5352882b10893b70DbcaA0C000965bd23c5, 0x7c68c42de679ffb0f16216154c996c354cf1161b]

This will grant role 0xb2b6…3ae6, which allows withdrawing from the FeeCollector (the same role renounced by the multisig) to the FeeWithdrawer. The address of the Withdrawer can be obtained from the Balancer Labs deployments repository.

The second role granted is 0x826a…23fe, which allows withdrawing from the Withdrawer to the original multisig at 0x7c68…161b. The role can be obtained by calling getActionId on the Withdrawer with 0x6daefab6, the selector of the withdrawCollectedFees(address[],uint256[],address) (i.e. the first eight bytes of that hash.


The ProtocolFeesWithdrawer is intentionally extremely simple to minimize smart contract risk. Its mitigations risk being uneffective in the case of double-entrypoint tokens if one of the entrypoints is updated before it can be added to the denylist - we’ve made the Synthetix team aware of this and they’ll report about any changes in advance.

Plans to fix the SNX and sBTC issue are unaffected by this, as we can always grant permission to withdraw them from the Collector to another contract down the line.