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: 91/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/main/src/Pair.sol#L63-L99 https://github.com/code-423n4/2022-12-caviar/blob/main/src/Pair.sol#L417-L428
The addQuote
function in Pair.sol
calculates the amount of LPTokens received for the amount of baseTokens and fractionalTokens sent. If LPToken's supply > 0 then the min amount of baseTokenShare and fractionaTokenShare is used. When the add
function is used to provide baseTokens and fractionalTokens, both amounts must be non-zero. It is possible a user sends a very small amount of 1 token and a large amount of the other (for example, the user has 1e3 fractionalTokens but can send 1e22 baseTokens). In this case, the share calculations for the token with the small amount sent could be 0 which means addQuote
would return 0 (the minimum). The result is that the user could receive 0 LPTokens.
The add
function allows the user to specify a minimum amount of LPTokens to receive, so a user must intentionally set minLPTokenAmount == 0
. This could happen if the user uses the addQuote
function to calculate minLPTokenAmount
.
The test below shows how a user that does not specify a minimum amount of LPTokens could receive 0 LPTokens.
Test code added to Add.t.sol
:
function testItMints0LpTokens() public { // arrange baseTokenAmount = 1e8; fractionalTokenAmount = 1e18; deal(address(usd), address(this), baseTokenAmount, true); deal(address(p), address(this), fractionalTokenAmount, true); uint256 minLpTokenAmount = Math.sqrt(baseTokenAmount * fractionalTokenAmount); p.add(baseTokenAmount, fractionalTokenAmount, minLpTokenAmount); // initial add uint256 lpTokenSupplyBefore = lpToken.totalSupply(); baseTokenAmount = 1e10; fractionalTokenAmount = 1; minLpTokenAmount = p.addQuote(baseTokenAmount, fractionalTokenAmount); deal(address(usd), babe, baseTokenAmount, true); deal(address(p), babe, fractionalTokenAmount, true); // act vm.startPrank(babe); usd.approve(address(p), type(uint256).max); uint256 lpTokenAmount = p.add(baseTokenAmount, fractionalTokenAmount, minLpTokenAmount); vm.stopPrank(); // assert assertEq(lpTokenAmount, 0, "0 LPTokens returned from add"); }
Consider adding a require condition that prevents 0 LPTokens minted in the add
function.
#0 - soosh1337
2022-12-20T02:32:12Z
This requires a user to send "a very small amount of 1 token and a large amount of the other", and " intentionally set minLPTokenAmount == 0
" and the end result is the user themselves losing funds (LP tokens).
For these reasons - Overinflated Severity.
#1 - Shungy
2022-12-20T06:23:14Z
Conditional on user error (i.e.: not setting proper slippage). Also minting 0
is equally bad to minting 1
wei, so very inflated severity, I think it should be invalidated.
#2 - c4-judge
2022-12-20T14:34:22Z
berndartmueller marked the issue as duplicate of #442
#3 - c4-judge
2023-01-16T11:54:02Z
berndartmueller marked the issue as satisfactory