feat: major refactor with calculation utilities and instruction optimization

- Add comprehensive calculation utilities for all protocols (bonk, pumpfun, pumpswap, raydium)
- Refactor instruction modules to reduce code complexity and improve maintainability
- Optimize trading parameters structure and enhance common utilities
- Separate calculation logic from trading modules for better code organization
- Update dependencies and module exports
This commit is contained in:
ysq
2025-08-18 18:00:14 +08:00
parent 350e34e0a0
commit 57474bfa6e
21 changed files with 1513 additions and 1107 deletions
+1 -89
View File
@@ -2,7 +2,7 @@ use crate::{
common::SolanaRpcClient,
constants::{
self,
raydium_cpmm::accounts::{self, WSOL_TOKEN_ACCOUNT},
raydium_cpmm::accounts::{self},
},
};
use anyhow::anyhow;
@@ -52,94 +52,6 @@ pub fn get_observation_state_pda(pool_state: &Pubkey) -> Option<Pubkey> {
pda.map(|pubkey| pubkey.0)
}
pub async fn get_buy_token_amount(
rpc: &SolanaRpcClient,
pool_state: &Pubkey,
sol_amount: u64,
) -> Result<u64, anyhow::Error> {
let pool = fetch_pool_state(rpc, pool_state).await?;
let is_token0_input = if pool.token0_mint == WSOL_TOKEN_ACCOUNT { true } else { false };
let (token0_balance, token1_balance) =
get_pool_token_balances(rpc, pool_state, &pool.token0_mint, &pool.token1_mint).await?;
// 使用恒定乘积公式计算
let (reserve_in, reserve_out) = if is_token0_input {
(token0_balance, token1_balance)
} else {
(token1_balance, token0_balance)
};
if reserve_in == 0 || reserve_out == 0 {
return Err(anyhow!("池子储备金为零,无法进行交换"));
}
// 使用 u128 防止溢出
let amount_in_128 = sol_amount as u128;
let reserve_in_128 = reserve_in as u128;
let reserve_out_128 = reserve_out as u128;
// 恒定乘积公式: amount_out = (amount_in * reserve_out) / (reserve_in + amount_in)
let numerator = amount_in_128 * reserve_out_128;
let denominator = reserve_in_128 + amount_in_128;
if denominator == 0 {
return Err(anyhow!("分母为零,计算错误"));
}
let amount_out = numerator / denominator;
// 检查是否超出储备金
if amount_out >= reserve_out_128 {
return Err(anyhow!("输出数量超过池子储备金"));
}
Ok(amount_out as u64)
}
pub async fn get_sell_sol_amount(
rpc: &SolanaRpcClient,
pool_state: &Pubkey,
token_amount: u64,
) -> Result<u64, anyhow::Error> {
let pool = fetch_pool_state(rpc, pool_state).await?;
let is_token0_sol = if pool.token0_mint == WSOL_TOKEN_ACCOUNT { true } else { false };
let (token0_balance, token1_balance) =
get_pool_token_balances(rpc, pool_state, &pool.token0_mint, &pool.token1_mint).await?;
let (reserve_in, reserve_out) = if is_token0_sol {
(token1_balance, token0_balance)
} else {
(token0_balance, token1_balance)
};
if reserve_in == 0 || reserve_out == 0 {
return Err(anyhow!("池子储备金为零,无法进行交换"));
}
// 使用 u128 防止溢出
let amount_in_128 = token_amount as u128;
let reserve_in_128 = reserve_in as u128;
let reserve_out_128 = reserve_out as u128;
// 恒定乘积公式: amount_out = (amount_in * reserve_out) / (reserve_in + amount_in)
let numerator = amount_in_128 * reserve_out_128;
let denominator = reserve_in_128 + amount_in_128;
if denominator == 0 {
return Err(anyhow!("分母为零,计算错误"));
}
let amount_out = numerator / denominator;
// 检查是否超出储备金
if amount_out >= reserve_out_128 {
return Err(anyhow!("输出数量超过池子储备金"));
}
Ok(amount_out as u64)
}
/// 获取池子中两个代币的余额
///
/// # 返回值