Uniswap v4 Must-Have Hooks: Effortless Fees & TWAMM Flows.

Time to Read
7 MINUTES
Category
Blog
Uniswap v4 Must-Have Hooks: Effortless Fees & TWAMM Flows

Uniswap v4 introduces hooks: user-defined smart contracts that run at key moments in a pool’s lifecycle. For swaps, you get two powerful touchpoints—before and after—letting you inspect, reshape, or settle logic around the core AMM. This opens the door to granular fee policies and TWAMM-style long-term orders without forking the protocol.

Think of a hook as a programmable interposer. It sees swaps as they enter, can veto or add fees, then afterward can finalize accounting or trigger side effects. With careful design, you can build custom pricing, route incentives, or drip a large trade over time to dampen price impact.

The hook surface: beforeSwap vs afterSwap

Both hook functions are useful, but they shine in different roles. The table below compares how developers typically split responsibilities.

Hook responsibilities at a glance
Moment Primary Use Data You Can Trust Common Patterns
beforeSwap Validation, dynamic fee setting, access control Caller intent, pre-swap price/liquidity, deadlines Volatility-based fee, allowlists, TWAMM tranche emission
afterSwap Settlement, accounting, emissions, refunds Actual swap outcome: amounts in/out, final price Protocol fee split, bribe distribution, TWAMM bookkeeping

A clean split reduces risk: decide the “rules of entry” in beforeSwap, then finalize and record what actually happened in afterSwap. If something must be deterministic and reversible, put it before the swap; if it depends on observed outcome, handle it afterward.

Custom fee policies with real teeth

Static fee tiers are blunt. Hooks let you compute fees per-swap, per-user, and per-market condition. Fees can change in response to volatility, inventory skew, or risk budgets. Done right, this can reduce loss-versus-rebalancing (LVR) and pay LPs when it matters.

Here are typical strategies builders ship in production-like setups, with tight checks and explicit math.

Dynamic fee recipe: volatility-aware spread

In beforeSwap, read a robust volatility proxy—e.g., an exponentially weighted moving average (EWMA) of log returns from the pool’s timepoints or a trusted oracle like Chainlink. Then compute a fee that scales with recent volatility, capped by a policy limit.

  1. Pull a price sample window (e.g., 30–120 blocks) and estimate realized volatility.
  2. Map vol to a fee: fee = base + k * vol with a ceiling to avoid ransom-like spikes.
  3. If fee jumps too fast vs last swap, rate-limit the change to smooth user experience.
  4. Write the fee into the swap parameters or reject the swap if caller-specified max fee is exceeded.

A tiny example: if ETH/USDC 30-block vol jumps from 0.6% to 2.0%, your hook can nudge fees from 5 bps to 20–30 bps for the next few minutes, compensating LPs as risk rises. If vol cools, the hook ratchets down automatically.

Address- or token-aware fee logic

Beyond markets, you can encode participant rules. Some pools treat KYC’d addresses or market-makers on an allowlist differently, or penalize tokens known to have transfer taxes.

  • Per-address: whitelist with reduced fees; blacklist known MEV bots during auctions.
  • Per-token: detect fee-on-transfer tokens and add a safety premium to cover slippage.
  • Inventory-aware: if LP inventory skews too far, temporarily widen fees to steer flow.

Always surface the effective fee to callers via read functions. Transparency keeps integrators friendly and reduces failed swaps from unexpected charges.

TWAMM-style long-term orders via hooks

A Time-Weighted Average Market Maker (TWAMM) splits a large order into many small virtual trades executed over time. The goal: reduce price impact and adversarial routing. In v4, a hook can emulate TWAMM without altering the AMM math by metering flow each block or swap.

At a high level, users deposit a long-term order into the hook. The hook then “drips” that order into the pool across intervals. When swaps happen, the hook updates the schedule and executes a slice. A keeper can also nudge the schedule during quiet periods.

Core design of a TWAMM hook

