RebateFi Hook

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

Params in `RebateFiHook::TokensWithdrawn` event are in wrong order!

In withdrawTokens, the TokensWithdrawn event is emitted with to and token params swapped indexers, subgraphs, off-chain analytics, and incident responders relying on logs will attribute withdrawals to the wrong token/recipient, breaking monitoring/accounting


Description

  • On owner-triggered withdrawals, the contract should emit TokensWithdrawn(token, to, amount) so that (a) token indexed is the token address and to indexed is the recipient. This keeps on-chain logs aligned with the event ABI and consumer expectations.


  • The emit statement swaps the first two arguments, so the first indexed param actually contains the recipient and the second contains the token, contradicting the event signature. This silently corrupts downstream consumers.


// Root cause (wrong argument order):
event TokensWithdrawn(address indexed token, address indexed to, uint256 amount);
function withdrawTokens(address token, address to, uint256 amount) external onlyOwner {
IERC20(token).transfer(to, amount);
// @> emit TokensWithdrawn(to, token, amount); // <- MISORDERED: (to, token) vs (token, to)
}

Risk

Likelihood:

  • Reason: Every successful withdrawTokens call will emit this event, so the condition is met whenever withdrawals occur.

Impact:

  • Impact: Off-chain accounting/alerting tools will attribute withdrawals to the wrong token/recipient, causing false positives/negatives in monitoring.

Proof of Concept

Paste the following into RabateFiHookTest.t.sol

function test_WithdrawTokens_EventParamsAreSwapped() public {
// Arrange: send tokens to the hook so it has a balance to withdraw
uint256 transferAmount = 1 ether;
reFiToken.transfer(address(rebateHook), transferAmount);
address token = address(reFiToken);
address to = address(this);
uint256 withdrawAmount = 0.5 ether;
// We intentionally expect the WRONG order that the contract currently emits:
// event TokensWithdrawn(address indexed token, address indexed to, uint256 amount);
// Current code emits (to, token, amount) instead of (token, to, amount).
vm.expectEmit(true, true, false, true, address(rebateHook));
emit TokensWithdrawn(to, token, withdrawAmount); // proves it's swapped on-chain
// Act
rebateHook.withdrawTokens(token, to, withdrawAmount);

Recommended Mitigation

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!