-
Notifications
You must be signed in to change notification settings - Fork 1
nobody2018 - mintRollovers does not update rolloverAccounting[_epochId] causing stuck #176
Comments
Escalate for 10 USDC
I don't think this is a duplicate of #62. |
You've created a valid escalation for 10 USDC! To remove the escalation from consideration: Delete your comment. You may delete or edit your escalation comment anytime before the 48-hour escalation window closes. After that, the escalation becomes final. |
Escalation accepted Although not a duplicate of #174, after further consideration, this issue is marked as a duplicate of #172 based on the large rolloverQueue. |
This issue's escalations have been accepted! Contestants' payouts and scores will be updated according to the changes made on this issue. |
nobody2018
high
mintRollovers does not update rolloverAccounting[_epochId] causing stuck
Summary
For each epochId, if the rolloverQueue is too long, the relayer will call
mintRollovers
multiple times to process the entire rolloverQueue. One block has a maximum gas limit, so relayer cannot process too many QueueItem at one time. The rolloverAccounting mapping records the currently processed rolloverQueue location for each epochId. However, at the end ofmintRollovers
, rolloverAccounting[_epochId] is updated only if executions > 0.executions
are only incremented by 1 if the QueueItem has won the current epoch and QueueItem.asset is bigger than relayerFee. Assuming that the maximum number of QueueItems that can be processed each time is 100, if none of the first 100 QueueItems in the rolloverQueue can increaseexecutions
, thenrolloverAccounting[_epochId]
will always be 0. No matter how many times the relayer callsmintRollovers
, it keeps looping through the first 100 QueueItems without moving forward.Vulnerability Detail
Due to the maximum block gas limit, we assume that
mintRollovers
can process at most 100 QueueItems at a time. Therefore, the relayer cannot change this number arbitrarily. If it is changed to a larger value, the trade will be reverted. Let's assume the following scenario:relayerFee is 1e18. The current epochId is E1, and the next epochId is E2. At present,
rolloverQueue
has 50 normal userQueueItem
. Bob has deposited 100e18 assets before the start of E1, sobalanceOf(bob, E1) = 100e18
.Bob creates 100 addresses, each address has
setApprovalForAll
to bob. He calls two functions for each address:Carousel.safeTransferFrom(bob, eachAddress, E1, 1e18)
Carousel.enlistInRollover(E1, 1e18, eachAddress)
, 1e18 equal to minRequiredDeposit.rolloverQueue.length
equals to 150(100+50).As time goes by, E1 ends. The relayer calls mintRollovers(E1, 100) twice, and the entire queue has been processed.
50 normal user has called
delistInRollover
to exit the rolloverQueue. Now, rolloverQueue only has QueueItems for those 100 addresses created by bob. These 100 QueueItem stay in rolloverQueue forever.E2 is coming. The new user's QueueItem(for E2) is pushed to the rolloverQueue, at the end of the queue.
As time goes by, E2 ends. The relayer calls mintRollovers(E2, 100) many times, rolloverAccounting[E2] is always 0.
Let's explain why the QueueItem of these 100 addresses does not increase the
executions
variable. There are two cases here:executions
will be not increased.executions
will be not increased also.As mentioned above, starting from E2,
mintRollovers
will always be stuck at the front 100 QueueItem.Impact
mintRollovers
never work properly.mintRollovers
cannot get the relayerFee from Carousel.Code Snippet
https://github.com/sherlock-audit/2023-03-Y2K/blob/main/Earthquake/src/v2/Carousel/Carousel.sol#L361-L459
Tool used
Manual Review
Recommendation
if (executions > 0)
.Duplicate of #172
The text was updated successfully, but these errors were encountered: