Core Contracts

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

Timestamp Manipulation Leading to Underflow in Duration Calculation

Description

The function calculateTimeWeightedAverage is vulnerable to timestamp manipulation, which can lead to an underflow in the calculation of duration. This occurs in the following lines of code:

uint256 endTime = timestamp > periods[i].endTime ? periods[i].endTime : timestamp;
uint256 duration = endTime - periods[i].startTime;

If timestamp is manipulated to be smaller than periods[i].startTime, the calculation of duration will underflow because endTime (which is set to timestamp) will be smaller than periods[i].startTime. This underflow will cause the transaction to revert, potentially disrupting the contract's functionality.

Impact

  1. Transaction Reverts: The underflow will cause the transaction to revert, leading to a denial-of-service (DoS) condition.

  2. Timestamp Manipulation: In blockchain environments, timestamps can sometimes be manipulated by miners (within certain limits). If the timestamp parameter is derived from block.timestamp or provided by an untrusted source, an attacker could exploit this to trigger the underflow.

  3. Invalid Input: If the periods array contains invalid data (e.g., startTime > endTime), the function will fail, even without malicious intent.

Affected Code

uint256 endTime = timestamp > periods[i].endTime ? periods[i].endTime : timestamp;
uint256 duration = endTime - periods[i].startTime;

Recommendation

To mitigate this issue, the following steps should be taken:

  1. Input Validation: Ensure that timestamp is greater than or equal to periods[i].startTime before performing the subtraction.

  2. Check Period Validity: Ensure that periods[i].startTime < periods[i].endTime for all periods.

  3. Handle Edge Cases: Skip periods where timestamp <= periods[i].startTime or startTime >= endTime.

Here’s an example of how to fix the issue:

function calculateTimeWeightedAverage(
PeriodParams[] memory periods,
uint256 timestamp
) public pure returns (uint256 weightedAverage) {
require(timestamp > 0, "Invalid timestamp");
uint256 totalWeightedSum;
uint256 totalDuration;
for (uint256 i = 0; i < periods.length; i++) {
// Validate period
require(periods[i].startTime < periods[i].endTime, "Invalid period: startTime >= endTime");
// Skip periods where timestamp is before the startTime
if (timestamp <= periods[i].startTime) continue;
// Ensure endTime is not less than startTime
uint256 endTime = timestamp > periods[i].endTime ? periods[i].endTime : timestamp;
require(endTime >= periods[i].startTime, "Invalid endTime: endTime < startTime");
// Calculate duration safely
uint256 duration = endTime - periods[i].startTime;
// Check for overflow in multiplication
uint256 timeWeightedValue = periods[i].value * duration;
require(timeWeightedValue / duration == periods[i].value, "Value overflow");
uint256 weightedValue = timeWeightedValue * periods[i].weight;
require(weightedValue / periods[i].weight == timeWeightedValue, "Weight overflow");
totalWeightedSum += weightedValue;
totalDuration += duration;
}
if (totalDuration == 0) {
return 0;
}
return totalWeightedSum / (totalDuration * 1e18);
}
Updates

Lead Judging Commences

inallhonesty Lead Judge 4 months ago
Submission Judgement Published
Invalidated
Reason: Incorrect statement

Support

FAQs

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