Core Contracts

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

Lack of enforcement of the `MAX_TOTAL_LOCKED_AMOUNT`

Summary

The issue allows users to lock more tokens than intended when creating the lock, leading to imbalances in the veRAAC ecosystem.

Vulnerability Details

Issue: MAX_TOTAL_LOCKED_AMOUNT Not Enforced

The veRAACToken contract defines a maximum total locked amount (MAX_TOTAL_LOCKED_AMOUNT), intended to limit the total amount of RAAC that can be locked in the system. However, the contract does not enforce this limit. While individual lock amounts (MAX_LOCK_AMOUNT) and lock durations (MAX_LOCK_DURATION) are checked, there is no check to prevent the sum of all locked amounts from exceeding MAX_TOTAL_LOCKED_AMOUNT.

Location: veRAACToken.sol:lock

function lock(uint256 amount, uint256 duration) external nonReentrant whenNotPaused {
//@audit there is no check if MAX_TOTAL_LOCKED_AMOUNT will be exceeded after the locked amount is added!
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();
raacToken.safeTransferFrom(msg.sender, address(this), amount);
uint256 unlockTime = block.timestamp + duration;
//@audit lock is created, boostState is changed but the MAX_TOTAL_LOCKED_AMOUNT is still not checked
_lockState.createLock(msg.sender, amount, duration);
_updateBoostState(msg.sender, amount);
//@audit votingPower is updated and can be inflated
(int128 bias, int128 slope) = _votingState.calculateAndUpdatePower(
msg.sender,
amount,
unlockTime
);
uint256 newPower = uint256(uint128(bias));
_checkpointState.writeCheckpoint(msg.sender, newPower);
//@audit votingPower created which will be inflated after a certain lockedAmount is passed
_mint(msg.sender, newPower);
emit LockCreated(msg.sender, amount, unlockTime);
}

Example:

  1. MAX_TOTAL_LOCKED_AMOUNT is set to 1,000,000,000e18

  2. The curent lockedAmount = 990,000,000e18

  3. Alice locks 10,000,000e18 RAAC.

  4. Bob locks 10,000,000e18 RAAC.

  5. Ema locks 10,000,000e18 RAAC.

The contract allows Bob's and Ema's lock, even though the total locked amount (1,020,000,000e18) now significantly exceeds MAX_TOTAL_LOCKED_AMOUNT.

Impact

Severity: High

Potential Consequences:

  • Unfair Rewards: The boost calculation mechanism in veRAACToken relies on the total locked amount. Inflating the total locked amount.

  • Potential for Manipulation: The boost mechanism is tied to governance, the inflated boost could allow manipulation of governance proposals and voting power.

Tools Used

  • Manual Code Review

Recommendations

  1. Enforce MAX_TOTAL_LOCKED_AMOUNT: Add check in the lock function to ensure that the total locked amount does not exceed MAX_TOTAL_LOCKED_AMOUNT. The provided code snippet below demonstrates the necessary changes:

function lock(uint256 amount, uint256 duration) external nonReentrant whenNotPaused {
// ... (other checks)
if (_lockState.totalLocked + amount > _lockState.maxTotalLocked) {
revert TotalLockedAmountExceeded(); // Custom error
}
// ... (rest of the lock logic)
}

(Recommended code is not tested)

Updates

Lead Judging Commences

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

`veRAACToken::lock` function doesn't check MAX_TOTAL_LOCKED_AMOUNT

Support

FAQs

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