Core Contracts

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

Delegation Lock Issue in `BoostController` Contract

Summary

The delegateBoost function in the BoostController contract does not allow users to delegate their boost more than once. Even after the delegation period expires, the original delegator cannot re-delegate unless the recipient manually removes the expired delegation. This creates a scenario where a user may be permanently blocked from delegating if the recipient does not actively clear the expired delegation.

Vulnerability Details

Affected Function

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(); // Locks delegation permanently if not removed
delegation.amount = amount;
delegation.expiry = block.timestamp + duration;
delegation.delegatedTo = to;
delegation.lastUpdateTime = block.timestamp;
emit BoostDelegated(msg.sender, to, amount, duration);
}

Root Cause

  • The condition if (delegation.amount > 0) revert BoostAlreadyDelegated(); permanently prevents a user from delegating again if the recipient does not manually remove the expired delegation.

  • The removeBoostDelegation function must be called by the recipient after the expiry for the original delegator to regain delegation ability.

  • If the recipient does not call removeBoostDelegation, the original delegator remains locked out of future delegations.

Impact

  • Users may be permanently unable to delegate their boost if the recipient is inactive or unwilling to remove the expired delegation.

  • This creates an unnecessary dependency on the recipient to take action, limiting usability and fairness.

Tools Used

  • Manual Code Review

Recommendations

Suggested Fix:

  1. Modify the delegateBoost function to allow re-delegation after expiry:

    if (delegation.expiry > block.timestamp && delegation.amount > 0) {
    revert BoostAlreadyDelegated(); // Prevent active redelegation but allow expired ones
    }
  2. Automatically clear expired delegations in delegateBoost before assigning a new one:

    if (delegation.expiry <= block.timestamp) {
    delete userBoosts[msg.sender][to]; // Clear expired delegation
    }
Updates

Lead Judging Commences

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

BoostController: Users unable to remove their own expired boost delegations, creating dependency on recipients and preventing efficient reallocation of boosts

Support

FAQs

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

Give us feedback!