Lucene search

K
code423n4Code4renaCODE423N4:2023-08-SHELL-FINDINGS-ISSUES-272
HistoryAug 28, 2023 - 12:00 a.m.

Swaps affect LP token mint/burn during liquidity addition/removal

2023-08-2800:00:00
Code4rena
github.com
6
vulnerability
lp token
bonding curve
liquidity addition
price manipulation
amm
frontrun
sandwich attack
uni v3
smart contract
mev

AI Score

6.9

Confidence

Low

Lines of code

Vulnerability details

Impact

The LP token removal/addition forces a recalculation of the bonding curve, and the utility of the curve. The utility curve in proteus looks like the graph below, where the point A represents a certain composition of the pool.

ab1 +ve u

If we try to remove add/remove liquidity form the pool, the new utility value needs to be calculated, and the bonding curve basically shifts to accomodate the new state of the pool. Here the new state is shown by point B and the curve in blue.

Liquidity addition

The issues is that if the pool is at a different price C, and the new state goes to D due to the same amount of liquidity removal, the new point D is not on the bblue bonding curve. This shows that the final bonding curve due to liquidity addition/removal depends on the price in the AMM.

Thus users can manipulate the price in the AMM, and this affects how many tokens other users will get when they add/remove liquidity.

Proof of Concept

In this POC, a user adds liquidity of 1 ETH. The same action is repeated, but at a different price after a large swap.

It is shown that after the swap, the user gets less LP tokens for the same amount of ETH added. Thus attackers can frontrun large LP additions/removals to cause losses in this manner, essentially a form of sandwich attack. In protocols like Uni V3 this isnt possible since the users get to choose the exact price ticks they want to supply to.

function testAttack() public {
    uint256 x0 = 100e18;
    uint256 y0 = 100e18;
    uint256 s0 = 100e18;
    uint256 depositedAmount = 1e18;

    SpecifiedToken depositedToken = SpecifiedToken.X;
    uint256 minted1 = DUT.depositGivenInputAmount(
        x0,
        y0,
        s0,
        depositedAmount,
        depositedToken
    );

    emit log_named_uint("minted1", minted1);

    //swap
    uint256 swapvalX = 100e18;
    uint256 swapvalY = DUT.swapGivenInputAmount(
        x0,
        y0,
        swapvalX,
        SpecifiedToken.X
    );

    // New values
    uint256 x1 = x0 + swapvalX;
    uint256 y1 = y0 - swapvalY;

    uint256 minted2 = DUT.depositGivenInputAmount(
        x1,
        y1,
        s0,
        depositedAmount,
        depositedToken
    );

    emit log_named_uint("minted2", minted2);
}

The output shows:

Running 1 test for src/test/EvolvingProteusProperties.t.sol:EvolvingProteusProperties
[PASS] testAttack() (gas: 140259)
Logs:
  minted1: 6801162225772413
  minted2: 6718681842515858

This shows that the user got lesser amount of tokens in the second minting.

Tools Used

Foundry

Recommended Mitigation Steps

Develop a price resistant way of calculating LP tokens.

Assessed type

MEV


The text was updated successfully, but these errors were encountered:

All reactions

AI Score

6.9

Confidence

Low