-
Notifications
You must be signed in to change notification settings - Fork 8
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Some ETH amount can be leftover and locked in DepositQueue
contract
#252
Comments
Expected Behaviour. The leftover ETH in deposit queue is not considered as bug in the protocol. |
Tbh, filling the WithdrawBuffer with the ETH balance of DepositQueue, instead of just with the last deposit, makes quite some sense. It's not clear that the impact ot the protocol is significant, so downgrading to QA, but still it is a good idea. |
alcueca changed the severity to QA (Quality Assurance) |
alcueca marked the issue as grade-a |
alcueca marked the issue as grade-b |
Hi @alcueca, thanks for judging! The following scenarios can occur in sequence for the issue described by this report.
Then, if continuing from Step 5:
Furthermore, if continuing from Step 8:
Since there is no guarantee that the leftover ETH amount in the
Historically, C4 issues, such as code-423n4/2023-01-ondo-findings#265, and external issues, such as sherlock-audit/2024-03-zivoe-judging#113, that show the possibility of funds being leftover in a contract were considered as medium risk issues. Similarly, this report also demonstrates such possibility that is a leak value case, which fits in the medium risk's criteria stated in https://docs.code4rena.com/awarding/judging-criteria/severity-categorization#estimating-risk that is For the reasons above, would this report be re-evaluated to be a medium risk issue? |
While I agree with the warden that the implementation is not great (a single buffer for deposits and withdrawals might make more sense), none of the scenarios presented is severe enough, exploitable enough, or sustained enough to warrant a medium rating. Under normal operations, the protocol will work without excessive complaint from the users. No funds will be lost either. |
Lines of code
https://github.com/code-423n4/2024-04-renzo/blob/549f774626b71dd13a427561d4743535a9cc0dca/contracts/RestakeManager.sol#L592-L616
https://github.com/code-423n4/2024-04-renzo/blob/549f774626b71dd13a427561d4743535a9cc0dca/contracts/Deposits/DepositQueue.sol#L123-L126
https://github.com/code-423n4/2024-04-renzo/blob/549f774626b71dd13a427561d4743535a9cc0dca/contracts/Deposits/DepositQueue.sol#L294-L306
https://github.com/code-423n4/2024-04-renzo/blob/549f774626b71dd13a427561d4743535a9cc0dca/contracts/Deposits/DepositQueue.sol#L187-L206
https://github.com/code-423n4/2024-04-renzo/blob/549f774626b71dd13a427561d4743535a9cc0dca/contracts/Deposits/DepositQueue.sol#L211-L250
Vulnerability details
Impact
Calling the following
RestakeManager.depositETH
function would call theDepositQueue.depositETHFromProtocol
andDepositQueue._checkAndFillETHWithdrawBuffer
functions below, which would fill the ETH withdraw buffer in theWithdrawQueue
contract. When the ETH withdraw buffer becomes full, calling theRestakeManager.depositETH
function would cause the part ofmsg.value
that is not used for filling the ETH withdraw buffer to remain in theDepositQueue
contract sincebufferToFill
would be 0 or less thanmsg.value
when calling theDepositQueue._checkAndFillETHWithdrawBuffer
function. Over time, the leftover ETH amount would accumulate in theDepositQueue
contract.https://github.com/code-423n4/2024-04-renzo/blob/549f774626b71dd13a427561d4743535a9cc0dca/contracts/RestakeManager.sol#L592-L616
https://github.com/code-423n4/2024-04-renzo/blob/549f774626b71dd13a427561d4743535a9cc0dca/contracts/Deposits/DepositQueue.sol#L123-L126
https://github.com/code-423n4/2024-04-renzo/blob/549f774626b71dd13a427561d4743535a9cc0dca/contracts/Deposits/DepositQueue.sol#L294-L306
When the leftover ETH amount does not accumulate to 32 ETH, calling the following
DepositQueue.stakeEthFromQueue
andDepositQueue.stakeEthFromQueueMulti
functions would revert. When the leftover ETH amount accumulates to exceed 32 ETH, calling theDepositQueue.stakeEthFromQueue
andDepositQueue.stakeEthFromQueueMulti
functions would cause the surplus ETH amount after subtracting 32 ETH or multiples of 32 ETH to still be leftover. Since there is no guarantee that the leftover ETH amount would always accumulate to multiples of 32 ETH, it is likely that some ETH amount would remain in theDepositQueue
contract.https://github.com/code-423n4/2024-04-renzo/blob/549f774626b71dd13a427561d4743535a9cc0dca/contracts/Deposits/DepositQueue.sol#L187-L206
https://github.com/code-423n4/2024-04-renzo/blob/549f774626b71dd13a427561d4743535a9cc0dca/contracts/Deposits/DepositQueue.sol#L211-L250
Besides the
DepositQueue.depositETHFromProtocol
function, the followingDepositQueue.forwardFullWithdrawalETH
andDepositQueue.receive
functions also call theDepositQueue._checkAndFillETHWithdrawBuffer
function for filling the ETH withdraw buffer. However, theseDepositQueue.depositETHFromProtocol
,DepositQueue.forwardFullWithdrawalETH
, andDepositQueue.receive
functions can only fill the ETH withdraw buffer with all or part ofmsg.value
. Hence, there is no way to use these leftover ETH of theDepositQueue
contract for filling the ETH withdraw buffer, and such leftover ETH would continue to remain and be locked in theDepositQueue
contract. While some ETH amount is leftover and locked in theDepositQueue
contract, another consequence is that after some depositors have withdrawn some of the available ETH amount to withdraw, for an unpredictable duration, which can be very long, when no or an insufficient ETH amount is deposited through the restake manager, is withdrawn from an operator delegator, and is sent to theDepositQueue
contract from outside the protocol, at least one depositor would be blocked from withdrawing all of her or his entitled ETH amount using her or his ezETH because the ETH withdraw buffer is not enough to cover her or his full ETH withdrawal.https://github.com/code-423n4/2024-04-renzo/blob/549f774626b71dd13a427561d4743535a9cc0dca/contracts/Deposits/DepositQueue.sol#L152-L156
https://github.com/code-423n4/2024-04-renzo/blob/549f774626b71dd13a427561d4743535a9cc0dca/contracts/Deposits/DepositQueue.sol#L163-L183
Proof of Concept
Please add the following test file. Using
forge
, thistest_ethCanBeLeftoverInDepositQueue
test will pass to demonstrate the described scenario.Tools Used
Manual Review
Recommended Mitigation Steps
The
DepositQueue
contract can be updated to add a function, which is only callable by the trusted protocol admin, for transferring theDepositQueue
contract's leftover ETH to fill theWithdrawQueue
contract's ETH withdraw buffer.Assessed type
ETH-Transfer
The text was updated successfully, but these errors were encountered: