perf: optimize constants and memory allocation for trading instruction performance

This commit is contained in:
ysq
2025-09-08 10:58:43 +08:00
parent 0968a93d4f
commit 31b5e2855b
13 changed files with 314 additions and 261 deletions
+12 -2
View File
@@ -65,9 +65,14 @@ impl BondingCurveAccount {
dev_sol_amount: u64,
creator: Pubkey,
) -> Self {
let account = if mint != &Pubkey::default() {
get_bonding_curve_pda(mint).unwrap()
} else {
Pubkey::default()
};
Self {
discriminator: 0,
account: get_bonding_curve_pda(mint).unwrap(),
account: account,
virtual_token_reserves: INITIAL_VIRTUAL_TOKEN_RESERVES - dev_token_amount,
virtual_sol_reserves: INITIAL_VIRTUAL_SOL_RESERVES + dev_sol_amount,
real_token_reserves: INITIAL_REAL_TOKEN_RESERVES - dev_token_amount,
@@ -79,9 +84,14 @@ impl BondingCurveAccount {
}
pub fn from_trade(event: &PumpFunTradeEvent) -> Self {
let account = if event.bonding_curve != Pubkey::default() {
event.bonding_curve
} else {
get_bonding_curve_pda(&event.mint).unwrap()
};
Self {
discriminator: 0,
account: get_bonding_curve_pda(&event.mint).unwrap(),
account: account,
virtual_token_reserves: event.virtual_token_reserves,
virtual_sol_reserves: event.virtual_sol_reserves,
real_token_reserves: event.real_token_reserves,
+37
View File
@@ -0,0 +1,37 @@
use solana_sdk::{pubkey, pubkey::Pubkey};
pub const SYSTEM_PROGRAM: Pubkey = solana_sdk::system_program::ID;
pub const SYSTEM_PROGRAM_META: solana_sdk::instruction::AccountMeta =
solana_sdk::instruction::AccountMeta {
pubkey: SYSTEM_PROGRAM,
is_signer: false,
is_writable: false,
};
pub const TOKEN_PROGRAM: Pubkey = spl_token::ID;
pub const TOKEN_PROGRAM_META: solana_sdk::instruction::AccountMeta =
solana_sdk::instruction::AccountMeta {
pubkey: TOKEN_PROGRAM,
is_signer: false,
is_writable: false,
};
pub const TOKEN_PROGRAM_2022: Pubkey = spl_token_2022::ID;
pub const TOKEN_PROGRAM_2022_META: solana_sdk::instruction::AccountMeta =
solana_sdk::instruction::AccountMeta {
pubkey: TOKEN_PROGRAM_2022,
is_signer: false,
is_writable: false,
};
pub const WSOL_TOKEN_ACCOUNT: Pubkey = pubkey!("So11111111111111111111111111111111111111112");
pub const WSOL_TOKEN_ACCOUNT_META: solana_sdk::instruction::AccountMeta =
solana_sdk::instruction::AccountMeta {
pubkey: WSOL_TOKEN_ACCOUNT,
is_signer: false,
is_writable: false,
};
pub const RENT: Pubkey = solana_sdk::sysvar::rent::id();
pub const RENT_META: solana_sdk::instruction::AccountMeta =
solana_sdk::instruction::AccountMeta { pubkey: RENT, is_signer: false, is_writable: false };
+2 -21
View File
@@ -1,26 +1,7 @@
use solana_sdk::{pubkey, pubkey::Pubkey};
pub mod accounts;
pub mod decimals;
pub mod swqos;
pub mod trade;
pub mod trade_platform;
pub const SYSTEM_PROGRAM: Pubkey = solana_sdk::system_program::ID;
pub const SYSTEM_PROGRAM_META: once_cell::sync::Lazy<solana_sdk::instruction::AccountMeta> =
once_cell::sync::Lazy::new(|| {
solana_sdk::instruction::AccountMeta::new_readonly(SYSTEM_PROGRAM, false)
});
pub const TOKEN_PROGRAM: Pubkey = spl_token::ID;
pub const TOKEN_PROGRAM_META: once_cell::sync::Lazy<solana_sdk::instruction::AccountMeta> =
once_cell::sync::Lazy::new(|| {
solana_sdk::instruction::AccountMeta::new_readonly(TOKEN_PROGRAM, false)
});
pub const TOKEN_PROGRAM_2022: Pubkey = spl_token_2022::ID;
pub const WSOL_TOKEN_ACCOUNT: Pubkey = pubkey!("So11111111111111111111111111111111111111112");
pub const WSOL_TOKEN_ACCOUNT_META: once_cell::sync::Lazy<solana_sdk::instruction::AccountMeta> =
once_cell::sync::Lazy::new(|| {
solana_sdk::instruction::AccountMeta::new_readonly(WSOL_TOKEN_ACCOUNT, false)
});
pub use accounts::*;
+14 -14
View File
@@ -109,8 +109,8 @@ impl InstructionBuilder for BonkInstructionBuilder {
// Create buy instruction
let accounts = vec![
solana_sdk::instruction::AccountMeta::new(params.payer.pubkey(), true), // Payer (signer)
accounts::AUTHORITY_META.clone(), // Authority (readonly)
accounts::GLOBAL_CONFIG_META.clone(), // Global Config (readonly)
accounts::AUTHORITY_META, // Authority (readonly)
accounts::GLOBAL_CONFIG_META, // Global Config (readonly)
solana_sdk::instruction::AccountMeta::new_readonly(
protocol_params.platform_config,
false,
@@ -121,15 +121,15 @@ impl InstructionBuilder for BonkInstructionBuilder {
solana_sdk::instruction::AccountMeta::new(base_vault_account, false), // Base Vault
solana_sdk::instruction::AccountMeta::new(quote_vault_account, false), // Quote Vault
solana_sdk::instruction::AccountMeta::new_readonly(params.mint, false), // Base Token Mint (readonly)
crate::constants::WSOL_TOKEN_ACCOUNT_META.clone(), // Quote Token Mint (readonly)
crate::constants::WSOL_TOKEN_ACCOUNT_META, // Quote Token Mint (readonly)
solana_sdk::instruction::AccountMeta::new_readonly(
protocol_params.mint_token_program,
false,
), // Base Token Program (readonly)
crate::constants::TOKEN_PROGRAM_META.clone(), // Quote Token Program (readonly)
accounts::EVENT_AUTHORITY_META.clone(), // Event Authority (readonly)
accounts::BONK_META.clone(), // Program (readonly)
crate::constants::SYSTEM_PROGRAM_META.clone(), // System Program (readonly)
crate::constants::TOKEN_PROGRAM_META, // Quote Token Program (readonly)
accounts::EVENT_AUTHORITY_META, // Event Authority (readonly)
accounts::BONK_META, // Program (readonly)
crate::constants::SYSTEM_PROGRAM_META, // System Program (readonly)
solana_sdk::instruction::AccountMeta::new(
protocol_params.platform_associated_account,
false,
@@ -243,8 +243,8 @@ impl InstructionBuilder for BonkInstructionBuilder {
// Create sell instruction
let accounts = vec![
solana_sdk::instruction::AccountMeta::new(params.payer.pubkey(), true), // Payer (signer)
accounts::AUTHORITY_META.clone(), // Authority (readonly)
accounts::GLOBAL_CONFIG_META.clone(), // Global Config (readonly)
accounts::AUTHORITY_META, // Authority (readonly)
accounts::GLOBAL_CONFIG_META, // Global Config (readonly)
solana_sdk::instruction::AccountMeta::new_readonly(
protocol_params.platform_config,
false,
@@ -255,15 +255,15 @@ impl InstructionBuilder for BonkInstructionBuilder {
solana_sdk::instruction::AccountMeta::new(base_vault_account, false), // Base Vault
solana_sdk::instruction::AccountMeta::new(quote_vault_account, false), // Quote Vault
solana_sdk::instruction::AccountMeta::new_readonly(params.mint, false), // Base Token Mint (readonly)
crate::constants::WSOL_TOKEN_ACCOUNT_META.clone(), // Quote Token Mint (readonly)
crate::constants::WSOL_TOKEN_ACCOUNT_META, // Quote Token Mint (readonly)
solana_sdk::instruction::AccountMeta::new_readonly(
protocol_params.mint_token_program,
false,
), // Base Token Program (readonly)
crate::constants::TOKEN_PROGRAM_META.clone(), // Quote Token Program (readonly)
accounts::EVENT_AUTHORITY_META.clone(), // Event Authority (readonly)
accounts::BONK_META.clone(), // Program (readonly)
crate::constants::SYSTEM_PROGRAM_META.clone(), // System Program (readonly)
crate::constants::TOKEN_PROGRAM_META, // Quote Token Program (readonly)
accounts::EVENT_AUTHORITY_META, // Event Authority (readonly)
accounts::BONK_META, // Program (readonly)
crate::constants::SYSTEM_PROGRAM_META, // System Program (readonly)
solana_sdk::instruction::AccountMeta::new(
protocol_params.platform_associated_account,
false,
+64 -83
View File
@@ -7,7 +7,7 @@ use spl_token::instruction::close_account;
use crate::{
instruction::utils::pumpfun::{
accounts, get_bonding_curve_pda, get_creator_vault_pda, get_user_volume_accumulator_pda,
accounts, get_bonding_curve_pda, get_creator, get_user_volume_accumulator_pda,
global_constants::{self},
},
utils::calc::{
@@ -16,7 +16,7 @@ use crate::{
},
};
use solana_sdk::{instruction::AccountMeta, pubkey::Pubkey};
use solana_sdk::instruction::AccountMeta;
use crate::{
constants::trade::trade::DEFAULT_SLIPPAGE,
@@ -50,21 +50,7 @@ impl InstructionBuilder for PumpFunInstructionBuilder {
params.slippage_basis_points.unwrap_or(DEFAULT_SLIPPAGE),
);
let creator_vault_pda = protocol_params.creator_vault;
// Optimize creator lookup - avoid PDA calculation if not default
let creator = if creator_vault_pda == Pubkey::default() {
Pubkey::default()
} else {
// Fast check against cached default creator vault
static DEFAULT_CREATOR_VAULT: std::sync::LazyLock<Option<Pubkey>> =
std::sync::LazyLock::new(|| get_creator_vault_pda(&Pubkey::default()));
if Some(creator_vault_pda) == *DEFAULT_CREATOR_VAULT {
Pubkey::default()
} else {
creator_vault_pda
}
};
let creator = get_creator(&creator_vault_pda);
let buy_token_amount = get_buy_token_amount_from_sol_amount(
bonding_curve.virtual_token_reserves as u128,
@@ -85,42 +71,44 @@ impl InstructionBuilder for PumpFunInstructionBuilder {
));
// Create buy instruction data
let mut buy_data = Vec::with_capacity(8 + 8 + 8);
buy_data.extend_from_slice(&[102, 6, 61, 18, 1, 218, 235, 234]); // discriminator
buy_data.extend_from_slice(&buy_token_amount.to_le_bytes());
buy_data.extend_from_slice(&max_sol_cost.to_le_bytes());
let mut buy_data = [0u8; 24];
buy_data[..8].copy_from_slice(&[102, 6, 61, 18, 1, 218, 235, 234]);
buy_data[8..16].copy_from_slice(&buy_token_amount.to_le_bytes());
buy_data[16..24].copy_from_slice(&max_sol_cost.to_le_bytes());
let accounts: [AccountMeta; 16] = [
global_constants::GLOBAL_ACCOUNT_META,
global_constants::FEE_RECIPIENT_META,
AccountMeta::new_readonly(params.mint, false),
AccountMeta::new(bonding_curve.account, false),
AccountMeta::new(
get_associated_token_address(&bonding_curve.account, &params.mint),
false,
),
AccountMeta::new(
get_associated_token_address(&params.payer.pubkey(), &params.mint),
false,
),
AccountMeta::new(params.payer.pubkey(), true),
crate::constants::SYSTEM_PROGRAM_META,
crate::constants::TOKEN_PROGRAM_META,
AccountMeta::new(creator_vault_pda, false),
accounts::EVENT_AUTHORITY_META,
accounts::PUMPFUN_META,
accounts::GLOBAL_VOLUME_ACCUMULATOR_META,
AccountMeta::new(
get_user_volume_accumulator_pda(&params.payer.pubkey()).unwrap(),
false,
),
accounts::FEE_CONFIG_META,
accounts::FEE_PROGRAM_META,
];
// Create buy instruction
instructions.push(Instruction::new_with_bytes(
accounts::PUMPFUN,
&buy_data,
vec![
global_constants::GLOBAL_ACCOUNT_META.clone(),
global_constants::FEE_RECIPIENT_META.clone(),
AccountMeta::new_readonly(params.mint, false),
AccountMeta::new(bonding_curve.account, false),
AccountMeta::new(
get_associated_token_address(&bonding_curve.account, &params.mint),
false,
),
AccountMeta::new(
get_associated_token_address(&params.payer.pubkey(), &params.mint),
false,
),
AccountMeta::new(params.payer.pubkey(), true),
crate::constants::SYSTEM_PROGRAM_META.clone(),
crate::constants::TOKEN_PROGRAM_META.clone(),
AccountMeta::new(creator_vault_pda, false),
accounts::EVENT_AUTHORITY_META.clone(),
accounts::PUMPFUN_META.clone(),
accounts::GLOBAL_VOLUME_ACCUMULATOR_META.clone(),
AccountMeta::new(
get_user_volume_accumulator_pda(&params.payer.pubkey()).unwrap(),
false,
),
accounts::FEE_CONFIG_META.clone(),
accounts::FEE_PROGRAM_META.clone(),
],
accounts.to_vec(),
));
Ok(instructions)
@@ -144,15 +132,9 @@ impl InstructionBuilder for PumpFunInstructionBuilder {
} else {
return Err(anyhow!("Amount token is required"));
};
let creator_vault_pda = protocol_params.creator_vault;
let ata = get_associated_token_address(&params.payer.pubkey(), &params.mint);
let mut creator = Pubkey::default();
if let Some(default_creator_ata) = get_creator_vault_pda(&creator) {
if default_creator_ata != creator_vault_pda {
creator = creator_vault_pda;
}
}
let creator_vault_pda = protocol_params.creator_vault;
let creator = get_creator(&creator_vault_pda);
let sol_amount = get_sell_sol_amount_from_token_amount(
bonding_curve.virtual_token_reserves as u128,
@@ -166,37 +148,36 @@ impl InstructionBuilder for PumpFunInstructionBuilder {
);
// Create sell instruction data
let mut sell_data = Vec::with_capacity(8 + 8 + 8);
sell_data.extend_from_slice(&[51, 230, 133, 164, 1, 127, 131, 173]); // discriminator
sell_data.extend_from_slice(&token_amount.to_le_bytes());
sell_data.extend_from_slice(&min_sol_output.to_le_bytes());
let mut sell_data = [0u8; 24];
sell_data[..8].copy_from_slice(&[51, 230, 133, 164, 1, 127, 131, 173]);
sell_data[8..16].copy_from_slice(&token_amount.to_le_bytes());
sell_data[16..24].copy_from_slice(&min_sol_output.to_le_bytes());
let bonding_curve = get_bonding_curve_pda(&params.mint).unwrap();
let accounts: [AccountMeta; 14] = [
global_constants::GLOBAL_ACCOUNT_META,
global_constants::FEE_RECIPIENT_META,
AccountMeta::new_readonly(params.mint, false),
AccountMeta::new(bonding_curve, false),
AccountMeta::new(get_associated_token_address(&bonding_curve, &params.mint), false),
AccountMeta::new(
get_associated_token_address(&params.payer.pubkey(), &params.mint),
false,
),
AccountMeta::new(params.payer.pubkey(), true),
crate::constants::SYSTEM_PROGRAM_META,
AccountMeta::new(creator_vault_pda, false),
crate::constants::TOKEN_PROGRAM_META,
accounts::EVENT_AUTHORITY_META,
accounts::PUMPFUN_META,
accounts::FEE_CONFIG_META,
accounts::FEE_PROGRAM_META,
];
// Create sell instruction
let mut instructions = vec![Instruction::new_with_bytes(
accounts::PUMPFUN,
&sell_data,
vec![
global_constants::GLOBAL_ACCOUNT_META.clone(),
global_constants::FEE_RECIPIENT_META.clone(),
AccountMeta::new_readonly(params.mint, false),
AccountMeta::new(bonding_curve, false),
AccountMeta::new(get_associated_token_address(&bonding_curve, &params.mint), false),
AccountMeta::new(
get_associated_token_address(&params.payer.pubkey(), &params.mint),
false,
),
AccountMeta::new(params.payer.pubkey(), true),
crate::constants::SYSTEM_PROGRAM_META.clone(),
AccountMeta::new(creator_vault_pda, false),
crate::constants::TOKEN_PROGRAM_META.clone(),
accounts::EVENT_AUTHORITY_META.clone(),
accounts::PUMPFUN_META.clone(),
accounts::FEE_CONFIG_META.clone(),
accounts::FEE_PROGRAM_META.clone(),
],
)];
let mut instructions =
vec![Instruction::new_with_bytes(accounts::PUMPFUN, &sell_data, accounts.to_vec())];
// If selling all tokens, close the account
if protocol_params.close_token_account_when_sell.unwrap_or(false) {
+18 -18
View File
@@ -175,21 +175,21 @@ impl InstructionBuilder for PumpSwapInstructionBuilder {
let mut accounts = vec![
solana_sdk::instruction::AccountMeta::new_readonly(pool, false), // pool_id (readonly)
solana_sdk::instruction::AccountMeta::new(params.payer.pubkey(), true), // user (signer)
accounts::GLOBAL_ACCOUNT_META.clone(), // global (readonly)
accounts::GLOBAL_ACCOUNT_META, // global (readonly)
solana_sdk::instruction::AccountMeta::new_readonly(base_mint, false), // base_mint (readonly)
solana_sdk::instruction::AccountMeta::new_readonly(quote_mint, false), // quote_mint (readonly)
solana_sdk::instruction::AccountMeta::new(user_base_token_account, false), // user_base_token_account
solana_sdk::instruction::AccountMeta::new(user_quote_token_account, false), // user_quote_token_account
solana_sdk::instruction::AccountMeta::new(pool_base_token_account, false), // pool_base_token_account
solana_sdk::instruction::AccountMeta::new(pool_quote_token_account, false), // pool_quote_token_account
accounts::FEE_RECIPIENT_META.clone(), // fee_recipient (readonly)
accounts::FEE_RECIPIENT_META, // fee_recipient (readonly)
solana_sdk::instruction::AccountMeta::new(fee_recipient_ata, false), // fee_recipient_ata
solana_sdk::instruction::AccountMeta::new_readonly(base_token_program, false), // TOKEN_PROGRAM_ID (readonly)
solana_sdk::instruction::AccountMeta::new_readonly(quote_token_program, false), // TOKEN_PROGRAM_ID (readonly, duplicated as in JS)
crate::constants::SYSTEM_PROGRAM_META.clone(), // System Program (readonly)
accounts::ASSOCIATED_TOKEN_PROGRAM_META.clone(), // ASSOCIATED_TOKEN_PROGRAM_ID (readonly)
accounts::EVENT_AUTHORITY_META.clone(), // event_authority (readonly)
accounts::AMM_PROGRAM_META.clone(), // PUMP_AMM_PROGRAM_ID (readonly)
crate::constants::SYSTEM_PROGRAM_META, // System Program (readonly)
accounts::ASSOCIATED_TOKEN_PROGRAM_META, // ASSOCIATED_TOKEN_PROGRAM_ID (readonly)
accounts::EVENT_AUTHORITY_META, // event_authority (readonly)
accounts::AMM_PROGRAM_META, // PUMP_AMM_PROGRAM_ID (readonly)
solana_sdk::instruction::AccountMeta::new(params_coin_creator_vault_ata, false), // coin_creator_vault_ata
solana_sdk::instruction::AccountMeta::new_readonly(
params_coin_creator_vault_authority,
@@ -197,14 +197,14 @@ impl InstructionBuilder for PumpSwapInstructionBuilder {
), // coin_creator_vault_authority (readonly)
];
if quote_mint_is_wsol {
accounts.push(accounts::GLOBAL_VOLUME_ACCUMULATOR_META.clone());
accounts.push(accounts::GLOBAL_VOLUME_ACCUMULATOR_META);
accounts.push(solana_sdk::instruction::AccountMeta::new(
get_user_volume_accumulator_pda(&params.payer.pubkey()).unwrap(),
false,
));
}
accounts.push(accounts::FEE_CONFIG_META.clone());
accounts.push(accounts::FEE_PROGRAM_META.clone());
accounts.push(accounts::FEE_CONFIG_META);
accounts.push(accounts::FEE_PROGRAM_META);
// Create instruction data
let mut data = vec![];
@@ -366,21 +366,21 @@ impl InstructionBuilder for PumpSwapInstructionBuilder {
let mut accounts = vec![
solana_sdk::instruction::AccountMeta::new_readonly(pool, false), // pool_id (readonly)
solana_sdk::instruction::AccountMeta::new(params.payer.pubkey(), true), // user (signer)
accounts::GLOBAL_ACCOUNT_META.clone(), // global (readonly)
accounts::GLOBAL_ACCOUNT_META, // global (readonly)
solana_sdk::instruction::AccountMeta::new_readonly(base_mint, false), // mint (readonly)
solana_sdk::instruction::AccountMeta::new_readonly(quote_mint, false), // WSOL_TOKEN_ACCOUNT (readonly)
solana_sdk::instruction::AccountMeta::new(user_base_token_account, false), // user_base_token_account
solana_sdk::instruction::AccountMeta::new(user_quote_token_account, false), // user_quote_token_account
solana_sdk::instruction::AccountMeta::new(pool_base_token_account, false), // pool_base_token_account
solana_sdk::instruction::AccountMeta::new(pool_quote_token_account, false), // pool_quote_token_account
accounts::FEE_RECIPIENT_META.clone(), // fee_recipient (readonly)
accounts::FEE_RECIPIENT_META, // fee_recipient (readonly)
solana_sdk::instruction::AccountMeta::new(fee_recipient_ata, false), // fee_recipient_ata
solana_sdk::instruction::AccountMeta::new_readonly(base_token_program, false), // TOKEN_PROGRAM_ID (readonly)
solana_sdk::instruction::AccountMeta::new_readonly(quote_token_program, false), // TOKEN_PROGRAM_ID (readonly, duplicated as in JS)
crate::constants::SYSTEM_PROGRAM_META.clone(), // System Program (readonly)
accounts::ASSOCIATED_TOKEN_PROGRAM_META.clone(), // ASSOCIATED_TOKEN_PROGRAM_ID (readonly)
accounts::EVENT_AUTHORITY_META.clone(), // event_authority (readonly)
accounts::AMM_PROGRAM_META.clone(), // PUMP_AMM_PROGRAM_ID (readonly)
crate::constants::SYSTEM_PROGRAM_META, // System Program (readonly)
accounts::ASSOCIATED_TOKEN_PROGRAM_META, // ASSOCIATED_TOKEN_PROGRAM_ID (readonly)
accounts::EVENT_AUTHORITY_META, // event_authority (readonly)
accounts::AMM_PROGRAM_META, // PUMP_AMM_PROGRAM_ID (readonly)
solana_sdk::instruction::AccountMeta::new(params_coin_creator_vault_ata, false), // coin_creator_vault_ata
solana_sdk::instruction::AccountMeta::new_readonly(
params_coin_creator_vault_authority,
@@ -388,15 +388,15 @@ impl InstructionBuilder for PumpSwapInstructionBuilder {
), // coin_creator_vault_authority (readonly)
];
if !quote_mint_is_wsol {
accounts.push(accounts::GLOBAL_VOLUME_ACCUMULATOR_META.clone());
accounts.push(accounts::GLOBAL_VOLUME_ACCUMULATOR_META);
accounts.push(solana_sdk::instruction::AccountMeta::new(
get_user_volume_accumulator_pda(&params.payer.pubkey()).unwrap(),
false,
));
}
accounts.push(accounts::FEE_CONFIG_META.clone());
accounts.push(accounts::FEE_PROGRAM_META.clone());
accounts.push(accounts::FEE_CONFIG_META);
accounts.push(accounts::FEE_PROGRAM_META);
// Create instruction data
let mut data = vec![];
+4 -4
View File
@@ -93,9 +93,9 @@ impl InstructionBuilder for RaydiumAmmV4InstructionBuilder {
// Create buy instruction
let accounts = vec![
crate::constants::TOKEN_PROGRAM_META.clone(), // Token Program (readonly)
crate::constants::TOKEN_PROGRAM_META, // Token Program (readonly)
solana_sdk::instruction::AccountMeta::new(protocol_params.amm, false), // Amm
accounts::AUTHORITY_META.clone(), // Authority (readonly)
accounts::AUTHORITY_META, // Authority (readonly)
solana_sdk::instruction::AccountMeta::new(protocol_params.amm, false), // Amm Open Orders
solana_sdk::instruction::AccountMeta::new(protocol_params.token_coin, false), // Pool Coin Token Account
solana_sdk::instruction::AccountMeta::new(protocol_params.token_pc, false), // Pool Pc Token Account
@@ -187,9 +187,9 @@ impl InstructionBuilder for RaydiumAmmV4InstructionBuilder {
// Create buy instruction
let accounts = vec![
crate::constants::TOKEN_PROGRAM_META.clone(), // Token Program (readonly)
crate::constants::TOKEN_PROGRAM_META, // Token Program (readonly)
solana_sdk::instruction::AccountMeta::new(protocol_params.amm, false), // Amm
accounts::AUTHORITY_META.clone(), // Authority (readonly)
accounts::AUTHORITY_META, // Authority (readonly)
solana_sdk::instruction::AccountMeta::new(protocol_params.amm, false), // Amm Open Orders
solana_sdk::instruction::AccountMeta::new(protocol_params.token_coin, false), // Pool Coin Token Account
solana_sdk::instruction::AccountMeta::new(protocol_params.token_pc, false), // Pool Pc Token Account
+8 -8
View File
@@ -112,16 +112,16 @@ impl InstructionBuilder for RaydiumCpmmInstructionBuilder {
// Create buy instruction
let accounts = vec![
solana_sdk::instruction::AccountMeta::new(params.payer.pubkey(), true), // Payer (signer)
accounts::AUTHORITY_META.clone(), // Authority (readonly)
accounts::AMM_CONFIG_META.clone(), // Amm Config (readonly)
accounts::AUTHORITY_META, // Authority (readonly)
accounts::AMM_CONFIG_META, // Amm Config (readonly)
solana_sdk::instruction::AccountMeta::new(pool_state, false), // Pool State
solana_sdk::instruction::AccountMeta::new(wsol_token_account, false), // Input Token Account
solana_sdk::instruction::AccountMeta::new(mint_token_account, false), // Output Token Account
solana_sdk::instruction::AccountMeta::new(wsol_vault_account, false), // Input Vault Account
solana_sdk::instruction::AccountMeta::new(mint_vault_account, false), // Output Vault Account
crate::constants::TOKEN_PROGRAM_META.clone(), // Input Token Program (readonly)
crate::constants::TOKEN_PROGRAM_META, // Input Token Program (readonly)
solana_sdk::instruction::AccountMeta::new_readonly(mint_token_program, false), // Output Token Program (readonly)
crate::constants::WSOL_TOKEN_ACCOUNT_META.clone(), // Input token mint (readonly)
crate::constants::WSOL_TOKEN_ACCOUNT_META, // Input token mint (readonly)
solana_sdk::instruction::AccountMeta::new_readonly(params.mint, false), // Output token mint (readonly)
solana_sdk::instruction::AccountMeta::new(observation_state_account, false), // Observation State Account
];
@@ -218,17 +218,17 @@ impl InstructionBuilder for RaydiumCpmmInstructionBuilder {
// Create sell instruction
let accounts = vec![
solana_sdk::instruction::AccountMeta::new(params.payer.pubkey(), true), // Payer (signer)
accounts::AUTHORITY_META.clone(), // Authority (readonly)
accounts::AMM_CONFIG_META.clone(), // Amm Config (readonly)
accounts::AUTHORITY_META, // Authority (readonly)
accounts::AMM_CONFIG_META, // Amm Config (readonly)
solana_sdk::instruction::AccountMeta::new(pool_state, false), // Pool State
solana_sdk::instruction::AccountMeta::new(mint_token_account, false), // Input Token Account
solana_sdk::instruction::AccountMeta::new(wsol_token_account, false), // Output Token Account
solana_sdk::instruction::AccountMeta::new(mint_vault_account, false), // Input Vault Account
solana_sdk::instruction::AccountMeta::new(wsol_vault_account, false), // Output Vault Account
solana_sdk::instruction::AccountMeta::new_readonly(mint_token_program, false), // Input Token Program (readonly)
crate::constants::TOKEN_PROGRAM_META.clone(), // Output Token Program (readonly)
crate::constants::TOKEN_PROGRAM_META, // Output Token Program (readonly)
solana_sdk::instruction::AccountMeta::new_readonly(params.mint, false), // Input token mint (readonly)
crate::constants::WSOL_TOKEN_ACCOUNT_META.clone(), // Output token mint (readonly)
crate::constants::WSOL_TOKEN_ACCOUNT_META, // Output token mint (readonly)
solana_sdk::instruction::AccountMeta::new(observation_state_account, false), // Observation State Account
];
// Create instruction data
+20 -16
View File
@@ -25,22 +25,26 @@ pub mod accounts {
pub const SHARE_FEE_RATE: u128 = 0; // 0%
// META
pub const AUTHORITY_META: once_cell::sync::Lazy<solana_sdk::instruction::AccountMeta> =
once_cell::sync::Lazy::new(|| {
solana_sdk::instruction::AccountMeta::new_readonly(AUTHORITY, false)
});
pub const GLOBAL_CONFIG_META: once_cell::sync::Lazy<solana_sdk::instruction::AccountMeta> =
once_cell::sync::Lazy::new(|| {
solana_sdk::instruction::AccountMeta::new_readonly(GLOBAL_CONFIG, false)
});
pub const EVENT_AUTHORITY_META: once_cell::sync::Lazy<solana_sdk::instruction::AccountMeta> =
once_cell::sync::Lazy::new(|| {
solana_sdk::instruction::AccountMeta::new_readonly(EVENT_AUTHORITY, false)
});
pub const BONK_META: once_cell::sync::Lazy<solana_sdk::instruction::AccountMeta> =
once_cell::sync::Lazy::new(|| {
solana_sdk::instruction::AccountMeta::new_readonly(BONK, false)
});
pub const AUTHORITY_META: solana_sdk::instruction::AccountMeta =
solana_sdk::instruction::AccountMeta {
pubkey: AUTHORITY,
is_signer: false,
is_writable: false,
};
pub const GLOBAL_CONFIG_META: solana_sdk::instruction::AccountMeta =
solana_sdk::instruction::AccountMeta {
pubkey: GLOBAL_CONFIG,
is_signer: false,
is_writable: false,
};
pub const EVENT_AUTHORITY_META: solana_sdk::instruction::AccountMeta =
solana_sdk::instruction::AccountMeta {
pubkey: EVENT_AUTHORITY,
is_signer: false,
is_writable: false,
};
pub const BONK_META: solana_sdk::instruction::AccountMeta =
solana_sdk::instruction::AccountMeta { pubkey: BONK, is_signer: false, is_writable: false };
}
pub const BUY_EXECT_IN_DISCRIMINATOR: [u8; 8] = [250, 234, 13, 123, 213, 156, 19, 236];
+64 -43
View File
@@ -51,7 +51,7 @@ pub mod global_constants {
pub const POOL_MIGRATION_FEE: u64 = 15_000_001;
pub const CREATOR_FEE: u64 = 5;
pub const CREATOR_FEE: u64 = 30;
pub const SCALE: u64 = 1_000_000; // 10^6 for token decimals
@@ -61,19 +61,21 @@ pub mod global_constants {
/// Public key for the fee recipient
pub const FEE_RECIPIENT: Pubkey = pubkey!("62qc2CNXwrYqQScmEdiZFFAnJR262PxWEuNQtxfafNgV");
/// Static AccountMeta for fee recipient (initialized once)
pub static FEE_RECIPIENT_META: once_cell::sync::Lazy<solana_sdk::instruction::AccountMeta> =
once_cell::sync::Lazy::new(|| {
solana_sdk::instruction::AccountMeta::new(FEE_RECIPIENT, false)
});
pub const FEE_RECIPIENT_META: solana_sdk::instruction::AccountMeta =
solana_sdk::instruction::AccountMeta {
pubkey: FEE_RECIPIENT,
is_signer: false,
is_writable: true,
};
/// Public key for the global PDA
pub const GLOBAL_ACCOUNT: Pubkey = pubkey!("4wTV1YmiEkRvAtNtsSGPtUrqRYQMe5SKy2uB4Jjaxnjf");
/// Static AccountMeta for global account (initialized once)
pub static GLOBAL_ACCOUNT_META: once_cell::sync::Lazy<solana_sdk::instruction::AccountMeta> =
once_cell::sync::Lazy::new(|| {
solana_sdk::instruction::AccountMeta::new_readonly(GLOBAL_ACCOUNT, false)
});
pub const GLOBAL_ACCOUNT_META: solana_sdk::instruction::AccountMeta =
solana_sdk::instruction::AccountMeta {
pubkey: GLOBAL_ACCOUNT,
is_signer: false,
is_writable: false,
};
/// Public key for the authority
pub const AUTHORITY: Pubkey = pubkey!("FFWtrEQ4B4PKQoVuHYzZq8FabGkVatYzDpEVHsK5rrhF");
@@ -95,10 +97,6 @@ pub mod global_constants {
pub mod accounts {
use solana_sdk::{pubkey, pubkey::Pubkey};
use crate::instruction::utils::pumpfun::{
get_fee_config_pda, get_global_volume_accumulator_pda,
};
/// Public key for the Pump.fun program
pub const PUMPFUN: Pubkey = pubkey!("6EF8rrecthR5Dkzon8Nwu78hRvfCKubJ14M5uBEwF6P");
@@ -112,43 +110,50 @@ pub mod accounts {
pub const ASSOCIATED_TOKEN_PROGRAM: Pubkey =
pubkey!("ATokenGPvbdGVxr1b2hvZbsiqW5xWH25efTNsLJA8knL");
/// Rent Sysvar ID
pub const RENT: Pubkey = pubkey!("SysvarRent111111111111111111111111111111111");
pub const AMM_PROGRAM: Pubkey = pubkey!("675kPX9MHTjS2zt1qfr1NYHuzeLXfQM9H24wFSUt1Mp8");
pub const FEE_PROGRAM: Pubkey = pubkey!("pfeeUxB6jkeY1Hxd7CsFCAjcbHA9rWtchMGdZ6VojVZ");
pub const GLOBAL_VOLUME_ACCUMULATOR: Pubkey =
pubkey!("Hq2wp8uJ9jCPsYgNHex8RtqdvMPfVGoYwjvF1ATiwn2Y"); // get_global_volume_accumulator_pda().unwrap();
pub const FEE_CONFIG: Pubkey = pubkey!("8Wf5TiAheLUqBrKXeYg2JtAFFMWtKdG2BSFgqUcPVwTt"); // get_fee_config_pda().unwrap();
// META
pub const PUMPFUN_META: solana_sdk::instruction::AccountMeta =
solana_sdk::instruction::AccountMeta {
pubkey: PUMPFUN,
is_signer: false,
is_writable: false,
};
pub const PUMPFUN_META: once_cell::sync::Lazy<solana_sdk::instruction::AccountMeta> =
once_cell::sync::Lazy::new(|| {
solana_sdk::instruction::AccountMeta::new_readonly(PUMPFUN, false)
});
pub const EVENT_AUTHORITY_META: solana_sdk::instruction::AccountMeta =
solana_sdk::instruction::AccountMeta {
pubkey: EVENT_AUTHORITY,
is_signer: false,
is_writable: false,
};
pub const EVENT_AUTHORITY_META: once_cell::sync::Lazy<solana_sdk::instruction::AccountMeta> =
once_cell::sync::Lazy::new(|| {
solana_sdk::instruction::AccountMeta::new_readonly(EVENT_AUTHORITY, false)
});
pub const FEE_PROGRAM_META: solana_sdk::instruction::AccountMeta =
solana_sdk::instruction::AccountMeta {
pubkey: FEE_PROGRAM,
is_signer: false,
is_writable: false,
};
pub const FEE_PROGRAM_META: once_cell::sync::Lazy<solana_sdk::instruction::AccountMeta> =
once_cell::sync::Lazy::new(|| {
solana_sdk::instruction::AccountMeta::new_readonly(FEE_PROGRAM, false)
});
pub const GLOBAL_VOLUME_ACCUMULATOR_META: solana_sdk::instruction::AccountMeta =
solana_sdk::instruction::AccountMeta {
pubkey: GLOBAL_VOLUME_ACCUMULATOR,
is_signer: false,
is_writable: true,
};
pub const GLOBAL_VOLUME_ACCUMULATOR_META: once_cell::sync::Lazy<
solana_sdk::instruction::AccountMeta,
> = once_cell::sync::Lazy::new(|| {
solana_sdk::instruction::AccountMeta::new(
get_global_volume_accumulator_pda().unwrap(),
false,
)
});
pub const FEE_CONFIG_META: once_cell::sync::Lazy<solana_sdk::instruction::AccountMeta> =
once_cell::sync::Lazy::new(|| {
solana_sdk::instruction::AccountMeta::new_readonly(get_fee_config_pda().unwrap(), false)
});
pub const FEE_CONFIG_META: solana_sdk::instruction::AccountMeta =
solana_sdk::instruction::AccountMeta {
pubkey: FEE_CONFIG,
is_signer: false,
is_writable: false,
};
}
pub struct Symbol;
@@ -185,6 +190,22 @@ pub fn get_bonding_curve_pda(mint: &Pubkey) -> Option<Pubkey> {
pda.map(|pubkey| pubkey.0)
}
#[inline]
pub fn get_creator(creator_vault_pda: &Pubkey) -> Pubkey {
if creator_vault_pda.eq(&Pubkey::default()) {
Pubkey::default()
} else {
// Fast check against cached default creator vault
static DEFAULT_CREATOR_VAULT: std::sync::LazyLock<Option<Pubkey>> =
std::sync::LazyLock::new(|| get_creator_vault_pda(&Pubkey::default()));
if creator_vault_pda.eq(&DEFAULT_CREATOR_VAULT.unwrap()) {
Pubkey::default()
} else {
*creator_vault_pda
}
}
}
#[inline]
pub fn get_creator_vault_pda(creator: &Pubkey) -> Option<Pubkey> {
let seeds: &[&[u8]; 2] = &[seeds::CREATOR_VAULT_SEED, creator.as_ref()];
+53 -40
View File
@@ -51,9 +51,6 @@ pub mod accounts {
pub const PROTOCOL_FEE_RECIPIENT: Pubkey =
pubkey!("62qc2CNXwrYqQScmEdiZFFAnJR262PxWEuNQtxfafNgV");
/// Rent Sysvar ID
pub const RENT: Pubkey = pubkey!("SysvarRent111111111111111111111111111111111");
pub const AMM_PROGRAM: Pubkey = pubkey!("pAMMBay6oceH9fJKBRHGP5D4bD4sWpmSwMn52FMfXEA");
pub const LP_FEE_BASIS_POINTS: u64 = 20;
@@ -62,52 +59,68 @@ pub mod accounts {
pub const FEE_PROGRAM: Pubkey = pubkey!("pfeeUxB6jkeY1Hxd7CsFCAjcbHA9rWtchMGdZ6VojVZ");
pub const GLOBAL_VOLUME_ACCUMULATOR: Pubkey =
pubkey!("C2aFPdENg4A2HQsmrd5rTw5TaYBX5Ku887cWjbFKtZpw"); // get_global_volume_accumulator_pda().unwrap();
pub const FEE_CONFIG: Pubkey = pubkey!("5PHirr8joyTMp9JMm6nW7hNDVyEYdkzDqazxPD7RaTjx"); // get_fee_config_pda().unwrap();
// META
pub const GLOBAL_ACCOUNT_META: once_cell::sync::Lazy<solana_sdk::instruction::AccountMeta> =
once_cell::sync::Lazy::new(|| {
solana_sdk::instruction::AccountMeta::new_readonly(GLOBAL_ACCOUNT, false)
});
pub const GLOBAL_ACCOUNT_META: solana_sdk::instruction::AccountMeta =
solana_sdk::instruction::AccountMeta {
pubkey: GLOBAL_ACCOUNT,
is_signer: false,
is_writable: false,
};
pub const FEE_RECIPIENT_META: once_cell::sync::Lazy<solana_sdk::instruction::AccountMeta> =
once_cell::sync::Lazy::new(|| {
solana_sdk::instruction::AccountMeta::new_readonly(FEE_RECIPIENT, false)
});
pub const FEE_RECIPIENT_META: solana_sdk::instruction::AccountMeta =
solana_sdk::instruction::AccountMeta {
pubkey: FEE_RECIPIENT,
is_signer: false,
is_writable: false,
};
pub const ASSOCIATED_TOKEN_PROGRAM_META: once_cell::sync::Lazy<
solana_sdk::instruction::AccountMeta,
> = once_cell::sync::Lazy::new(|| {
solana_sdk::instruction::AccountMeta::new_readonly(ASSOCIATED_TOKEN_PROGRAM, false)
});
pub const ASSOCIATED_TOKEN_PROGRAM_META: solana_sdk::instruction::AccountMeta =
solana_sdk::instruction::AccountMeta {
pubkey: ASSOCIATED_TOKEN_PROGRAM,
is_signer: false,
is_writable: false,
};
pub const EVENT_AUTHORITY_META: once_cell::sync::Lazy<solana_sdk::instruction::AccountMeta> =
once_cell::sync::Lazy::new(|| {
solana_sdk::instruction::AccountMeta::new_readonly(EVENT_AUTHORITY, false)
});
pub const EVENT_AUTHORITY_META: solana_sdk::instruction::AccountMeta =
solana_sdk::instruction::AccountMeta {
pubkey: EVENT_AUTHORITY,
is_signer: false,
is_writable: false,
};
pub const AMM_PROGRAM_META: once_cell::sync::Lazy<solana_sdk::instruction::AccountMeta> =
once_cell::sync::Lazy::new(|| {
solana_sdk::instruction::AccountMeta::new_readonly(AMM_PROGRAM, false)
});
pub const AMM_PROGRAM_META: solana_sdk::instruction::AccountMeta =
solana_sdk::instruction::AccountMeta {
pubkey: AMM_PROGRAM,
is_signer: false,
is_writable: false,
};
pub const GLOBAL_VOLUME_ACCUMULATOR_META: once_cell::sync::Lazy<
solana_sdk::instruction::AccountMeta,
> = once_cell::sync::Lazy::new(|| {
solana_sdk::instruction::AccountMeta::new(
get_global_volume_accumulator_pda().unwrap(),
false,
)
});
pub const GLOBAL_VOLUME_ACCUMULATOR_META: solana_sdk::instruction::AccountMeta =
solana_sdk::instruction::AccountMeta {
pubkey: GLOBAL_VOLUME_ACCUMULATOR,
is_signer: false,
is_writable: true,
};
pub const FEE_CONFIG_META: once_cell::sync::Lazy<solana_sdk::instruction::AccountMeta> =
once_cell::sync::Lazy::new(|| {
solana_sdk::instruction::AccountMeta::new_readonly(get_fee_config_pda().unwrap(), false)
});
pub const FEE_CONFIG_META: solana_sdk::instruction::AccountMeta =
solana_sdk::instruction::AccountMeta {
pubkey: FEE_CONFIG,
is_signer: false,
is_writable: false,
};
pub const FEE_PROGRAM_META: once_cell::sync::Lazy<solana_sdk::instruction::AccountMeta> =
once_cell::sync::Lazy::new(|| {
solana_sdk::instruction::AccountMeta::new_readonly(FEE_PROGRAM, false)
});
pub const FEE_PROGRAM_META: solana_sdk::instruction::AccountMeta =
solana_sdk::instruction::AccountMeta {
pubkey: FEE_PROGRAM,
is_signer: false,
is_writable: false,
};
}
pub const BUY_DISCRIMINATOR: [u8; 8] = [102, 6, 61, 18, 1, 218, 235, 234];
+6 -4
View File
@@ -24,10 +24,12 @@ pub mod accounts {
// META
pub const AUTHORITY_META: once_cell::sync::Lazy<solana_sdk::instruction::AccountMeta> =
once_cell::sync::Lazy::new(|| {
solana_sdk::instruction::AccountMeta::new_readonly(AUTHORITY, false)
});
pub const AUTHORITY_META: solana_sdk::instruction::AccountMeta =
solana_sdk::instruction::AccountMeta {
pubkey: AUTHORITY,
is_signer: false,
is_writable: false,
};
}
pub const SWAP_BASE_IN_DISCRIMINATOR: &[u8] = &[9];
+12 -8
View File
@@ -24,15 +24,19 @@ pub mod accounts {
pub const PROTOCOL_FEE_RATE: u64 = 120000;
pub const FUND_FEE_RATE: u64 = 40000;
// META
pub const AUTHORITY_META: once_cell::sync::Lazy<solana_sdk::instruction::AccountMeta> =
once_cell::sync::Lazy::new(|| {
solana_sdk::instruction::AccountMeta::new_readonly(AUTHORITY, false)
});
pub const AUTHORITY_META: solana_sdk::instruction::AccountMeta =
solana_sdk::instruction::AccountMeta {
pubkey: AUTHORITY,
is_signer: false,
is_writable: false,
};
pub const AMM_CONFIG_META: once_cell::sync::Lazy<solana_sdk::instruction::AccountMeta> =
once_cell::sync::Lazy::new(|| {
solana_sdk::instruction::AccountMeta::new_readonly(AMM_CONFIG, false)
});
pub const AMM_CONFIG_META: solana_sdk::instruction::AccountMeta =
solana_sdk::instruction::AccountMeta {
pubkey: AMM_CONFIG,
is_signer: false,
is_writable: false,
};
}
pub const SWAP_BASE_IN_DISCRIMINATOR: &[u8] = &[143, 190, 90, 218, 196, 30, 51, 222];