Core Contracts

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

Premature Emission Rate Update Skips Minting for Previous Period

Summary

The RAACMinter::updateEmissionRate function updates the emission rate without minting RAAC tokens for the stability pool corresponding to the previous emission phase. For example:

  • Phase 1: Blocks 100-200 with 50% emission rate

  • Phase 2: Blocks 200-300 with 60% emission rate
    Current implementation calculates amountToMint as (300-100)*60% instead of the correct (200-100)*50% + (300-200)*60%.Causing discrepancies between the quantities calculated externally via RAACMinter::getEmissionRate and the actual amounts.

Vulnerability Details

function updateEmissionRate() public whenNotPaused { <==@found
if (emissionUpdateInterval > 0 && block.timestamp < lastEmissionUpdateTimestamp + emissionUpdateInterval) {
revert EmissionUpdateTooFrequent();
}
uint256 newRate = calculateNewEmissionRate();
emissionRate = newRate;
lastEmissionUpdateTimestamp = block.timestamp;
emit EmissionRateUpdated(newRate);
}

Impact

  • Accounting Discrepancy: Stability pool receives incorrect RAAC token balances

  • Emission Distortion: Historical emission periods become mathematically unreconcilable

Tools Used

  • Manual Review

Recommendations

step1.Call the RAACMinter::tick function before updating emissionRate in RAACMinter::updateEmissionRate.
step2.Refactor RAACMinter::tick to Prevent Infinite Loops Between RAACMinter::tick and RAACMinter::updateEmissionRate:

function updateEmissionRate() public whenNotPaused {
if (emissionUpdateInterval > 0 && block.timestamp < lastEmissionUpdateTimestamp + emissionUpdateInterval) {
revert EmissionUpdateTooFrequent();
}
uint256 newRate = calculateNewEmissionRate();
+ tick();
emissionRate = newRate;
lastEmissionUpdateTimestamp = block.timestamp;
emit EmissionRateUpdated(newRate);
}
function tick() external nonReentrant whenNotPaused {
if (emissionUpdateInterval == 0 || block.timestamp >= lastEmissionUpdateTimestamp + emissionUpdateInterval) {
- updateEmissionRate();
+ emissionRate=calculateNewEmissionRate();
}
uint256 currentBlock = block.number;
uint256 blocksSinceLastUpdate = currentBlock - lastUpdateBlock;
if (blocksSinceLastUpdate > 0) {
uint256 amountToMint = emissionRate * blocksSinceLastUpdate;
if (amountToMint > 0) {
excessTokens += amountToMint;
lastUpdateBlock = currentBlock;
raacToken.mint(address(stabilityPool), amountToMint);
emit RAACMinted(amountToMint);
}
}
}
Updates

Lead Judging Commences

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

RAACMinter tick applies new emission rates retroactively to past blocks by updating rate before minting tokens for previous period

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

RAACMinter tick applies new emission rates retroactively to past blocks by updating rate before minting tokens for previous period

Support

FAQs

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

Give us feedback!