Issue:
The underlying.safeApprove(router, type(uint256).max)
call in both _initStrategy
and setRouter
grants unlimited token allowance to the current router
. However, the existing approval is not reset to zero before setting a new router. If the previous router is compromised, it retains the ability to transfer unlimited funds, even after the router is updated.
Impact:
High. Why?
Unlimited Fund Access by a Compromised Router:
A malicious or compromised router can drain the underlying
tokens using the retained approval.
Lack of Control Over Token Transfers:
The contract cannot prevent misuse of allowances granted to previously approved routers.
Extended Attack Surface:
Multiple routers with type(uint256).max
approvals significantly increase the protocol's vulnerability.
setRouter
Function:
Router Compromise Before Update:
A malicious actor gains control of the current router
.
Approval Retention:
The router retains its type(uint256).max
allowance even after setRouter
is called to update the router.
Fund Drain:
The malicious router transfers all underlying
tokens using the retained unlimited allowance.
Exploit Execution:
The attacker repeatedly drains the strategy’s tokens until the protocol identifies and revokes the allowance manually.
Revoke existing approvals by setting them to zero before updating the router.
Introduce a timelock mechanism for router updates to allow for auditing and review before execution.
Maintain a whitelist of trusted routers and enforce validation before updates.
Exploit Scenario:
The attacker compromises the current router and exploits its unlimited allowance after setRouter
updates to a new router.
Exploit Implementation:
Exploit Execution:
Deploy MaliciousRouter
with the address of the underlying
token.
Call exploit
after observing that the router has been updated without resetting allowances.
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.