Core Contracts

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

Incorrect Supply Limit Validation in `veRAACToken.lock` Allows Voting Power Inflation

Summary

A critical miscalculation in the veRAAC token locking mechanism allows users to bypass supply caps and mint excessive governance tokens. The veRAACToken.lock function improperly validates total supply against raw token amounts rather than time-weighted voting power, enabling attackers to systematically exceed protocol-defined supply limits through strategic long-duration locks. This flaw fundamentally undermines the governance system's integrity by allowing artificial inflation of voting power beyond designed constraints.

Vulnerability Details

The vulnerability exists in the voting power calculation and supply limit enforcement of the veRAAC token locking mechanism veRAACToken.lock (veRAACToken.sol#L215). The function improperly validates the total supply limit against the raw locked amount rather than the actual minted voting power amount, which is calculated using a time-weighted formula.

contract veRAACToken is ERC20, Ownable, ReentrancyGuard, IveRAACToken {
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) revert TotalSupplyLimitExceeded();
if (duration < MIN_LOCK_DURATION || duration > MAX_LOCK_DURATION)
revert InvalidLockDuration();
// Do the transfer first - this will revert with ERC20InsufficientBalance if user doesn't have enough tokens
raacToken.safeTransferFrom(msg.sender, address(this), amount);
// Calculate unlock time
uint256 unlockTime = block.timestamp + duration;
// Create lock position
_lockState.createLock(msg.sender, amount, duration);
_updateBoostState(msg.sender, amount);
// Calculate initial voting power
(int128 bias, int128 slope) = _votingState.calculateAndUpdatePower(
msg.sender,
amount,
unlockTime
);
// Update checkpoints
uint256 newPower = uint256(uint128(bias));
_checkpointState.writeCheckpoint(msg.sender, newPower);
// Mint veTokens
@> _mint(msg.sender, newPower);
emit LockCreated(msg.sender, amount, unlockTime);
}
}

The lock function calculates voting power (newPower) using a duration-based multiplier but only checks the supply limit against the base token amount being locked. This allows attackers to mint more veRAAC tokens than permitted by the protocol's supply cap when creating long-duration locks, as the voting power increases with lock duration while the validation remains based on the initial token amount.

Impact

This vulnerability directly impacts the protocol's governance integrity and token supply control mechanisms:

  1. Governance Manipulation Risk
    Attackers could accumulate disproportionate voting power by exploiting long-duration locks, enabling them to:

  • Control proposal outcomes

  • Bypass quorum requirements

  • Influence protocol parameter changes

  1. Tokenomics Inflation
    Unauthorized veRAAC minting bypasses the supply cap, potentially:

  • Diluting legitimate users' voting power

  • Devaluing locked positions

  • Creating artificial scarcity for governance participation

  1. Protocol Parameter Integrity
    The MAX_TOTAL_SUPPLY constant becomes ineffective, removing a key safeguard against:

  • Voting power concentration

  • Sybil attack mitigation

  • Long-term sustainability controls

The vulnerability enables systemic governance takeover at the cost of temporary capital lockup rather than genuine protocol commitment, fundamentally undermining the ve-token model's security assumptions.

Tools Used

Manual Review

Recommendations

Replace the existing supply check with a validation against the calculated voting power:

if (amount == 0) revert InvalidAmount();
if (amount > MAX_LOCK_AMOUNT) revert AmountExceedsLimit();
- if (totalSupply() + amount > MAX_TOTAL_SUPPLY) revert TotalSupplyLimitExceeded();
if (duration < MIN_LOCK_DURATION || duration > MAX_LOCK_DURATION)
revert InvalidLockDuration();
// ...
// Mint veTokens
+ if (totalSupply() + newPower > MAX_TOTAL_SUPPLY) revert TotalSupplyLimitExceeded();
_mint(msg.sender, newPower);
emit LockCreated(msg.sender, amount, unlockTime);
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.