Parcel #glxm5dth1gvowby
Created by Anonymous
Public
Created April 28, 2025 Expires in 19 days
Loading editor...
use anchor_gen::generate_cpi_crate; generate_cpi_crate!("./idl.json"); declare_id!("6EF8rrecthR5Dkzon8Nwu78hRvfCKubJ14M5uBEwF6P"); const BUY_SIGNATURE: [u8; 8] = [102, 6, 61, 18, 1, 218, 235, 234]; const SELL_SIGNATURE: [u8; 8] = [51, 230, 133, 164, 1, 127, 131, 173]; impl BondingCurve { pub fn fee(&self, config: &Global, amount: u128) -> u128 { amount * (config.fee_basis_points as u128) / 10000 } pub fn buy_quote(&self, config: &Global, amount: u64, is_exact_in: bool) -> u64 { let mut amount = amount as u128; let virtual_sol_reserves = self.virtual_sol_reserves as u128; let virtual_token_reserves = self.virtual_token_reserves as u128; let real_token_reserves = self.real_token_reserves as u128; let (max_amount_in, amount_out) = if is_exact_in { let k = virtual_sol_reserves * virtual_token_reserves; let new_sol_reserves = virtual_sol_reserves + amount; let new_token_reserves = k.checked_div(new_sol_reserves).unwrap_or(0) + 1; let mut amount_out = virtual_token_reserves.saturating_sub(new_token_reserves); amount_out = std::cmp::min(amount_out, real_token_reserves); (amount, amount_out) } else { amount = std::cmp::min(amount, real_token_reserves); let max_amount_in = (amount * virtual_sol_reserves) .checked_div(virtual_token_reserves - amount) .unwrap_or(0) + 1; (max_amount_in, amount) }; if is_exact_in { amount_out as u64 } else { let fee = self.fee(config, max_amount_in); (max_amount_in + fee) as u64 } } pub fn sell_quote(&self, amount_in: u64) -> u64 { let amount_in = amount_in as u128; let virtual_sol_reserves = self.virtual_sol_reserves as u128; let virtual_token_reserves = self.virtual_token_reserves as u128; let numerator = amount_in.checked_mul(virtual_sol_reserves).unwrap_or(0); let denominator = virtual_token_reserves.checked_add(amount_in).unwrap_or(0); let amount_out = numerator.checked_div(denominator).unwrap_or(0); amount_out as u64 } pub fn get_amount_out(&self, config: &Global, amount_in: u64, is_buy: bool) -> u64 { match is_buy { true => { let denominator = 10000 + config.fee_basis_points as u128; let amount_in_less_fee = amount_in as u128 * 10000 / denominator; self.buy_quote(config, amount_in_less_fee as u64, true) } false => { let amount_out = self.sell_quote(amount_in); if amount_out > self.real_sol_reserves { return 0; } let fee = self.fee(config, amount_out as u128) as u64; amount_out.saturating_sub(fee) } } } pub fn encode_swap(&self, config: &Global, is_buy: bool, amount_in: u64) -> Vec<u8> { let mut data = Vec::default(); if is_buy { data.extend(BUY_SIGNATURE); let amount_out = self.get_amount_out(config, amount_in, is_buy); instruction::Buy { _amount: amount_out, _max_sol_cost: amount_in } .serialize(&mut data) .unwrap(); } else { data.extend(SELL_SIGNATURE); instruction::Sell { _amount: amount_in, _min_sol_output: 0 } .serialize(&mut data) .unwrap(); } data } }