solana_clmm_raydium/lib.rs
1// Math is extracted byte-for-byte from raydium-io/raydium-clmm and we want
2// to keep it diffable against upstream. We therefore turn off most clippy
3// lints on the lib itself (the extracted code) — tests are linted normally.
4#![allow(clippy::all)]
5
6//! Pure-Rust, no-RPC swap math for the Raydium concentrated-liquidity AMM
7//! (CLMM) on Solana.
8//!
9//! This crate contains the deterministic integer arithmetic that the on-chain
10//! Raydium CLMM program executes — extracted unchanged into a library that has
11//! no dependency on `anchor-lang`, `solana-program`, the Solana runtime, or
12//! the Anchor account model. Given pre-decoded pool state and tick-array data,
13//! every function here is a pure function of its inputs.
14//!
15//! # Scope
16//!
17//! - Tick ↔ sqrt-price conversions ([`get_sqrt_price_at_tick`],
18//! [`get_tick_at_sqrt_price`])
19//! - Liquidity ↔ token-amount conversions
20//! ([`get_liquidity_from_amounts`], [`get_delta_amounts_signed`], …)
21//! - Single-tick swap step ([`compute_swap_step`])
22//! - Multi-tick swap orchestration
23//! ([`compute_swap_full`])
24//! - Tick-array bitmap navigation
25//! ([`next_initialized_tick_array_start_index`])
26//! - Token-2022 transfer-fee math ([`calculate_fee`],
27//! [`apply_transfer_fee`], [`reverse_apply_transfer_fee`]) — mirrors
28//! `spl_token_2022_interface::extension::transfer_fee` byte-exactly
29//!
30//! # Out of scope
31//!
32//! - Pool / tick-array account decoding (this crate takes pre-decoded state;
33//! caller flattens decoded `TickArrayState`s into the
34//! [`InitializedTick`] slice that [`compute_swap_full`] consumes)
35//! - Token-2022 mint-extension TLV decoding and transfer-hook execution
36//! (caller resolves the active [`TransferFee`] and CPIs hook programs)
37//! - Position fee and reward accumulation beyond `liquidity_from_amounts`
38//!
39//! # Provenance
40//!
41//! Math is extracted from
42//! `raydium-io/raydium-clmm/programs/amm/src/libraries/`. The arithmetic
43//! itself is byte-for-byte identical to the on-chain implementation; the only
44//! changes are import paths, an internal `ErrorCode` enum that replaces
45//! `anchor_lang::error::Error`, and free-function rehosting of three static
46//! methods that used no struct fields.
47
48// `core_` alias is referenced by the `construct_bignum!` macro in `big_num`.
49pub use core as core_;
50
51#[doc(hidden)]
52pub mod big_num;
53#[doc(hidden)]
54pub mod fixed_point_64;
55#[doc(hidden)]
56pub mod full_math;
57#[doc(hidden)]
58pub mod unsafe_math;
59
60pub mod error;
61pub mod liquidity_math;
62pub mod sqrt_price_math;
63pub mod state_helpers;
64pub mod swap_full;
65pub mod swap_math;
66pub mod tick_array_bit_map;
67pub mod tick_math;
68pub mod transfer_fee;
69
70// ---- curated public API ----
71
72pub use error::ErrorCode;
73
74pub use tick_math::{
75 get_sqrt_price_at_tick, get_tick_at_sqrt_price, MAX_SQRT_PRICE_X64, MAX_TICK,
76 MIN_SQRT_PRICE_X64, MIN_TICK,
77};
78
79pub use liquidity_math::{
80 add_delta, cross, get_delta_amount_0_signed, get_delta_amount_0_unsigned,
81 get_delta_amount_1_signed, get_delta_amount_1_unsigned, get_delta_amounts_signed,
82 get_liquidity_from_amount_0, get_liquidity_from_amount_1, get_liquidity_from_amounts,
83 get_liquidity_from_single_amount_0, get_liquidity_from_single_amount_1,
84};
85
86pub use sqrt_price_math::{
87 get_next_sqrt_price_from_amount_0_rounding_up, get_next_sqrt_price_from_amount_1_rounding_down,
88 get_next_sqrt_price_from_input, get_next_sqrt_price_from_output,
89};
90
91pub use swap_math::{compute_swap_step, SwapStep};
92
93pub use swap_full::{compute_swap_full, InitializedTick, SwapPool, SwapResult};
94
95pub use tick_array_bit_map::{
96 check_current_tick_array_is_initialized, next_initialized_tick_array_start_index,
97 PoolTickBitmap, TICK_ARRAY_BITMAP_SIZE,
98};
99
100pub use state_helpers::{
101 array_start_index_for_tick, is_tick_out_of_boundary, is_valid_tick_array_start_index,
102 tick_count_in_array, FEE_RATE_DENOMINATOR_VALUE, TICK_ARRAY_SIZE,
103};
104
105pub use transfer_fee::{
106 apply_transfer_fee, calculate_fee, reverse_apply_transfer_fee, TransferFee,
107 MAX_FEE_BASIS_POINTS,
108};