Core Contracts

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

Incorrect Boost Delegation Handling Leading to State Manipulation

Summary

The delegateBoost and removeBoostDelegation functions introduce a vulnerability that allows users to manipulate the boost delegation system. The core issues arise from improper state updates when delegating boosts and when removing expired delegations. Additionally, the removeBoostDelegation function incorrectly assumes that msg.sender is a pool, leading to unintended behavior and potential exploitation.

Vulnerability Details

1. Incorrect Handling of Pool Boost Totals in removeBoostDelegation

The removeBoostDelegation function contains a critical flaw where it assumes msg.sender is a pool when updating poolBoost.totalBoost and poolBoost.workingSupply. Since the function is called by the recipient of the delegation, this leads to incorrect state updates.

Affected Code:

https://github.com/Cyfrin/2025-02-raac/blob/89ccb062e2b175374d40d824263a4c0b601bcb7f/contracts/core/governance/boost/BoostController.sol#L248

function removeBoostDelegation(address from) external override nonReentrant {
UserBoost storage delegation = userBoosts[from][msg.sender];
if (delegation.delegatedTo != msg.sender) revert DelegationNotFound();
if (delegation.expiry > block.timestamp) revert InvalidDelegationDuration();
// Incorrect assumption that msg.sender is a pool
PoolBoost storage poolBoost = poolBoosts[msg.sender];
if (poolBoost.totalBoost >= delegation.amount) {
poolBoost.totalBoost -= delegation.amount;
}
if (poolBoost.workingSupply >= delegation.amount) {
poolBoost.workingSupply -= delegation.amount;
}
poolBoost.lastUpdateTime = block.timestamp;
emit DelegationRemoved(from, msg.sender, delegation.amount);
delete userBoosts[from][msg.sender];
}

https://docs.raac.io/core/governance/boost/BoostController

This function is designed to allow a user to delegate their boost to another user. Therefore, msg.sender is expected to be the address receiving the boost, not a pool or contract address.

2. Delegation Removal Exploitation

The pool boost values are not updated when a boost is delegated, but only when removed.

https://github.com/Cyfrin/2025-02-raac/blob/89ccb062e2b175374d40d824263a4c0b601bcb7f/contracts/core/governance/boost/BoostController.sol#L212

Impact

These vulnerabilities allows users to manipulate boost delegation.

Tools Used

  • Manual code review

Recommendations

  1. Correct Pool Boost Updates in removeBoostDelegation:

    • Ensure the function updates the correct pool’s totalBoost and workingSupply instead of assuming msg.sender is a pool.

    • Introduce a mapping to track which pool the delegation applies to and update it accordingly.

  2. Update Boost Totals When Delegating:

    • Adjust totalBoost and workingSupply immediately when a boost is delegated to prevent later manipulation.

Updates

Lead Judging Commences

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

BoostController's delegation system fundamentally broken due to missing pool associations, treating recipient addresses as pools and never properly updating pool boost metrics

BoostController removes pool boost on delegation removal without adding it on delegation creation, leading to accounting inconsistencies and potential underflows

Support

FAQs

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