Implementations vary, but most share a structure like this, with clear storage and predictable settlement.

  1. Position creation: user approves tokens and opens a long-term order with amount, direction, and duration (e.g., 100k USDC over 6 hours).
  2. Emission schedule: store per-pool emission rates (amount per second or per block), keyed by direction (token0→token1, token1→token0).
  3. beforeSwap execution: compute elapsed time since last update; emit the corresponding virtual amount into the pool as an internal swap tranche.
  4. afterSwap accounting: attribute the realized output to each active position proportionally; update claimable balances.
  5. Keepers: allow an external poke function to process emissions when no swaps occur, so TWAMM flow continues in quiet markets.

Micro-scenario: Alice schedules 50 ETH→USDC over 3 hours. Bob schedules 60k USDC→ETH over the same window. The hook nets flows first—much of Alice’s ETH crosses with Bob’s USDC virtually at the mid, with only the residual hitting the pool. Price impact shrinks, and both see better execution than a single market order.

Integrating TWAMM with before/after swap

The split between the two functions helps you keep the math clean and auditable. Use pre-swap for deterministic flow emission and post-swap for finalized crediting.

Below is a practical pattern that keeps state consistent and reduces reentrancy risk.

  • beforeSwap: settle pending emissions since the last timestamp; push netted amounts into the current swap path, adjusting the input amount or enqueuing a sub-swap; enforce guardrails (max emission per block, rate caps).
  • afterSwap: read actual amounts in/out; update per-position claims; collect or rebate the TWAMM fee share; mark last update time.
  • Failure handling: if the swap reverts, state changes done beforeSwap should be minimal and reproducible on retry. Favor “compute, don’t commit” before the core swap when possible.

To make this smoother for integrators, expose view functions: next emission timestamp, active notional, and estimated per-block tranche. Wallets can render an ETA and projected slippage bands.

Security and correctness checklist

Building fee and TWAMM hooks touches guardrails most projects care about. The following list focuses on issues that regularly cause reverts and fund mismatches.

  1. Reentrancy discipline: restrict external calls in afterSwap. If you must transfer tokens, prefer pulling on user claim instead of pushing during swap.
  2. Oracle safety: clamp volatility and price inputs; sanity check for stale or wildly out-of-range values before setting fees.
  3. Arithmetic: use fixed-point math with explicit rounding direction; document it so integrators can replicate quotes off-chain.
  4. State minimalism: in beforeSwap, compute pending emissions but commit to storage only after the swap succeeds, or commit to a shadow buffer that’s reconciled in afterSwap.
  5. Access control: if you run allowlists, make them immutable or timelocked; expose events for every policy change.

A small dry run on a forked network with adversarial sequences—zero-liquidity swaps, fee-on-transfer tokens, and deadline races—catches most edge cases early.

Gas and UX trade-offs

Every line in a hook costs gas. TWAMM math and dynamic fees add overhead, so design for common paths first. Cache timepoints, coalesce updates, and keep storage writes to a minimum. Where possible, precompute emission deltas and apply them in bulk once per block.

For users, clarity beats cleverness. Publish the effective fee, the TWAMM execution window, and claimable balances. Provide a cancel function that returns the remaining notional promptly, even if the market is quiet and no keeper has ticked the schedule.

Example flow: dynamic fee plus TWAMM in one hook

A combined policy is straightforward if responsibilities don’t overlap. Here’s a compact sketch of how the swap lifecycle feels to a caller and to your hook.

  • Caller submits a regular swap or interacts with the TWAMM UI to open a long-term order.
  • beforeSwap runs: it settles elapsed TWAMM emissions, nets opposing flow, calculates a current fee from volatility, and validates the caller’s max-fee constraint.
  • The core AMM executes with the adjusted input and fee.
  • afterSwap runs: it books the realized amounts to claimable balances, routes the protocol fee cut, and emits events for indexers.

Because fees and emissions are orthogonal, you can toggle either part off via config flags. That makes audits and staged rollouts far simpler.

What good looks like in production

Battle-tested hooks share a few traits: deterministic math, clear limits, and clean observability. If your fee can spike 10x, prove it’s bounded. If your TWAMM can emit more than the pool can absorb, cap it per block. And if something goes wrong, a pause-switch scoped to the smallest safe surface (per pool, not global) saves headaches.

On the happy path, custom fees pay LPs when they shoulder more risk, and TWAMM smooths large flow into the market. Builders get finer control without forking Uniswap’s core, and traders get better execution without arcane settings.