Skip to content

Math library

Current fixed-point domain, public primitives, and rounding contracts.

Source: programs/grapl-amm/src/math/mod.rs and its focused modules. The library performs pure calculations; it does not validate Solana account ownership or move tokens.

Numeric domain

ConstantValue
Q641 << 64
MIN_TICK-443636
MAX_TICK443636
MIN_SQRT_PRICE4295048016
MAX_SQRT_PRICE79226673515401279992447579061
FEE_DENOMINATOR1000000
MAX_FEE_BENEFICIARIES8 in the math helper; the core currently has four beneficiary slots

Square-root prices use Q64.64. The tick lattice uses the implementation's Q192 factors and integer algorithm; matching a domain used by another CLMM does not promise bit-for-bit parity with that protocol.

Public primitives

ModuleExports
widemul_div, Rounding::{Down, Up}
tickstick_to_sqrt_price, sqrt_price_to_tick, validate_sqrt_price, validate_tick_range
quantitiesTokenAmounts, checked_token_amount, add_liquidity_delta
liquidityamount_a_delta, amount_b_delta, amounts_for_liquidity, liquidity_from_amounts
swapcompute_swap_step, SwapDirection, SwapStepParams, SwapStep
feesFeeRate, split_fee_amount
growthaccrue_fee_growth, fees_owed

sqrt_price_to_tick returns the greatest tick whose encoded square-root price does not exceed the input. validate_tick_range requires ordered endpoints and a positive spacing with aligned ticks.

Fees and residues

FeeRate::new accepts rates below one million ppm; a pool imposes its own lower cap. net_from_gross rounds the net budget down. fee_from_net rounds the required fee up.

split_fee_amount(fee, shares, residue_index) floors each ppm allocation and sends the remaining units to the selected nonzero share. It is a per-event allocation helper, not cumulative beneficiary entitlement accounting.

accrue_fee_growth rounds growth down and uses checked accumulation rather than wrapping. fees_owed rounds the liquidity-times-growth claim down. The caller is responsible for inside-growth computation, atomic checkpoints, and retaining rounding residue as a liability.

A swap step is not a complete swap

compute_swap_step moves within one interval toward a target price, reporting input, output, fee, remaining amount, and whether the target was reached. Full execution still needs tick traversal, account validation, settlement, limits, and rollback. Do not treat a successful step calculation as a tradable pool.

Check arithmetic against independent rational or high-precision calculations, including one-unit rounding and boundary cases. See outcome validation.

Curves and exact output

curve_output floor-rounds the virtual-reserve output for net input. curve_input ceil-rounds the net input needed for a requested output; curve_sqrt_price derives the bounded Q64.64 marginal price. compute_exact_output_step performs a requested-output CLMM step; settlement separately includes input and output fees.

Read worked AMM equations for a numerical example and ExactIn / ExactOut for the user-facing contract. Pure math never treats virtual reserves as permission to withdraw unbacked assets.