Core Contracts

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

Unauthorized boost manipulation in BoostController leading to protocol-wide distortions

Summary

The updateUserBoost function in BoostController.sol lacks proper access controls, allowing any external actor to modify users' boost parameters and pool metrics. This enables malicious manipulation of reward distributions, governance voting weights, and liquidity mining allocations across the protocol.

Finding Description

The issue exists in the updateUserBoost function of the BoostController contract, which updates user boost calculations and pool metrics without proper authorization checks. The relevant code block shows no access control modifiers beyond basic transaction safety measures:

function updateUserBoost(address user, address pool) external override nonReentrant whenNotPaused {
// Missing access control check
if (paused()) revert EmergencyPaused();
if (user == address(0)) revert InvalidPool();
if (!supportedPools[pool]) revert PoolNotSupported();
UserBoost storage userBoost = userBoosts[user][pool];
PoolBoost storage poolBoost = poolBoosts[pool];
uint256 oldBoost = userBoost.amount;
uint256 newBoost = _calculateBoost(user, pool, 10000);
userBoost.amount = newBoost;
userBoost.lastUpdateTime = block.timestamp;
if (newBoost >= oldBoost) {
poolBoost.totalBoost = poolBoost.totalBoost + (newBoost - oldBoost);
} else {
poolBoost.totalBoost = poolBoost.totalBoost - (oldBoost - newBoost);
}
poolBoost.workingSupply = newBoost;
poolBoost.lastUpdateTime = block.timestamp;
}

The function's external visibility combined with missing role-based checks allows any address to trigger boost recalculations for arbitrary users and pools. This violates the protocol's design principle stated in the contract comments: "Manages boost calculations and delegations for the RAAC protocol" which implies controlled access to these sensitive operations.

The root cause manifests through three key flaws:

  1. No validation of caller's relationship to the target user/pool

  2. Direct modification of poolBoost.workingSupply without authorization

  3. Unrestricted ability to reset lastUpdateTime timestamps

The highest impact scenario involves an attacker repeatedly calling updateUserBoost for high-value users in active pools, artificially inflating/deflating workingSupply metrics that feed into gauge reward calculations. This would allow siphoning rewards from legitimate users through manipulated boost multipliers.

Impact

Attackers can distort all boost-dependent protocol mechanisms including reward distributions (stealing funds), governance voting weights (manipulating proposals), and liquidity mining allocations (creating unfair advantages). The impact is protocol-wide and affects all pools integrated with the BoostController.

Proof Of Concept

  1. Attacker identifies a victim with significant veToken holdings in PoolA

  2. Attacker calls:
    BoostController.updateUserBoost(victimAddress, poolAAddress)

  3. The forced update:

    • Recalculates victim's boost using current veToken balance (via _calculateBoost)

    • Overwrites poolBoost.workingSupply with new value (line 127)

    • Updates lastUpdateTime (line 128)

  4. Gauge systems pulling getWorkingBalance() now use manipulated values:
    BaseGauge.calculateRewards() uses corrupted boost data

  5. Attaker repeats across multiple pools to maximize distortion

Mitigation

Add role-based access control to restrict boost updates to either the user themselves or authorized managers. The fix should implement a permission check at the function entry point.

function updateUserBoost(address user, address pool) external override nonReentrant whenNotPaused {
+ require(
+ msg.sender == user || hasRole(MANAGER_ROLE, msg.sender),
+ "Unauthorized boost update"
+ );
+
if (paused()) revert EmergencyPaused();
if (user == address(0)) revert InvalidPool();
Updates

Lead Judging Commences

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

BoostController::updateUserBoost lacks caller validation, allowing anyone to force delegation of any user's boost to any pool without consent, hijacking voting power

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

BoostController::updateUserBoost lacks caller validation, allowing anyone to force delegation of any user's boost to any pool without consent, hijacking voting power

Support

FAQs

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

Give us feedback!