Core Contracts

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

Incorrect poolBoosts Updates Due to Inconsistent Key Usage

Summary

The contract inconsistently updates poolBoosts across different functions:

  • updateUserBoost() correctly uses pool as the key.

  • removeBoostDelegation() incorrectly uses msg.sender instead of the correct pool.

Vulnerability Details

Inconsistent Access in removeBoostDelegation()

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();
PoolBoost storage poolBoost = poolBoosts[msg.sender]; // Uses `msg.sender` instead of `pool`
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];
}

Problem:

  • The function removes boost from poolBoosts[msg.sender] instead of the actual pool.

  • If msg.sender is not the correct pool, boost removal could affect the wrong pool.

  • This creates governance weight miscalculations, misallocates voting power, and incorrectly adjusts staking rewards.

Correct Behavior in updateUserBoost()

PoolBoost storage poolBoost = poolBoosts[pool]; // ✅ Correctly uses `pool`

Impact

  • Boost tracking can be incorrect, leading to voting power miscalculations.

    Users may remove boosts from the wrong pool, creating governance imbalances.

Tools Used

Manual Review

Recommendations

Modify removeBoostDelegation() to correctly reference the delegated pool instead of msg.sender.

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();
address pool = delegation.delegatedTo; // Get the correct pool address
PoolBoost storage poolBoost = poolBoosts[pool]; // Now correctly using `pool`
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, pool, delegation.amount);
delete userBoosts[from][msg.sender];
}
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

Support

FAQs

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