Core Contracts

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

In `TimeWeightedAverage::calculateAverage`, the returned value may be incorrect when `timestamp <= self.startTime` due to `updateValue`.

Summary

The TimeWeightedAverage::calculateAverage function returns an incorrect value when timestamp <= self.startTime after executing the updateValue function. The intended behavior of calculateAverage is to return the original initial value of self.value when the timestamp precedes the start time. However, since the updateValue function modifies self.value, the returned value after an update no longer reflects the original initial value.

Vulnerability Details

function calculateAverage(
Period storage self,
uint256 timestamp
) internal view returns (uint256) {
if (timestamp <= self.startTime) return self.value; <==@found
uint256 endTime = timestamp > self.endTime ? self.endTime : timestamp;
uint256 totalWeightedSum = self.weightedSum;
if (endTime > self.lastUpdateTime) {
uint256 duration = endTime - self.lastUpdateTime;
uint256 timeWeightedValue = self.value * duration;
if (duration > 0 && timeWeightedValue / duration != self.value) revert ValueOverflow();
totalWeightedSum += timeWeightedValue;
}
return totalWeightedSum / (endTime - self.startTime);
}

Impact

the returned value may be incorrect

Tools Used

  • Manual Review

Recommendations

1.Record the initialValue in createPeriod:

+ uint256 initialValue;
function createPeriod(
Period storage self,
uint256 startTime,
uint256 duration,
uint256 initialValue,
uint256 weight
) internal {
if (self.startTime != 0 && startTime < self.startTime + self.totalDuration) {
revert PeriodNotElapsed();
}
if (duration == 0) revert ZeroDuration();
if (weight == 0) revert ZeroWeight();
self.startTime = startTime;
self.endTime = startTime + duration;
self.lastUpdateTime = startTime;
+ initialValue=initialValue;
self.value = initialValue;
self.weightedSum = 0;
self.totalDuration = duration;
self.weight = weight;
emit PeriodCreated(startTime, duration, initialValue);
}

2.Return initialValue instead of self.value:

function calculateAverage(
Period storage self,
uint256 timestamp
) internal view returns (uint256) {
- if (timestamp <= self.startTime) return self.value;
+ if (timestamp <= self.startTime) return initialValue;
uint256 endTime = timestamp > self.endTime ? self.endTime : timestamp;
uint256 totalWeightedSum = self.weightedSum;
if (endTime > self.lastUpdateTime) {
uint256 duration = endTime - self.lastUpdateTime;
uint256 timeWeightedValue = self.value * duration;
if (duration > 0 && timeWeightedValue / duration != self.value) revert ValueOverflow();
totalWeightedSum += timeWeightedValue;
}
return totalWeightedSum / (endTime - self.startTime);
}
Updates

Lead Judging Commences

inallhonesty Lead Judge 4 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.