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

Hook

The Hook class provides utilities for working with V4 hook permissions. V4 hooks encode their permissions in the last 14 bits of the hook contract address.

Import

import { Hook, HookOptions } from '@uniswap/v4-sdk-next'

Overview

In Uniswap V4, hooks are smart contracts that can execute custom logic at various points during pool operations. The permissions a hook has are encoded directly in its contract address, making it impossible to change permissions after deployment.

The last 14 bits of a hook address indicate which hook functions are enabled:

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

Static Methods

permissions(address)

static permissions(address: string): HookPermissions

Returns all permissions for a given hook address.

const hookAddress = '0x000000000000000000000000000000000000C0C0'
const perms = Hook.permissions(hookAddress)
 
console.log(perms)
// {
//   beforeInitialize: false,
//   afterInitialize: false,
//   beforeAddLiquidity: false,
//   afterAddLiquidity: false,
//   beforeRemoveLiquidity: false,
//   afterRemoveLiquidity: false,
//   beforeSwap: true,
//   afterSwap: true,
//   beforeDonate: false,
//   afterDonate: false,
//   beforeSwapReturnsDelta: false,
//   afterSwapReturnsDelta: false,
//   afterAddLiquidityReturnsDelta: false,
//   afterRemoveLiquidityReturnsDelta: false
// }

hasPermission(address, hookOption)

static hasPermission(address: string, hookOption: HookOptions): boolean

Check if a hook has a specific permission.

import { HookOptions } from '@uniswap/v4-sdk-next'
 
const hookAddress = '0x000000000000000000000000000000000000C0C0'
 
Hook.hasPermission(hookAddress, HookOptions.BeforeSwap)  // true
Hook.hasPermission(hookAddress, HookOptions.AfterSwap)   // true
Hook.hasPermission(hookAddress, HookOptions.BeforeDonate) // false

hasInitializePermissions(address)

static hasInitializePermissions(address: string): boolean

Check if a hook has any initialize permissions (beforeInitialize or afterInitialize).

const hookAddress = '0x000000000000000000000000000000000000C0C0'
Hook.hasInitializePermissions(hookAddress) // false

hasLiquidityPermissions(address)

static hasLiquidityPermissions(address: string): boolean

Check if a hook has any liquidity-related permissions. This includes:

  • beforeAddLiquidity
  • afterAddLiquidity
  • beforeRemoveLiquidity
  • afterRemoveLiquidity

Note: This implicitly covers the delta permissions since they require the base permissions.

const hookAddress = '0x0000000000000000000000000000000000000C00'
Hook.hasLiquidityPermissions(hookAddress) // true (has beforeAddLiquidity)

hasSwapPermissions(address)

static hasSwapPermissions(address: string): boolean

Check if a hook has any swap-related permissions (beforeSwap or afterSwap).

const hookAddress = '0x000000000000000000000000000000000000C0C0'
Hook.hasSwapPermissions(hookAddress) // true

hasDonatePermissions(address)

static hasDonatePermissions(address: string): boolean

Check if a hook has any donate-related permissions (beforeDonate or afterDonate).

const hookAddress = '0x000000000000000000000000000000000000C0C0'
Hook.hasDonatePermissions(hookAddress) // false

Example: Analyzing a Hook Address

import { Hook, HookOptions } from '@uniswap/v4-sdk-next'
 
function analyzeHook(hookAddress: string) {
  console.log('Hook Analysis:', hookAddress)
  console.log('---')
 
  const perms = Hook.permissions(hookAddress)
 
  // Group permissions by category
  console.log('Initialize:',
    perms.beforeInitialize ? 'before' : '',
    perms.afterInitialize ? 'after' : ''
  )
 
  console.log('Add Liquidity:',
    perms.beforeAddLiquidity ? 'before' : '',
    perms.afterAddLiquidity ? 'after' : '',
    perms.afterAddLiquidityReturnsDelta ? '(returns delta)' : ''
  )
 
  console.log('Remove Liquidity:',
    perms.beforeRemoveLiquidity ? 'before' : '',
    perms.afterRemoveLiquidity ? 'after' : '',
    perms.afterRemoveLiquidityReturnsDelta ? '(returns delta)' : ''
  )
 
  console.log('Swap:',
    perms.beforeSwap ? 'before' : '',
    perms.afterSwap ? 'after' : '',
    perms.beforeSwapReturnsDelta ? '(before returns delta)' : '',
    perms.afterSwapReturnsDelta ? '(after returns delta)' : ''
  )
 
  console.log('Donate:',
    perms.beforeDonate ? 'before' : '',
    perms.afterDonate ? 'after' : ''
  )
}
 
// Analyze a swap-only hook
analyzeHook('0x000000000000000000000000000000000000C0C0')

Example: Pool with Hook Validation

import { Pool, Hook, ADDRESS_ZERO } from '@uniswap/v4-sdk-next'
 
function createPool(currencyA, currencyB, fee, tickSpacing, hookAddress, ...poolParams) {
  // Validate hook if provided
  if (hookAddress !== ADDRESS_ZERO) {
    const perms = Hook.permissions(hookAddress)
 
    // Log which hooks are active
    console.log('Creating pool with hook permissions:', perms)
 
    // Warn if hook affects swap calculations
    if (Hook.hasSwapPermissions(hookAddress)) {
      console.warn('Warning: Hook may affect swap calculations')
    }
  }
 
  return new Pool(currencyA, currencyB, fee, tickSpacing, hookAddress, ...poolParams)
}

Address Validation

All Hook methods validate that the provided address is a valid Ethereum address:

// Valid addresses work
Hook.permissions('0x000000000000000000000000000000000000C0C0') // OK
 
// Invalid addresses throw
Hook.permissions('invalid') // throws 'invalid address'
Hook.permissions('0x123')   // throws 'invalid address'

Common Hook Address Patterns

// No hooks (zero address)
const NO_HOOK = '0x0000000000000000000000000000000000000000'
 
// Swap hooks only (bits 6-7)
const SWAP_HOOK = '0x000000000000000000000000000000000000C0' // 0b11000000
 
// Liquidity hooks only (bits 8-11)
const LIQUIDITY_HOOK = '0x000000000000000000000000000000000000F00' // 0b111100000000
 
// All hooks
const ALL_HOOKS = '0x0000000000000000000000000000000000003FFF' // 0b11111111111111