use crate::core::events::*;
use crate::instr::inner_common::*;
pub mod discriminators {
#[allow(dead_code)]
const MAGIC_PREFIX: [u8; 8] = [228, 69, 165, 46, 81, 203, 154, 29];
pub const BUY: [u8; 16] = [
228, 69, 165, 46, 81, 203, 154, 29, 103, 244, 82, 31, 44, 245, 119, 119, ];
pub const SELL: [u8; 16] = [
228, 69, 165, 46, 81, 203, 154, 29, 62, 47, 55, 10, 165, 3, 220, 42, ];
pub const CREATE_POOL: [u8; 16] = [
228, 69, 165, 46, 81, 203, 154, 29, 177, 49, 12, 210, 160, 118, 167, 116, ];
pub const ADD_LIQUIDITY: [u8; 16] = [
228, 69, 165, 46, 81, 203, 154, 29, 120, 248, 61, 83, 31, 142, 107, 144, ];
pub const REMOVE_LIQUIDITY: [u8; 16] = [
228, 69, 165, 46, 81, 203, 154, 29, 22, 9, 133, 26, 160, 44, 71, 192, ];
}
#[inline]
pub fn parse_pumpswap_inner_instruction(
discriminator: &[u8; 16],
data: &[u8],
metadata: EventMetadata,
) -> Option<DexEvent> {
match discriminator {
&discriminators::BUY => parse_buy_inner(data, metadata),
&discriminators::SELL => parse_sell_inner(data, metadata),
&discriminators::CREATE_POOL => parse_create_pool_inner(data, metadata),
&discriminators::ADD_LIQUIDITY => parse_add_liquidity_inner(data, metadata),
&discriminators::REMOVE_LIQUIDITY => parse_remove_liquidity_inner(data, metadata),
_ => None,
}
}
#[inline(always)]
fn parse_buy_inner(data: &[u8], metadata: EventMetadata) -> Option<DexEvent> {
#[cfg(feature = "parse-borsh")]
{
parse_buy_inner_borsh(data, metadata)
}
#[cfg(feature = "parse-zero-copy")]
{
parse_buy_inner_zero_copy(data, metadata)
}
}
#[cfg(feature = "parse-borsh")]
#[inline(always)]
fn parse_buy_inner_borsh(data: &[u8], metadata: EventMetadata) -> Option<DexEvent> {
let event = borsh::from_slice::<PumpSwapBuyEvent>(data).ok()?;
Some(DexEvent::PumpSwapBuy(PumpSwapBuyEvent { metadata, ..event }))
}
#[cfg(feature = "parse-zero-copy")]
#[inline(always)]
fn parse_buy_inner_zero_copy(data: &[u8], metadata: EventMetadata) -> Option<DexEvent> {
unsafe {
const MIN_SIZE: usize = 8 * 17 + 32 * 7 + 1;
if !check_length(data, MIN_SIZE) {
return None;
}
let mut offset = 0;
let timestamp = read_i64_unchecked(data, offset);
offset += 8;
let base_amount_out = read_u64_unchecked(data, offset);
offset += 8;
let max_quote_amount_in = read_u64_unchecked(data, offset);
offset += 8;
let user_base_token_reserves = read_u64_unchecked(data, offset);
offset += 8;
let user_quote_token_reserves = read_u64_unchecked(data, offset);
offset += 8;
let pool_base_token_reserves = read_u64_unchecked(data, offset);
offset += 8;
let pool_quote_token_reserves = read_u64_unchecked(data, offset);
offset += 8;
let quote_amount_in = read_u64_unchecked(data, offset);
offset += 8;
let lp_fee_basis_points = read_u64_unchecked(data, offset);
offset += 8;
let lp_fee = read_u64_unchecked(data, offset);
offset += 8;
let protocol_fee_basis_points = read_u64_unchecked(data, offset);
offset += 8;
let protocol_fee = read_u64_unchecked(data, offset);
offset += 8;
let quote_amount_in_with_lp_fee = read_u64_unchecked(data, offset);
offset += 8;
let user_quote_amount_in = read_u64_unchecked(data, offset);
offset += 8;
let pool = read_pubkey_unchecked(data, offset);
offset += 32;
let user = read_pubkey_unchecked(data, offset);
offset += 32;
let user_base_token_account = read_pubkey_unchecked(data, offset);
offset += 32;
let user_quote_token_account = read_pubkey_unchecked(data, offset);
offset += 32;
let protocol_fee_recipient = read_pubkey_unchecked(data, offset);
offset += 32;
let protocol_fee_recipient_token_account = read_pubkey_unchecked(data, offset);
offset += 32;
let coin_creator = read_pubkey_unchecked(data, offset);
offset += 32;
let coin_creator_fee_basis_points = read_u64_unchecked(data, offset);
offset += 8;
let coin_creator_fee = read_u64_unchecked(data, offset);
offset += 8;
let track_volume = data[offset] != 0;
offset += 1;
let total_unclaimed_tokens = read_u64_unchecked(data, offset);
offset += 8;
let total_claimed_tokens = read_u64_unchecked(data, offset);
offset += 8;
let current_sol_volume = read_u64_unchecked(data, offset);
offset += 8;
let last_update_timestamp = read_i64_unchecked(data, offset);
offset += 8;
let min_base_amount_out = if offset + 8 <= data.len() {
let v = read_u64_unchecked(data, offset);
offset += 8;
v
} else {
0
};
let ix_name = if offset + 4 <= data.len() {
if let Some((s, consumed)) = unsafe { read_string_unchecked(data, offset) } {
offset += consumed;
s
} else {
String::new()
}
} else {
String::new()
};
let cashback_fee_basis_points = if offset + 8 <= data.len() {
let v = read_u64_unchecked(data, offset);
offset += 8;
v
} else {
0
};
let cashback = if offset + 8 <= data.len() { read_u64_unchecked(data, offset) } else { 0 };
Some(DexEvent::PumpSwapBuy(PumpSwapBuyEvent {
metadata,
timestamp,
base_amount_out,
max_quote_amount_in,
user_base_token_reserves,
user_quote_token_reserves,
pool_base_token_reserves,
pool_quote_token_reserves,
quote_amount_in,
lp_fee_basis_points,
lp_fee,
protocol_fee_basis_points,
protocol_fee,
quote_amount_in_with_lp_fee,
user_quote_amount_in,
pool,
user,
user_base_token_account,
user_quote_token_account,
protocol_fee_recipient,
protocol_fee_recipient_token_account,
coin_creator,
coin_creator_fee_basis_points,
coin_creator_fee,
track_volume,
total_unclaimed_tokens,
total_claimed_tokens,
current_sol_volume,
last_update_timestamp,
min_base_amount_out,
ix_name,
cashback_fee_basis_points,
cashback,
..Default::default()
}))
}
}
#[inline(always)]
fn parse_sell_inner(data: &[u8], metadata: EventMetadata) -> Option<DexEvent> {
#[cfg(feature = "parse-borsh")]
{
parse_sell_inner_borsh(data, metadata)
}
#[cfg(feature = "parse-zero-copy")]
{
parse_sell_inner_zero_copy(data, metadata)
}
}
#[cfg(feature = "parse-borsh")]
#[inline(always)]
fn parse_sell_inner_borsh(data: &[u8], metadata: EventMetadata) -> Option<DexEvent> {
const SELL_EVENT_SIZE: usize = 368;
if data.len() < SELL_EVENT_SIZE {
return None;
}
let event = borsh::from_slice::<PumpSwapSellEvent>(&data[..SELL_EVENT_SIZE]).ok()?;
Some(DexEvent::PumpSwapSell(PumpSwapSellEvent {
metadata,
is_pump_pool: true, ..event
}))
}
#[cfg(feature = "parse-zero-copy")]
#[inline(always)]
fn parse_sell_inner_zero_copy(data: &[u8], metadata: EventMetadata) -> Option<DexEvent> {
unsafe {
const MIN_SIZE: usize = 8 * 16 + 32 * 7 + 8 + 8; if !check_length(data, MIN_SIZE) {
return None;
}
let mut offset = 0;
let timestamp = read_i64_unchecked(data, offset);
offset += 8;
let base_amount_in = read_u64_unchecked(data, offset);
offset += 8;
let min_quote_amount_out = read_u64_unchecked(data, offset);
offset += 8;
let user_base_token_reserves = read_u64_unchecked(data, offset);
offset += 8;
let user_quote_token_reserves = read_u64_unchecked(data, offset);
offset += 8;
let pool_base_token_reserves = read_u64_unchecked(data, offset);
offset += 8;
let pool_quote_token_reserves = read_u64_unchecked(data, offset);
offset += 8;
let quote_amount_out = read_u64_unchecked(data, offset);
offset += 8;
let lp_fee_basis_points = read_u64_unchecked(data, offset);
offset += 8;
let lp_fee = read_u64_unchecked(data, offset);
offset += 8;
let protocol_fee_basis_points = read_u64_unchecked(data, offset);
offset += 8;
let protocol_fee = read_u64_unchecked(data, offset);
offset += 8;
let quote_amount_out_without_lp_fee = read_u64_unchecked(data, offset);
offset += 8;
let user_quote_amount_out = read_u64_unchecked(data, offset);
offset += 8;
let pool = read_pubkey_unchecked(data, offset);
offset += 32;
let user = read_pubkey_unchecked(data, offset);
offset += 32;
let user_base_token_account = read_pubkey_unchecked(data, offset);
offset += 32;
let user_quote_token_account = read_pubkey_unchecked(data, offset);
offset += 32;
let protocol_fee_recipient = read_pubkey_unchecked(data, offset);
offset += 32;
let protocol_fee_recipient_token_account = read_pubkey_unchecked(data, offset);
offset += 32;
let coin_creator = read_pubkey_unchecked(data, offset);
offset += 32;
let coin_creator_fee_basis_points = read_u64_unchecked(data, offset);
offset += 8;
let coin_creator_fee = read_u64_unchecked(data, offset);
offset += 8;
let cashback_fee_basis_points = read_u64_unchecked(data, offset);
offset += 8;
let cashback = read_u64_unchecked(data, offset);
Some(DexEvent::PumpSwapSell(PumpSwapSellEvent {
metadata,
timestamp,
base_amount_in,
min_quote_amount_out,
user_base_token_reserves,
user_quote_token_reserves,
pool_base_token_reserves,
pool_quote_token_reserves,
quote_amount_out,
lp_fee_basis_points,
lp_fee,
protocol_fee_basis_points,
protocol_fee,
quote_amount_out_without_lp_fee,
user_quote_amount_out,
pool,
user,
user_base_token_account,
user_quote_token_account,
protocol_fee_recipient,
protocol_fee_recipient_token_account,
coin_creator,
coin_creator_fee_basis_points,
coin_creator_fee,
cashback_fee_basis_points,
cashback,
is_pump_pool: true,
..Default::default()
}))
}
}
#[inline(always)]
fn parse_create_pool_inner(data: &[u8], metadata: EventMetadata) -> Option<DexEvent> {
unsafe {
if !check_length(data, 32 + 32 + 32 + 32 + 8 + 8) {
return None;
}
let mut offset = 0;
let pool = read_pubkey_unchecked(data, offset);
offset += 32;
let creator = read_pubkey_unchecked(data, offset);
offset += 32;
let base_mint = read_pubkey_unchecked(data, offset);
offset += 32;
let quote_mint = read_pubkey_unchecked(data, offset);
offset += 32;
let base_amount = read_u64_unchecked(data, offset);
offset += 8;
let quote_amount = read_u64_unchecked(data, offset);
Some(DexEvent::PumpSwapCreatePool(PumpSwapCreatePoolEvent {
metadata,
pool,
creator,
base_mint,
quote_mint,
base_amount_in: base_amount,
quote_amount_in: quote_amount,
..Default::default()
}))
}
}
#[inline(always)]
fn parse_add_liquidity_inner(data: &[u8], metadata: EventMetadata) -> Option<DexEvent> {
unsafe {
if !check_length(data, 32 + 32 + 8 + 8 + 8) {
return None;
}
let mut offset = 0;
let _pool = read_pubkey_unchecked(data, offset);
offset += 32;
let _user = read_pubkey_unchecked(data, offset);
offset += 32;
let base_amount = read_u64_unchecked(data, offset);
offset += 8;
let quote_amount = read_u64_unchecked(data, offset);
offset += 8;
let lp_amount = read_u64_unchecked(data, offset);
Some(DexEvent::PumpSwapLiquidityAdded(PumpSwapLiquidityAdded {
metadata,
base_amount_in: base_amount,
quote_amount_in: quote_amount,
lp_token_amount_out: lp_amount,
..Default::default()
}))
}
}
#[inline(always)]
fn parse_remove_liquidity_inner(data: &[u8], metadata: EventMetadata) -> Option<DexEvent> {
unsafe {
if !check_length(data, 32 + 32 + 8 + 8 + 8) {
return None;
}
let mut offset = 0;
let _pool = read_pubkey_unchecked(data, offset);
offset += 32;
let _user = read_pubkey_unchecked(data, offset);
offset += 32;
let lp_amount = read_u64_unchecked(data, offset);
offset += 8;
let base_amount_out = read_u64_unchecked(data, offset);
offset += 8;
let quote_amount_out = read_u64_unchecked(data, offset);
Some(DexEvent::PumpSwapLiquidityRemoved(PumpSwapLiquidityRemoved {
metadata,
lp_token_amount_in: lp_amount,
base_amount_out,
quote_amount_out,
..Default::default()
}))
}
}