Platform: Code4rena
Start Date: 12/12/2022
Pot Size: $36,500 USDC
Total HM: 8
Participants: 103
Period: 7 days
Judge: berndartmueller
Id: 193
League: ETH
Rank: 99/103
Findings: 1
Award: $6.99
🌟 Selected for report: 0
🚀 Solo Findings: 0
🌟 Selected for report: minhquanym
Also found by: 0x52, 0xDecorativePineapple, Apocalypto, BAHOZ, ElKu, Franfran, HE1M, Jeiwan, KingNFT, Koolex, SamGMK, Tointer, Tricko, UNCHAIN, __141345__, ak1, aviggiano, bytehat, carrotsmuggler, cccz, chaduke, cozzetti, dipp, eyexploit, fs0c, haku, hansfriese, hihen, immeas, izhelyazkov, koxuan, ladboy233, lumoswiz, rajatbeladiya, rjs, rvierdiiev, seyni, supernova, unforgiven, yixxas
6.9881 USDC - $6.99
An attacker could raise the price of the liquidity token, making it infeasible for small liquidity providers to provide any liquidity.
Pair.sol contract uses the same Maths applied in Uniswap v2. When the totalSupply of the LP token is zero, this means the LP provider is the first and thus initially, the contract mints shares equal to the geometric mean of the amounts deposited. In this case, that would be baseTokenAmount fractionalTokenAmount provided by the user. However, there is a risk due to the increase of value of the LP token, either through fees or “donations” directly sent in that could make the value of the smallest unit of the LP token(1e-18
) so expensive that it is not feasible for small liquidity providers to provide as the LP token they would getting after looking up their tokens is negligible. To avoid this, Uniswap v2 deducts (1e-15
) which is 1000 times the smallest unit of the LP token(1e-18) during initial mint to make this type of attack substantially more difficult. However, in caviar pair.sol
, addQuote
simply returns the geometric mean of the tokens provided without any initial deductions.
For further understanding see Uniswap v2 whitepaper section 3.4
Manual Review
Add a deduction on the geometric mean of the two tokens similar to what is implemented in the Uniswap v2 pair then permanently lock the amount deducted( MINIMUM_LIQUIDITY) by sending it to address(0) . This would look like:
//declare this as a state variable.
uint public constant MINIMUM_LIQUIDITY = 10**3
Math.sqrt(baseTokenAmount * fractionalTokenAmount) - MINIMUM_LIQUIDITY
_mint(address(0), MINIMUM_LIQUIDITY)
#0 - c4-judge
2022-12-28T15:46:03Z
berndartmueller marked the issue as duplicate of #442
#1 - c4-judge
2023-01-10T09:19:02Z
berndartmueller marked the issue as satisfactory
🌟 Selected for report: minhquanym
Also found by: 0x52, 0xDecorativePineapple, Apocalypto, BAHOZ, ElKu, Franfran, HE1M, Jeiwan, KingNFT, Koolex, SamGMK, Tointer, Tricko, UNCHAIN, __141345__, ak1, aviggiano, bytehat, carrotsmuggler, cccz, chaduke, cozzetti, dipp, eyexploit, fs0c, haku, hansfriese, hihen, immeas, izhelyazkov, koxuan, ladboy233, lumoswiz, rajatbeladiya, rjs, rvierdiiev, seyni, supernova, unforgiven, yixxas
6.9881 USDC - $6.99
An attacker could raise the price of the liquidity token, making it infeasible for small liquidity providers to provide any liquidity.
Pair.sol contract uses the same Maths applied in Uniswap v2. When the totalSupply of the LP token is zero, this means the LP provider is the first and thus initially, the contract mints shares equal to the geometric mean of the amounts deposited. In this case, that would be baseTokenAmount fractionalTokenAmount provided by the user. However, there is a risk due to the increase of value of the LP token, either through fees or “donations” directly sent in that could make the value of the smallest unit of the LP token(1e-18
) so expensive that it is not feasible for small liquidity providers to provide as the LP token they would getting after looking up their tokens is negligible. To avoid this, Uniswap v2 deducts (1e-15
) which is 1000 times the smallest unit of the LP token(1e-18) during initial mint to make this type of attack substantially more difficult. However, in caviar pair.sol
, addQuote
simply returns the geometric mean of the tokens provided without any initial deductions.
For further understanding see Uniswap v2 whitepaper section 3.4
Manual
Add a deduction on the geometric mean of the two tokens similar to what is implemented in the Uniswap v2 pair then permanently lock the amount deducted( MINIMUM_LIQUIDITY) by sending it to address(0) . This would look like:
//declare this as a state variable.
uint public constant MINIMUM_LIQUIDITY = 10**3
Math.sqrt(baseTokenAmount * fractionalTokenAmount) - MINIMUM_LIQUIDITY
_mint(address(0), MINIMUM_LIQUIDITY)
#0 - c4-judge
2022-12-28T15:21:02Z
berndartmueller marked the issue as duplicate of #442
#1 - c4-judge
2023-01-10T09:18:06Z
berndartmueller marked the issue as satisfactory