Core Contracts

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

Time and Price Validation Issues in Auction Constructor

Summary

The Auction contract constructor lacks several critical input validations that could lead to contract malfunction, underflows, and division by zero errors:

  1. Missing validation that _startTime is in the future

  2. Missing validation that _endTime is greater than _startTime

  3. Missing validation that _reservePrice is less than or equal to _startingPrice

Vulnerability Details

In the constructor:

constructor(
address _zenoAddress,
address _usdcAddress,
address _businessAddress,
uint256 _startTime,
uint256 _endTime, // No check for _endTime > _startTime
uint256 _startingPrice,
uint256 _reservePrice, // No check for _reservePrice <= _startingPrice
uint256 _totalAllocated,
address _initialOwner
)

https://github.com/Cyfrin/2025-02-raac/blob/89ccb062e2b175374d40d824263a4c0b601bcb7f/contracts/zeno/Auction.sol#L55

While there is validation that _endTime must be greater than _startTime, there is no check to ensure _startTime is greater than block.timestamp. This allows the auction to be immediately active upon deployment if _startTime is set to a past timestamp.

Impact

These missing validations can lead to several critical issues:

  1. If _startTime is set to a past timestamp, the auction becomes instantly active

  2. If _endTime <= _startTime, the price calculation in getPrice() will result in division by zero:

(block.timestamp - state.startTime) / (state.endTime - state.startTime) // Division by zero!
  1. If _reservePrice > _startingPrice, price calculations will underflow due to unsigned arithmetic:

(state.startingPrice - state.reservePrice) // Will underflow if reservePrice > startingPrice

Results in Complete dysfunction of the auction mechanics

Proof of concept

// Deploy auction with invalid parameters
uint256 pastTimestamp = block.timestamp - 1 hours;
uint256 sameTimestamp = block.timestamp;
Auction auction = new Auction(
zenoAddress,
usdcAddress,
businessAddress,
sameTimestamp, // startTime
sameTimestamp, // endTime == startTime (division by zero)
1000, // startingPrice
2000, // reservePrice > startingPrice (underflow)
totalAllocated,
owner
);
// Any call to getPrice() will revert due to division by zero
auction.getPrice(); // reverts

Recommended Mitigation

Add comprehensive validation checks in the constructor:

constructor(...) {
require(_startTime > block.timestamp, "Start time must be in the future");
require(_endTime > _startTime, "End time must be after start time");
require(_reservePrice <= _startingPrice, "Reserve price must be less than or equal to starting price");
// ...existing code...
}
Updates

Lead Judging Commences

inallhonesty Lead Judge 7 months ago
Submission Judgement Published
Invalidated
Reason: Non-acceptable severity

Support

FAQs

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

Give us feedback!