Core Contracts

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

RWAGauge Sequencer Downtime Period Misalignment

Summary

The RWAGauge.sol contract calculates new period start times using absolute timestamp alignment, which can cause period misalignment with real-world asset payment cycles when L2 sequencer downtime occurs. This misalignment disrupts the synchronization between on-chain reward distributions and real-world rent collection cycles.

Vulnerability Details

The RWAGauge contract handles 30-day periods for real-world asset yield distribution. The period transition mechanism in BaseGauge.sol calculates the next period start time using:

uint256 nextPeriodStart = ((currentTime / periodDuration) + 2) * periodDuration;

When sequencer downtime occurs near a period transition, the contract calculates the new period start by rounding to the next absolute 30-day boundary from timestamp 0. This creates a permanent misalignment between protocol periods and real-world payment cycles.

For example:

  1. Period 1 starts January 1st

  2. Period should transition on January 31st

  3. Sequencer goes down on January 30th for 5 days

  4. When sequencer resumes on February 4th, next period starts February 5th

  5. All subsequent periods now start on the 5th instead of the 1st

The root cause is that the period calculation uses absolute timestamp alignment rather than maintaining relative 30-day increments from the previous period.

Impact

Medium - Protocol reward distributions become permanently misaligned with real-world rent collection cycles

Likelihood

Low - requires L2 sequencer to go down and timings to align,

Recommendations

Consider implementing these changes:

  1. Calculate next period based on previous period rather than absolute alignment:

uint256 nextPeriodStart = periodState.periodStartTime + getPeriodDuration();
  1. Add emergency realignment capability:

function realignPeriod(uint256 targetTimestamp) external onlyRole(EMERGENCY_ADMIN) {
require(targetTimestamp > block.timestamp, "Invalid target");
periodState.periodStartTime = targetTimestamp;
}
Updates

Lead Judging Commences

inallhonesty Lead Judge 3 months ago
Submission Judgement Published
Validated
Assigned finding tags:

BaseGauge::updatePeriod uses ((currentTime / periodDuration) + 2) calculation causing entire reward periods to be skipped, resulting in permanent loss of user rewards

inallhonesty Lead Judge 3 months ago
Submission Judgement Published
Validated
Assigned finding tags:

BaseGauge::updatePeriod uses ((currentTime / periodDuration) + 2) calculation causing entire reward periods to be skipped, resulting in permanent loss of user rewards

Support

FAQs

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