DEXs: Uniswap V2, V3, V4, and Their Forks

Decentralized exchanges are the most-forked category in DeFi. Any new chain spawns a Uniswap V2 fork (often called Sushi-style), then a V3 fork (concentrated liquidity), and increasingly a V4 fork (with hooks). The vast majority of "novel" DEX audits are audits of forks with modifications — and the modifications are almost always where the bugs live.

Uniswap V2: Constant-Product AMM

The canonical x·y = k pool. Each pool holds two tokens; the product of reserves is preserved (modulo fees) across swaps. Liquidity providers deposit both tokens proportionally and receive LP tokens.

Critical Mechanics

  • Swap formula: dy = (y * dx * 997) / (x * 1000 + dx * 997) — the 30 bps fee is built into the math.
  • LP token minting uses geometric-mean accounting (sqrt(x * y) for the first deposit, proportional shares thereafter).
  • skim lets anyone claim tokens sent to the pool outside of mint (donations) — preventing the pool's accounting from falling out of sync with the actual balance.
  • sync resyncs the pool's stored reserves with the actual token balances.

Common Findings

  • Inflated-token compatibility issues. Fee-on-transfer tokens (some legacy mainnet tokens), rebasing tokens (Ampleforth), and tokens with hooks (ERC-777) break the constant-product invariant in subtle ways. A V2 fork that doesn't restrict its token whitelist is exposed.
  • Donation-based pool manipulation. A first-deposit donation attack: send 1 wei to a freshly-created pool, then donate a large amount, then mint LP shares at a manipulated rate.
  • skim/sync abuse as part of multi-step manipulation sequences (e.g., bZx 2020 used sync).
  • Block-timestamp manipulation of TWAPs. V2 exposes a cumulative-price oracle that integrators read as a TWAP. The window must be long enough to make manipulation expensive; many integrators read it over far-too-short windows.

Audit Posture for V2 Forks

The fork's diff against canonical V2 (Uniswap V2 Core) is where the bugs are. Run a diff; review every changed line; the unchanged code is well-audited and can usually be trusted.

Common diff patterns to scrutinize:

  • Custom fee schedules (fee tiers, dynamic fees, fee recipients).
  • Token-tax / fee-on-transfer handling.
  • Custom oracle integration (e.g., a TWAP exposed for a different protocol to consume).
  • Init-code changes (the pair-creation init code hash must match what the factory expects, or getPair is wrong).

Uniswap V3: Concentrated Liquidity

V3 lets LPs concentrate their capital in price ranges of their choosing. Each LP position is a non-fungible NFT (ERC-721) representing liquidity in a specific tick range.

Critical Mechanics

  • Price as sqrtPriceX96: the pool's price is stored as the square root of token1/token0, in Q64.96 fixed-point. Off-by-bit-shifts here are common bugs.
  • Tick math: liquidity is bucketed into ticks; each tick is a fixed price ratio (1.0001^tick). A swap traverses ticks until the input is consumed.
  • Position management via the NonfungiblePositionManager (NPM): LPs mint NFTs by depositing into a tick range; they collect fees as those fees accrue.
  • Oracle: V3 exposes a more sophisticated TWAP than V2, sampled at multiple sub-window granularities.

Common Findings

  • Tick boundary math errors. Custom fork modifications to tick spacing, tick-to-price conversion, or sqrtPrice math reliably introduce off-by-one bugs that compound.
  • Hookless V3 forks with custom callbacks. V3 calls back to the swap initiator for token transfers (uniswapV3SwapCallback). A custom integrator that doesn't validate the caller is the pool is exploitable: anyone can call the integrator's callback claiming to be a pool.
  • Slippage on multi-hop swaps. Routers that don't enforce slippage at each hop expose users to sandwich on intermediate legs.
  • Position-collection re-entrancy. Old V3-Periphery had subtle reentrancy on NFT operations; forks that re-implement these can re-introduce the bugs.
  • NFT position transfers with stale fee accounting. Transferring an NFT before collecting fees can lose them in some custom periphery implementations.

V3 Oracle Use

