| Crates.io | clmm-swap-math |
| lib.rs | clmm-swap-math |
| version | 0.1.0 |
| created_at | 2025-11-24 18:56:07.367839+00 |
| updated_at | 2025-11-24 18:56:07.367839+00 |
| description | Uniswap V3 Math written in Rust, with Swap possibility |
| homepage | https://github.com/aleexeyy/rust-uniswap-v3 |
| repository | https://github.com/aleexeyy/rust-uniswap-v3 |
| max_upload_size | |
| id | 1948396 |
| size | 217,185 |
A small, focused Rust crate that implements the core Uniswap V3 pool math in a reusable, test‑driven way. It exposes:
math module) for ticks, sqrt prices, liquidity and swap steps.V3Pool type for simulating swaps off‑chain.The crate is designed to be embeddable in trading tools, research scripts, or other DeFi infrastructure.
src/lib.rs – crate root, exports:
math – all core math modules.pool – pool structs and swap logic.FastMap – feature‑selectable hash map alias.src/error.rs – error types (MathError, StateError, SwapError, OnchainError, Error).src/math/
bit_math.rs – bit operations (MSB/LSB) on U256.tick_math.rs – tick ↔ sqrt ratio conversions (get_sqrt_ratio_at_tick, get_tick_at_sqrt_ratio).tick_bitmap.rs – tick bitmap operations for initialized ticks.sqrt_price_math.rs – price movement and amount deltas.liquidity_math.rs – liquidity add/remove with bounds checks.math_helpers.rs – high‑precision mul_div helpers.swap_math.rs – single‑step swap math (compute_swap_step).src/pool/
swap.rs – high‑level V3Pool::swap logic, SwapParams, SwapResult, Slot0.v3_pool.rs – V3Pool<P> struct, tick/bitmap fetching, and optional on‑chain RPC integration.src/hash.rs – defines FastMap<K, V> as HashMap, FxHashMap, or AHashMap depending on enabled features.benches/ – Criterion benchmarks for each math module and for all math combined.Defined in Cargo.toml:
default = ["std-hash"]
HashMap backend.onchain
alloy-provider and alloy-contract.V3Pool<P> (e.g. fetch_slot0, fetch_liquidity, bitmap/tick loading).Hash backends (mutually exclusive in practice, but not enforced):
std-hash – FastMap<K, V> = std::collections::HashMap<K, V>.rustc-hash – FastMap<K, V> = rustc_hash::FxHashMap<K, V>.ahash – FastMap<K, V> = ahash::AHashMap<K, V>.Add this crate to your Cargo.toml (local path or git, depending on your setup) and import the math functions:
use uniswap_v3_math::math::tick_math::{
get_sqrt_ratio_at_tick,
get_tick_at_sqrt_ratio,
MIN_TICK,
MAX_TICK,
};
use alloy_primitives::U256;
fn example_ticks() {
let sqrt_min = get_sqrt_ratio_at_tick(MIN_TICK).unwrap();
let sqrt_mid = get_sqrt_ratio_at_tick(0).unwrap();
let tick_back = get_tick_at_sqrt_ratio(sqrt_mid).unwrap();
assert_eq!(tick_back, 0);
let _: U256 = sqrt_min;
}
Other commonly used modules:
math::sqrt_price_math for get_next_sqrt_price_from_input / get_next_sqrt_price_from_output.math::swap_math for compute_swap_step.math::liquidity_math for liquidity deltas (add_delta).V3PoolWithout the onchain feature (pure in‑memory simulation):
use alloy_primitives::{I256, U256, address};
use uniswap_v3_math::V3Pool;
use uniswap_v3_math::pool::swap::{Slot0, SwapParams};
fn simulate_swap() {
let pool_address = address!("0x1000000000000000000000000000000000000000");
let token0 = address!("0x0000000000000000000000000000000000000001");
let token1 = address!("0x0000000000000000000000000000000000000002");
// math-only constructor: no provider, no RPC
let mut pool: V3Pool<()> = V3Pool::new(pool_address, token0, token1, 3000);
// manually seed state
pool.slot0 = Slot0 {
sqrt_price_x96: U256::from(1u128) << 96,
tick: 0,
};
pool.liquidity = 1_000_000u128;
pool.tick_spacing = 1;
let params = SwapParams {
zero_for_one: true,
amount_specified: I256::from(1_000i64),
sqrt_price_limit_x96: pool.slot0.sqrt_price_x96 - U256::from(1u8),
};
let result = pool.swap(params).unwrap();
println!("amount0: {}, amount1: {}, fees: {}", result.amount0_delta, result.amount1_delta, result.fees_paid);
}
This path does not require any network access or alloy-provider at runtime.
When you enable onchain, you can construct V3Pool<P> with a real provider and call async methods to fetch state:
use std::sync::Arc;
use alloy_primitives::address;
use alloy_provider::{Provider, ProviderBuilder};
use uniswap_v3_math::V3Pool;
#[tokio::main]
async fn main() -> eyre::Result<()> {
let provider = Arc::new(ProviderBuilder::new().on_http("https://rpc.example")?);
let pool_address = address!("0x...");
let token0 = address!("0x...");
let token1 = address!("0x...");
let mut pool: V3Pool<_> = V3Pool::new(pool_address, token0, token1, 3000, provider);
// Fetch latest liquidity + slot0 + tick spacing in one shot
pool.refresh_latest().await?;
println!("liquidity: {}", pool.liquidity);
println!("slot0.tick: {}", pool.slot0.tick);
Ok(())
}
Compile with:
cargo build --features onchain