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

Position

The Position class represents a liquidity position on a Uniswap V4 pool. It provides methods to calculate token amounts, handle slippage, and generate permit data.

Import

import { Position } from '@uniswap/v4-sdk-next'

Constructor

new Position({
  pool: Pool,
  liquidity: BigintIsh,
  tickLower: number,
  tickUpper: number
})

Parameters

NameTypeDescription
poolPoolThe pool on which the position exists
liquidityBigintIshThe amount of liquidity in the position
tickLowernumberThe lower tick boundary of the position
tickUppernumberThe upper tick boundary of the position

Example

import { Pool, Position, ADDRESS_ZERO } from '@uniswap/v4-sdk-next'
import { Token, Ether, Percent } from '@uniswap/sdk-core-next'
 
// Create pool
const ETH = Ether.onChain(1)
const USDC = new Token(1, '0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48', 6, 'USDC')
 
const pool = new Pool(
  ETH,
  USDC,
  3000,
  60,
  ADDRESS_ZERO,
  '79228162514264337593543950336',
  '1000000000000000000',
  0
)
 
// Create a position
const position = new Position({
  pool,
  liquidity: '1000000000000000000',
  tickLower: -887220,
  tickUpper: 887220
})
 
// Get token amounts
console.log(position.amount0.toSignificant(6))
console.log(position.amount1.toSignificant(6))
 
// Calculate amounts with slippage
const slippage = new Percent(50, 10000) // 0.5%
const { amount0, amount1 } = position.mintAmountsWithSlippage(slippage)

Properties

pool

readonly pool: Pool

The pool on which this position exists.

tickLower

readonly tickLower: number

The lower tick boundary of the position.

tickUpper

readonly tickUpper: number

The upper tick boundary of the position.

liquidity

readonly liquidity: bigint

The amount of liquidity in this position.

token0PriceLower

get token0PriceLower(): Price<Currency, Currency>

The price of token0 at the lower tick boundary.

token0PriceUpper

get token0PriceUpper(): Price<Currency, Currency>

The price of token0 at the upper tick boundary.

amount0

get amount0(): CurrencyAmount<Currency>

The amount of currency0 that this position's liquidity could be burned for at the current pool price.

amount1

get amount1(): CurrencyAmount<Currency>

The amount of currency1 that this position's liquidity could be burned for at the current pool price.

mintAmounts

get mintAmounts(): Readonly<{ amount0: bigint; amount1: bigint }>

The minimum amounts that must be sent to mint the amount of liquidity held by the position at the current price.

Static Methods

fromAmounts(params)

static fromAmounts({
  pool: Pool,
  tickLower: number,
  tickUpper: number,
  amount0: BigintIsh,
  amount1: BigintIsh,
  useFullPrecision: boolean
}): Position

Computes the maximum amount of liquidity received for given amounts of token0 and token1.

const position = Position.fromAmounts({
  pool,
  tickLower: -887220,
  tickUpper: 887220,
  amount0: '1000000000000000000', // 1 ETH
  amount1: '1000000000',          // 1000 USDC
  useFullPrecision: true
})

fromAmount0(params)

static fromAmount0({
  pool: Pool,
  tickLower: number,
  tickUpper: number,
  amount0: BigintIsh,
  useFullPrecision: boolean
}): Position

Computes a position with maximum liquidity for a given amount of token0, assuming unlimited token1.

const position = Position.fromAmount0({
  pool,
  tickLower: -887220,
  tickUpper: 887220,
  amount0: '1000000000000000000', // 1 ETH
  useFullPrecision: true
})

fromAmount1(params)

static fromAmount1({
  pool: Pool,
  tickLower: number,
  tickUpper: number,
  amount1: BigintIsh
}): Position

Computes a position with maximum liquidity for a given amount of token1, assuming unlimited token0. Always uses full precision.

const position = Position.fromAmount1({
  pool,
  tickLower: -887220,
  tickUpper: 887220,
  amount1: '1000000000' // 1000 USDC
})

Methods

mintAmountsWithSlippage(slippageTolerance)

mintAmountsWithSlippage(slippageTolerance: Percent): Readonly<{ amount0: bigint; amount1: bigint }>

Returns the maximum amounts of token0 and token1 that must be sent to safely mint the position with the given slippage tolerance.

In V4, minting is protected by maximum amounts (unlike V3 which uses minimum amounts).

const slippage = new Percent(50, 10000) // 0.5%
const { amount0, amount1 } = position.mintAmountsWithSlippage(slippage)

burnAmountsWithSlippage(slippageTolerance)

burnAmountsWithSlippage(slippageTolerance: Percent): Readonly<{ amount0: bigint; amount1: bigint }>

Returns the minimum amounts that should be requested when burning the position's liquidity with the given slippage tolerance.

const slippage = new Percent(50, 10000) // 0.5%
const { amount0, amount1 } = position.burnAmountsWithSlippage(slippage)

permitBatchData(slippageTolerance, spender, nonce, deadline)

permitBatchData(
  slippageTolerance: Percent,
  spender: string,
  nonce: BigintIsh,
  deadline: BigintIsh
): AllowanceTransferPermitBatch

Returns the AllowanceTransferPermitBatch data for adding liquidity using Permit2.

const permitData = position.permitBatchData(
  new Percent(50, 10000),                    // 0.5% slippage
  '0x...PositionManagerAddress',             // Spender (Position Manager)
  1n,                                         // Permit2 nonce
  Math.floor(Date.now() / 1000) + 3600       // Deadline (1 hour from now)
)
 
// permitData can be signed and submitted with the transaction
// {
//   details: [
//     { token: '0x...', amount: ..., expiration: ..., nonce: ... },
//     { token: '0x...', amount: ..., expiration: ..., nonce: ... }
//   ],
//   spender: '0x...',
//   sigDeadline: ...
// }

Tick Validation

The constructor validates that:

  • tickLower is less than tickUpper
  • Both ticks are within the valid range (MIN_TICK to MAX_TICK)
  • Both ticks are divisible by the pool's tick spacing
// Valid position
const position = new Position({
  pool,
  liquidity: '1000000000000000000',
  tickLower: -60,  // Must be divisible by tickSpacing (60)
  tickUpper: 60
})
 
// Invalid - will throw
const invalid = new Position({
  pool,
  liquidity: '1000000000000000000',
  tickLower: -50,  // Not divisible by 60
  tickUpper: 50
})

V4-Specific Features

Native Currency Positions

V4 positions can include native ETH directly:

import { Ether } from '@uniswap/sdk-core-next'
 
const ETH = Ether.onChain(1)
const pool = new Pool(ETH, USDC, 3000, 60, ADDRESS_ZERO, ...)
 
const position = new Position({
  pool,
  liquidity: '1000000000000000000',
  tickLower: -887220,
  tickUpper: 887220
})
 
// amount0 is native ETH (not WETH)
console.log(position.pool.currency0.isNative) // true

Hook-Enabled Pools

Positions can exist in pools with hooks:

const poolWithHook = new Pool(
  ETH,
  USDC,
  3000,
  60,
  '0x1234...', // Hook address
  sqrtPriceX96,
  liquidity,
  tick
)
 
const position = new Position({
  pool: poolWithHook,
  liquidity: '1000000000000000000',
  tickLower: -887220,
  tickUpper: 887220
})