Skip to main content

pump_rust_client/math/
mod.rs

1//! Quote math primitives. Mirrors `@pump-fun/pump-sdk-internal` (bonding
2//! curve) and `@pump-fun/pump-swap-sdk` (AMM) so Rust callers can compute
3//! quotes locally without round-tripping through JS or the chain.
4//!
5//! All arithmetic uses `u128` intermediates; reserves and amounts are `u64`
6//! at the API boundary but their products do not fit in `u64`.
7
8pub mod amm;
9pub mod bonding_curve;
10pub mod fees;
11pub mod utils;
12
13pub use bonding_curve::TOKEN_SUPPLY;
14
15/// Reasons a quote computation can fail. Returned in place of a panic for
16/// any case where the inputs are inconsistent with a well-formed pool or
17/// trade — empty reserves, oversized requests, or fee configurations whose
18/// total bps would consume the entire trade.
19#[derive(Debug, Clone, Copy, PartialEq, Eq)]
20pub enum QuoteError {
21    /// `base_reserve` or `quote_reserve` is zero, so the pool cannot price
22    /// any trade.
23    EmptyReserves,
24    /// Caller asked for `base_out` >= `base_reserve` on a buy. Equivalent
25    /// to draining the pool; the constant-product denominator would be
26    /// `<= 0`.
27    BaseOutExceedsReserve,
28    /// Sum of LP, protocol, and coin-creator fees exceeds the raw quote
29    /// output — only reachable with a degenerate fee table whose total bps
30    /// > 10_000.
31    FeesExceedOutput,
32    /// Bonding curve degeneracy where `real_token_reserves ==
33    /// virtual_token_reserves`, which would zero the constant-product
34    /// denominator on a token-out buy.
35    DepletedBondingCurve,
36    /// A `u128` intermediate overflowed, or a subtraction would underflow
37    /// (e.g. `sol_out >= virtual_sol_reserves` on the `sell_token_quote_with_sol`
38    /// inverse). Surfaced from the fee-less primitive quote helpers so callers
39    /// don't need to wrap primitive arithmetic.
40    MathOverflow,
41    /// Observed market cap fell outside the caller's `target ± slippage_bps`
42    /// envelope. Returned by `validate_market_cap` on both quote paths.
43    SlippageExceeded,
44}
45
46impl std::fmt::Display for QuoteError {
47    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
48        match self {
49            Self::EmptyReserves => write!(f, "pool reserves are zero"),
50            Self::BaseOutExceedsReserve => {
51                write!(f, "base_out exceeds the pool's base reserve")
52            }
53            Self::FeesExceedOutput => write!(f, "fees exceed the pool's quote output"),
54            Self::DepletedBondingCurve => {
55                write!(f, "bonding curve is depleted (real == virtual reserves)")
56            }
57            Self::MathOverflow => write!(f, "checked arithmetic overflowed"),
58            Self::SlippageExceeded => {
59                write!(f, "market cap fell outside the slippage envelope")
60            }
61        }
62    }
63}
64
65impl std::error::Error for QuoteError {}
66
67pub type QuoteResult<T> = std::result::Result<T, QuoteError>;