Core Contracts

Regnum Aurum Acquisition Corp
HardhatReal World AssetsNFT
77,280 USDC
View results
Submission Details
Severity: medium
Invalid

Precision Loss in `getPrice()` Leading to Underpricing in `Auction.sol` contract

Summary

The getPrice() function in the Auction.sol contract suffers from precision loss due to Solidity’s integer division behavior. Since Solidity truncates decimal values instead of rounding them, the calculated price is sometimes lower than expected. This results in users paying slightly less than they should when purchasing ZENO tokens via the buy() function.

Vulnerability Details

The getPrice() function calculates the price of ZENO using the formula: https://github.com/Cyfrin/2025-02-raac/blob/main/contracts/zeno/Auction.sol#L69-L78

function getPrice() public view returns (uint256) {
if (block.timestamp < state.startTime) return state.startingPrice;
if (block.timestamp >= state.endTime) return state.reservePrice;
return state.startingPrice - (
(state.startingPrice - state.reservePrice) *
(block.timestamp - state.startTime) /
(state.endTime - state.startTime)
);
}

Solidity’s integer division truncates decimals instead of rounding, leading to an artificially lower price in certain cases.
This error is most evident when (block.timestamp - state.startTime) / (state.endTime - state.startTime) is not a whole number.
As a result, the computed price is slightly lower than the expected theoretical value, allowing users to purchase ZENO tokens at a discounted rate.

Proof of Concept (PoC)

Assumptions

  • startingPrice = 105

  • reservePrice = 20

  • startTime = 10

  • endTime = 20

Expected vs. Actual Behavior

t (timestamp) Expected Price Solidity-Truncated Price Difference
10 105 105 0
11 96.5 96 -0.5
12 88 88 0
13 79.5 79 -0.5
14 71 71 0
15 62.5 62 -0.5
16 54 54 0
17 45.5 45 -0.5
18 37 37 0
19 28.5 28 -0.5
20 20 20 0

This precision loss issue results in users getting a small, unintended discount when buying ZENO tokens.

Impact

Since the price is slightly lower than expected, users can consistently buy ZENO at a discount over time. While this doesn’t lead to direct losses for the protocol, it reduces expected revenue from the auction, impacting the intended pricing mechanism.

Tools Used

Manual Review

Recommendations

To preserve precision and avoid unintended rounding, modify the getPrice() function to use fixed-point arithmetic.

Updates

Lead Judging Commences

inallhonesty Lead Judge about 1 month ago
Submission Judgement Published
Invalidated
Reason: Non-acceptable severity

Support

FAQs

Can't find an answer? Chat with us on Discord, Twitter or Linkedin.