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);
}
<details>
<summary>POC</summary>
1. Import it in `RebateFiHookTest.t.sol` test file.
import {Vm} from "forge-std/Vm.sol";
2. Add this test to `RebateFiHookTest.t.sol` test file.
```javascript
function test_TokensWithdrawn_EventMisordered() public {
address tokenAddr = address(reFiToken);
address recipient = user1;
uint256 amount = 1 ether;
reFiToken.mint(address(rebateHook), amount);
vm.recordLogs();
rebateHook.withdrawTokens(tokenAddr, recipient, amount);
Vm.Log[] memory logs = vm.getRecordedLogs();
bytes32 sig = keccak256("TokensWithdrawn(address,address,uint256)");
address loggedParam1;
address loggedParam2;
uint256 loggedAmount;
bool found;
for (uint256 i = 0; i < logs.length; i++) {
if (logs[i].topics[0] == sig) {
found = true;
loggedParam1 = address(uint160(uint256(logs[i].topics[1])));
loggedParam2 = address(uint160(uint256(logs[i].topics[2])));
loggedAmount = abi.decode(logs[i].data, (uint256));
}
}
require(found, "Event not emitted");
assertEq(loggedParam1, recipient, "BUG: event first param == to (should be token)");
assertEq(loggedParam2, tokenAddr, "BUG: event second param == token (should be to)");
assertEq(loggedAmount, amount);
}
```
</details>
1.Modify the `withdrawTokens` function to work correctly.
```diff
/// @notice Withdraws tokens from the hook contract
/// @param token Address of the token to withdraw
/// @param to Address to send the tokens to
/// @param amount Amount of tokens to withdraw
/// @dev Only callable by owner
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);
}
```