Dynamic fee hook on Unichain

Uniswap v4 Hook Contract 0x6398f3c67b03c4622bdaa48d9e340d66e23a1bc0 on Unichain · Dynamic fee

Volume (24h)
$1.37K
Value locked (TVL)
$14.88K
All-time volume
$52.38K
Pools using this hook
10
Swaps (24h)
247 (60 traders)
Total swaps
7,413

What it does

A Uniswap v4 hook that adjusts each swap's fee based on how far the current pool price has moved from an exponential moving average of recent prices, and blocks liquidity removal for 300 blocks after an add to discourage JIT liquidity.

How it works step by step

  • Seeds an EMA of the pool's sqrt price when the pool is initialized.
  • Before each swap, computes the percentage deviation of the current price from the stored EMA and maps it to a fee from a 30-step lookup table between 0.01% and 3.00%.
  • After each swap, updates the EMA with a fixed 8% weight on the new price and 92% on the prior EMA, and emits SwapFeeUpdated.
  • Records the block number when a sender adds liquidity, keyed by tx.origin, and rejects removals from that same origin for 300 blocks.
  • Clears the recorded add-block after a successful removal.
  • Has no owner, admin functions, or hook fee, per its own documentation.
Swap behaviour
Before each swap the hook reads the pool price, compares it to the EMA and overrides the LP fee with a value from the schedule (higher deviation, higher fee). After each swap it updates the EMA and emits an event. It returns zero for the before-swap delta and does not take or redirect tokens.
Liquidity behaviour
On add, the hook stores the block number for tx.origin. On remove, it reverts unless 300 blocks have passed since that origin's last add, or no add is recorded. After removal it deletes the record. It does not alter amounts.
Fee behaviour
The fee is set dynamically per swap by the hook through the override-fee flag, using the deviation-based lookup table. The hook takes no fee of its own and does not share fees.
Owner & admin controls
No admin controls found. There is no owner, pause, upgrade proxy, or parameter setter in the verified source.

Enabled Uniswap v4 callbacks

afterInitialize, beforeAddLiquidity, beforeRemoveLiquidity, afterRemoveLiquidity, beforeSwap, afterSwap

afterInitialize seeds the EMA; beforeAddLiquidity records the add block; beforeRemoveLiquidity enforces the anti-JIT cooldown; afterRemoveLiquidity clears the record; beforeSwap sets the dynamic fee; afterSwap updates the EMA and emits the fee event.

Security & trust assessment

Risk level: low (verified source, high confidence).

Who controls it: No privileged role exists in the verified source, so no key can change fees, pause swaps, or move funds.

Risk to user funds: The hook does not hold or move pool funds: it returns zero deltas and only affects fees and removal timing. The anti-JIT check can block a liquidity removal from the same origin for 300 blocks, which temporarily locks the ability to withdraw that liquidity through the pool.

Security findings

  • [low] Anti-JIT keyed on tx.origin: The cooldown uses tx.origin rather than the msg.sender of the liquidity call. Liquidity added through a router is tied to the EOA that signed the transaction, so a user who adds through a smart-wallet or contract that also routes other flows could see unexpected cooldowns, and a determined actor can bypass it by using a different EOA for removal or by adding via a different origin.
  • [info] Fee manipulable via price moves: beforeSwap reads the current slot0 price and the EMA only updates after swaps, so a trader can move the price within a transaction to set the fee for their own swap. The fee is capped at 3.00% and the EMA is a one-step smoothing, which limits but does not remove this effect.
  • [info] Hook-side EMA update uses integer truncation: The EMA update divides before multiplying to avoid overflow, which loses precision for small values. Impact on fees is minor because the EMA is in sqrt-price units with large magnitude.
  • [info] Fee lookup mapping is fixed: The schedule is hard-coded in _lookupFee and cannot be changed after deployment, so there is no way to respond to market conditions without deploying a new hook.

Contract details

Verified source
No
Bytecode size
9,720 bytes
Upgradeable proxy
No

Pools using Dynamic fee hook