RebateFi Hook

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

The `ReFiSwapRebateHook::withdrawTokens` function emits `TokensWithdrawn` event with wrong parameters order.

TokensWithdrawn event emitted with swapped parameters, indexers and frontends parse the wrong addresses (token vs recipient)

Description

  • The contract defines the TokensWithdrawn event with the standard and expected parameter order:
    event TokensWithdrawn(address indexed token, address indexed to, uint256 amount);

  • However, when emitting, the arguments are passed in reverse order (to, token, amount).

  • As a result, off-chain tools that rely on the event signature and ABI (The Graph, Dune, Etherscan, wallets, internal dashboards) will interpret the first indexed topic as the token address being the recipient, and the second as the token address — completely swapping the meaning.

// Root cause in the codebase with @> marks to highlight the relevant section
function withdrawTokens(address token, address to, uint256 amount) external onlyOwner {
IERC20(token).transfer(to, amount);
@> emit TokensWithdrawn(to, token, amount);
}

Risk

Likelihood:

  • Every successful withdrawal by the owner triggers the incorrectly ordered event

  • All existing and future indexers already use the declared event ABI

Impact:

  • Analytics show withdrawals going to the token contract address and tokens being sent to the actual recipient

  • Monitoring alerts (e.g., “large withdrawal of USDC”) fire on the wrong address

  • Frontends and explorers display misleading or completely incorrect withdrawal data

  • Breaks compatibility with any tool that auto-parses this common event pattern

Proof of Concept

Event parameters should be in the defined order.

event TokensWithdrawn(address indexed token, address indexed to, uint256 amount);

Recommended Mitigation

Change the event emission to the correct order: first the token address, then the to receiver address, and finally the amount.

function 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 12 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!