In the _beforeSwap function of RebateFiHook.sol, the hook derives the swap amount using:
This assumes amountSpecified != 0.
However, in Uniswap V4, swap() calls with amountSpecified == 0 are valid and used for:
oracle updates
triggering hooks
dry runs / sandwich protection
internal router operations
If a user calls swap with amountSpecified = 0, the hook:
Treats the swap as a buy or sell (even though it's neither)
Emits ReFiBought or ReFiSold events with amount = 0
Applies buyFee or sellFee override (even though no swap occurred)
Consumes gas and changes user-facing analytics
May cause systems depending on events (rebates, rewards, airdrops) to mis-execute
This contradicts expected Uniswap V4 hook behavior, where no swap should mean no side effects.
Unexpected hook execution, including:
Incorrect swap events with zero volume
Gas and execution overhead
Wrong analytics, misleading swap tracking
Potential reward system manipulation (fake swap events)
Fee override applied where it should not be
Possible griefing vector: attacker can spam swap(0) and distort data
Although no funds are lost directly, this introduces correctness risks and ecosystem-wide data corruption.
Most severe scenario:
A protocol relying on ReFiBought / ReFiSold events for rewards or rebates can be exploited with zero-cost swaps.
Executing the above emits a buy or sell event despite no swap.
Add a guard clause early in _beforeSwap:
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.