Description
It is stated in both the documentation and code that the maximum boost multiplier allowed in the BoostController contract should be 2.5x. However, the BoostController::setBoostParameters() function allows the manager to set the max boost up to 5x, which is twice the intended maximum value.
Context
Impact
Medium. This issue allows the contract manager to set the max boost multiplier to a value that's twice as large as what's advertised in the documentation and code.
Likelihood
Low. Requires the contract manager to deliberately update the max boost multiplier to a value larger than 2.5x.
Proof of Concept
To execute this proof of concept integrate foundry by running the following commands in your terminal, in the project's root directory:
mkdir out lib
git submodule add https://github.com/foundry-rs/forge-std lib/forge-std
touch foundry.toml
Next, configure foundry by adding the following settings to foundry.toml:
[profile.default]
src = "contracts"
out = "out"
lib = "lib"
After that, create a foundry/ directory inside the test/ directory. Inside foundry/, create the following file:
And then paste the following code to BoostModule.t.sol:
pragma solidity ^0.8.19;
import {Test, console} from "../../lib/forge-std/src/Test.sol";
import {RAACToken} from "../../contracts/core/tokens/RAACToken.sol";
import {veRAACToken} from "../../contracts/core/tokens/veRAACToken.sol";
import {BoostController} from "../../contracts/core/governance/boost/BoostController.sol";
contract BoostModuleTest is Test {
address public immutable OWNER = makeAddr("owner");
address public immutable TIMELOCK = makeAddr("timelock");
address public immutable USER = makeAddr("user");
address public immutable POOL_1 = makeAddr("pool-1");
address public immutable POOL_2 = makeAddr("pool-2");
RAACToken public raac;
veRAACToken public veRaac;
BoostController public boostController;
function setUp() public {
vm.startPrank(OWNER);
raac = new RAACToken(TIMELOCK, 0, 0);
veRaac = new veRAACToken(address(this));
boostController = new BoostController(address(veRaac));
vm.stopPrank();
}
function test_poc_invalid_max_boost_check() public {
vm.startPrank(OWNER);
uint256 theoreticalMaxBoost = boostController.MAX_BOOST();
uint256 newMaxBoost = 50000;
boostController.setBoostParameters(newMaxBoost, 10000, 7 days);
assertTrue(newMaxBoost > theoreticalMaxBoost);
}
}
And finally, run the proof of concept with the following command:
forge test --mt test_poc_invalid_max_boost_check -vvv
Recommendations
function setBoostParameters(
uint256 maxBoost,
uint256 minBoost,
uint256 boostWindow
) external onlyRole(MANAGER_ROLE) {
if (maxBoost < minBoost) revert InvalidBoostAmount();
- if (maxBoost > 50000) revert MaxBoostExceeded(); // Max 5x absolute limit
+ if (maxBoost > MAX_BOOST) revert MaxBoostExceeded();
if (boostWindow < 1 days || boostWindow > 30 days) revert InvalidDelegationDuration();
boostState.maxBoost = maxBoost;
boostState.minBoost = minBoost;
boostState.boostWindow = boostWindow;
emit BoostParametersUpdated(maxBoost, minBoost, boostWindow);
}