V3's TWAP is much better than V2's but still requires:

  • A sufficient observations array (increaseObservationCardinalityNext to expand the oracle's storage).
  • A window long enough that manipulation requires substantial capital for the full duration.
  • A check that the pool has enough liquidity for the oracle to be meaningful.

A protocol that reads a V3 TWAP from a low-liquidity pool, or from a freshly-deployed pool without an expanded observation array, is reading garbage.

Uniswap V4: Hooks and Singleton

V4 (mainnet-live as of 2024) restructures V3 around two ideas:

  • Singleton architecture: all pools live in a single PoolManager contract; pool state is internal accounting rather than per-pool balances.
  • Hooks: pools can attach hook contracts that run at well-defined points (before/after swap, before/after add/remove liquidity, before/after donate).

Hooks dramatically expand what's possible (anti-MEV pools, dynamic fees, custom LP curves) and dramatically expand audit surface.

Critical Mechanics

  • Flash accounting: the singleton uses a "take" / "settle" pattern; balances are tracked as deltas during a transaction and must net to zero at the end. This is gas-efficient and re-entrancy-resistant by design.
  • Hook permissions are encoded in the hook contract's address (specific address bits = which hooks are enabled). An address with the wrong bits set has the wrong hooks.
  • Hook ordering: before-hooks run, the action runs, after-hooks run. Hooks can revert any of these.

Common Findings (Early)

V4 is new enough that the bug catalogue is still forming, but early findings cluster around:

  • Custom hook contracts with incorrect flash-accounting interactions. The singleton's invariant is fragile to hooks that move balances unexpectedly.
  • Hook address-bit collisions — deploying a hook at an address whose bits accidentally enable hooks the hook doesn't actually implement.
  • Re-entrancy through hooks. A hook can call back into the singleton; if the hook's own callers don't expect this, state is desynced.
  • Permissionless pool creation with malicious hooks. Anyone can create a pool with arbitrary hook contracts; aggregators that route through arbitrary pools must be careful about which hooks they trust.

V4 audits in 2026 still warrant specialist review. The mental model is different enough from V2/V3 that experience matters.

Other DEX Architectures Worth Recognizing

  • Curve (StableSwap): invariant designed for low-slippage swaps between similarly-priced assets (stablecoins, LSTs). Custom math; the 2023 Vyper reentrancy was specifically a Vyper-language bug, but the StableSwap math itself has been a source of findings.
  • Balancer (weighted pools, stable pools, composable stable pools): generalized invariants. The 2023 Balancer "rounding" bug class affected several pool types.
  • DODO (PMM): proactive market maker with external price oracle. The oracle dependency is the security model; in 2021, oracle issues caused real losses.
  • CowSwap / Uniswap X / 1inch Fusion: intent-based, off-chain matching. Audit focus shifts from pool math to signature verification, settlement validation, and solver authorization.

A Checklist for Any DEX Audit

  • Pool math: does it preserve the claimed invariant under all operations? (mint, burn, swap, skim, sync, donations.)
  • Token compatibility: which token behaviors are supported? Fee-on-transfer? Rebasing? ERC-777 hooks?
  • Slippage enforcement: every swap path enforces minAmountOut (or maxAmountIn); deadlines are required.
  • Callback authentication: any callback (V3 swapCallback, flash-loan callback, V4 hook) verifies the caller.
  • Oracle exposure: if the DEX provides a price oracle, what's its TWAP window? What's its liquidity threshold for usefulness?
  • Pool init: can a malicious first deposit corrupt accounting? Donation attacks?
  • Re-entrancy: every state-mutating function either follows CEI or has a nonReentrant modifier; cross-function reentrancy considered.
  • Fork-diff review: every line that differs from the canonical implementation is justified and tested.
  • V4 hooks (if applicable): address-bit hook permissions match implemented hooks; flash-accounting deltas net to zero in all paths.
  • Fee distribution: where do fees go? Are protocol fees subject to admin upgrade or governance? Are LPs' fees accounted for atomically with swaps?

A DEX that passes all of these has solid mechanical correctness. Most surviving findings will be at the periphery (routers, aggregators, integration contracts) rather than the core pool logic.