RebateFi Hook

First Flight #53
Beginner FriendlyDeFi
100 EXP
View results
Submission Details
Impact: high
Likelihood: medium
Invalid

H01. Incorrect pool token validation

Root + Impact

Description

  • Normally, a Uniswap V4 hook validates that swaps and liquidity modifications occur only for pools that contain the designated tokens. This ensures that fee logic or custom behavior is applied only to intended pools.

  • In ReFiSwapRebateHook, the _beforeSwap function does not validate that the PoolKey corresponds to the designated ReFi token. This allows the hook to be attached to, or invoked by, arbitrary pools containing different tokens, potentially applying unintended fee overrides.

function _beforeSwap(
address sender,
PoolKey calldata key,
SwapParams calldata params,
bytes calldata
) internal override returns (bytes4, BeforeSwapDelta, uint24) {
bool isReFiBuy = _isReFiBuy(key, params.zeroForOne); // @> relies on _isReFiBuy but no explicit token validation
uint256 swapAmount = params.amountSpecified < 0
? uint256(-params.amountSpecified)
: uint256(params.amountSpecified);
uint24 fee;
if (isReFiBuy) {
fee = buyFee;
emit ReFiBought(sender, swapAmount);
} else {
fee = sellFee;
uint256 feeAmount = (swapAmount * sellFee) / 100000;
emit ReFiSold(sender, swapAmount, feeAmount);
}
return (
BaseHook.beforeSwap.selector,
BeforeSwapDeltaLibrary.ZERO_DELTA,
fee | LPFeeLibrary.OVERRIDE_FEE_FLAG
);
}

Risk

Likelihood:

  • The hook will apply its fee logic to any pool calling _beforeSwap, including pools that do not contain the ReFi token, because there is no explicit check on key against the designated ReFi token.

  • Users or contracts attaching this hook to other pools will inadvertently trigger fee overrides without being restricted.

Impact:

  • Incorrect fees may be applied to unrelated pools, allowing a malicious user to manipulate swaps for profit or disrupt other liquidity pools.

  • Incentive mechanisms (buy/sell rebates) could be misapplied, undermining economic models and potentially causing token imbalance or unintended revenue generation.

Proof of Concept

Written explanation: The following PoC demonstrates that a malicious pool containing a different ERC20 token can call the hook and trigger ReFi sell fees, even though the pool does not contain the ReFi token. This can be tested in a Forge unit test environment.

function test_IncorrectPoolTokenValidation() public {
// Deploy a mock token and pool
MockERC20 fakeToken = new MockERC20("Fake", "FAKE", 18);
Currency fakeCurrency = Currency.wrap(address(fakeToken));
// Mint some tokens to user
fakeToken.mint(user1, 1 ether);
// Initialize a pool with fake token and ETH, but attach the ReFi hook
PoolKey memory fakeKey;
(fakeKey, ) = initPool(
ethCurrency,
fakeCurrency,
rebateHook,
LPFeeLibrary.DYNAMIC_FEE_FLAG,
79228162514264337593543950336
);
// Attempt a swap in the fake pool
vm.deal(user1, 1 ether);
vm.startPrank(user1);
SwapParams memory params = SwapParams({
zeroForOne: false,
amountSpecified: -int256(0.01 ether),
sqrtPriceLimitX96: TickMath.MAX_SQRT_PRICE - 1
});
PoolSwapTest.TestSettings memory testSettings = PoolSwapTest.TestSettings({
takeClaims: false,
settleUsingBurn: false
});
// This triggers the hook even though it's the wrong pool
swapRouter.swap(fakeKey, params, testSettings, ZERO_BYTES);
vm.stopPrank();
// The ReFi sold event will emit even though the pool contains a fake token
uint24 currentSellFee;
(, currentSellFee) = rebateHook.getFeeConfig();
assertEq(currentSellFee, 3000, "Sell fee incorrectly applied to unrelated pool");
}

Recommended Mitigation

Explicitly check that the pool’s token matches the ReFi token before applying fee logic.

- bool isReFiBuy = _isReFiBuy(key, params.zeroForOne);
+ require(key.token1 == Currency.wrap(ReFi()) || key.token0 == Currency.wrap(ReFi()), "Hook only valid for ReFi pool");
+ bool isReFiBuy = _isReFiBuy(key, params.zeroForOne);
Updates

Lead Judging Commences

chaossr Lead Judge 11 days ago
Submission Judgement Published
Invalidated
Reason: Incorrect statement

Support

FAQs

Can't find an answer? Chat with us on Discord, Twitter or Linkedin.

Give us feedback!