A malicious user can deny user reward enlisted in rollover
Summary
A malicious user can edit rolloverQueue amounts for other users and to deprive of potential rewards.
Vulnerability Detail
Developer intention was to set an unique index for each user enlisted in rollover and save it to ownerToRollOverQueueIndex.
But when an already enlisted user edits his entries, ownerToRollOverQueueIndex[_receiver] is set to the rolloverQueue.length.
Let's take an example:
Alice calls enlistInRollover for the first time with 100 assets
ownerToRollOverQueueIndex[Allice] = 1
rolloverQueue[0] is Alices data - OK
Bob calls enlistInRollover for the first time with 100 assets
ownerToRollOverQueueIndex[Bob] = 2
rolloverQueue[1] is Bobs data -> OK
Allice calls for the 2nd time enlist in rollover with same amount, 100:
Since Allice was prevously enrolled, getRolloverIndex returns 1-1 = 0 -> OK
function getRolloverIndex(address _owner) public view returns (uint256) {
return ownerToRollOverQueueIndex[_owner] - 1;
}
rolloverQueue[0] is updated - OK
ownerToRollOverQueueIndex[Allice] = 2 -> inccorectly updated to the rolloverQueue.length
Alice calls for the 3rd time enlistInRollover with relayerFee amount.
getRolloverIndex returns 2-1 = 1 -> NOK( since it's Bobs index )
rolloverQueue[1] is Bobs data ( not Alices) and and queue[index].assets is set to relayerFee.
AlexCzm
high
A malicious user can deny user reward enlisted in rollover
Summary
A malicious user can edit rolloverQueue amounts for other users and to deprive of potential rewards.
Vulnerability Detail
Developer intention was to set an unique index for each user enlisted in rollover and save it to
ownerToRollOverQueueIndex
. But when an already enlisted user edits his entries,ownerToRollOverQueueIndex[_receiver]
is set to the rolloverQueue.length.Let's take an example:
Alice calls
enlistInRollover
for the first time with 100 assets ownerToRollOverQueueIndex[Allice] = 1 rolloverQueue[0] is Alices data - OKBob calls
enlistInRollover
for the first time with 100 assets ownerToRollOverQueueIndex[Bob] = 2 rolloverQueue[1] is Bobs data -> OKAllice calls for the 2nd time enlist in rollover with same amount, 100: Since Allice was prevously enrolled,
getRolloverIndex
returns 1-1 = 0 -> OKrolloverQueue[0] is updated - OK ownerToRollOverQueueIndex[Allice] = 2 -> inccorectly updated to the
rolloverQueue.length
Alice calls for the 3rd time
enlistInRollover
withrelayerFee
amount.getRolloverIndex
returns 2-1 = 1 -> NOK( since it's Bobs index ) rolloverQueue[1] is Bobs data ( not Alices) and andqueue[index].assets
is set torelayerFee
.When relayer will call
mintRollovers
Bob will getassets - relayerFee
which is 0 shares. Moreover, Bob will not get his share of premium/ collateral for the assets amount he enlisted in rollover. https://github.com/sherlock-audit/2023-03-Y2K/blob/main/Earthquake/src/v2/Carousel/Carousel.sol#L436Impact
Users can loose relayerFee amount + potential reward from premium/ collateral.
Code Snippet
https://github.com/sherlock-audit/2023-03-Y2K/blob/main/Earthquake/src/v2/Carousel/Carousel.sol#L238-L271
Tool used
Manual Review
Recommendation
Move
ownerToRollOverQueueIndex[_receiver] = rolloverQueue.length;
in same branch where QueueItem is pushed to rolloverQueueDuplicate of #2