Skip to main content
These are stateless ports of the on-chain math, using Alephium’s rounding (MathUtil.alphDiv), so results match the contracts to the unit.

ClmmLiquidityUtils

Conventions: sqrtRatioX96 is the current price. sqrtRatioAX96 and sqrtRatioBX96 are the range bounds (getSqrtRatioAtTick(tickLower/Upper)). Amounts are in sorted token0/token1 order.

getLiquidityFromAmounts(sqrtRatioX96, sqrtRatioAX96, sqrtRatioBX96, amount0, amount1)

The maximum liquidity mintable from the given amounts:
  • price at or below the lower bound → only amount0 counts
  • price inside the range → min(L from amount0, L from amount1)
  • price above the range → only amount1 counts

getAmountsForLiquidity(sqrtRatioX96, sqrtRatioAX96, sqrtRatioBX96, liquidity)

[amount0, amount1] for a signed liquidity delta. Contract convention: pass -liquidity to get the (negated) amounts required to add liquidity, and +liquidity for amounts received when removing.

getAmountsAndLiquidityAtSqrtPrice(sqrtRatioX96, sqrtRatioAX96, sqrtRatioBX96, amount0, amount1)

Returns [amount0Used, amount1Used, liquidity]: the balanced amounts actually deposited for the desired amount0 and amount1. This is the usual call for a “you will deposit” preview.

getAmountsAndLiquidityAtPrice(price, token0, token1, lowerTick, upperTick, amount0, amount1)

Same as above, taking a human price and TokenInfos.

getPositionAmountsFromPrice(props)

UI-oriented variant that works in base/quote terms and accepts ticks in any order:
Returns zeros if either input amount is 0n. To size a position from one side, pass UNLIMITED_AMOUNT (2^128 − 1) for the other side.

Lower-level

PoolUtils

getPositionId(poolAddress, owner, tickLower, tickUpper)

Derives the position contract ID from the pool address. Unlike clmm.getPositionId, it normalizes groupless owner addresses for you.

offlineSwap

Replays a swap locally over the liquidity curve returned by clmm.simulateSwap, and returns the other side’s amount as a signed value:
  • exact-in (amountSpecified > 0): returns the output as a negative number (-offlineSwap(...) is what you receive)
  • exact-out (amountSpecified < 0): returns the input required (take the absolute value)
The integration tests check that this matches the pool’s on-chain simulateSwap return value exactly.

computeSwapStep(sqrtPriceX96, sqrtPriceTargetX96, liquidity, amount, feePips)

A single swap step within one liquidity range. Returns [sqrtPriceNextX96, amountIn, amountOut, feeAmount]. offlineSwap calls this once per row.