Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

vinica_boy - Initial AMM price ratio can be manipulated #168

Closed
sherlock-admin3 opened this issue Sep 10, 2024 · 0 comments
Closed

vinica_boy - Initial AMM price ratio can be manipulated #168

sherlock-admin3 opened this issue Sep 10, 2024 · 0 comments
Labels
Duplicate A valid issue that is a duplicate of an issue with `Has Duplicates` label Medium A Medium severity issue. Reward A payout will be made for this issue

Comments

@sherlock-admin3
Copy link

sherlock-admin3 commented Sep 10, 2024

vinica_boy

High

Initial AMM price ratio can be manipulated

Summary

When providing liquidity to the AMM during new DS issuance, when depositing to the vault, or with fees, the protocol checks the current price ratio of RA:CT in order to calculate how much RA and CT are needed to be sent to the pair. Current implementation account for the case where the pool might be empty and calculating the ratio based on the reserves in it wont work. This provides an opportunity for attackers to manipulate the price ratio before the first provision of liquidity.

Vulnerability Detail

____getAmmCtPriceRatio() is used to get the current RA:CT price ration in the AMM.

function __getAmmCtPriceRatio(State storage self, IDsFlashSwapCore flashSwapRouter, uint256 dsId)
        internal
        view
        returns (uint256 ratio)
    {
        // This basically means that if the reserve is empty, then we use the default ratio supplied at deployment
        ratio = self.ds[dsId].exchangeRate() - self.vault.initialDsPrice;

        // will always fail for the first deposit
        try flashSwapRouter.getCurrentPriceRatio(self.info.toId(), dsId) returns (uint256, uint256 _ctRatio) {
            ratio = _ctRatio;
        } catch {}
    }

Since Ethereum’s mainnet has a public mempool, attackers can monitor when the first vault deposit is about to occur. It is expected that the initial liquidity provision will use a specific price ratio set by the protocol. However,since the AMM pair is empty, an attacker can frontrun the transaction by providing a small amount of liquidity to the pool first. This allows the attacker to set an incorrect RA:CT price ratio that deviates significantly from the expected initial ratio.

Consider the following scenario: (for simplicity AMM X*Y =K is not correct in the current example, but is close to a correct one)
1. New issuance has occured with exchange rate between RA:CT+DS = 1.
2. Attacker mints 10 CT + 10 DS by providing 10 RA
3. Another user decide to deposit 50 RA to the LV
4. It is expected that liquidty sent to the AMM would be ~50% RA ~ 50% CT
5. Attacker frontrun the deposit transaction and deposits 1 RA and 0.1 CT
6. Now the price ration between RA:CT would be much higher than expected.
7. Only small amount of the user's 50 RA would be used to mint CT and almost all of it(RA) are going to be provided to the pair
8. New pair reserves are going to be ~45 RA and 4.5 CT
9. Now attacker can provide his CT tokens in order to get more RA than initially invested.

This deviation from the initial price would persist over time, undermining the protocol’s core functionality and making it unusable. The issue arises because the protocol does not provide initial liquidity to the newly created pair, leaving it vulnerable to manipulation. Without setting the initial price through a controlled liquidity provision, attackers can easily deviate the RA:CT price ratio, causing long-term imbalances that disrupt the protocol's intended operations.

Impact

Protocol is going to be completely unusable as intended.

Code Snippet

VaultLib.onNewIssuance():
https://github.com/sherlock-audit/2024-08-cork-protocol/blob/db23bf67e45781b00ee6de5f6f23e621af16bd7e/Depeg-swap/contracts/libraries/VaultLib.sol#L92
VaultLib.deposit():
https://github.com/sherlock-audit/2024-08-cork-protocol/blob/db23bf67e45781b00ee6de5f6f23e621af16bd7e/Depeg-swap/contracts/libraries/VaultLib.sol#L191
VaultLib.provideLiquidityWithFee():
https://github.com/sherlock-audit/2024-08-cork-protocol/blob/db23bf67e45781b00ee6de5f6f23e621af16bd7e/Depeg-swap/contracts/libraries/VaultLib.sol#L602
VaultLib.__getAmmCtPriceRatio():
https://github.com/sherlock-audit/2024-08-cork-protocol/blob/db23bf67e45781b00ee6de5f6f23e621af16bd7e/Depeg-swap/contracts/libraries/VaultLib.sol#L139

Tool used

Manual Review

Recommendation

Always provide initial liquidity to newly created pairs to set the initial price ratio.

Duplicate of #186

@github-actions github-actions bot added Duplicate A valid issue that is a duplicate of an issue with `Has Duplicates` label Medium A Medium severity issue. labels Sep 14, 2024
@cvetanovv cvetanovv removed the Medium A Medium severity issue. label Sep 24, 2024
@sherlock-admin3 sherlock-admin3 changed the title Raspy Silver Finch - Initial AMM price ratio can be manipulated vinica_boy - Initial AMM price ratio can be manipulated Sep 25, 2024
@sherlock-admin3 sherlock-admin3 added Non-Reward This issue will not receive a payout and removed Duplicate A valid issue that is a duplicate of an issue with `Has Duplicates` label labels Sep 25, 2024
@WangSecurity WangSecurity added Duplicate A valid issue that is a duplicate of an issue with `Has Duplicates` label Medium A Medium severity issue. labels Oct 17, 2024
@sherlock-admin2 sherlock-admin2 added Reward A payout will be made for this issue and removed Non-Reward This issue will not receive a payout labels Oct 17, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Duplicate A valid issue that is a duplicate of an issue with `Has Duplicates` label Medium A Medium severity issue. Reward A payout will be made for this issue
Projects
None yet
Development

No branches or pull requests

4 participants