The three strategies grant infinite approval to their respective routers, but in the case of StrategyOp.sol and StrategyArb.sol, these routers can be changed. However, when the routers are changed, the infinite approval is not revoked from the previous router. StrategyMainnet.sol itself can't change the router.
Using StrategyArb.sol as an example, in _initStrategy
, max approval is granted to the router.
And in the setRouter
function, the management can change the router. But as can be observed, approval from the previous router is not revoked, and cannot be.
This is very dangerous, because if the router is compromised, it can be used to drain assets from the strategy. Since the router an external integration, outside the control of the protocol, hence the ability to change it, the older router still holds max approval. Even if its changed because of a compromise or any other reason, it still has access to the strategy's assets.
Also, we can observe that the router in use is upgradeable, and currently points to an implementation that has an admin. A potential attack vector here is that if ramses admin gets compromised, the roter can be upgraded to a malicious implementation that can be used to transfer assets from various addresses that had given the router max approval, which will incidentally include our strategy, leading to loss of funds for the protocol. So even if news gets out that the router is now compromised, there's no way to protect the protocol from the compromised router, though setRouter
can be used to change router, because the approval is still there.
A fairly similar attack type occured on Socket protocol sometime this year, in which the attacker injected a malicious transferFrom
function through which wallets that had given the contract max approvals had their approved assets drained.
The same issue exists in StrategyOp.sol, where router can be changed but previous approval is also not revoked.
Zero out the old router's approval before setting a new one.
In the StrategyMainnet.sol, _initStrategy
, is called to approve curve router to spend all of the protcol's tokens. But, in comparison to StrategyArb.sol and StrategyOp.sol, there's no equivalent function to update the curve router address if need be. So if curve router gets compromised, the protocol will not be able to update the router address.
Also, similar to l-01 above, the protocol has no way to revoke the router's max approval if it gets compromised.
Introduce an equivalent to setRouter
and revoke all approvals before setting new one.
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.