use crate::core::events::*;
use solana_sdk::pubkey::Pubkey;
pub type AccountGetter<'a> = dyn Fn(usize) -> Pubkey + 'a;
pub fn fill_trade_accounts(e: &mut PumpFunTradeEvent, get: &AccountGetter<'_>) {
let is_v2 = matches!(e.ix_name.as_str(), "buy_v2" | "sell_v2" | "buy_exact_quote_in_v2");
let is_sell = matches!(e.ix_name.as_str(), "sell" | "sell_v2") || !e.is_buy;
let fill_pk = |to: &mut Pubkey, idx: usize| {
if *to == Pubkey::default() {
let from = get(idx);
if from != Pubkey::default() {
*to = from;
}
}
};
if is_v2 {
fill_pk(&mut e.global, 0);
fill_pk(&mut e.quote_mint, 2);
fill_pk(&mut e.fee_recipient, 6);
fill_pk(&mut e.bonding_curve, 10);
fill_pk(&mut e.associated_bonding_curve, 11);
fill_pk(&mut e.associated_quote_bonding_curve, 12);
fill_pk(&mut e.associated_user, 14);
fill_pk(&mut e.associated_quote_user, 15);
fill_pk(&mut e.user, 13);
fill_pk(&mut e.system_program, if is_sell { 23 } else { 24 });
fill_pk(&mut e.token_program, 3);
fill_pk(&mut e.quote_token_program, 4);
fill_pk(&mut e.associated_token_program, 5);
fill_pk(&mut e.creator_vault, 16);
fill_pk(&mut e.associated_quote_fee_recipient, 7);
fill_pk(&mut e.buyback_fee_recipient, 8);
fill_pk(&mut e.associated_quote_buyback_fee_recipient, 9);
fill_pk(&mut e.associated_creator_vault, 17);
fill_pk(&mut e.sharing_config, 18);
fill_pk(&mut e.event_authority, if is_sell { 24 } else { 25 });
fill_pk(&mut e.program, if is_sell { 25 } else { 26 });
if !is_sell {
fill_pk(&mut e.global_volume_accumulator, 19);
fill_pk(&mut e.user_volume_accumulator, 20);
fill_pk(&mut e.associated_user_volume_accumulator, 21);
fill_pk(&mut e.fee_config, 22);
fill_pk(&mut e.fee_program, 23);
} else {
fill_pk(&mut e.user_volume_accumulator, 19);
fill_pk(&mut e.associated_user_volume_accumulator, 20);
fill_pk(&mut e.fee_config, 21);
fill_pk(&mut e.fee_program, 22);
}
return;
}
fill_pk(&mut e.global, 0);
fill_pk(&mut e.fee_recipient, 1);
fill_pk(&mut e.bonding_curve, 3);
fill_pk(&mut e.associated_bonding_curve, 4);
fill_pk(&mut e.associated_user, 5);
fill_pk(&mut e.user, 6);
fill_pk(&mut e.system_program, 7);
fill_pk(&mut e.creator_vault, if e.is_buy { 9 } else { 8 });
fill_pk(&mut e.token_program, if e.is_buy { 8 } else { 9 });
fill_pk(&mut e.event_authority, 10);
fill_pk(&mut e.program, 11);
if e.is_buy {
fill_pk(&mut e.global_volume_accumulator, 12);
fill_pk(&mut e.user_volume_accumulator, 13);
fill_pk(&mut e.fee_config, 14);
fill_pk(&mut e.fee_program, 15);
fill_pk(&mut e.bonding_curve_v2, 16);
fill_pk(&mut e.buyback_fee_recipient, 17);
let a18 = get(17);
if e.account.is_none() && a18 != Pubkey::default() {
e.account = Some(a18);
}
} else {
fill_pk(&mut e.fee_config, 12);
fill_pk(&mut e.fee_program, 13);
let a14 = get(14);
let a15 = get(15);
let a16 = get(16);
if a16 != Pubkey::default() {
fill_pk(&mut e.user_volume_accumulator, 14);
fill_pk(&mut e.bonding_curve_v2, 15);
fill_pk(&mut e.buyback_fee_recipient, 16);
if e.account.is_none() {
e.account = Some(a16);
}
} else if e.is_cashback_coin {
if a14 != Pubkey::default() {
fill_pk(&mut e.user_volume_accumulator, 14);
}
if a15 != Pubkey::default() {
fill_pk(&mut e.bonding_curve_v2, 15);
}
} else {
if a14 != Pubkey::default() {
fill_pk(&mut e.bonding_curve_v2, 14);
}
if a15 != Pubkey::default() {
fill_pk(&mut e.buyback_fee_recipient, 15);
if e.account.is_none() {
e.account = Some(a15);
}
}
}
return;
}
}
pub fn fill_create_accounts(e: &mut PumpFunCreateTokenEvent, get: &AccountGetter<'_>) {
if e.mint == Pubkey::default() {
e.mint = get(0);
}
if e.bonding_curve == Pubkey::default() {
e.bonding_curve = get(2);
}
if e.user == Pubkey::default() {
e.user = get(7);
}
}
pub fn fill_create_v2_accounts(e: &mut PumpFunCreateV2TokenEvent, get: &AccountGetter<'_>) {
if e.mint == Pubkey::default() {
e.mint = get(0);
}
if e.bonding_curve == Pubkey::default() {
e.bonding_curve = get(2);
}
if e.user == Pubkey::default() {
e.user = get(5);
}
if e.mint_authority == Pubkey::default() {
e.mint_authority = get(1);
}
if e.associated_bonding_curve == Pubkey::default() {
e.associated_bonding_curve = get(3);
}
if e.global == Pubkey::default() {
e.global = get(4);
}
if e.system_program == Pubkey::default() {
e.system_program = get(6);
}
if e.token_program == Pubkey::default() {
e.token_program = get(7);
}
if e.associated_token_program == Pubkey::default() {
e.associated_token_program = get(8);
}
if e.mayhem_program_id == Pubkey::default() {
e.mayhem_program_id = get(9);
}
if e.global_params == Pubkey::default() {
e.global_params = get(10);
}
if e.sol_vault == Pubkey::default() {
e.sol_vault = get(11);
}
if e.mayhem_state == Pubkey::default() {
e.mayhem_state = get(12);
}
if e.mayhem_token_vault == Pubkey::default() {
e.mayhem_token_vault = get(13);
}
if e.event_authority == Pubkey::default() {
e.event_authority = get(14);
}
if e.program == Pubkey::default() {
e.program = get(15);
}
}
pub fn fill_migrate_accounts(_e: &mut PumpFunMigrateEvent, _get: &AccountGetter<'_>) {
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn fill_trade_accounts_sets_legacy_buy_upgrade_accounts() {
let bonding_curve_v2 = Pubkey::new_from_array([16u8; 32]);
let buyback_fee_recipient = Pubkey::new_from_array([17u8; 32]);
let get = |i: usize| -> Pubkey {
match i {
16 => bonding_curve_v2,
17 => buyback_fee_recipient,
_ => Pubkey::default(),
}
};
let mut e = PumpFunTradeEvent { is_buy: true, account: None, ..Default::default() };
fill_trade_accounts(&mut e, &get);
assert_eq!(e.bonding_curve_v2, bonding_curve_v2);
assert_eq!(e.buyback_fee_recipient, buyback_fee_recipient);
assert_eq!(e.account, Some(buyback_fee_recipient));
}
#[test]
fn fill_trade_accounts_sets_cashback_sell_upgrade_accounts() {
let user_volume = Pubkey::new_from_array([14u8; 32]);
let bonding_curve_v2 = Pubkey::new_from_array([15u8; 32]);
let buyback_fee_recipient = Pubkey::new_from_array([16u8; 32]);
let get = |i: usize| -> Pubkey {
match i {
14 => user_volume,
15 => bonding_curve_v2,
16 => buyback_fee_recipient,
_ => Pubkey::default(),
}
};
let mut e = PumpFunTradeEvent { is_buy: false, account: None, ..Default::default() };
fill_trade_accounts(&mut e, &get);
assert_eq!(e.user_volume_accumulator, user_volume);
assert_eq!(e.bonding_curve_v2, bonding_curve_v2);
assert_eq!(e.buyback_fee_recipient, buyback_fee_recipient);
assert_eq!(e.account, Some(buyback_fee_recipient));
}
#[test]
fn fill_trade_accounts_sets_fee_recipient_from_ix_account_1() {
let fee = Pubkey::new_from_array([42u8; 32]);
let get = |i: usize| -> Pubkey {
if i == 1 {
fee
} else {
Pubkey::default()
}
};
let mut e = PumpFunTradeEvent { fee_recipient: Pubkey::default(), ..Default::default() };
fill_trade_accounts(&mut e, &get);
assert_eq!(e.fee_recipient, fee);
}
}