StableStableHook on Ethereum

Uniswap v4 Hook Contract 0x4509b7eb3f9641226804fea4976963435d1c6080 on Ethereum · Dynamic fee · Verified contract

Volume (24h)
$0
Value locked (TVL)
$0
All-time volume
$120.87M
Pools using this hook
1
Swaps (24h)
0 (0 traders)
Total swaps
38,084

What it does

A dynamic fee hook for stable-stable pools that charges a fee only when the price drifts from a reference price outside an optimal range, with the fee decaying over time toward a target.

How it works step by step

  • Restricts pool initialization to the owner via initializePool, requiring a dynamic fee and this hook address
  • Reverts any external attempt to initialize a pool using this hook
  • Computes a per-swap LP fee from the ratio of AMM price to a reference sqrt price
  • Keeps a fixed optimal range around the reference price where the fee keeps pre-impact price at the boundary
  • Decays the fee exponentially toward a target fee outside the optimal range, based on blocks elapsed
  • Lets a configManager update each pool's fee configuration (k, logK, optimal fee, target multiplier, reference price) with validation
Swap behaviour
Each swap computes a dynamic LP fee from the pool price relative to a reference price, with zero fee for swaps that move price back toward reference and a decaying fee for swaps that move it further away, and returns it with the override flag; no balance delta is taken.
Liquidity behaviour
No liquidity callbacks.
Fee behaviour
Dynamic LP fee returned per swap via OVERRIDE_FEE_FLAG. Inside an optimal price range around a reference sqrt price the fee is set so pre-impact prices stay at the range boundary; outside the range, the fee decays exponentially toward a target fee (derived from far boundary minus close boundary scaled by targetMultiplier) based on blocks elapsed, and only the direction moving away from reference is charged. Fee is capped by validation of optimalFeeE6 <= 1e4 (1%) for the optimal range parameter.
Owner & admin controls
Owner (Ownable) can call initializePool and renounceOwnership or transferOwnership. A configManager address (set at deployment, changeable only by the current configManager via setConfigManager) can call updateFeeConfig to change per-pool k, logK, optimalFeeE6 (capped at 1%), targetMultiplier and referenceSqrtPriceX96, subject to validation; setting configManager to address(0) freezes fee config. No pause or upgrade mechanism found.

Enabled Uniswap v4 callbacks

beforeInitialize, beforeSwap

beforeInitialize reverts for any sender other than the hook flow, so pools can only be initialized through initializePool which enforces a dynamic fee and this hook address. beforeSwap computes and returns the dynamic fee override for each swap.

Security & trust assessment

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

Who controls it: The owner controls which pools get initialized with this hook, and the configManager can change fee parameters (decay constant, optimal range width, target multiplier and reference price) for any pool at any time, which directly changes the fee users pay on swaps. The configManager can set a fee range that is valid but economically unfavourable to traders or LPs, and reference price changes can shift which swaps are charged.

Risk to user funds: The hook does not take or hold user tokens and does not use return deltas, so it cannot directly seize funds. Users are exposed to the fee level set by the configManager, which can be changed for live pools, and a bug in the decay or boundary math could cause unexpected fees, which the source's comments indicate may revert on out-of-range prices.

Security findings

  • [medium] Privileged fee parameter control: The configManager can call updateFeeConfig at any time to change the reference sqrt price, k, optimal fee and target multiplier of a live pool, changing swap fees immediately without a timelock.
  • [low] Bounded but mutable fee parameters: Validation caps optimalFeeE6 at 1% and checks k/logK consistency and price bounds, which limits the extreme values a configManager can set, but fee levels within these bounds can still be changed.
  • [info] Owner and configManager roles are separate: The owner can transfer ownership or renounce it; ownership controls only pool initialization, not fee updates. The configManager can be set to address(0) to permanently freeze fee configuration.
  • [info] No direct fund custody: The hook does not use beforeSwapReturnDelta or any return delta, and does not hold or move user funds beyond normal pool accounting; fees are applied through the LP fee override only.
  • [info] Start-of-block price caching: Fee state is cached per block; the start-of-block sqrt price is used for fee calculation in subsequent swaps of the same block, which the source documents as a deliberate trade-off against swap splitting.

Contract details

Verified source
Yes (StableStableHook)
Compiler
solc 0.8.26+commit.8a97fa7a
Bytecode size
11,277 bytes
Upgradeable proxy
No
Detected patterns
dynamic-fee, ownable

Pools using StableStableHook