1#![deny(missing_docs)]
3#![deny(rustdoc::all)]
4#![allow(rustdoc::missing_doc_code_examples)]
5#![deny(clippy::integer_arithmetic)]
6
7use std::cmp::Ordering;
8
9pub const CASH_DECIMALS: u8 = 6;
11
12pub use stable_swap_math::price::SaberSwap;
13
14#[derive(Copy, Clone, Default, Debug, PartialEq, Eq)]
16pub struct CashSwap {
17 pub lp_mint_decimals: u8,
20 pub saber: SaberSwap,
22}
23
24impl CashSwap {
25 pub fn calculate_cash_for_pool_tokens(&self, pool_token_amount: u64) -> Option<u64> {
27 self.scale_lp_to_cash_decimals(
28 self.saber
29 .calculate_virtual_price_of_pool_tokens(pool_token_amount)?,
30 )
31 }
32
33 pub fn calculate_pool_tokens_for_cash(&self, cash_amount: u64) -> Option<u64> {
35 self.saber
36 .calculate_pool_tokens_from_virtual_amount(self.scale_cash_to_lp_decimals(cash_amount)?)
37 }
38
39 fn scale_lp_to_cash_decimals(&self, amount: u64) -> Option<u64> {
40 match CASH_DECIMALS.cmp(&self.lp_mint_decimals) {
41 Ordering::Equal => amount.into(),
42 Ordering::Less => amount.checked_mul(
43 10u64.checked_pow(self.lp_mint_decimals.checked_sub(CASH_DECIMALS)?.into())?,
44 ),
45 Ordering::Greater => amount.checked_div(
46 10u64.checked_pow(CASH_DECIMALS.checked_sub(self.lp_mint_decimals)?.into())?,
47 ),
48 }
49 }
50
51 fn scale_cash_to_lp_decimals(&self, amount: u64) -> Option<u64> {
52 match CASH_DECIMALS.cmp(&self.lp_mint_decimals) {
53 Ordering::Equal => amount.into(),
54 Ordering::Less => amount.checked_div(
55 10u64.checked_pow(self.lp_mint_decimals.checked_sub(CASH_DECIMALS)?.into())?,
56 ),
57 Ordering::Greater => amount.checked_mul(
58 10u64.checked_pow(CASH_DECIMALS.checked_sub(self.lp_mint_decimals)?.into())?,
59 ),
60 }
61 }
62}