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.
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:
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:
No validation of caller's relationship to the target user/pool
Direct modification of poolBoost.workingSupply without authorization
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.
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.
Attacker identifies a victim with significant veToken holdings in PoolA
Attacker calls:
BoostController.updateUserBoost(victimAddress, poolAAddress)
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)
Gauge systems pulling getWorkingBalance() now use manipulated values:
BaseGauge.calculateRewards() uses corrupted boost data
Attaker repeats across multiple pools to maximize distortion
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.
The contest is live. Earn rewards by submitting a finding.
This is your time to appeal against judgements on your submissions.
Appeals are being carefully reviewed by our judges.