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: 62/103
Findings: 1
Award: $45.94
🌟 Selected for report: 0
🚀 Solo Findings: 0
🌟 Selected for report: Zarf
Also found by: 0xDave, Apocalypto, CRYP70, Franfran, Jeiwan, UNCHAIN, adriro, bytehat, chaduke, hansfriese, hihen, kiki_dev, koxuan, minhtrng, rajatbeladiya, unforgiven, wait, yixxas
45.9386 USDC - $45.94
https://github.com/code-423n4/2022-12-caviar/blob/main/src/Pair.sol#L398-L400
The function buyQuote
present in the Pair
contract is used to calculate the amount of base tokens required to buy a given amount of fractional tokens.
https://github.com/code-423n4/2022-12-caviar/blob/main/src/Pair.sol#L398-L400
function buyQuote(uint256 outputAmount) public view returns (uint256) { return (outputAmount * 1000 * baseTokenReserves()) / ((fractionalTokenReserves() - outputAmount) * 997); }
The integer division will round down the return value, while the correct behavior should be to round up in favor of the protocol.
The buyQuote
function will round down the division, which means that the required amount of base tokens that the user needs to input to take a given amount of fractional tokens will be rounded down.
The result amount will then be rounded down in favor of the user calling the buy
instead of favoring the LPs.
If the numerator outputAmount * 1000 * baseTokenReserves()
isn't a multiple of the denominator (fractionalTokenReserves() - outputAmount) * 997
, then the integer division will round the result down.
Following UniswapV2 getAmountIn
implementation, a +1
can be added to the calculation to force the rounding to be up:
function buyQuote(uint256 outputAmount) public view returns (uint256) { return ((outputAmount * 1000 * baseTokenReserves()) / ((fractionalTokenReserves() - outputAmount) * 997)) + 1; }
As a more technically correct alternative, it is also possible to use solmate's FixedPointMathLib.mulDivUp
to calculate the buyQuote
formula (this library is already used and imported in the project).
#0 - Shungy
2022-12-21T07:35:19Z
Seems valid.
#1 - c4-judge
2022-12-23T13:42:01Z
berndartmueller marked the issue as primary issue
#2 - c4-judge
2022-12-23T13:49:52Z
berndartmueller marked the issue as duplicate of #243
#3 - c4-judge
2023-01-10T09:43:19Z
berndartmueller marked the issue as satisfactory