Core Contracts

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

Price Calculation Rounding Errors

Summary

After analyzing the price calculation in Auction.sol, while there are rounding effects from integer division, the impact is minimal and follows standard DeFi practices.

Technical Analysis

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)
);
}

Impact Analysis

  1. Maximum Rounding Loss

// Example calculation
startingPrice = 100 USDC
reservePrice = 90 USDC
duration = 100 seconds
// At 75 seconds
Expected: 92.5 USDC
Actual: 92 USDC
Loss: 0.5 USDC (0.54% of price)
  1. Cumulative Impact

Total Allocation = 1,000,000 ZENO
Maximum cumulative loss = 0.54% * Total Value
= 5,400 USDC for a 1M USDC auction

Why This Is Low Severity

  1. Standard Practice

  • Integer arithmetic is standard in Solidity

  • Similar implementations in major protocols

  • Follows expected behavior

  1. Minimal Impact

  • Maximum loss per transaction < 1%

  • No compound effect

  • Predictable behavior

  1. Built-in Bounds

if (block.timestamp < state.startTime) return state.startingPrice;
if (block.timestamp >= state.endTime) return state.reservePrice;

Recommended Improvement

contract Auction is IAuction, Ownable {
// Add precision scaling
uint256 private constant PRECISION = 1e6;
function getPrice() public view returns (uint256) {
if (block.timestamp < state.startTime) return state.startingPrice;
if (block.timestamp >= state.endTime) return state.reservePrice;
uint256 timeElapsed = block.timestamp - state.startTime;
uint256 duration = state.endTime - state.startTime;
// Scale for precision
uint256 progress = (timeElapsed * PRECISION) / duration;
uint256 priceDiff = state.startingPrice - state.reservePrice;
return state.startingPrice - ((priceDiff * progress) / PRECISION);
}
}

Test Cases

contract AuctionPriceTest is Test {
function testPriceCalculation() public {
// Setup
uint256 startTime = block.timestamp;
uint256 endTime = startTime + 100;
uint256 startPrice = 100e6;
uint256 reservePrice = 90e6;
Auction auction = new Auction(
address(zeno),
address(usdc),
address(business),
startTime,
endTime,
startPrice,
reservePrice,
1000e18,
address(this)
);
// Test mid-auction price
vm.warp(startTime + 50);
uint256 midPrice = auction.getPrice();
assertApproximatelyEqual(midPrice, 95e6, 1e4); // Within 0.01 USDC
}
}
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!