Core Contracts

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

Double token accounting in `tick` function

Summary

The tick() function in the RAACMinter contract contains a bug where newly minted tokens are simultaneously recorded in excessTokens and directly minted to the StabilityPool, leading to double accounting of the same tokens.

Vulnerability Details

In the tick() function:

function tick() external nonReentrant whenNotPaused {
// ... emission rate update logic ...
if (blocksSinceLastUpdate > 0) {
uint256 amountToMint = emissionRate * blocksSinceLastUpdate;
if (amountToMint > 0) {
excessTokens += amountToMint; // First accounting
lastUpdateBlock = currentBlock;
raacToken.mint(address(stabilityPool), amountToMint); // Second accounting
emit RAACMinted(amountToMint);
}
}
}

The bug arises when excessTokens += amountToMint records tokens as available for future distribution and when raacToken.mint(address(stabilityPool), amountToMint) immediately mints and distributes these same tokens.

This conflicts with the intended token distribution mechanism shown in mintRewards():

function mintRewards(address to, uint256 amount) external nonReentrant whenNotPaused {
if (msg.sender != address(stabilityPool)) revert OnlyStabilityPool();
uint256 toMint = excessTokens >= amount ? 0 : amount - excessTokens;
excessTokens = excessTokens >= amount ? excessTokens - amount : 0;
// ... minting logic ...
}

Impact

  1. Incorrect accounting of available tokens

  2. Potential over-minting of tokens beyond intended emission schedule

Tools Used

  • Manual code review

Recommendations

Remove direct minting to StabilityPool

function tick() external nonReentrant whenNotPaused {
// ... emission rate update logic ...
if (blocksSinceLastUpdate > 0) {
uint256 amountToMint = emissionRate * blocksSinceLastUpdate;
if (amountToMint > 0) {
excessTokens += amountToMint;
lastUpdateBlock = currentBlock;
emit RAACMinted(amountToMint);
}
}
}

or remove excess tokens accounting and maintain direct minting

function tick() external nonReentrant whenNotPaused {
// ... emission rate update logic ...
if (blocksSinceLastUpdate > 0) {
uint256 amountToMint = emissionRate * blocksSinceLastUpdate;
if (amountToMint > 0) {
lastUpdateBlock = currentBlock;
raacToken.mint(address(stabilityPool), amountToMint);
emit RAACMinted(amountToMint);
}
}
}
Updates

Lead Judging Commences

inallhonesty Lead Judge 7 months ago
Submission Judgement Published
Invalidated
Reason: Too generic

Support

FAQs

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

Give us feedback!