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

computePoolAddress

The computePoolAddress utility computes the address of a Uniswap V3 pool given the factory, tokens, and fee tier. It uses CREATE2 address derivation.

Import

import { computePoolAddress } from '@uniswap/v3-sdk'

Function Signature

function computePoolAddress({
  factoryAddress?: Address.Address,
  tokenA: Token,
  tokenB: Token,
  fee: FeeAmount,
  initCodeHashManualOverride?: `0x${string}`
}): Address.Address

Parameters

ParameterTypeDescription
factoryAddressAddress.AddressThe V3 factory address (defaults to mainnet factory)
tokenATokenThe first token of the pair (order doesn't matter)
tokenBTokenThe second token of the pair (order doesn't matter)
feeFeeAmountThe fee tier of the pool
initCodeHashManualOverride`0x${string}`Optional override for the init code hash

Returns

Returns the computed pool address as Address.Address.

Example

import { computePoolAddress, FeeAmount } from '@uniswap/v3-sdk'
import { Token } from '@uniswap/sdk-core'
 
const USDC = new Token(1, '0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48', 6, 'USDC')
const WETH = new Token(1, '0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2', 18, 'WETH')
 
const poolAddress = computePoolAddress({
  tokenA: USDC,
  tokenB: WETH,
  fee: FeeAmount.MEDIUM
})
 
console.log(poolAddress) // '0x8ad599c3A0ff1De082011EFDDc58f1908eb6e6D8'

Token Order Independence

The function automatically sorts tokens, so the order of tokenA and tokenB doesn't matter:

// These produce the same address
const address1 = computePoolAddress({
  tokenA: USDC,
  tokenB: WETH,
  fee: FeeAmount.MEDIUM
})
 
const address2 = computePoolAddress({
  tokenA: WETH,
  tokenB: USDC,
  fee: FeeAmount.MEDIUM
})
 
console.log(address1 === address2) // true

Custom Factory Address

For non-mainnet deployments or custom factories:

const poolAddress = computePoolAddress({
  factoryAddress: '0x1F98431c8aD98523631AE4a59f267346ea31F984',
  tokenA: USDC,
  tokenB: WETH,
  fee: FeeAmount.MEDIUM
})

Chain-Specific Init Code Hash

Different chains may have different bytecode for the pool contract. The SDK automatically handles this for known chains like ZKSync:

import { Token, ChainId } from '@uniswap/sdk-core'
 
// ZKSync tokens
const zkSyncToken0 = new Token(ChainId.ZKSYNC, '0x...', 18, 'TOKEN0')
const zkSyncToken1 = new Token(ChainId.ZKSYNC, '0x...', 18, 'TOKEN1')
 
// SDK automatically uses the correct init code hash for ZKSync
const poolAddress = computePoolAddress({
  tokenA: zkSyncToken0,
  tokenB: zkSyncToken1,
  fee: FeeAmount.MEDIUM
})

For chains not built into the SDK, you can override the init code hash:

const poolAddress = computePoolAddress({
  tokenA: customToken0,
  tokenB: customToken1,
  fee: FeeAmount.MEDIUM,
  initCodeHashManualOverride: '0x...' // Custom init code hash
})

Using with Pool.getAddress

The Pool class also provides a static method that calls computePoolAddress:

import { Pool, FeeAmount } from '@uniswap/v3-sdk'
 
const poolAddress = Pool.getAddress(USDC, WETH, FeeAmount.MEDIUM)

How CREATE2 Works

The pool address is deterministically computed using CREATE2:

  1. Salt: Computed from keccak256(abi.encodePacked(token0, token1, fee))
  2. Init Code Hash: The keccak256 hash of the pool contract bytecode
  3. Factory Address: The V3 factory that deploys pools
address = keccak256(0xff ++ factory ++ salt ++ initCodeHash)[12:]

Constants

Default Factory Address

const FACTORY_ADDRESS = '0x1F98431c8aD98523631AE4a59f267346ea31F984'

Default Init Code Hash

const POOL_INIT_CODE_HASH = '0xe34f199b19b2b4f47f68442619d555527d244f78a3297ea89325f843f87b8b54'

ZKSync Init Code Hash

const ZKSYNC_POOL_INIT_CODE_HASH = '0x010013f177ea1fcbc4520f9a3ca7cd2d1d77959e05aa66484027cb38e712aeed'

Use Cases

Verifying Pool Existence

import { computePoolAddress, FeeAmount } from '@uniswap/v3-sdk'
import { ethers } from 'ethers'
 
const poolAddress = computePoolAddress({
  tokenA: USDC,
  tokenB: WETH,
  fee: FeeAmount.MEDIUM
})
 
// Check if pool exists by checking code at address
const code = await provider.getCode(poolAddress)
const poolExists = code !== '0x'

Finding All Fee Tier Pools

import { computePoolAddress, FeeAmount } from '@uniswap/v3-sdk'
 
const feeTiers = [
  FeeAmount.LOWEST,   // 0.01%
  FeeAmount.LOW,      // 0.05%
  FeeAmount.MEDIUM,   // 0.3%
  FeeAmount.HIGH      // 1%
]
 
const poolAddresses = feeTiers.map(fee =>
  computePoolAddress({
    tokenA: USDC,
    tokenB: WETH,
    fee
  })
)