n the router update mechanism across all strategy contracts (StrategyArb.sol, StrategyOp.sol, StrategyMainnet.sol).
It is equired that when setRouter()
is called, the router address must change to a new value different from the current one, but the implementation allows setting the router to the same address that's currently set.
The bug is because the implementation makes no comparison between the new and current router addresses before updating.
When newRouter == routerBefore
:
The update proceeds without reverting
An unnecessary approval is granted
The assertion router() != routerBefore
fails
Gas is wasted on a no-op transaction
In StrategyArb.sol, StrategyOp.sol, and StrategyMainnet.sol:
The implementation violates a core state transition requirement - router updates must result in actual state changes. The code blindly updates and approves without validating if the new router differs from the current one.
Impact Flow:
Management calls setRouter with current router address
State remains unchanged but triggers token approval
Underlying token gets unnecessarily re-approved for max amount
Gas is wasted on redundant state updates
Violates specification's state transition requirements
The bug affects all three strategy contracts since they share this implementation pattern:
StrategyArb.sol
StrategyOp.sol
StrategyMainnet.sol
Each strategy interacts with different DEX routers (Ramses, Velodrome, Curve) but shares the same flawed router update mechanism that allows redundant state updates and approvals.
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.