Are you an LLM? Read llms.txt for a summary of the docs, or llms-full.txt for the full context.
Hook Permissions – Uniswap SDK
Skip to content

Hook Permissions

Uniswap V4 hooks encode their permissions in the contract address. This page documents the HookOptions enum and all 14 hook permission types.

Import

import { HookOptions, hookFlagIndex, type HookPermissions } from '@uniswap/v4-sdk-next'

HookOptions Enum

The HookOptions enum defines all available hook permissions:

enum HookOptions {
  AfterRemoveLiquidityReturnsDelta = 'afterRemoveLiquidityReturnsDelta',
  AfterAddLiquidityReturnsDelta = 'afterAddLiquidityReturnsDelta',
  AfterSwapReturnsDelta = 'afterSwapReturnsDelta',
  BeforeSwapReturnsDelta = 'beforeSwapReturnsDelta',
  AfterDonate = 'afterDonate',
  BeforeDonate = 'beforeDonate',
  AfterSwap = 'afterSwap',
  BeforeSwap = 'beforeSwap',
  AfterRemoveLiquidity = 'afterRemoveLiquidity',
  BeforeRemoveLiquidity = 'beforeRemoveLiquidity',
  AfterAddLiquidity = 'afterAddLiquidity',
  BeforeAddLiquidity = 'beforeAddLiquidity',
  AfterInitialize = 'afterInitialize',
  BeforeInitialize = 'beforeInitialize',
}

HookPermissions Type

The HookPermissions type represents all permissions as a boolean object:

type HookPermissions = {
  [key in HookOptions]: boolean
}

Hook Flag Index

The hookFlagIndex constant maps each permission to its bit position in the hook address:

const hookFlagIndex: { [key in HookOptions]: number } = {
  afterRemoveLiquidityReturnsDelta: 0,
  afterAddLiquidityReturnsDelta: 1,
  afterSwapReturnsDelta: 2,
  beforeSwapReturnsDelta: 3,
  afterDonate: 4,
  beforeDonate: 5,
  afterSwap: 6,
  beforeSwap: 7,
  afterRemoveLiquidity: 8,
  beforeRemoveLiquidity: 9,
  afterAddLiquidity: 10,
  beforeAddLiquidity: 11,
  afterInitialize: 12,
  beforeInitialize: 13,
}

Permission Categories

Initialize Permissions

Called when a pool is initialized.

PermissionBitDescription
BeforeInitialize13Called before pool initialization
AfterInitialize12Called after pool initialization
import { Hook, HookOptions } from '@uniswap/v4-sdk-next'
 
// Check initialize permissions
Hook.hasPermission(hookAddress, HookOptions.BeforeInitialize)
Hook.hasPermission(hookAddress, HookOptions.AfterInitialize)
 
// Or use convenience method
Hook.hasInitializePermissions(hookAddress)

Liquidity Permissions

Called during liquidity operations (mint, burn, modify).

PermissionBitDescription
BeforeAddLiquidity11Called before adding liquidity
AfterAddLiquidity10Called after adding liquidity
BeforeRemoveLiquidity9Called before removing liquidity
AfterRemoveLiquidity8Called after removing liquidity
// Check liquidity permissions
Hook.hasPermission(hookAddress, HookOptions.BeforeAddLiquidity)
Hook.hasPermission(hookAddress, HookOptions.AfterAddLiquidity)
Hook.hasPermission(hookAddress, HookOptions.BeforeRemoveLiquidity)
Hook.hasPermission(hookAddress, HookOptions.AfterRemoveLiquidity)
 
// Or use convenience method
Hook.hasLiquidityPermissions(hookAddress)

Swap Permissions

Called during swap operations.

PermissionBitDescription
BeforeSwap7Called before a swap
AfterSwap6Called after a swap
// Check swap permissions
Hook.hasPermission(hookAddress, HookOptions.BeforeSwap)
Hook.hasPermission(hookAddress, HookOptions.AfterSwap)
 
// Or use convenience method
Hook.hasSwapPermissions(hookAddress)

Donate Permissions

Called during donate operations (adding to pool fees without receiving LP tokens).

