Root + Impact
Description
The `TokensWithdrawn` event is emitted with parameters in the wrong order compared to its declaration, causing incorrect event indexing and potential issues with off-chain monitoring.
**Description**:
* The normal behavior expects events to be emitted with parameters in the same order as declared in the event definition for proper indexing and off-chain parsing.
* The specific issue is that `withdrawTokens` emits the event with `(to, token, amount)` but the event is declared as `TokensWithdrawn(address indexed token, address indexed to, uint256 amount)`, causing the token and recipient addresses to be swapped in the event logs.
**Root cause in the codebase**:
```solidity
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);
}
```
Risk
Likelihood:
Impact:
-
* Off-chain monitoring systems will incorrectly identify which token was withdrawn and to which address
* Event indexing will be wrong, making it difficult to track token withdrawals
* Analytics and compliance tools relying on events will have incorrect data
Proof of Concept
The following demonstrates how the parameter mismatch causes incorrect event indexing:
```solidity
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);
}
address reFiToken = 0x1234...;
address recipient = 0x5678...;
uint256 amount = 100 ether;
rebateHook.withdrawTokens(reFiToken, recipient, amount);
```
**Step-by-step execution:**
1. Owner calls `withdrawTokens(0x1234..., 0x5678..., 100 ether)`
2. Transfer executes successfully
3. Event emitted with parameters: `(0x5678..., 0x1234..., 100 ether)`
4. Event log stores: `token = 0x5678...` (should be `0x1234...`)
5. Event log stores: `to = 0x1234...` (should be `0x5678...`)
6. Off-chain system queries: "All withdrawals of token 0x1234..."
7. Query searches indexed `token` field, finds `0x5678...` (wrong!)
8. System cannot find the actual withdrawal, data integrity compromised
Recommended Mitigation
Fix the parameter order to match the event declaration:
```diff
// src/RebateFiHook.sol:73-75
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);
}
```
**Explanation:**
- Event declaration: `TokensWithdrawn(address indexed token, address indexed to, uint256 amount)`
- Parameters must be emitted in the same order: `(token, to, amount)`
- This ensures proper event indexing for off-chain monitoring systems
- Indexed parameters allow efficient filtering by token address or recipient address
- Correct order enables accurate analytics and compliance tracking