Caviar contest - SamGMK'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: 99/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
duplicate-442

External Links

Lines of code

https://github.com/code-423n4/2022-12-caviar/blob/0212f9dc3b6a418803dbfacda0e340e059b8aae2/src/Pair.sol#L426

Vulnerability details

Impact

An attacker could raise the price of the liquidity token, making it infeasible for small liquidity providers to provide any liquidity.

Proof of Concept

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

Tools Used

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

Awards

6.9881 USDC - $6.99

Labels

bug
3 (High Risk)
satisfactory
duplicate-442

External Links

Lines of code

https://github.com/code-423n4/2022-12-caviar/blob/0212f9dc3b6a418803dbfacda0e340e059b8aae2/src/Pair.sol#L426

Vulnerability details

Impact

An attacker could raise the price of the liquidity token, making it infeasible for small liquidity providers to provide any liquidity.

Proof of Concept

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

Tools Used

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

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