Core Contracts

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

Incorrectly reducing pool boost

Summary

In the BoostController contract, the removeBoostDelegation function incorrectly reduces pool boost totals even though these totals were never increased during delegation. Pool addresses and user addresses are mixed, leading to broken delegation system.

Vulnerability Details

Pool boost totals are decreased when removing delegations despite never being increased during delegation. The accounting mismatch allows draining pool boosts.

This is an example illustrating the issue by treating Alice as if she were a pool (as the current implementation does):

  1. poolBoosts[Alice].totalBoost = 15000

  2. Bob delegates 10,000 boost to Alice:

    • poolBoosts[Alice].totalBoost is not changed

    • userBoosts[Bob][Alice].amount = 10000

  3. Alice calls removeBoostDelegation:

    • poolBoosts[Alice].totalBoost = poolBoosts[Alice].totalBoost - userBoosts[Bob][Alice].amount

    • poolBoosts[Alice].totalBoost = 15000 - 10000 = 5000

    • delete userBoosts[Bob][Alice] sets default values

Alice should still have 15,000 total boost after removing the delegation, but she only has 5,000.

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();
// Update pool boost totals before removing delegation
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];
}

However, the userBoosts and poolBoosts mappings should contain addresses of pools only, because functions such as updateUserBoost check if the pool is supported and a user's address cannot be a supported pool. The problem is that delegation uses user addresses that cannot be supported pools. When removing delegations, the function attempts to modify pool boosts using user addresses (poolBoosts[msg.sender]), which leads to other issues.

Impact

High: Incorrect reduction of pool boost totals leading to incorrect reward calculations. The delegation mechanism is broken.

Recommendations

Consider fixing the delegation mechanism and ensure pool boost accounting matches delegation lifecycle.

Updates

Lead Judging Commences

inallhonesty Lead Judge 5 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.