In normal behavior, the withdrawTokens function allows the contract owner to withdraw ERC20 tokens from the hook contract to a designated address. The function is expected to safely transfer tokens and emit an accurate event reflecting the withdrawal.
The issue is twofold:
The function uses a raw IERC20(token).transfer(to, amount) call. Some non-standard ERC20 tokens do not revert on failure and instead return false. Using raw transfer may silently fail, leaving tokens locked in the contract.
The emitted TokensWithdrawn event has arguments in the wrong order (to, token, amount), which can cause incorrect indexing or misinterpretation of event data.
Likelihood:
High, because any call to withdrawTokens on non-standard ERC20 tokens that return false on failed transfer will trigger this issue.
Medium, as the event mismatch affects monitoring, analytics, and off-chain tracking tools relying on correct event data.
Impact:
Tokens may become permanently stuck in the hook contract if transfer fails silently.
Event data is unreliable, which can mislead auditing, monitoring, or user interfaces tracking withdrawals.
Explanation
A non-standard ERC20 token is deployed that returns false on transfer failure instead of reverting. When the owner calls withdrawTokens, the transfer does not revert, but no tokens are moved. The event emitted does not correctly identify the token and recipient.
Written explanation:
The test shows that withdrawTokens fails to safely transfer non-standard ERC20 tokens.
Tokens remain trapped in the contract, demonstrating the vulnerability.
Use OpenZeppelin SafeERC20 to handle non-standard tokens and fix the event argument order.
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.