The getPrice
function suffers from precision loss due to integer division rounding down in Solidity. Since Solidity uses integer division (without floating-point support), intermediate calculations may lose precision when dividing, resulting in inaccurate pricing values.
The formula for price calculation involves a division operation:
(state.startingPrice - state.reservePrice) *
(block.timestamp - state.startTime) /
(state.endTime - state.startTime)
Solidity rounds down when performing integer division. If the numerator is not perfectly divisible by the denominator, the result will be lower than expected.
This rounding issue is especially problematic in auctions or time-sensitive price adjustments, where small inaccuracies can accumulate over time.
Example of the issue:
Suppose :
state.startingPrice = 1000
state.reservePrice = 500
state.startTime = 0
state.endTime = 10
block.timestamp = 3
The wrong price will be :
1000 - ((1000 - 500) * (3 - 0) / (10 - 0))
= 1000 - (500 * 3 / 10)
= 1000 - 0
= 100
The price does not decrease correctly due to early rounding.
The right price will be :
1000 - ((500 * 3) / 10)
= 1000 - (1500 / 10)
= 1000 - 150
= 850
Now the price adjusts smoothly without rounding errors.
Inaccurate Pricing: Small errors in pricing may accumulate, leading to unexpected final prices.
Unfair Auctions: If used in an auction mechanism, rounding errors could lead to unexpected price floors or price steps.
Reduced Revenue or Incorrect Settlements: In financial contracts or market-making applications, rounding issues can lead to incorrect price quotes, affecting profitability.
Manual Review
Multiply Before Dividing: To preserve precision, always perform multiplications before divisions:
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.