Users that want to withdraw from Renzo can’t do it directly, and will be subject to a two-step process, where they will first need to create the withdrawal request by calling withdraw in the withdraw queue, and then actually obtain the tokens by triggering claim after waiting for a specified cooldown period:
As we can see, when creating a withdrawal block.timestamp will be passed as the createdAt field in the WithdrawRequest struct. Then, _withdrawRequest.createdAt will be substracted from block.timestamp to see if the minimum coolDownPeriod has passed.
The problem with this approach is that if coolDownPeriod is changed, then it will affect the currently queued withdrawals. This should not be the case, as currently queued withdrawals should only be limited by the cooldown period set in the moment of withdrawal.
For example, a situation could arise where a user submits a withdrawal request and the cooldown period in that moment is set to 7 days. After 4 days (3 days remaining to be able to claim the assets), the cooldown period is changed to 14 days. This will affect the user that initially queued the withdrawal for 7 days, making its waiting period extend by an additional 7 days.
Impact
Medium. Users that initially queued withdrawals with a certain duration could end up waiting more time than the expected to withdraw their assets.
Recommended Mitigation
Consider storing the end timestamp in a cooldownFinish field instead of storing the current block.timestamp in the createdAt when creating the withdrawRequests struct, and checking against it when performing the claim, like the following:
Lines of code
https://github.com/code-423n4/2024-04-renzo/blob/main/contracts/Withdraw/WithdrawQueue.sol#L287 https://github.com/code-423n4/2024-04-renzo/blob/main/contracts/Withdraw/WithdrawQueue.sol#L129-L133
Vulnerability details
Bug description
Users that want to withdraw from Renzo can’t do it directly, and will be subject to a two-step process, where they will first need to create the withdrawal request by calling
withdraw
in the withdraw queue, and then actually obtain the tokens by triggeringclaim
after waiting for a specified cooldown period:As we can see, when creating a withdrawal
block.timestamp
will be passed as thecreatedAt
field in theWithdrawRequest
struct. Then,_withdrawRequest.createdAt
will be substracted fromblock.timestamp
to see if the minimumcoolDownPeriod
has passed.The problem with this approach is that if
coolDownPeriod
is changed, then it will affect the currently queued withdrawals. This should not be the case, as currently queued withdrawals should only be limited by the cooldown period set in the moment of withdrawal.For example, a situation could arise where a user submits a withdrawal request and the cooldown period in that moment is set to 7 days. After 4 days (3 days remaining to be able to claim the assets), the cooldown period is changed to 14 days. This will affect the user that initially queued the withdrawal for 7 days, making its waiting period extend by an additional 7 days.
Impact
Medium. Users that initially queued withdrawals with a certain duration could end up waiting more time than the expected to withdraw their assets.
Recommended Mitigation
Consider storing the end timestamp in a
cooldownFinish
field instead of storing the currentblock.timestamp
in thecreatedAt
when creating thewithdrawRequests
struct, and checking against it when performing the claim, like the following:Tools used
Manual review
Assessed type
Other