RebateFiHook::_isReFiBuy returns zeroForOne when ReFi is currency0 and !zeroForOne otherwise. This causes The hook to apply the wrong fee tier and emits the wrong event.Normal behavior
The hook should classify a swap as buy if the output side is ReFi (user ends the swap holding more ReFi), and sellotherwise. That choice controls which LP fee (buyFee vs sellFee) overrides the pool and which event is emitted.
Issue
Current logic flips that classification for common cases. For example, with a pool ETH (currency0) ↔ ReFi (currency1), a swap zeroForOne == true (ETH→ReFi) is a buy, but the function returns false, treating it as a sell(applies sellFee and emits ReFiSold).
Likelihood:
Every swap path uses _isReFiBuy; with the default pool in tests (currency0 = ETH, currency1 = ReFi), common buys (ETH→ReFi) are always misclassified
Impact:
Buys are charged sellFee (default 3000 pips = 0.30%) instead of buyFee (default 0), changing user pricing and liquidity incentives.
Add to RebateFiHookTest.t.sol. It shows that a clear buy (ETH→ReFi with zeroForOne = true in the default setup) emits ReFiSold (misclassification), not ReFiBought. We only check the indexed address to avoid amount encoding nuances.
Use a predicate that directly encodes “buy ReFi = ReFi is the output side”:
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.