use solana_sdk::pubkey::Pubkey;
fn sol_to_lamports(sol: f64) -> u64 {
(sol * 1_000_000_000.0) as u64
}
use crate::{
instruction::utils::pumpfun::global_constants::{CREATOR_FEE, FEE_BASIS_POINTS},
utils::calc::common::compute_fee,
};
#[inline]
fn sol_str_to_lamports(sol: &str) -> Option<u64> {
sol.parse::<f64>().ok().map(|s| sol_to_lamports(s))
}
#[inline]
pub fn get_buy_token_amount_from_sol_amount(
virtual_token_reserves: u128,
virtual_sol_reserves: u128,
real_token_reserves: u128,
creator: Pubkey,
amount: u64,
) -> u64 {
if amount == 0 {
return 0;
}
if virtual_token_reserves == 0 {
return 0;
}
let total_fee_basis_points =
FEE_BASIS_POINTS + if creator != Pubkey::default() { CREATOR_FEE } else { 0 };
let amount_128 = amount as u128;
let total_fee_basis_points_128 = total_fee_basis_points as u128;
let input_amount = amount_128
.checked_mul(10_000)
.unwrap()
.checked_div(total_fee_basis_points_128 + 10_000)
.unwrap();
let denominator = virtual_sol_reserves + input_amount;
let mut tokens_received =
input_amount.checked_mul(virtual_token_reserves).unwrap().checked_div(denominator).unwrap();
tokens_received = tokens_received.min(real_token_reserves);
if tokens_received <= 100 * 1_000_000_u128 {
tokens_received = if amount > sol_str_to_lamports("0.01").unwrap_or(0) {
25547619 * 1_000_000_u128
} else {
255476 * 1_000_000_u128
};
}
tokens_received as u64
}
#[inline]
pub fn get_sell_sol_amount_from_token_amount(
virtual_token_reserves: u128,
virtual_sol_reserves: u128,
creator: Pubkey,
amount: u64,
) -> u64 {
if amount == 0 {
return 0;
}
if virtual_token_reserves == 0 {
return 0;
}
let amount_128 = amount as u128;
let numerator = amount_128.checked_mul(virtual_sol_reserves).unwrap_or(0);
let denominator = virtual_token_reserves.checked_add(amount_128).unwrap_or(1);
let sol_cost = numerator.checked_div(denominator).unwrap_or(0);
let total_fee_basis_points =
FEE_BASIS_POINTS + if creator != Pubkey::default() { CREATOR_FEE } else { 0 };
let total_fee_basis_points_128 = total_fee_basis_points as u128;
let fee = compute_fee(sol_cost, total_fee_basis_points_128);
sol_cost.saturating_sub(fee) as u64
}