PermissionBitDescription
BeforeDonate5Called before a donate
AfterDonate4Called after a donate
// Check donate permissions
Hook.hasPermission(hookAddress, HookOptions.BeforeDonate)
Hook.hasPermission(hookAddress, HookOptions.AfterDonate)
 
// Or use convenience method
Hook.hasDonatePermissions(hookAddress)

Delta Permissions

These special permissions allow hooks to modify the token amounts in operations.

PermissionBitDescription
BeforeSwapReturnsDelta3beforeSwap can modify swap amounts
AfterSwapReturnsDelta2afterSwap can modify swap amounts
AfterAddLiquidityReturnsDelta1afterAddLiquidity can modify token amounts
AfterRemoveLiquidityReturnsDelta0afterRemoveLiquidity can modify token amounts
// Check delta permissions
Hook.hasPermission(hookAddress, HookOptions.BeforeSwapReturnsDelta)
Hook.hasPermission(hookAddress, HookOptions.AfterSwapReturnsDelta)
Hook.hasPermission(hookAddress, HookOptions.AfterAddLiquidityReturnsDelta)
Hook.hasPermission(hookAddress, HookOptions.AfterRemoveLiquidityReturnsDelta)

Computing Hook Addresses

Hook addresses must have specific bits set to enable permissions. Here's how to compute them:

import { hookFlagIndex, HookOptions } from '@uniswap/v4-sdk-next'
 
function computeHookFlags(permissions: HookOptions[]): number {
  let flags = 0
  for (const permission of permissions) {
    flags |= (1 << hookFlagIndex[permission])
  }
  return flags
}
 
// Example: Hook with beforeSwap and afterSwap
const swapHookFlags = computeHookFlags([
  HookOptions.BeforeSwap,
  HookOptions.AfterSwap
])
// Result: 0xC0 (bits 6 and 7 set)
 
// The hook address must end with these flags
// e.g., 0x000000000000000000000000000000000000C0C0

Example: Creating Permission-Aware Code

import { Pool, Hook, HookOptions, ADDRESS_ZERO } from '@uniswap/v4-sdk-next'
 
async function getSwapQuote(pool: Pool, inputAmount: CurrencyAmount) {
  // Check if the hook affects swap calculations
  if (pool.hooks !== ADDRESS_ZERO) {
    const hasSwapHooks = Hook.hasSwapPermissions(pool.hooks)
    const hasDeltaHooks =
      Hook.hasPermission(pool.hooks, HookOptions.BeforeSwapReturnsDelta) ||
      Hook.hasPermission(pool.hooks, HookOptions.AfterSwapReturnsDelta)
 
    if (hasSwapHooks || hasDeltaHooks) {
      throw new Error(
        'Cannot compute quote for pools with swap hooks. ' +
        'Use an on-chain quoter instead.'
      )
    }
  }
 
  // Safe to compute quote off-chain
  return pool.getOutputAmount(inputAmount)
}

Permission Bit Layout

The last 14 bits of a hook address determine its permissions:

Address: 0x...............XXXX
                          ^^^^
                          |||\- bits 0-3: Delta permissions
                          ||\-- bits 4-5: Donate permissions
                          |\--- bits 6-7: Swap permissions
                          \---- bits 8-13: Liquidity & Initialize permissions

Visual representation of bits:

Bit 13: beforeInitialize
Bit 12: afterInitialize
Bit 11: beforeAddLiquidity
Bit 10: afterAddLiquidity
Bit 9:  beforeRemoveLiquidity
Bit 8:  afterRemoveLiquidity
Bit 7:  beforeSwap
Bit 6:  afterSwap
Bit 5:  beforeDonate
Bit 4:  afterDonate
Bit 3:  beforeSwapReturnsDelta
Bit 2:  afterSwapReturnsDelta
Bit 1:  afterAddLiquidityReturnsDelta
Bit 0:  afterRemoveLiquidityReturnsDelta

Common Permission Combinations

Use CaseHex SuffixPermissions
No hooks0x0000None
Swap monitoring0x00C0beforeSwap, afterSwap
Fee taking0x00C4beforeSwap, afterSwap, afterSwapReturnsDelta
Liquidity management0x0F00All liquidity hooks
Full control0x3FFFAll permissions