fix(pumpfun): resolve creator_vault vs PDA(creator); validate fee recipient pool

- Add resolve_creator_vault_for_ix: use gRPC creator_vault only when it matches
  PDA(['creator-vault', bonding_curve.creator]); on mismatch use derived PDA to
  avoid ConstraintSeeds (2006) from stale/wrong stream vaults
- pump_fun_fee_recipient_meta: only use event fee_recipient if authorized for
  is_mayhem_mode (avoids 6000 NotAuthorized when standard AMM fee is used on
  Mayhem coins)
- Align PumpFunParams::from_trade/from_dev_trade cached creator_vault with the
  same resolution logic

Made-with: Cursor
This commit is contained in:
0xfnzero
2026-04-11 19:37:05 +08:00
parent 9c9ecf3e5b
commit 4dec087ea6
3 changed files with 65 additions and 53 deletions
+11 -13
View File
@@ -127,7 +127,7 @@ impl std::fmt::Debug for SwapParams {
pub struct PumpFunParams {
pub bonding_curve: Arc<BondingCurveAccount>,
pub associated_bonding_curve: Pubkey,
/// From events/parsed ix when set; else derived from `bonding_curve.creator`. Buy/sell prefer non-default.
/// `PDA(["creator-vault", bonding_curve.creator])`; from_trade resolves when event vault mismatches.
pub creator_vault: Pubkey,
pub token_program: Pubkey,
/// Whether to close token account when selling, only effective during sell operations
@@ -182,12 +182,11 @@ impl PumpFunParams {
is_mayhem_mode,
is_cashback_coin,
);
let creator_vault_resolved = if creator_vault != Pubkey::default() {
creator_vault
} else {
crate::instruction::utils::pumpfun::get_creator_vault_pda(&bonding_curve_account.creator)
.unwrap_or_default()
};
let creator_vault_resolved = crate::instruction::utils::pumpfun::resolve_creator_vault_for_ix(
&bonding_curve_account.creator,
creator_vault,
)
.unwrap_or_default();
Self {
bonding_curve: Arc::new(bonding_curve_account),
associated_bonding_curve: associated_bonding_curve,
@@ -230,12 +229,11 @@ impl PumpFunParams {
is_mayhem_mode,
is_cashback_coin,
);
let creator_vault_resolved = if creator_vault != Pubkey::default() {
creator_vault
} else {
crate::instruction::utils::pumpfun::get_creator_vault_pda(&bonding_curve.creator)
.unwrap_or_default()
};
let creator_vault_resolved = crate::instruction::utils::pumpfun::resolve_creator_vault_for_ix(
&bonding_curve.creator,
creator_vault,
)
.unwrap_or_default();
Self {
bonding_curve: Arc::new(bonding_curve),
associated_bonding_curve: associated_bonding_curve,