Pending withdrawals prevent safe removal of collateral assets
mediumLines of code
https://github.com/code-423n4/2024-04-renzo/blob/main/contracts/RestakeManager.sol#L244 https://github.com/code-423n4/2024-04-renzo/blob/main/contracts/RestakeManager.sol#L316-L321 https://github.com/code-423n4/2024-04-renzo/blob/main/contracts/Withdraw/WithdrawQueue.sol#L279
Vulnerability details
The RestakeManager contract allows the admin to add and remove collateral tokens that are accepted for deposits into the protocol via the addCollateralToken() and removeCollateralToken() functions.
From the protocol team:
[In order to] remove a collateral token we can withdraw full and increase the withdraw buffer to let users withdraw it.
However, since users cannot be forced to claim their withdrawals, it is always possible that a significant amount of the collateral token remains in the WithdrawQueue indefinitely in outstanding withdrawals.
In that case, calling removeCollateralToken() for that token would break accounting in the protocol. The ezETH total supply would still reflect the amounts that were burned to initiate those withdrawals, but the token balance in the WithdrawQueue would no longer be counted towards the TVL.
Impact
The RestakeManager admin is unable to safely remove a collateral token. Removing the token anyway would inflate the ezETH mint and redeem rate compared to the actual backing collateral value.
Proof of Concept
Assume token1 has a balance of Y in the WithdrawQueue from pending user withdrawals. If removeCollateralToken(token1) is called:
token1is removed from thecollateralTokensarraytoken1balance ofYis still inWithdrawQueuebut no longer counted intotalTVL- Mint rate for
ezETHincreases sincetotalTVLis lower butezETHtotal supply is unchanged - Redeem rate for
ezETHalso increases sinceezETHis now redeemable for a larger share of the remaining collateral
The mint and redeem rates for ezETH are now inflated compared to the true value of the collateral backing it, since Y worth of token1 is not accounted for in totalTVL but is still effectively backing the ezETH that was burned to withdraw it.
Tools Used
Manual review
Recommended Mitigation Steps
Consider forcing pending withdrawals of a token to be claimed before that token can be removed as collateral. This could be done by only allowing removeCollateralToken() to be called if claimReserve[token] == 0.
Alternatively, include the balance of the WithdrawQueue in the TVL calculation even for tokens that have been removed, as long as there are still pending withdrawals of that token. This would ensure mint and redeem rates remain correct.
Assessed type
Other
