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
| Constant | Value |
|---|---|
Q64 | 1 << 64 |
MIN_TICK | -443636 |
MAX_TICK | 443636 |
MIN_SQRT_PRICE | 4295048016 |
MAX_SQRT_PRICE | 79226673515401279992447579061 |
FEE_DENOMINATOR | 1000000 |
MAX_FEE_BENEFICIARIES | 8 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
| Module | Exports |
|---|---|
wide | mul_div, Rounding::{Down, Up} |
ticks | tick_to_sqrt_price, sqrt_price_to_tick, validate_sqrt_price, validate_tick_range |
quantities | TokenAmounts, checked_token_amount, add_liquidity_delta |
liquidity | amount_a_delta, amount_b_delta, amounts_for_liquidity, liquidity_from_amounts |
swap | compute_swap_step, SwapDirection, SwapStepParams, SwapStep |
fees | FeeRate, split_fee_amount |
growth | accrue_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.