Core Contracts

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

Bypassing `MAX_TOTAL_SUPPLY` Limit via `extend(...)`

Overview

The contract sets MAX_TOTAL_SUPPLY = 100_000_000e18. It partially enforces this cap in lock(...):

// In lock(...)
if (totalSupply() + amount > MAX_TOTAL_SUPPLY) revert TotalSupplyLimitExceeded();

The problem is -> extend(...) mints additional veRAAC tokens without checking MAX_TOTAL_SUPPLY. When a user extends their lock from (for instance) 1 year to 4 years, their voting power (and thus minted veRAAC) can surge—potentially pushing total supply above 100 million.

Attack Path / Proof of Concept

  1. Initial Short‑Term Lock
    The user locks a certain amount of RAAC for a minimal duration (e.g., 1 year), producing a smaller minted amount of veRAAC. This call respects the MAX_TOTAL_SUPPLY check in lock(...).

  2. Extend Lock to Maximum
    The user then calls extend(...) to stretch the lock from 1 year to 4 years:

    function extend(uint256 newDuration) external {
    ...
    uint256 oldPower = balanceOf(msg.sender);
    uint256 newPower = ... // can be significantly higher
    if (newPower > oldPower) {
    _mint(msg.sender, newPower - oldPower); // <— No total supply check!
    }
    ...
    }

    This difference (newPower - oldPower) can be large—pushing totalSupply() beyond 100 million tokens if multiple users do it or if one user initially locked a significant amount.

  3. No Revert
    Because extend(...) never verifies totalSupply() + minted <= MAX_TOTAL_SUPPLY, the total minted veRAAC can surpass 100,000,000.

Impact

Circumventing the Hard Cap: If the user(s) keep extending short locks into longer locks, the minted supply can outgrow the nominal 100 million limit.

Distorted Voting & Rewards: The inflated veRAAC supply yields more voting power than intended, skewing governance or reward distributions.

Recommended Fix

Similar to increase(...):

// After computing newPower, but before minting:
uint256 newlyMinted = newPower - oldPower;
if (totalSupply() + newlyMinted > MAX_TOTAL_SUPPLY) {
revert TotalSupplyLimitExceeded();
}

This ensures every mint path (lock(...), increase(...), and extend(...)) respects the MAX_TOTAL_SUPPLY cap.

Updates

Lead Judging Commences

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

Incorrect `MAX_TOTAL_SUPPLY` check in the `veRAACToken::lock/extend` function of `veRAACToken` could harm locking functionality

Support

FAQs

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

Give us feedback!