You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
This repository has been archived by the owner on Oct 1, 2023. It is now read-only.
sherlock-admin opened this issue
Mar 27, 2023
· 0 comments
Labels
DuplicateA valid issue that is a duplicate of an issue with `Has Duplicates` labelHighA valid High severity issueRewardA payout will be made for this issue
Updating rollover details in enlistInRollover for one user overrides existing rollover details of another user
Summary
enlistInRollover is used to create/update new/existing rollover requests by users for a given epoch Id. Current implementation assigns a wrong roll-over index when updating roll-over details. This can be exploited by a malicious user who can delist the roll-over details placed by other users & even worse, steal funds of other users by replacing receiver address with his own
Vulnerability Detail
enlistRollover in Carousel allows users to place new roll-over requests or update existing roll-over requests.
Note that, when an existing roll-over request for a receiver is updated, on line 268, the ownerToRollOverQueueIndex for that receiver is updated to the last element in the rolloverQueue although the position of the actual request is unchanged. getRolloverIndex for the receiver will now point to the last index that belongs to different user.
User can then call delistInRollover and delete roll-over requests of other users. Another serious attack here is, a user can overwrite the receiver address of a roll-over request that has a higher asset value. Assets and emissions of another receiver can get minted to malicious user who changed the receiver address when mintRollovers is called.
function enlistInRollover(
uint256_epochId,
uint256_assets,
address_receiver
) publicepochIdExists(_epochId) minRequiredDeposit(_assets) {
// check if sender is approved by ownerif (
msg.sender!= _receiver &&isApprovedForAll(_receiver, msg.sender) ==false
) revertOwnerDidNotAuthorize(msg.sender, _receiver);
// check if user has enough balanceif (balanceOf(_receiver, _epochId) < _assets)
revertInsufficientBalance();
// check if user has already queued up a rolloverif (ownerToRollOverQueueIndex[_receiver] !=0) {
// if so, update the queueuint256 index =getRolloverIndex(_receiver);
rolloverQueue[index].assets = _assets;
rolloverQueue[index].epochId = _epochId;
} else {
// if not, add to queue
rolloverQueue.push(
QueueItem({
assets: _assets,
receiver: _receiver,
epochId: _epochId
})
);
}
ownerToRollOverQueueIndex[_receiver] = rolloverQueue.length; //@audit -> this should only be done for new requestemitRolloverQueued(_receiver, _assets, _epochId);
}
Impact
A user can delete other users roll-over requests at will & even worse, can change receiver address of other user's roll-over requests with higher asset value
The line 268 is only applicable for new roll-over requests and should be inside the else rather than outside.
if (ownerToRollOverQueueIndex[_receiver] !=0) {
// if so, update the queueuint256 index =getRolloverIndex(_receiver);
rolloverQueue[index].assets = _assets;
rolloverQueue[index].epochId = _epochId;
} else {
// if not, add to queue
rolloverQueue.push(
QueueItem({
assets: _assets,
receiver: _receiver,
epochId: _epochId
})
);
ownerToRollOverQueueIndex[_receiver] = rolloverQueue.length; // @audit - this is inside the `else` flow
}
Sign up for freeto subscribe to this conversation on GitHub.
Already have an account?
Sign in.
Labels
DuplicateA valid issue that is a duplicate of an issue with `Has Duplicates` labelHighA valid High severity issueRewardA payout will be made for this issue
0Kage
high
Updating rollover details in
enlistInRollover
for one user overrides existing rollover details of another userSummary
enlistInRollover
is used to create/update new/existing rollover requests by users for a given epoch Id. Current implementation assigns a wrong roll-over index when updating roll-over details. This can be exploited by a malicious user who can delist the roll-over details placed by other users & even worse, steal funds of other users by replacingreceiver
address with his ownVulnerability Detail
enlistRollover
in Carousel allows users to place new roll-over requests or update existing roll-over requests.Note that, when an existing roll-over request for a
receiver
is updated, on line 268, theownerToRollOverQueueIndex
for that receiver is updated to the last element in therolloverQueue
although the position of the actual request is unchanged.getRolloverIndex
for the receiver will now point to the last index that belongs to different user.User can then call
delistInRollover
and delete roll-over requests of other users. Another serious attack here is, a user can overwrite thereceiver
address of a roll-over request that has a higher asset value. Assets and emissions of another receiver can get minted to malicious user who changed thereceiver
address whenmintRollovers
is called.Impact
A user can delete other users roll-over requests at will & even worse, can change
receiver
address of other user's roll-over requests with higher asset valueCode Snippet
https://github.com/Y2K-Finance/Earthquake/blob/736b2e1e51bef6daa6a5ecd1decb7d156316d795/src/v2/Carousel/Carousel.sol#L268
Tool used
Manual Review
Recommendation
The line 268 is only applicable for new roll-over requests and should be inside the
else
rather than outside.Duplicate of #2
The text was updated successfully, but these errors were encountered: