Spot on Unichain

Uniswap v4 Hook Contract 0x88c9ff9fc0b22cca42265d3f1d1c2c39e41cdacc on Unichain · Dynamic fee · Verified contract

Volume (24h)
$1.98K
Value locked (TVL)
$35.45K
All-time volume
$203.93K
Pools using this hook
33
Swaps (24h)
125 (21 traders)
Total swaps
22,666

What it does

Spot is a dynamic-fee hook that sets each swap's fee from oracle volatility and a decaying surge after cap events, and takes a protocol share of swap fees to fund full-range liquidity reinvestment.

How it works step by step

  • Sets a per-swap dynamic fee from oracle-derived base fee plus a linearly decaying surge fee after cap events
  • Lets the policy owner override the fee per pool with a manual value
  • Takes a configurable protocol share of swap input tokens and mints it to the FullRangeLiquidityManager
  • Records TruncGeo oracle observations on swaps and liquidity changes to track tick movement
  • Reinvests accumulated fees into a protocol-owned full-range position when price is within TWAP tolerance
  • Requires dynamic fee pools during initialization
Swap behaviour
On each swap the hook applies either a manual fee or base plus surge fee, takes the protocol share from the input token via return delta, records oracle observations, and in afterSwap updates cap state and attempts reinvestment.
Liquidity behaviour
Before adding or removing liquidity the hook records an oracle observation at the current tick so the oracle's accumulator stays accurate. It does not take or modify user liquidity; liquidity is managed by the separate FullRangeLiquidityManager, which deploys protocol-owned liquidity in a full-range position and mints shares 1:1 with liquidity.
Fee behaviour
Each swap uses a manual fee if the policy owner has set one, otherwise base fee (derived from oracle tick movement, clamped by policy min/max) plus a linearly decaying surge fee after cap events. A protocol share (POL share) of the swap fee is minted as ERC6909 claims to the FullRangeLiquidityManager, emitted as HookFee or HookFeeReinvested events, and recorded as pending fees for later reinvestment.
Owner & admin controls
Owner of PoolPolicyManager (policyManager.owner()) can toggle reinvestmentPaused via setReinvestmentPaused, and can call depositToFRLM and withdrawFromFRLM. Policy owner can set manual pool fees (setManualFee, clearManualFee), POL share, base fee bounds, and surge parameters, and can also sweep excess tokens and set oracle/TWAP tolerance in FullRangeLiquidityManager. Hook has no upgrade mechanism; contracts are immutable deployments.

Enabled Uniswap v4 callbacks

afterInitialize, beforeAddLiquidity, beforeRemoveLiquidity, beforeSwap, afterSwap, beforeSwapReturnDelta, afterSwapReturnDelta

afterInitialize: enforces dynamic fee pools and initializes policy, oracle and fee manager state. beforeAddLiquidity and beforeRemoveLiquidity: record oracle observations. beforeSwap: sets the dynamic fee override, records the pre-swap tick, takes the protocol fee for exact-input swaps via return delta, and records an oracle observation. afterSwap: updates oracle cap frequency and fee manager, takes the protocol fee for exact-output swaps via return delta, and triggers reinvestment. beforeSwapReturnDelta and afterSwapReturnDelta: allow the hook to take a share of input tokens as protocol fee.

Security & trust assessment

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

Who controls it: The policy owner can set any pool's manual fee within 0.001% to 10%, change base fee bounds and surge multiplier, change the POL share, pause reinvestment, withdraw protocol-owned liquidity, and sweep unaccounted tokens to any address. A compromised owner key could raise fees on swaps or redirect protocol-owned funds.

Risk to user funds: The hook takes a protocol fee share from each swap's input token and mints it to the liquidity manager, and it can set dynamic fees, but it does not directly custody user LP principal. The policy owner controls protocol-owned liquidity, pending fees and excess balances held by the liquidity manager, and can pause reinvestment. Swaps are not blocked by a pause.

Security findings

  • [medium] Owner can set swap fees and protocol share: Owner-set manual fee can be raised up to 10% per swap on any pool, and setPoolPOLShare can take up to 100% of the swap fee as protocol fee.
  • [medium] Owner can withdraw protocol-owned liquidity: withdrawProtocolLiquidity and sweepExcessTokens/sweepExcessERC6909 allow the policy owner to remove protocol-owned liquidity and unaccounted balances.
  • [low] Hook takes swap input via return deltas: The hook takes tokens through beforeSwapReturnDelta and afterSwapReturnDelta, so it holds a cut of each swap's input; reinvestment is gated only by a TWAP deviation check.
  • [info] Failures are non-blocking by design: Errors in oracle or fee manager calls are caught and emitted as events, so swaps continue even if oracle updates fail; reinvestment failures are also swallowed.

Contract details

Verified source
Yes (Spot)
Compiler
solc 0.8.26+commit.8a97fa7a
Bytecode size
12,200 bytes
Upgradeable proxy
No
Detected patterns
dynamic-fee, oracle, return-delta

Pools using Spot