sherlock-audit / 2023-03-Y2K-judging

7 stars 1 forks source link

carrot - Users lose premium gained when enrolled to `mintRollovers` #489

Closed sherlock-admin closed 1 year ago

sherlock-admin commented 1 year ago

carrot

high

Users lose premium gained when enrolled to mintRollovers

Summary

mintRollovers function in Carousel.sol is used to invest the winnings of one epoch into another epoch. The user must enlist into the system, which creates a QueueItem struct for the user, storing their position details. This function however does not take into account the change in the user's balance due to the premium earned, and only re-invests the old amount, losing the users premium.

Vulnerability Detail

mintRollovers is used to re-invest earnings from one epoch into another. It does this in a series of steps shown in the following steps.

First, it does some checks to make sure the user has won the epoch, and has enough funds to cover relayer fees.

if (queue[index].assets < relayerFee) {
    index++;
    continue;
    }

Next, it withdraws both the assets and the emissions, burning the positions.

_burn(
    queue[index].receiver,
    queue[index].epochId,
    queue[index].assets
);
_burnEmissions(
    queue[index].receiver,
    queue[index].epochId,
    queue[index].assets
);

It transfers out only the emissions, and then re-invests the assets (after deducting relayer fee) into another epoch.

uint256 assetsToMint = queue[index].assets - relayerFee;
    _mintShares(queue[index].receiver, _epochId, assetsToMint);

The code however never updates the value of queue[index].assets to reflect the new value after previous epoch ended. So the protocol only reinvests the old amount, which doesnt include the premium amount, and thus the end user loses all premium earnings. These earnings are sent to the carousel contract when the position is burnt, but they are never transferred out to the end user.

Impact

User unable to earn premium.

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

Update the value of queue[index].assets to reflect premium earned. The new value is already calculated and stored in the entitledShares variable, so a simple assignment before re-investing is enough.

queue[index].assets = entitledShares;

Duplicate of #163