clmm-common 0.1.39

Blockchain, Clmm for Solana
Documentation
use std::fmt;
use std::ops::{Add, Div, Mul};

use rust_decimal::prelude::*;

pub struct SqrtPrice {
    pub fixed_point: u128,
}

impl SqrtPrice {
    pub fn new(sqrt_price: u128) -> SqrtPrice {
        SqrtPrice {
            fixed_point: sqrt_price,
        }
    }

    pub fn from(price: Decimal, base_decimal: u8, quote_decimal: u8) -> SqrtPrice {
        let exp = quote_decimal as i32 - base_decimal as i32;
        let multi = Decimal::from_f64(10f64.powi(exp)).unwrap();
        let sqrt_price = multi.mul(price).sqrt().unwrap();
        SqrtPrice {
            fixed_point: sqrt_price
                .mul(Decimal::from_u64(u64::MAX).unwrap())
                .to_u128()
                .unwrap(),
        }
    }

    pub fn to_decimal(&self) -> Decimal {
        let integer = Decimal::from_i128_with_scale((self.fixed_point >> 64) as i128, 0);
        Decimal::from_i128_with_scale((self.fixed_point & (u64::MAX as u128)) as i128, 0)
            .div(Decimal::from_i128_with_scale(u64::MAX as i128, 0))
            .add(integer)
    }

    pub fn to_ui_price(&self) -> Decimal {
        let d = self.to_decimal();
        d.mul(d)
    }
}

impl fmt::Display for SqrtPrice {
    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
        let s = self.to_decimal().round_dp(12).to_string();
        write!(f, "{}", s)
    }
}

#[cfg(test)]
mod sqrt_price {
    use crate::utils::sqrt_price::*;
    use rust_decimal::Decimal;

    #[test]
    fn test_from() {
        assert_eq!(
            SqrtPrice::from(Decimal::from_f64(1f64).unwrap(), 6, 6).fixed_point,
            u64::MAX as u128
        );
        let sp1 = SqrtPrice::from(Decimal::from_f64(1f64).unwrap(), 6, 9);
        println!("{} {}", sp1, sp1.fixed_point);
    }
}