Open code423n4 opened 1 year ago
trust1995 marked the issue as primary issue
trust1995 marked the issue as satisfactory
trust1995 changed the severity to 3 (High Risk)
0xLightt marked the issue as sponsor acknowledged
0xLightt marked the issue as disagree with severity
0xLightt marked the issue as sponsor confirmed
Hey, this happens due to the not being able to remove strategies from FlyWheelCore and the immutability in bribes. In accruing bribes for gauges, there is only one general FlyWheel per token, so removing it from the RewardsDepot would actually brick all rewards of the FlyWheel's token.
The goal with removing the flywheel from the gauge is to stop forcing the user to call accrue
and update the rewardIndex for that flywheel to save gas or remove an unwanted token. After removing this forced accrual, users can increase their voting balance, accrue and then decrease the voting balance without accruing again. So the balances to accrue rewards can't be trusted and would lead to issues if we tried to reuse the same FlyWheel for the same strategy. One solution would be to add the option to remove the strategy from the flywheel but could lead to not accrued rewards being bricked.
If there is a need to migrate bribe system, there needs to be a migration of the gauge system as well. This is intended so that users can opt in into the migration, in turn, protecting them.
I believe the best solution would be to leave it up to users to choose the bribes they want to accrue. By default all user could have all bribes set as optOut for all strategies and FlywheelBooster
would always return 0 when querying boostedBalanceOf
and wouldn't take the user's balance into account in boostedTotalSupply
. If the user decides to optIn into a bribe for strategy (we would mimic a minting scenario), would accrue with 0 balance, have his current balance added to the the strategy's boostedTotalSupply
and boostedBalanceOf
would return the allocated gaugeWeight instead of 0. The opposite when a user tries to optOut after being optIn, but there should be the option to give up rewards, actually bricking in them, but would be useful in case there is an issue with the token and for example reverts when transferring from the rewardsDepot. The gauge would force the user to accrue rewards for all optIn bribes when changing it's balance.
This way we can completely remove governance around bribes, but would still keep the immutability of the bribes system intact.
trust1995 marked the issue as selected for report
Lines of code
https://github.com/code-423n4/2023-05-maia/blob/main/src/gauges/BaseV2Gauge.sol#L144-L152
Vulnerability details
Impact
Removing a bribe Flywheel (
FlywheelCore
) from a Gauge (viaBaseV2Gauge::removeBribeFlywheel
) does not remove the reward asset (callMultiRewardsDepot::removeAsset
) from the rewards depo (BaseV2Gauge::multiRewardsDepot
), making it impossible to add a new Flywheel (by callingBaseV2Gauge::addBribeFlywheel
) with the same reward token (becauseMultiRewardsDepot::addAsset
reverts as the assets already exists).Impact is limiting protocol functionality in unwanted ways, possibly impacting gains in the long run. Example due to incentives lost by not having a specific token bribe reward.
Proof of Concept
Observation: a
BribeFlywheel
is aFlywheelCore
with aFlywheelBribeRewards
set as theFlywheelRewards
, typically created using theBribesFactory::createBribeFlywheel
Scenario and execution flow
BribeFlywheel
to the recently deployedUniswapV3Gauge
contract.UniswapV3GaugeFactory::BaseV2GaugeFactory::addBribeToGauge
BaseV2Gauge::addGaugetoFlywheel
where the bribe flywheel reward token is added to the multi reward depoUniswapV3GaugeFactory::BaseV2GaugeFactory::removeBribeFromGauge
BaseV2Gauge::removeBribeFlywheel
where the flywheel is removed but the reward token asset is not remove from the multi reward depo, there is no call toMultiRewardsDepot::removeAsset
:ErrorAddingAsset
since theaddAsset
call reverts since the rewards token was not removed with the previous call toBaseV2Gauge::removeBribeFlywheel
.Tools Used
Manual analysis
Recommended Mitigation Steps
when
BaseV2Gauge::removeBribeFlywheel
is called for a particular flywheel, also remove it's corresponding reward depo token.Example implementation
Assessed type
Other