Core Contracts

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

Boost Inflation via Multiple Delegations

Summary

The delegateBoost function in BoostController.sol allows a user to delegate their entire veToken balance multiple times to different pools. This results in an inflated total boost across pools, allowing users to gain excessive benefits beyond their actual voting power.

Vulnerability Details

The issue arises because there is no tracking mechanism to ensure that a user’s delegated boost does not exceed their available veToken balance. As a result, a user can delegate their full balance multiple times, effectively creating an inflated boost across multiple pools.

Relevant Code

function delegateBoost(
address to,
uint256 amount,
uint256 duration
) external override nonReentrant {
if (paused()) revert EmergencyPaused();
if (to == address(0)) revert InvalidPool();
if (amount == 0) revert InvalidBoostAmount();
if (duration < MIN_DELEGATION_DURATION || duration > MAX_DELEGATION_DURATION)
revert InvalidDelegationDuration();
uint256 userBalance = IERC20(address(veToken)).balanceOf(msg.sender);
if (userBalance < amount) revert InsufficientVeBalance();
UserBoost storage delegation = userBoosts[msg.sender][to];
if (delegation.amount > 0) revert BoostAlreadyDelegated();
delegation.amount = amount;
delegation.expiry = block.timestamp + duration;
delegation.delegatedTo = to;
delegation.lastUpdateTime = block.timestamp;
emit BoostDelegated(msg.sender, to, amount, duration);
}

The contract verifies that the user has a sufficient balance before delegating, but it does not check if the same balance has already been delegated elsewhere. This enables multiple delegations that exceed the actual veToken holdings of the user.

Impact

Boost inflation allows users to unfairly gain higher rewards or governance influence.
Pools may be misled into overestimating their boost, leading to unfair advantage distribution.

Tools Used

Manual code review

Recommended Mitigation

To prevent multiple delegations exceeding a user’s balance:

  1. Introduce a mapping to track the total delegated amount per user.

  2. Before delegating, check that the sum of all delegated amounts does not exceed the user’s veToken balance.

  3. Modify delegateBoost to update and enforce this tracking mechanism.

Suggested Fix

mapping(address => uint256) public totalDelegatedBoost;
function delegateBoost(
address to,
uint256 amount,
uint256 duration
) external override nonReentrant {
if (paused()) revert EmergencyPaused();
if (to == address(0)) revert InvalidPool();
if (amount == 0) revert InvalidBoostAmount();
if (duration < MIN_DELEGATION_DURATION || duration > MAX_DELEGATION_DURATION)
revert InvalidDelegationDuration();
uint256 userBalance = IERC20(address(veToken)).balanceOf(msg.sender);
if (totalDelegatedBoost[msg.sender] + amount > userBalance) revert InsufficientVeBalance();
UserBoost storage delegation = userBoosts[msg.sender][to];
if (delegation.amount > 0) revert BoostAlreadyDelegated();
totalDelegatedBoost[msg.sender] += amount;
delegation.amount = amount;
delegation.expiry = block.timestamp + duration;
delegation.delegatedTo = to;
delegation.lastUpdateTime = block.timestamp;
emit BoostDelegated(msg.sender, to, amount, duration);
}

This ensures that a user cannot delegate more than their available balance.

Updates

Lead Judging Commences

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

BoostController::delegateBoost lacks total delegation tracking, allowing users to delegate the same veTokens multiple times to different pools for amplified influence and rewards

Support

FAQs

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