attacker steal funds because functions buy() shouldn't revert when user pays 0 amount and receive fractional token #391
Labels
2 (Med Risk)
Assets not at direct risk, but function/availability of the protocol could be impacted or leak value
bug
Something isn't working
duplicate-243
judge review requested
Judge should review this issue
satisfactory
satisfies C4 submission criteria; eligible for awards
Lines of code
https://github.com/code-423n4/2022-12-caviar/blob/0212f9dc3b6a418803dbfacda0e340e059b8aae2/src/Pair.sol#L147-L176
Vulnerability details
Impact
Function
buy()
buys fractional tokens from the pair, there is no check in those functions that what user pays or receives isn't 0 so it's possible for attacker to buy some fractional tokens and pay 0 base token. so liquidity providers would lose funds because of this.Proof of Concept
This is
buy()
code:As you can see the amount user pays calculated in
buyQuote()
and the return value of that function has been used to transfer funds from user. there is no check that what user pays is not 0 and if the return value was 0 then user would pay 0 base token and receive some fractional tokens.This is
buyQuote()
code:so when
outputAmount * 1000 * baseTokenReserves() < (fractionalTokenReserves() - outputAmount) * 997
then user would pay 0 amount but receives fractional tokens. for example if:fractionalTokenReserves()
would equal to1000 * (1e18 +1)
baseTokenReserves()
equal to997 * 1e15
outputAmount * 1000 * 997 * 1e15 < (1000 * (1e18 +1) - outputAmount) * 997
outputAmount * 997 * 1e18 < (1000 * (1e18 +1) - outputAmount) * 997
outputAmount * 1e18 < 1000 * (1e18 +1) - outputAmount
outputAmount (1+1e18) < 1000 * (1e18 +1)
outputAmount < 1000
.the attack is more practical if those 1000 fractional token worth more than fee, but if the numbers changes the amount could be higher and attack could become practical, the severity is Medium and not High because the attack is not always practical. the real cause if this issue is rounding error when price (base token to fractional token) is too high or too low but contract should prevent this cases too because it's a permission-less protocol which wants to support all pairs of NFTs and base tokens.
Tools Used
VIM
Recommended Mitigation Steps
add more precision to fractional token and also revert if user is going to pay 0 amount of base token.
The text was updated successfully, but these errors were encountered: