Skip to content
This repository has been archived by the owner on Oct 1, 2023. It is now read-only.

p0wd3r - In certain situations, legitimate users may not be able to participate in Rollover. #41

Closed
sherlock-admin opened this issue Mar 27, 2023 · 0 comments
Labels
Duplicate A valid issue that is a duplicate of an issue with `Has Duplicates` label Medium A valid Medium severity issue Reward A payout will be made for this issue

Comments

@sherlock-admin
Copy link
Contributor

sherlock-admin commented Mar 27, 2023

p0wd3r

high

In certain situations, legitimate users may not be able to participate in Rollover.

Summary

In certain situations, legitimate users may not be able to participate in Rollover.

Vulnerability Detail

In mintRollovers, there is the following code, which only performs roll over for those who had an increase in assets in the previous epoch.

https://github.com/Y2K-Finance/Earthquake/blob/736b2e1e51bef6daa6a5ecd1decb7d156316d795/src/v2/Carousel/Carousel.sol#L400

uint256 entitledShares = previewWithdraw(
                    queue[index].epochId,
                    queue[index].assets
);
// mint only if user won epoch he is rolling over
if (entitledShares > queue[index].assets) {

However, in the following two cases, users' assets will remain unchanged in a resolved epoch.

  1. The epoch ends up being a Null epoch, and the assets of the party with non-zero TVL do not change.

https://github.com/Y2K-Finance/Earthquake/blob/736b2e1e51bef6daa6a5ecd1decb7d156316d795/src/v2/Controllers/ControllerPeggedAssetV2.sol#L231

//set claim TVL to final TVL if total assets are 0
        if (premiumVault.totalAssets(_epochId) == 0) {
            premiumVault.resolveEpoch(_epochId);
            collateralVault.resolveEpoch(_epochId);

            premiumVault.setClaimTVL(_epochId, 0);
            collateralVault.setClaimTVL(
                _epochId,
                collateralVault.finalTVL(_epochId) //@audit claimTVL == finalTVL previewWithdraw == asset
            );

            collateralVault.setEpochNull(_epochId);
  1. Depeg is triggered, but collateralTVL - collateralFee == premiumTVL.

https://github.com/Y2K-Finance/Earthquake/blob/736b2e1e51bef6daa6a5ecd1decb7d156316d795/src/v2/Controllers/ControllerPeggedAssetV2.sol#L106

        premiumVault.setClaimTVL(_epochId, collateralTVL - collateralFee);
        collateralVault.setClaimTVL(_epochId, premiumTVL - premiumFee);

        // send fees to treasury and remaining TVL to respective counterparty vault
        // strike price reached so premium is entitled to collateralTVL - collateralFee
        premiumVault.sendTokens(_epochId, premiumFee, treasury);
        premiumVault.sendTokens(
            _epochId,
            premiumTVL - premiumFee,
            address(collateralVault)
        );
        // strike price is reached so collateral is still entitled to premiumTVL - premiumFee but looses collateralTVL
        collateralVault.sendTokens(_epochId, collateralFee, treasury);
        collateralVault.sendTokens(
            _epochId,
            collateralTVL - collateralFee,
            address(premiumVault)
        );

The implementation of previewWithdraw is as follows. As we can see, in the above two cases, where one party's claimTVL and finalTVL are the same, the return value of previewWithdraw is equal to queue[index].assets. Those legitimate users should be able to participate in roll over, but due to the existence of entitledShares > queue[index].assets, users cannot complete roll over.

https://github.com/Y2K-Finance/Earthquake/blob/736b2e1e51bef6daa6a5ecd1decb7d156316d795/src/v2/VaultV2.sol#L357

    function previewWithdraw(uint256 _id, uint256 _assets)
        public
        view
        override(SemiFungibleVault)
        returns (uint256 entitledAmount)
    {
        // entitledAmount amount is derived from the claimTVL and the finalTVL
        // if user deposited 1000 assets and the claimTVL is 50% lower than finalTVL, the user is entitled to 500 assets
        // if user deposited 1000 assets and the claimTVL is 50% higher than finalTVL, the user is entitled to 1500 assets
        entitledAmount = _assets.mulDivDown(claimTVL[_id], finalTVL[_id]);
    }

Impact

Legitimate users may not be able to participate in Rollover.

Code Snippet

https://github.com/Y2K-Finance/Earthquake/blob/736b2e1e51bef6daa6a5ecd1decb7d156316d795/src/v2/Carousel/Carousel.sol#L400
https://github.com/Y2K-Finance/Earthquake/blob/736b2e1e51bef6daa6a5ecd1decb7d156316d795/src/v2/Controllers/ControllerPeggedAssetV2.sol#L231
https://github.com/Y2K-Finance/Earthquake/blob/736b2e1e51bef6daa6a5ecd1decb7d156316d795/src/v2/Controllers/ControllerPeggedAssetV2.sol#L106
https://github.com/Y2K-Finance/Earthquake/blob/736b2e1e51bef6daa6a5ecd1decb7d156316d795/src/v2/VaultV2.sol#L357

Tool used

Manual Review + Vscode

Recommendation

entitledShares > queue[index].assets -> entitledShares >= queue[index].assets

Duplicate of #442

@github-actions github-actions bot closed this as completed Apr 3, 2023
@github-actions github-actions bot added Medium A valid Medium severity issue Duplicate A valid issue that is a duplicate of an issue with `Has Duplicates` label labels Apr 3, 2023
@sherlock-admin sherlock-admin added the Reward A payout will be made for this issue label Apr 11, 2023
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
Duplicate A valid issue that is a duplicate of an issue with `Has Duplicates` label Medium A valid Medium severity issue Reward A payout will be made for this issue
Projects
None yet
Development

No branches or pull requests

1 participant