Core Contracts

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

Incorrect Total Supply Validation Leads to Premature Lock Restrictions in veRAACToken

Summary

In the veRAACToken's lock function, the validation check totalSupply() + amount > MAX_TOTAL_SUPPLY incorrectly compares veRAAC tokens (voting power) with RAAC tokens (lock amount), which are fundamentally different. Since veRAAC tokens are always a fraction of RAAC tokens, this comparison leads to an artificially high sum that causes premature lock restrictions.

Vulnerability Details

The issue occurs in the lock function's validation:

function lock(uint256 amount, uint256 duration) external nonReentrant whenNotPaused {
if (amount == 0) revert InvalidAmount();
if (amount > MAX_LOCK_AMOUNT) revert AmountExceedsLimit();
if (totalSupply() + amount > MAX_TOTAL_SUPPLY) // @audit problematic check
revert TotalSupplyLimitExceeded();
//...
}

The fundamental problem lies in comparing two different token standards with inherently different scales:

totalSupply() - Returns the total supply of veRAAC tokens which represent voting power. Voting power is calculated based on both amount and lock duration:

veRAACAmount = (lockAmount * lockDuration) / MAX_LOCK_DURATION

Due to this formula, veRAAC amount is always less than or equal to the RAAC amount since lockDuration/MAX_LOCK_DURATION is always ≤ 1

amount - Represents raw RAAC tokens that the user wants to lock. These are the underlying tokens before any time-weighted voting power calculation, meaning they are always larger than or equal to their corresponding veRAAC value.

This creates a critical mismatch because:

  • If a user locks 100 RAAC for 4 years (MAX_LOCK_DURATION), they get 100 veRAAC

  • If a user locks 100 RAAC for 2 years, they get 50 veRAAC

  • If a user locks 100 RAAC for 1 year, they get 25 veRAAC

The validation adds a large number (raw RAAC amount) to a smaller number (veRAAC total supply), creating an artificially high sum that triggers the MAX_TOTAL_SUPPLY limit prematurely hence the lock function will revert even though the limit is not actually reached yet.

PoC

  1. MAX_TOTAL_SUPPLY = 100M veRAAC

  2. MAX_LOCK_AMOUNT per position = 10M RAAC

  3. Several users have already locked tokens totaling to:

    • Current totalSupply() = 95M veRAAC

  4. Alice tries to lock 10M RAAC (maximum allowed) for 1 year

  5. Check performs: 95M + 10M > 100M (evaluates to true)

    • Even though Alice's actual voting power would only be 2.5M veRAAC (10M * 1/4)

    • True total would be 97.5M veRAAC, still under MAX_TOTAL_SUPPLY

  6. Transaction reverts due to incorrect comparison, despite being within actual voting power limits

Impact

Users are prevented from locking tokens prematurely due to artificial supply limits, severely restricting protocol participation and proper voting power distribution. This effectively creates a much tighter cap on the system than intended by the protocol design.

Tools Used

Manual Review

Recommendations

Compare equivalent voting power values:

uint256 newVotePower = (amount * duration) / MAX_LOCK_DURATION;
if (totalSupply() + newVotePower > MAX_TOTAL_SUPPLY)
revert TotalSupplyLimitExceeded();
Updates

Lead Judging Commences

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