In normal Uniswap V4 behavior, hooks determine the nature of a swap (buy vs sell) per pool, and each hook is responsible only for the pool it is attached to. If a swap is routed through multiple pools (multi‑hop), each hop should interpret swap direction correctly relative to its own token pair.
In the ReFiSwapRebateHook, the _isReFiBuy function classifies a swap as a buy or sell solely based on the boolean zeroForOne, assuming a simple 2‑token pool containing the ReFi token once. This logic fails when swaps occur through multi-hop paths, because the hook cannot reliably know whether the user is “buying ReFi” or is in an intermediate hop unrelated to ReFi. As a result, sell fees may incorrectly apply during legitimate multi-hop buys or buys may be incorrectly fee‑exempt while executing an intermediate hop.
The logic treats every pool swap as the “main swap” and misattributes buy/sell intent in multi-hop paths.
Likelihood:
Multi-hop routing occurs whenever users trade through aggregators (1inch, Matcha, CowSwap) or when liquidity is fragmented across multiple pools.
The hook is globally callable by any pool containing the hook’s address flags, so multi-hop paths routinely trigger it.
Impact:
The hook incorrectly charges sell fees on legitimate buys when a hop direction seems inverted.
The hook incorrectly applies zero buy fees on effective sells when the ReFi token is only touched in an intermediate hop.
Explanation
A user wants to buy ReFi using token X. The router chooses the path:
During the first hop (X → WETH), zeroForOne may classify the hop as a sell relative to the pool’s ordering, and the ReFiHook applies a sell fee even though ReFi is not involved yet.
During the second hop (WETH → ReFi), the hook correctly sees a buy direction, but the first hop already incorrectly applied sell fees.
Below is a simplified Foundry test PoC:
Written explanation:
The first hop does not involve ReFi, but _isReFiBuy misclassifies the direction.
As a result, the hook treats an unrelated swap as a “sell of ReFi”, charging sell fees.
The user ends up paying unintended fees, violating expected routing behavior.
Mitigation should modify the function _isReFiBuy to explicitly verify that the ReFi token is present in the pool before determining buy/sell direction. Only apply fee logic when ReFi is part of the pool.
The contest is live. Earn rewards by submitting a finding.
This is your time to appeal against judgements on your submissions.
Appeals are being carefully reviewed by our judges.