User may lose funds when adding liquidity #252
Labels
3 (High Risk)
Assets can be stolen/lost/compromised directly
bug
Something isn't working
duplicate-376
satisfactory
satisfies C4 submission criteria; eligible for awards
upgraded by judge
Original issue severity upgraded from QA/Gas by judge
Lines of code
https://github.com/code-423n4/2022-12-caviar/blob/0212f9dc3b6a418803dbfacda0e340e059b8aae2/src/Pair.sol#L63
Vulnerability details
Impact
When a user adds liquidity they need to provide the two assets from the pool. The number of
LPToken
received by the user is computed in theaddQuote
function. When there is liquidity in the pool, theaddQuote
function will compute, per each provided asset, the number ofLPToken
that represent the same share between the provided asset and the reserve, and will return the minimum of the two numbers. This means that the user sends some tokens to the pool that are not returned asLPToken
, those tokens are still sent to the pool and distributed automatically on a pro-rata basis between all theLPToken
holders.This mechanism can create bad incentives,
LPToken
holders may try to create these scenarios in order to get more value for theirLPTokens
. There are multiple scenarios that can happen, below I described one, that from my point of view, is the most suitable to happen:NFT1
andWETH
NFT1
getting in return1 fractional token (1e18)
from the pool.1 fractional token (1e18)
and1 WETH (1e18)
to the pool. Alice sets the minimumLPToken
she is willing to receive to0 LPToken
(assuming that the pool does not have liquidity yet).1 fractional token (1e18)
and0.1 WETH (1e17)
, Bob receives approximately0.3 LPToken
in return.fractional token
sent by her represents100%
of the reserve offractional token
in the pool, and the amount ofWETH
sent by her represents1000%
of the reserve of the pool. For computing the amount ofLPToken
she receives, the minimum percentage of shares is used, so she receives100%
of the existingLPToken
, which is the same amount received by Bob previously.2 fractional tokens (2e18)
and1.1 WETH (11e17)
. And both Alice and Bob have the same amount ofLPTokens
, which means they have the same shares over the pool's funds.1 fractional token (1e18)
and0.55 WETH (55e16)
.Note: It is important to note that Alice could have avoided this setting a better value for the minimum amount of
LPToken
expected.Proof of Concept
The next code can be copied into a solidity file in the
test
folder. After adding it, the test can be run to check a scenario similar to the one explained above.Recommended Mitigation Steps
When adding liquidity, only transfer from the users the number of tokens that are being used for backing the
LPTokens
, any surplus token should not be sent to the pool. In the case ofETH
, the surplus amount should be refunded to the user. I think this could be done similarly to how it is done in Uniswap V2 https://github.com/Uniswap/v2-periphery/blob/0335e8f7e1bd1e8d8329fd300aea2ef2f36dd19f/contracts/UniswapV2Router02.sol#L33The text was updated successfully, but these errors were encountered: