Open sherlock-admin3 opened 8 months ago
Valid bug - currentEpochsByAsset[asset] += 1;
should be called in queueCurrentEpochSettlement
.
The protocol team fixed this issue in the following PRs/commits: https://github.com/rio-org/rio-sherlock-audit/pull/1
The protocol team fixed this issue in PR/commit rio-org/rio-sherlock-audit#1.
Fixed The epoch is now incremented inside queueCurrentEpochSettlement function
The Lead Senior Watson signed off on the fix.
popular
high
Creating new withdrawal requests in conjunction with
settleEpochFromEigenLayer
will render system unusableSummary
This issue pertains to the flow where a user requests to withdraw more funds than are currently present in the
depositPool
and the system must withdraw from Eigenlayer.Users are able to create new withdrawal requests for the current epoch while the Eigenlayer withdrawal request is pending, as well as after the epoch has been marked
settled
insettleEpochFromEigenLayer()
. This is due to the fact thatsettleEpochFromEigenLayer()
does not increment the current epoch, as well as that there is no way to fulfill withdrawal requests submitted after the 7 day waiting period has been initiated. Submitting a withdrawal request will result in an inability to progress epochs and a locking of the system.Vulnerability Detail
Consider the system in the following state:
depositPool
rebalance() --> withdrawalQueue_.queueCurrentEpochSettlement()
has been calledRioLRTWithdrawalQueue:settleEpochFromEigenLayer()
linkThe function
settleEpochFromEigenLayer()
performs several important tasks - completing pending withdrawals from Eigenlayer, accounting for the amounts received, burning the appropriate amount of LRTs, and marking the epoch as settled. It does NOT increment the epoch counter for the asset - the only way to do that is insettleCurrentEpoch()
, which is only called inrebalance()
when there is enough present in thedepositPool
to cover withdrawals.After calling
settleEpochFromEigenLayer()
, the system is in a state where the current epoch has been marked as settled. However, while waiting for the 7 day Eigenlayer delay it is possible that more users sent withdrawal requests. These withdrawal requests would be queued for epoch 0 (and incrementsharesOwed
for epoch 0) , but were not considered when performing the withdrawal from Eigenlayer. There is no way to process these requests, as the epoch has already been settled + we can only callqueueCurrentEpochSettlement
once per epoch due to theif (epochWithdrawals.aggregateRoot != bytes32(0)) revert WITHDRAWALS_ALREADY_QUEUED_FOR_EPOCH();
checkNotably, users that requested withdrawals have already sent the LRT amount to be burned and are unable to reclaim their funds.
Also note that there is no access control on
settleEpochFromEigenLayer()
, so as long as the provided withdrawal parameters are correct anybody can call the function.Impact
Critical - system no longer operates, loss of users funds
Code Snippet
The following test can be dropped into
RioLRTWithdrawalQueue.t.sol
Tool used
Manual Review
Recommendation
Consider incrementing the current epoch as soon as the withdrawal process has been initiated, such that user withdrawal requests sent after an epoch has been queued for settlement will be considered a part of the next epoch