Submitted by Banditx0x, also found by 0xMango and jasonxiale
The first depositor in the AMM can lose the majority of their tokens to a frontrunning attack even if they set the correct minShares slippage parameters.
Summary:
By using $x + y$ instead of $sqrt(x \* y)$ as the formula for determining the initial liquidity shares, minshares is no longer a effective slippage parameter for the first deposit as front running can change the shares minted even when the token ratio is the same.
Explanation:
Salty is a Uniswap style pool which maintains an $x \* y = k$ invaraint. However, the equation determining the initial liquidity amount is different from Uniswap v2
Here is Uniswaps:
Here is Saltys (implemented in the _addLiquidity function):
Here is a quote from Uniswaps whitepaper:
Uniswap v2 initially mints shares equal to the geometric mean of the amounts, liquidity = sqrt(xy). This formula ensures that the value of a liquidity pool share at any time is essentially independent of the ratio at which liquidity was initially deposited The above formula ensures that a liquidity pool share will never be worth less than the geometric mean of the reserves in that pool.
Uniswaps liquidity formula is path-independent. As long as we know the x and y values in a deposit, we know that the liquidity will conform to the $L = sqrt(x \* y)$ formula.
Saltys formula is not path independent. The number of shares minted for a token deposit is affected by the initial liquidity deposit.
This is the basis for this attack.
The only slippage parameter used for depositing into the AMM is minShares. However, during the first deposit, an attacker can exploit the difference in the initial deposit liquidity equation $x + y$ and the invariant $x \* y$ to inflate the number of shares minted per token, and then use the inflated shares to set the AMM at an incorrect reserve ratio such that it can be arbitraged.
First lets examine a base case, where a user makes an initial deposit with correct minShares parameters:
User deposits 10000 DAI and 10000 USDT at a 1-1 reserve ratio. This is correct as they are both tokens with 18 decimals and value of $1.
Lets calculate the minShares slippage parameters they should set. During the first deposit they are depositing 10000 * 1e18 wei of each token, so 1e22 wei. Liquidity minted is the sum of the 2 amounts (1e22 + 1e22). So liquidity minted = 2e22
Now lets examine how a frontrunner can inflate the shares so that the slippage parameter is no longer effective.
Frontrunning Case, Step by step:
Consider using minAmount0 and minAmount1 deposited into the AMM. This is how Uniswap V3 implements their slippage parameters.
Alternatively, using the same liquidity formula as Uniswap v2 - $L = sqrt(x \* y)$ will prevent this attack.
othernet-global (Salty.IO) confirmed and commented:
Picodes (Judge) decreased severity to Medium
Note: For full discussion, see here.
Status: Mitigation confirmed. Full details in reports from 0xpiken, zzebra83, and t0x1c.
