RebateFi Hook

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

Incorrect Event Argument Order in withdrawTokens (Data Integrity)

Description:
The withdrawTokens function emits the TokensWithdrawn event with swapped arguments.

function withdrawTokens(address token, address to, uint256 amount) ... {
...
emit TokensWithdrawn(to, token , amount);
}

The event definition is:

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

The code passes to (recipient) as the first argument (token), and token (token address) as the second argument (to).

Impact:
Off-chain indexers will misinterpret the event, showing the recipient address as the token address and vice versa.

Proof of Concept:
demonstrates that buying ReFi triggers the ReFiSold event (Sell path).
demonstrates that selling ReFi incurs 0 fee (Buy Fee) instead of the intended 0.3%.

// SPDX-License-Identifier: MIT
pragma solidity ^0.8.26;
import {Test} from "forge-std/Test.sol";
import {ReFiSwapRebateHook} from "../src/RebateFiHook.sol";
import {MockERC20} from "solmate/src/test/utils/mocks/MockERC20.sol";
import {PoolManager} from "v4-core/PoolManager.sol";
import {IPoolManager} from "v4-core/interfaces/IPoolManager.sol";
import {HookMiner} from "v4-periphery/src/utils/HookMiner.sol";
import {Hooks} from "v4-core/libraries/Hooks.sol";
contract M4_EventOrderTest is Test {
ReFiSwapRebateHook public rebateHook;
MockERC20 reFiToken;
PoolManager manager;
function setUp() public {
manager = new PoolManager(address(0));
reFiToken = new MockERC20("ReFi Token", "ReFi", 18);
bytes memory creationCode = type(ReFiSwapRebateHook).creationCode;
bytes memory constructorArgs = abi.encode(manager, address(reFiToken));
uint160 flags = uint160(
Hooks.BEFORE_INITIALIZE_FLAG |
Hooks.AFTER_INITIALIZE_FLAG |
Hooks.BEFORE_SWAP_FLAG
);
(address hookAddress, bytes32 salt) = HookMiner.find(
address(this),
flags,
creationCode,
constructorArgs
);
rebateHook = new ReFiSwapRebateHook{salt: salt}(manager, address(reFiToken));
}
function test_M4_WithdrawEvent_SwappedArgs() public {
// Mint tokens to hook
reFiToken.mint(address(rebateHook), 1000);
address recipient = address(0x123);
uint256 amount = 500;
vm.expectEmit(true, true, false, true);
// We expect the SWAPPED values
emit ReFiSwapRebateHook.TokensWithdrawn(recipient, address(reFiToken), amount);
rebateHook.withdrawTokens(address(reFiToken), recipient, amount);
}
}

Recommended Mitigation:
Swap the arguments in the emit statement.

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!