Core Contracts

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

totalSupply is checked incorrectly when calling lock() in VeRAACToken.sol

Summary

When calling lock() in veRAACToken.sol, the total amount of veRAAC token cannot exceed MAX_TOTAL_SUPPLY.

RAAC token and veRAAC token has different value according the the duration locked. The check assumes that RAAC token have the same value as veRAAC token when checking MAX_TOTAL_SUPPLY, which is incorrect.

if (totalSupply() + amount > MAX_TOTAL_SUPPLY) revert TotalSupplyLimitExceeded();

Vulnerability Details

In lock(), the function checks whether the totalSupply, which refers to veRAACToken, + amount, which is the RAAC token, is not greater than MAX_TOTAL_SUPPLY.

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();

Assuming that 1 RAACToken is worth 1 veRAACToken if the duration is locked for 4 years, and 1 RAACToken is worth 0.25 veRAACToken if the duration is locked for 1 year.

A user has 500,000 RAACTokens to deposit and the total supply of veRAACToken is currently at 99.7M (left 300k). The user cannot deposit 500,000 RAACTokens for 1 year to get 125,000 veRAACTokens because it will exceed the MAX_TOTAL_SUPPLY since the lock() function assumes all RAACToken is equal to veRAACToken, (99.7 + 0.5 = 100.2M, fails), instead of (99.7 + 0.125 = 99.825M, passes)

Impact

Some lock() positions cannot be created.

Tools Used

Manual Review

Recommendations

Recommend having the check when veRAAC token is calculated

// Calculate initial voting power
(int128 bias, int128 slope) = _votingState.calculateAndUpdatePower(
msg.sender,
amount,
unlockTime
);
// Update checkpoints
> uint256 newPower = uint256(uint128(bias));
+ if (totalSupply() + newPower > MAX_TOTAL_SUPPLY) revert TotalSupplyLimitExceeded();
_checkpointState.writeCheckpoint(msg.sender, newPower);
// Mint veTokens
> _mint(msg.sender, newPower);
emit LockCreated(msg.sender, amount, unlockTime);
Updates

Lead Judging Commences

inallhonesty Lead Judge about 1 month 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.