RebateFi Hook

First Flight #53
Beginner FriendlyDeFi
100 EXP
View results
Submission Details
Severity: low
Valid

TokensWithdrawn event emits parameters in the wrong order – breaks all off-chain indexing

The contract defines a TokensWithdrawn event whose indexed parameters are ordered as (token, to, amount). However, when emitting the event inside withdrawTokens, the arguments are passed in the reversed order (to, token, amount). This mismatch causes the indexed topic for "token" to contain the recipient address and the indexed topic for "to" to contain the token address, rendering all off-chain indexing permanently incorrect.

// Root cauevent TokensWithdrawn(address indexed token, address indexed to, uint256 amount);
function withdrawTokens(address token, address to, uint256 amount) external onlyOwner {
IERC20(token).transfer(to, amount);
// @> BUG: arguments are emitted in the wrong order
emit TokensWithdrawn(to, token , amount); // @> should be (token, to, amount)
}se in the codebase with @> marks to highlight the relevant section
https://github.com/CodeHawks-Contests/2025-11-rebatefi-hook/blob/add4b298d1246ad2f1df726216849c1c31f83065/src/RebateFiHook.sol#L75

Risk

Likelihood:

  • Occurs on every execution of withdrawTokens

  • Owner withdrawals are expected and will happen repeatedly in production

Impact:

  • Etherscan, The Graph, Dune, Covalent, and every subgraph show garbage data (token address displayed as recipient and vice versa)

  • Frontends, analytics dashboards, tax tools, and monitoring bots become unusable or misleading

Proof of Concept

// Assume owner withdraws 1000 USDC to 0xDeaD...
address token = 0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48; // USDC
address to = 0xDeaD000000000000000000000000000000000000;
uint256 amount = 1000e6;
// Correct emission should produce topics:
// topic1 (token): 0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48
// topic2 (to) : 0xDeaD000000000000000000000000000000000000
// Actual emission (buggy):
emit TokensWithdrawn(to, token, amount);
// → topic1 (token) = 0xDeaD... (recipient address)
// → topic2 (to) = 0xA0b8699... (USDC address)
// All indexers now show: "Withdrew 0xDeaD... of token 1000e6" instead of correct data

Recommended Mitigation

- remove this code
+ add thfunction withdrawTokens(address token, address to, uint256 amount) external onlyOwner {
IERC20(token).transfer(to, amount);
- emit TokensWithdrawn(to, token , amount);
+ emit TokensWithdrawn(token, to, amount);
}
Updates

Lead Judging Commences

chaossr Lead Judge 8 days ago
Submission Judgement Published
Validated
Assigned finding tags:

Swapped token and to parameters in TokensWithdrawn event.

Support

FAQs

Can't find an answer? Chat with us on Discord, Twitter or Linkedin.

Give us feedback!