Summary
The BoostController.sol contract contains a critical vulnerability where the _calculateBoost function enforces a hardcoded boost cap through MAX_BOOST, overriding the configurable parameters set via governance.
Vulnerable Code
function _calculateBoost(address user, address pool, uint256 amount) internal view returns (uint256) {
uint256 maxBoostAmount = amount * MAX_BOOST / 10000;
if (boostedAmount > maxBoostAmount) {
return maxBoostAmount;
}
return boostedAmount;
}
function setBoostParameters(
uint256 maxBoost,
uint256 minBoost,
uint256 boostWindow
) external onlyRole(MANAGER_ROLE) {
if (maxBoost < minBoost) revert InvalidBoostAmount();
if (maxBoost > 50000) revert MaxBoostExceeded();
boostState.maxBoost = maxBoost;
}
Impact Analysis
Parameter Override
boostState.maxBoost = 40000;
amount = 1000e18;
maxBoostAmount = 1000e18 * 25000 / 10000;
Economic Impact
Users receive 40% less boost than governance intended
Protocol loses competitive advantage
Staking incentives reduced
Governance Implications
Manager role authority undermined
Protocol flexibility limited
Documentation contradictions
Proof of Concept
contract BoostOverrideTest {
BoostController controller;
function testBoostOverride() public {
controller.setBoostParameters(40000, 10000, 7 days);
uint256 baseAmount = 1000e18;
(uint256 basisPoints, uint256 boosted) = controller.calculateBoost(
user,
pool,
baseAmount
);
assert(boosted <= baseAmount * 25000 / 10000);
assert(boosted < baseAmount * 40000 / 10000);
}
}
Recommended Mitigation
contract BoostController {
function _calculateBoost(
address user,
address pool,
uint256 amount
) internal view returns (uint256) {
uint256 maxBoostAmount = amount * boostState.maxBoost / 10000;
if (boostedAmount > maxBoostAmount) {
return maxBoostAmount;
}
return boostedAmount;
}
event MaxBoostUpdated(
uint256 oldMaxBoost,
uint256 newMaxBoost,
address indexed governor
);
}
Additional Recommendations
Parameter Validation:
function setBoostParameters(
uint256 maxBoost,
uint256 minBoost,
uint256 boostWindow
) external onlyRole(MANAGER_ROLE) {
require(maxBoost >= MIN_PROTOCOL_BOOST, "Below min protocol boost");
require(maxBoost <= MAX_PROTOCOL_BOOST, "Exceeds max protocol boost");
}
Timelock for Parameter Changes:
struct PendingBoostParams {
uint256 maxBoost;
uint256 minBoost;
uint256 boostWindow;
uint256 effectiveTime;
}
PendingBoostParams public pendingParams;
uint256 public constant PARAM_TIMELOCK = 2 days;
Emergency Controls:
modifier whenBoostActive {
require(!boostPaused, "Boost system paused");
_;
}