UniswapV3FullRangeMath
Title: UniswapV3FullRangeMath
Author: Modified from Uniswap V3 — TickMath
(https://github.com/Uniswap/v3-core/blob/main/contracts/libraries/TickMath.sol) and LiquidityAmounts (https://github.com/Uniswap/v3-periphery/blob/main/contracts/libraries/LiquidityAmounts.sol).
Pure-math helpers the Lattice UniswapV3Adapter needs to value a full-range position
from a TWAP tick: getSqrtRatioAtTick (tick → sqrtPriceX96) and getAmountsForLiquidity
(liquidity + price range → (amount0, amount1)). Stateless utility library — no own storage,
no facet, no interface file (Lattice utility-library pattern).
The original Uniswap libraries target Solidity 0.7/0.8 with explicit unchecked blocks; the
ports here preserve the exact arithmetic (wrapping is intentional and required for the magic
constants) inside unchecked so the bit-twiddling matches the canonical results. MIN_TICK
/ MAX_TICK are the v3 tick bounds; a full-range position uses the min/max usable ticks
(these bounds floored/ceiled to the pool's tickSpacing), computed by the caller.
The ports' FullMath.mulDiv calls go through Math.mulDiv: the same 512-bit floor division
with identical results, except that a zero denominator or an overflowing quotient reverts with
Panic(0x12) / Panic(0x11), where this library's own port (through 0.4.0) raised
Error("mulDiv:0") / Error("mulDiv:OF").
Constants
MIN_TICK
The minimum tick that may be used on any pool (TickMath.MIN_TICK).
int24 internal constant MIN_TICK = -887272;MAX_TICK
The maximum tick that may be used on any pool (TickMath.MAX_TICK).
int24 internal constant MAX_TICK = 887272;MIN_SQRT_RATIO
The minimum value getSqrtRatioAtTick can return (== getSqrtRatioAtTick(MIN_TICK)).
uint160 internal constant MIN_SQRT_RATIO = 4295128739;MAX_SQRT_RATIO
The maximum value getSqrtRatioAtTick can return (== getSqrtRatioAtTick(MAX_TICK)).
uint160 internal constant MAX_SQRT_RATIO = 1461446703485210103287273052203988822378723970342;Functions
getSqrtRatioAtTick
Calculates sqrt(1.0001^tick) * 2^96 (a Q64.96 sqrt price) for the given tick.
Verbatim port of Uniswap V3 TickMath.getSqrtRatioAtTick. The chained conditional
multiplications reconstruct the fixed-point sqrt-ratio from the tick's set bits; the magic
constants and wrapping multiplies are exactly the v3 originals and MUST run unchecked.
function getSqrtRatioAtTick(int24 tick) internal pure returns (uint160 sqrtPriceX96);Parameters
| Name | Type | Description |
|---|---|---|
| tick | int24 | The tick to convert; must satisfy MIN_TICK <= tick <= MAX_TICK. |
Returns
| Name | Type | Description |
|---|---|---|
| sqrtPriceX96 | uint160 | The sqrt(token1/token0) ratio as a Q64.96 value. |
getAmount0ForLiquidity
Computes the token0 amount for liquidity between two sqrt prices.
Port of Uniswap V3 LiquidityAmounts.getAmount0ForLiquidity. Assumes sqrtA <= sqrtB.
function getAmount0ForLiquidity(uint160 sqrtA, uint160 sqrtB, uint128 liquidity)
internal
pure
returns (uint256 amount0);Parameters
| Name | Type | Description |
|---|---|---|
| sqrtA | uint160 | |
| sqrtB | uint160 | |
| liquidity | uint128 |
Returns
| Name | Type | Description |
|---|---|---|
| amount0 | uint256 |
getAmount1ForLiquidity
Computes the token1 amount for liquidity between two sqrt prices.
Port of Uniswap V3 LiquidityAmounts.getAmount1ForLiquidity. Assumes sqrtA <= sqrtB.
function getAmount1ForLiquidity(uint160 sqrtA, uint160 sqrtB, uint128 liquidity)
internal
pure
returns (uint256 amount1);Parameters
| Name | Type | Description |
|---|---|---|
| sqrtA | uint160 | |
| sqrtB | uint160 | |
| liquidity | uint128 |
Returns
| Name | Type | Description |
|---|---|---|
| amount1 | uint256 |
getAmountsForLiquidity
Computes (amount0, amount1) currently composing liquidity at the current sqrt price,
for a position spanning [sqrtLower, sqrtUpper].
Port of Uniswap V3 LiquidityAmounts.getAmountsForLiquidity. Three regimes:
- price below the range → all token0;
- price inside the range → a split of both (the full-range, in-price case);
- price above the range → all token1.
function getAmountsForLiquidity(uint160 sqrtCurrent, uint160 sqrtLower, uint160 sqrtUpper, uint128 liquidity)
internal
pure
returns (uint256 amount0, uint256 amount1);Parameters
| Name | Type | Description |
|---|---|---|
| sqrtCurrent | uint160 | The current sqrt price (Q64.96), e.g. derived from the TWAP tick. |
| sqrtLower | uint160 | The sqrt price at the position's lower tick. |
| sqrtUpper | uint160 | The sqrt price at the position's upper tick. |
| liquidity | uint128 | The position's liquidity. |
Returns
| Name | Type | Description |
|---|---|---|
| amount0 | uint256 | |
| amount1 | uint256 |
getLiquidityForAmount0
Computes the liquidity for a given token0 amount between two sqrt prices.
Port of Uniswap V3 LiquidityAmounts.getLiquidityForAmount0. Assumes sqrtA <= sqrtB.
function getLiquidityForAmount0(uint160 sqrtA, uint160 sqrtB, uint256 amount0)
internal
pure
returns (uint128 liquidity);Parameters
| Name | Type | Description |
|---|---|---|
| sqrtA | uint160 | |
| sqrtB | uint160 | |
| amount0 | uint256 |
Returns
| Name | Type | Description |
|---|---|---|
| liquidity | uint128 |
getLiquidityForAmount1
Computes the liquidity for a given token1 amount between two sqrt prices.
Port of Uniswap V3 LiquidityAmounts.getLiquidityForAmount1. Assumes sqrtA <= sqrtB.
function getLiquidityForAmount1(uint160 sqrtA, uint160 sqrtB, uint256 amount1)
internal
pure
returns (uint128 liquidity);Parameters
| Name | Type | Description |
|---|---|---|
| sqrtA | uint160 | |
| sqrtB | uint160 | |
| amount1 | uint256 |
Returns
| Name | Type | Description |
|---|---|---|
| liquidity | uint128 |
getLiquidityForAmounts
Computes the maximum liquidity for (amount0, amount1) at the current sqrt price over
the range [sqrtLower, sqrtUpper] (the liquidity actually mintable from both amounts).
Port of Uniswap V3 LiquidityAmounts.getLiquidityForAmounts. In-range (the full-range,
in-price case) takes the binding minimum of the two single-token liquidities.
function getLiquidityForAmounts(
uint160 sqrtCurrent,
uint160 sqrtLower,
uint160 sqrtUpper,
uint256 amount0,
uint256 amount1
) internal pure returns (uint128 liquidity);Parameters
| Name | Type | Description |
|---|---|---|
| sqrtCurrent | uint160 | |
| sqrtLower | uint160 | |
| sqrtUpper | uint160 | |
| amount0 | uint256 | |
| amount1 | uint256 |
Returns
| Name | Type | Description |
|---|---|---|
| liquidity | uint128 |
fullRangeTicks
Returns the min/max usable ticks for a full-range position on a pool with the given
tickSpacing (the v3 tick bounds floored/ceiled to a multiple of tickSpacing).
function fullRangeTicks(int24 tickSpacing) internal pure returns (int24 tickLower, int24 tickUpper);Parameters
| Name | Type | Description |
|---|---|---|
| tickSpacing | int24 | The pool's tick spacing (must be > 0). |
Returns
| Name | Type | Description |
|---|---|---|
| tickLower | int24 | The lowest initializable tick (full-range lower bound). |
| tickUpper | int24 | The highest initializable tick (full-range upper bound). |
valueInToken0
Values a sqrt-priced (amount0, amount1) pair in token0 units at price sqrtPriceX96.
token1→token0 conversion: the pool price is token1/token0 = sqrtPriceX96^2 / 2^192, so
amount1 (token1 units) is worth amount1 * 2^192 / sqrtPriceX96^2 in token0 units. Done
in two mulDiv steps so the * 2^96 factors never overflow.
function valueInToken0(uint256 amount0, uint256 amount1, uint160 sqrtPriceX96)
internal
pure
returns (uint256 value0);Parameters
| Name | Type | Description |
|---|---|---|
| amount0 | uint256 | The token0 amount (already in token0 units). |
| amount1 | uint256 | The token1 amount to convert to token0 units. |
| sqrtPriceX96 | uint160 | The sqrt price (Q64.96) to value at. |
Returns
| Name | Type | Description |
|---|---|---|
| value0 | uint256 | amount0 + (amount1 valued in token0). |
Errors
TickOutOfBounds
Thrown when a tick passed to getSqrtRatioAtTick is out of the v3 bounds.
error TickOutOfBounds(int24 tick);Parameters
| Name | Type | Description |
|---|---|---|
| tick | int24 |