Search Apps Documentation Source Content File Folder Download Copy Actions Download

/p/gnoswap/gnsmath

Directory · 10 Files
README.md Open

gnsmath

Core mathematical operations for GnoSwap's concentrated liquidity AMM.

Overview

This package provides the fundamental calculations for concentrated liquidity, including tick conversion, liquidity math calculations, sqrt price math, swap calculations, and bit manipulation utilities. All operations use Q96 and Q160 fixed-point arithmetic for precision.

The implementation follows Uniswap V3's mathematical model, ensuring compatibility and correctness for cross-chain liquidity operations.

Features

  • Bit Math: MSB/LSB calculations for tick bitmap operations
  • Tick Math: Tick and Q64.96 sqrt-price conversions
  • Liquidity Math: Liquidity and token amount conversions for price ranges
  • Sqrt Price Math: Token amount conversions using Q64.96 format
  • Swap Math: Single-step swap calculations with fee handling
  • Overflow Protection: Built-in int256 overflow detection
  • Rounding Control: Configurable rounding for AMM safety

Core Concepts

Q96 Fixed-Point Format

Square root prices use Q64.96 representation:

  • sqrtPriceX96 = sqrt(token1/token0) * 2^96
  • Enables precise integer arithmetic without floating-point

Rounding Directions

  • Round UP: Amounts owed TO pool (deposits, exact input)
  • Round DOWN: Amounts owed FROM pool (withdrawals, exact output)

Usage

 1import (
 2    "gno.land/p/gnoswap/gnsmath"
 3    i256 "gno.land/p/gnoswap/int256"
 4    u256 "gno.land/p/gnoswap/uint256"
 5)
 6
 7// Calculate token amounts for liquidity change
 8sqrtPriceA := u256.MustFromDecimal("79228162514264337593543950336")
 9sqrtPriceB := u256.MustFromDecimal("79625275426524748796330556128")
10liquidity := i256.MustFromDecimal("1000000000000000000")
11
12amount0 := gnsmath.GetAmount0Delta(sqrtPriceA, sqrtPriceB, liquidity)
13amount1 := gnsmath.GetAmount1Delta(sqrtPriceA, sqrtPriceB, liquidity)
14
15// Compute swap step
16feePips := uint64(3000) // 0.3% fee
17sqrtPriceNext, amountIn, amountOut, feeAmount := gnsmath.SwapMathComputeSwapStep(
18    currentPrice,
19    targetPrice,
20    liquidity,
21    amountRemaining,
22    feePips,
23)
24
25// Bit operations for tick bitmap
26tickBitmap := u256.NewUint(0xFF00)
27msb := gnsmath.BitMathMostSignificantBit(tickBitmap)
28println(msb) // Output: 15
29
30lsb := gnsmath.BitMathLeastSignificantBit(tickBitmap)
31println(lsb) // Output: 8

API

Bit Math

  • BitMathMostSignificantBit(x *u256.Uint) uint8 - Find MSB position (0-255)
  • BitMathLeastSignificantBit(x *u256.Uint) uint8 - Find LSB position (0-255)

Tick Math

  • TickMathGetSqrtRatioAtTick(tick int32) *u256.Uint - Convert tick to Q64.96 sqrt price
  • TickMathGetTickAtSqrtRatio(sqrtPriceX96 *u256.Uint) int32 - Convert Q64.96 sqrt price to tick

Liquidity Math

  • GetLiquidityForAmounts(sqrtRatioX96, sqrtRatioAX96, sqrtRatioBX96, amount0, amount1 *u256.Uint) *u256.Uint
    • Calculate max liquidity from token amounts and price range
  • GetAmountsForLiquidity(sqrtRatioX96, sqrtRatioAX96, sqrtRatioBX96, liquidity *u256.Uint) (*u256.Uint, *u256.Uint)
    • Calculate token amounts represented by liquidity and price range
  • LiquidityMathAddDelta(x *u256.Uint, y *i256.Int) *u256.Uint
    • Apply signed liquidity delta with overflow/underflow protection

Sqrt Price Math

  • GetAmount0Delta(sqrtRatioAX96, sqrtRatioBX96 *u256.Uint, liquidity *i256.Int) *i256.Int
    • Calculate token0 amount: liquidity * (1/√Pb - 1/√Pa)
  • GetAmount1Delta(sqrtRatioAX96, sqrtRatioBX96 *u256.Uint, liquidity *i256.Int) *i256.Int
    • Calculate token1 amount: liquidity * (√Pb - √Pa)

Swap Math

  • SwapMathComputeSwapStep(sqrtRatioCurrentX96, sqrtRatioTargetX96, liquidity *u256.Uint, amountRemaining *i256.Int, feePips uint64) (*u256.Uint, *u256.Uint, *u256.Uint, *u256.Uint)
    • Returns: (nextSqrtPrice, amountIn, amountOut, feeAmount)
    • Handles both exact input and exact output swaps