The Auction contract's getPrice() function uses integer arithmetic for its price calculation, which leads to truncation errors. As a result, if the difference between the starting price and the reserve price is not perfectly divisible by the duration of the auction, the computed price will never exactly reach the reserve price until the auction's end, violating the intended auction design.
The price calculation in the getPrice() function is as follows:
The multiplication and division operations are performed using integer arithmetic. If the value (state.startingPrice - state.reservePrice) is not perfectly divisible by (state.endTime - state.startTime), the division will truncate the fractional part.
For example, if state.startingPrice = 100, state.reservePrice = 10 (difference = 90), and the duration is 100 seconds, then at block.timestamp = state.startTime + 99 seconds:
The calculation is:
(90 * 99) / 100 = floor(8910 / 100) = 89.
Thus, the price becomes 100 - 89 = 11, which is above the reserve price of 10.
This truncation error means that the auction price will remain slightly above the reserve price until the very last moment (or may never exactly equal it under certain conditions), undermining the auction's design to gradually decrease to the reserve price.
Example
Parameters:
state.startingPrice = 100 USDC
state.reservePrice = 10 USDC
Auction duration: 100 seconds
Calculation at 99 seconds after start:
Price difference = 100 - 10 = 90 USDC
Time elapsed = 99 seconds
Computed decrement = (90 * 99) / 100 = 8910 / 100 = floor(89.10) = 89 USDC
Resulting Price: 100 - 89 = 11 USDC
Observation: The price should ideally reach 10 USDC at auction end, but due to truncation it remains at 11 USDC.
The auction may not reach the intended reserve price, potentially resulting in higher-than-expected prices and unfair outcomes.
Buyers expecting the price to drop to the reserve price may end up paying more, impacting market fairness and efficiency.
Manual Review
Implement fixed-point arithmetic to maintain precision in the price calculation. For example, use a library like PRBMath or Solidity's built-in fixed-point math techniques to perform the division without truncation, ensuring that the computed price accurately decreases to the reserve price as intended.
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.