The getPrice
function in the Auction
contract uses integer division to calculate the price decay over time. This approach can lead to rounding errors, causing the calculated price to deviate from the intended formula. As a result, earlier or later buyers may be favored due to improper rounding, potentially underpaying or overpaying the protocol.
Integer Division in Price Calculation :
The getPrice
function calculates the current price as:
Solidity performs integer division, which truncates fractional results. If (block.timestamp - state.startTime)
is not perfectly divisible by (state.endTime - state.startTime)
, the result will be rounded down, leading to inaccuracies in the price calculation.
The intended formula for price is:
Due to integer division, the actual price may differ slightly from this formula, especially when elapsed % duration != 0
.
Suppose:
startingPrice = 1000
reservePrice = 500
startTime = 100
endTime = 200
block.timestamp = 150
The intended price at t = 150
is:
However, if elapsed = 51 instead of 50 (due to block timing variations), the calculation becomes:
Here, the price is slightly lower than intended due to truncation during integer division.
Depending on the direction of the rounding error, earlier or later buyers may pay slightly less or more than intended, this creates an unfair advantage or disadvantage for certain buyers.
Manual Review
Use higher precision (e.g., multiply before dividing):
This fixed the issue
The contest is live. Earn rewards by submitting a finding.
This is your time to appeal against judgements on your submissions.
Appeals are being carefully reviewed by our judges.