diff --git a/idl/pump_amm.json b/idl/pump_amm.json index 47d7b95..372cf2a 100644 --- a/idl/pump_amm.json +++ b/idl/pump_amm.json @@ -4835,7 +4835,7 @@ }, { "code": 6052, - "name": "CashbackEarnedDoesNotMatchTokenInVault" + "name": "TokensInVaultLessThanCashbackEarned" } ], "types": [ diff --git a/idl/pump_fees.json b/idl/pump_fees.json index 66ed115..fc21546 100644 --- a/idl/pump_fees.json +++ b/idl/pump_fees.json @@ -7,115 +7,6 @@ "description": "Created with Anchor" }, "instructions": [ - { - "name": "claim_social_fee_pda", - "discriminator": [ - 225, - 21, - 251, - 133, - 161, - 30, - 199, - 226 - ], - "accounts": [ - { - "name": "recipient", - "writable": true - }, - { - "name": "social_fee_pda", - "writable": true - }, - { - "name": "fee_program_global", - "pda": { - "seeds": [ - { - "kind": "const", - "value": [ - 102, - 101, - 101, - 45, - 112, - 114, - 111, - 103, - 114, - 97, - 109, - 45, - 103, - 108, - 111, - 98, - 97, - 108 - ] - } - ] - } - }, - { - "name": "social_claim_authority", - "signer": true, - "relations": [ - "fee_program_global" - ] - }, - { - "name": "event_authority", - "pda": { - "seeds": [ - { - "kind": "const", - "value": [ - 95, - 95, - 101, - 118, - 101, - 110, - 116, - 95, - 97, - 117, - 116, - 104, - 111, - 114, - 105, - 116, - 121 - ] - } - ] - } - }, - { - "name": "program" - } - ], - "args": [ - { - "name": "user_id", - "type": "string" - }, - { - "name": "platform", - "type": "u8" - } - ], - "returns": { - "option": { - "defined": { - "name": "SocialFeePdaClaimed" - } - } - } - }, { "name": "create_fee_sharing_config", "docs": [ @@ -480,106 +371,6 @@ ], "args": [] }, - { - "name": "create_social_fee_pda", - "discriminator": [ - 144, - 224, - 59, - 211, - 78, - 248, - 202, - 220 - ], - "accounts": [ - { - "name": "payer", - "writable": true, - "signer": true - }, - { - "name": "social_fee_pda", - "writable": true - }, - { - "name": "system_program", - "address": "11111111111111111111111111111111" - }, - { - "name": "fee_program_global", - "pda": { - "seeds": [ - { - "kind": "const", - "value": [ - 102, - 101, - 101, - 45, - 112, - 114, - 111, - 103, - 114, - 97, - 109, - 45, - 103, - 108, - 111, - 98, - 97, - 108 - ] - } - ] - } - }, - { - "name": "event_authority", - "pda": { - "seeds": [ - { - "kind": "const", - "value": [ - 95, - 95, - 101, - 118, - 101, - 110, - 116, - 95, - 97, - 117, - 116, - 104, - 111, - 114, - 105, - 116, - 121 - ] - } - ] - } - }, - { - "name": "program" - } - ], - "args": [ - { - "name": "user_id", - "type": "string" - }, - { - "name": "platform", - "type": "u8" - } - ] - }, { "name": "get_fees", "docs": [ @@ -737,165 +528,6 @@ ], "args": [] }, - { - "name": "initialize_fee_program_global", - "discriminator": [ - 35, - 215, - 130, - 84, - 233, - 56, - 124, - 167 - ], - "accounts": [ - { - "name": "authority", - "writable": true, - "signer": true, - "relations": [ - "pump_global" - ] - }, - { - "name": "pump_global", - "pda": { - "seeds": [ - { - "kind": "const", - "value": [ - 103, - 108, - 111, - 98, - 97, - 108 - ] - } - ], - "program": { - "kind": "const", - "value": [ - 1, - 86, - 224, - 246, - 147, - 102, - 90, - 207, - 68, - 219, - 21, - 104, - 191, - 23, - 91, - 170, - 81, - 137, - 203, - 151, - 245, - 210, - 255, - 59, - 101, - 93, - 43, - 182, - 253, - 109, - 24, - 176 - ] - } - } - }, - { - "name": "fee_program_global", - "writable": true, - "pda": { - "seeds": [ - { - "kind": "const", - "value": [ - 102, - 101, - 101, - 45, - 112, - 114, - 111, - 103, - 114, - 97, - 109, - 45, - 103, - 108, - 111, - 98, - 97, - 108 - ] - } - ] - } - }, - { - "name": "system_program", - "address": "11111111111111111111111111111111" - }, - { - "name": "event_authority", - "pda": { - "seeds": [ - { - "kind": "const", - "value": [ - 95, - 95, - 101, - 118, - 101, - 110, - 116, - 95, - 97, - 117, - 116, - 104, - 111, - 114, - 105, - 116, - 121 - ] - } - ] - } - }, - { - "name": "program" - } - ], - "args": [ - { - "name": "social_claim_authority", - "type": "pubkey" - }, - { - "name": "disable_flags", - "type": "u8" - }, - { - "name": "claim_rate_limit", - "type": "u64" - } - ] - }, { "name": "reset_fee_sharing_config", "docs": [ @@ -1193,374 +825,6 @@ ], "args": [] }, - { - "name": "set_authority", - "discriminator": [ - 133, - 250, - 37, - 21, - 110, - 163, - 26, - 121 - ], - "accounts": [ - { - "name": "authority", - "writable": true, - "signer": true, - "relations": [ - "fee_program_global" - ] - }, - { - "name": "fee_program_global", - "writable": true, - "pda": { - "seeds": [ - { - "kind": "const", - "value": [ - 102, - 101, - 101, - 45, - 112, - 114, - 111, - 103, - 114, - 97, - 109, - 45, - 103, - 108, - 111, - 98, - 97, - 108 - ] - } - ] - } - }, - { - "name": "event_authority", - "pda": { - "seeds": [ - { - "kind": "const", - "value": [ - 95, - 95, - 101, - 118, - 101, - 110, - 116, - 95, - 97, - 117, - 116, - 104, - 111, - 114, - 105, - 116, - 121 - ] - } - ] - } - }, - { - "name": "program" - } - ], - "args": [ - { - "name": "new_authority", - "type": "pubkey" - } - ] - }, - { - "name": "set_claim_rate_limit", - "discriminator": [ - 185, - 211, - 159, - 174, - 212, - 49, - 88, - 4 - ], - "accounts": [ - { - "name": "authority", - "writable": true, - "signer": true, - "relations": [ - "fee_program_global" - ] - }, - { - "name": "fee_program_global", - "writable": true, - "pda": { - "seeds": [ - { - "kind": "const", - "value": [ - 102, - 101, - 101, - 45, - 112, - 114, - 111, - 103, - 114, - 97, - 109, - 45, - 103, - 108, - 111, - 98, - 97, - 108 - ] - } - ] - } - }, - { - "name": "event_authority", - "pda": { - "seeds": [ - { - "kind": "const", - "value": [ - 95, - 95, - 101, - 118, - 101, - 110, - 116, - 95, - 97, - 117, - 116, - 104, - 111, - 114, - 105, - 116, - 121 - ] - } - ] - } - }, - { - "name": "program" - } - ], - "args": [ - { - "name": "claim_rate_limit", - "type": "u64" - } - ] - }, - { - "name": "set_disable_flags", - "discriminator": [ - 194, - 217, - 112, - 35, - 114, - 222, - 51, - 190 - ], - "accounts": [ - { - "name": "authority", - "writable": true, - "signer": true, - "relations": [ - "fee_program_global" - ] - }, - { - "name": "fee_program_global", - "writable": true, - "pda": { - "seeds": [ - { - "kind": "const", - "value": [ - 102, - 101, - 101, - 45, - 112, - 114, - 111, - 103, - 114, - 97, - 109, - 45, - 103, - 108, - 111, - 98, - 97, - 108 - ] - } - ] - } - }, - { - "name": "event_authority", - "pda": { - "seeds": [ - { - "kind": "const", - "value": [ - 95, - 95, - 101, - 118, - 101, - 110, - 116, - 95, - 97, - 117, - 116, - 104, - 111, - 114, - 105, - 116, - 121 - ] - } - ] - } - }, - { - "name": "program" - } - ], - "args": [ - { - "name": "disable_flags", - "type": "u8" - } - ] - }, - { - "name": "set_social_claim_authority", - "discriminator": [ - 147, - 54, - 184, - 154, - 136, - 237, - 185, - 153 - ], - "accounts": [ - { - "name": "authority", - "writable": true, - "signer": true, - "relations": [ - "fee_program_global" - ] - }, - { - "name": "fee_program_global", - "writable": true, - "pda": { - "seeds": [ - { - "kind": "const", - "value": [ - 102, - 101, - 101, - 45, - 112, - 114, - 111, - 103, - 114, - 97, - 109, - 45, - 103, - 108, - 111, - 98, - 97, - 108 - ] - } - ] - } - }, - { - "name": "event_authority", - "pda": { - "seeds": [ - { - "kind": "const", - "value": [ - 95, - 95, - 101, - 118, - 101, - 110, - 116, - 95, - 97, - 117, - 116, - 104, - 111, - 114, - 105, - 116, - 121 - ] - } - ] - } - }, - { - "name": "program" - } - ], - "args": [ - { - "name": "social_claim_authority", - "type": "pubkey" - } - ] - }, { "name": "transfer_fee_sharing_authority", "docs": [ @@ -2559,19 +1823,6 @@ 155 ] }, - { - "name": "FeeProgramGlobal", - "discriminator": [ - 162, - 165, - 245, - 49, - 29, - 37, - 55, - 242 - ] - }, { "name": "Global", "discriminator": [ @@ -2610,19 +1861,6 @@ 93, 75 ] - }, - { - "name": "SocialFeePda", - "discriminator": [ - 139, - 96, - 53, - 17, - 42, - 169, - 206, - 150 - ] } ], "events": [ @@ -2652,19 +1890,6 @@ 126 ] }, - { - "name": "InitializeFeeProgramGlobalEvent", - "discriminator": [ - 40, - 233, - 156, - 78, - 95, - 0, - 8, - 199 - ] - }, { "name": "ResetFeeSharingConfigEvent", "discriminator": [ @@ -2691,84 +1916,6 @@ 62 ] }, - { - "name": "SetAuthorityEvent", - "discriminator": [ - 18, - 175, - 132, - 66, - 208, - 201, - 87, - 242 - ] - }, - { - "name": "SetClaimRateLimitEvent", - "discriminator": [ - 13, - 143, - 143, - 235, - 181, - 19, - 51, - 40 - ] - }, - { - "name": "SetDisableFlagsEvent", - "discriminator": [ - 5, - 8, - 179, - 65, - 49, - 55, - 145, - 126 - ] - }, - { - "name": "SetSocialClaimAuthorityEvent", - "discriminator": [ - 60, - 118, - 127, - 132, - 239, - 52, - 254, - 14 - ] - }, - { - "name": "SocialFeePdaClaimed", - "discriminator": [ - 50, - 18, - 193, - 65, - 237, - 210, - 234, - 236 - ] - }, - { - "name": "SocialFeePdaCreated", - "discriminator": [ - 183, - 183, - 218, - 147, - 24, - 124, - 137, - 169 - ] - }, { "name": "TransferFeeSharingAuthorityEvent", "discriminator": [ @@ -2940,16 +2087,6 @@ "code": 6020, "name": "ShareholderAccountMismatch", "msg": "Remaining account key doesn't match shareholder address" - }, - { - "code": 6021, - "name": "FeatureDeactivated", - "msg": "Feature is currently deactivated" - }, - { - "code": 6022, - "name": "UserIdTooLong", - "msg": "User ID exceeds maximum length" } ], "types": [ @@ -3105,43 +2242,6 @@ ] } }, - { - "name": "FeeProgramGlobal", - "type": { - "kind": "struct", - "fields": [ - { - "name": "bump", - "type": "u8" - }, - { - "name": "authority", - "type": "pubkey" - }, - { - "name": "disable_flags", - "type": "u8" - }, - { - "name": "social_claim_authority", - "type": "pubkey" - }, - { - "name": "claim_rate_limit", - "type": "u64" - }, - { - "name": "_reserved", - "type": { - "array": [ - "u8", - 256 - ] - } - } - ] - } - }, { "name": "FeeTier", "type": { @@ -3300,34 +2400,6 @@ ] } }, - { - "name": "InitializeFeeProgramGlobalEvent", - "type": { - "kind": "struct", - "fields": [ - { - "name": "timestamp", - "type": "i64" - }, - { - "name": "authority", - "type": "pubkey" - }, - { - "name": "social_claim_authority", - "type": "pubkey" - }, - { - "name": "disable_flags", - "type": "u8" - }, - { - "name": "claim_rate_limit", - "type": "u64" - } - ] - } - }, { "name": "Pool", "type": { @@ -3452,74 +2524,6 @@ ] } }, - { - "name": "SetAuthorityEvent", - "type": { - "kind": "struct", - "fields": [ - { - "name": "timestamp", - "type": "i64" - }, - { - "name": "old_authority", - "type": "pubkey" - }, - { - "name": "new_authority", - "type": "pubkey" - } - ] - } - }, - { - "name": "SetClaimRateLimitEvent", - "type": { - "kind": "struct", - "fields": [ - { - "name": "timestamp", - "type": "i64" - }, - { - "name": "claim_rate_limit", - "type": "u64" - } - ] - } - }, - { - "name": "SetDisableFlagsEvent", - "type": { - "kind": "struct", - "fields": [ - { - "name": "timestamp", - "type": "i64" - }, - { - "name": "disable_flags", - "type": "u8" - } - ] - } - }, - { - "name": "SetSocialClaimAuthorityEvent", - "type": { - "kind": "struct", - "fields": [ - { - "name": "timestamp", - "type": "i64" - }, - { - "name": "social_claim_authority", - "type": "pubkey" - } - ] - } - }, { "name": "Shareholder", "type": { @@ -3582,134 +2586,6 @@ ] } }, - { - "name": "SocialFeePda", - "docs": [ - "Platform identifier: 0=pump, 1=twitter, etc." - ], - "type": { - "kind": "struct", - "fields": [ - { - "name": "bump", - "type": "u8" - }, - { - "name": "version", - "type": "u8" - }, - { - "name": "user_id", - "docs": [ - "Max 20 characters to fit u64::MAX (18,446,744,073,709,551,615) as a string.", - "Actual storage: 4 bytes (length prefix) + 20 bytes (content) = 24 bytes." - ], - "type": "string" - }, - { - "name": "platform", - "type": "u8" - }, - { - "name": "total_claimed", - "type": "u64" - }, - { - "name": "last_claimed", - "type": "u64" - }, - { - "name": "_reserved", - "type": { - "array": [ - "u8", - 128 - ] - } - } - ] - } - }, - { - "name": "SocialFeePdaClaimed", - "type": { - "kind": "struct", - "fields": [ - { - "name": "timestamp", - "type": "i64" - }, - { - "name": "user_id", - "type": "string" - }, - { - "name": "platform", - "type": "u8" - }, - { - "name": "social_fee_pda", - "type": "pubkey" - }, - { - "name": "recipient", - "type": "pubkey" - }, - { - "name": "social_claim_authority", - "type": "pubkey" - }, - { - "name": "amount_claimed", - "type": "u64" - }, - { - "name": "claimable_before", - "type": "u64" - }, - { - "name": "lifetime_claimed", - "type": "u64" - }, - { - "name": "recipient_balance_before", - "type": "u64" - }, - { - "name": "recipient_balance_after", - "type": "u64" - } - ] - } - }, - { - "name": "SocialFeePdaCreated", - "type": { - "kind": "struct", - "fields": [ - { - "name": "timestamp", - "type": "i64" - }, - { - "name": "user_id", - "type": "string" - }, - { - "name": "platform", - "type": "u8" - }, - { - "name": "social_fee_pda", - "type": "pubkey" - }, - { - "name": "created_by", - "type": "pubkey" - } - ] - } - }, { "name": "TransferFeeSharingAuthorityEvent", "type": { @@ -3871,29 +2747,6 @@ "type": "bytes", "value": "[102, 101, 101, 95, 99, 111, 110, 102, 105, 103]" }, - { - "name": "FEE_PROGRAM_GLOBAL_SEED", - "type": { - "array": [ - "u8", - 18 - ] - }, - "value": "[102, 101, 101, 45, 112, 114, 111, 103, 114, 97, 109, 45, 103, 108, 111, 98, 97, 108]" - }, - { - "name": "PUMP_GLOBAL_SEED", - "docs": [ - "Bonding Curve Program Global Seed" - ], - "type": { - "array": [ - "u8", - 6 - ] - }, - "value": "[103, 108, 111, 98, 97, 108]" - }, { "name": "SHARING_CONFIG_SEED", "type": { @@ -3903,16 +2756,6 @@ ] }, "value": "[115, 104, 97, 114, 105, 110, 103, 45, 99, 111, 110, 102, 105, 103]" - }, - { - "name": "SOCIAL_FEE_PDA_SEED", - "type": { - "array": [ - "u8", - 14 - ] - }, - "value": "[115, 111, 99, 105, 97, 108, 45, 102, 101, 101, 45, 112, 100, 97]" } ] } \ No newline at end of file diff --git a/src/instruction/pumpfun.rs b/src/instruction/pumpfun.rs index 7029e53..c654d2e 100755 --- a/src/instruction/pumpfun.rs +++ b/src/instruction/pumpfun.rs @@ -118,10 +118,11 @@ impl InstructionBuilder for PumpFunInstructionBuilder { ); } - let mut buy_data = [0u8; 24]; + // IDL: buy/buy_exact_sol_in 第三参数 track_volume: OptionBool,仅代币支持返现时传 Some(true) + let track_volume = if bonding_curve.is_cashback_coin { [1u8, 1u8] } else { [1u8, 0u8] }; // Some(true) / Some(false) + let mut buy_data = [0u8; 26]; if params.use_exact_sol_amount.unwrap_or(true) { - // buy_exact_sol_in(spendable_sol_in: u64, min_tokens_out: u64) - // Spend exactly the input SOL amount, get at least min_tokens_out + // buy_exact_sol_in(spendable_sol_in: u64, min_tokens_out: u64, track_volume) let min_tokens_out = calculate_with_slippage_sell( buy_token_amount, params.slippage_basis_points.unwrap_or(DEFAULT_SLIPPAGE), @@ -129,12 +130,13 @@ impl InstructionBuilder for PumpFunInstructionBuilder { buy_data[..8].copy_from_slice(&BUY_EXACT_SOL_IN_DISCRIMINATOR); buy_data[8..16].copy_from_slice(¶ms.input_amount.unwrap_or(0).to_le_bytes()); buy_data[16..24].copy_from_slice(&min_tokens_out.to_le_bytes()); + buy_data[24..26].copy_from_slice(&track_volume); } else { - // buy(token_amount: u64, max_sol_cost: u64) - // Buy exactly token_amount tokens, pay up to max_sol_cost + // buy(token_amount: u64, max_sol_cost: u64, track_volume) buy_data[..8].copy_from_slice(&BUY_DISCRIMINATOR); 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()); + buy_data[24..26].copy_from_slice(&track_volume); } // Determine fee recipient based on mayhem mode (pump-public-docs: 2nd account = Mayhem fee recipient; use any one randomly) @@ -163,7 +165,7 @@ impl InstructionBuilder for PumpFunInstructionBuilder { accounts::FEE_CONFIG_META, accounts::FEE_PROGRAM_META, ]; - accounts.push(AccountMeta::new_readonly(bonding_curve_v2, false)); // bonding_curve_v2 (readonly) at end + accounts.push(AccountMeta::new_readonly(bonding_curve_v2, false)); // remainingAccounts: @pump-fun/pump-sdk 要求末尾传 bondingCurveV2Pda(mint),勿删 instructions.push(Instruction::new_with_bytes( accounts::PUMPFUN, @@ -289,7 +291,7 @@ impl InstructionBuilder for PumpFunInstructionBuilder { get_user_volume_accumulator_pda(¶ms.payer.pubkey()).unwrap(); accounts.push(AccountMeta::new(user_volume_accumulator, false)); } - // Program upgrade: bonding_curve_v2 (readonly) at end of account list + // remainingAccounts: @pump-fun/pump-sdk sell 要求末尾传 bondingCurveV2Pda(mint)(cashback 时在 user_volume_accumulator 之后),勿删 let bonding_curve_v2 = get_bonding_curve_v2_pda(¶ms.input_mint).unwrap(); accounts.push(AccountMeta::new_readonly(bonding_curve_v2, false)); diff --git a/src/instruction/pumpswap.rs b/src/instruction/pumpswap.rs index 8644d0f..40de9f4 100755 --- a/src/instruction/pumpswap.rs +++ b/src/instruction/pumpswap.rs @@ -2,8 +2,9 @@ use crate::{ constants::trade::trade::DEFAULT_SLIPPAGE, instruction::utils::pumpswap::{ accounts, fee_recipient_ata, get_mayhem_fee_recipient_random, get_pool_v2_pda, - get_user_volume_accumulator_pda, get_user_volume_accumulator_wsol_ata, BUY_DISCRIMINATOR, - BUY_EXACT_QUOTE_IN_DISCRIMINATOR, SELL_DISCRIMINATOR, + get_user_volume_accumulator_pda, get_user_volume_accumulator_quote_ata, + get_user_volume_accumulator_wsol_ata, BUY_DISCRIMINATOR, BUY_EXACT_QUOTE_IN_DISCRIMINATOR, + SELL_DISCRIMINATOR, }, trading::{ common::wsol_manager, @@ -192,48 +193,44 @@ impl InstructionBuilder for PumpSwapInstructionBuilder { accounts.push(AccountMeta::new(wsol_ata, false)); } } - // Program upgrade: pool_v2 (readonly) at end of account list + // remainingAccounts: @pump-fun/pump-swap-sdk 要求末尾传 poolV2Pda(baseMint),勿删 accounts.push(AccountMeta::new_readonly( get_pool_v2_pda(&base_mint).unwrap(), false, )); - // Create instruction data - let mut data = [0u8; 24]; - if quote_is_wsol_or_usdc { + // Create instruction data(buy/buy_exact_quote_in 第三参数 track_volume: OptionBool,仅代币支持返现时传 Some(true);sell 仅两参数) + let track_volume = if protocol_params.is_cashback_coin { [1u8, 1u8] } else { [1u8, 0u8] }; // Some(true) / Some(false) + let data: Vec = if quote_is_wsol_or_usdc { + let mut buf = [0u8; 26]; if params.use_exact_sol_amount.unwrap_or(true) { - // buy_exact_quote_in(spendable_quote_in: u64, min_base_amount_out: u64) - // Spend exactly the input SOL/quote amount, get at least min_base_amount_out let min_base_amount_out = crate::utils::calc::common::calculate_with_slippage_sell( token_amount, params.slippage_basis_points.unwrap_or(DEFAULT_SLIPPAGE), ); - data[..8].copy_from_slice(&BUY_EXACT_QUOTE_IN_DISCRIMINATOR); - // spendable_quote_in (exact SOL amount to spend) - data[8..16].copy_from_slice(¶ms.input_amount.unwrap_or(0).to_le_bytes()); - // min_base_amount_out (minimum tokens to receive) - data[16..24].copy_from_slice(&min_base_amount_out.to_le_bytes()); + buf[..8].copy_from_slice(&BUY_EXACT_QUOTE_IN_DISCRIMINATOR); + buf[8..16].copy_from_slice(¶ms.input_amount.unwrap_or(0).to_le_bytes()); + buf[16..24].copy_from_slice(&min_base_amount_out.to_le_bytes()); + buf[24..26].copy_from_slice(&track_volume); } else { - // buy(base_amount_out: u64, max_quote_amount_in: u64) - // Buy exactly base_amount_out tokens, pay up to max_quote_amount_in - data[..8].copy_from_slice(&BUY_DISCRIMINATOR); - // base_amount_out - data[8..16].copy_from_slice(&token_amount.to_le_bytes()); - // max_quote_amount_in - data[16..24].copy_from_slice(&sol_amount.to_le_bytes()); + buf[..8].copy_from_slice(&BUY_DISCRIMINATOR); + buf[8..16].copy_from_slice(&token_amount.to_le_bytes()); + buf[16..24].copy_from_slice(&sol_amount.to_le_bytes()); + buf[24..26].copy_from_slice(&track_volume); } + buf.to_vec() } else { - data[..8].copy_from_slice(&SELL_DISCRIMINATOR); - // base_amount_in - data[8..16].copy_from_slice(&sol_amount.to_le_bytes()); - // min_quote_amount_out - data[16..24].copy_from_slice(&token_amount.to_le_bytes()); - } + let mut buf = [0u8; 24]; + buf[..8].copy_from_slice(&SELL_DISCRIMINATOR); + buf[8..16].copy_from_slice(&sol_amount.to_le_bytes()); + buf[16..24].copy_from_slice(&token_amount.to_le_bytes()); + buf.to_vec() + }; let buy_instruction = Instruction { program_id: accounts::AMM_PROGRAM, accounts: accounts.clone(), - data: data.to_vec(), + data, }; instructions.push(buy_instruction); @@ -391,17 +388,21 @@ impl InstructionBuilder for PumpSwapInstructionBuilder { } accounts.push(accounts::FEE_CONFIG_META); accounts.push(accounts::FEE_PROGRAM_META); - // Cashback: remaining_accounts[0] = WSOL ATA of UserVolumeAccumulator, remaining_accounts[1] = UserVolumeAccumulator PDA + // Cashback sell: 官方 remainingAccounts = [accumulator 的 quote_mint ATA, accumulator PDA, poolV2](用 quote_mint 非固定 WSOL) if protocol_params.is_cashback_coin { - if let (Some(wsol_ata), Some(accumulator)) = ( - get_user_volume_accumulator_wsol_ata(¶ms.payer.pubkey()), + if let (Some(quote_ata), Some(accumulator)) = ( + get_user_volume_accumulator_quote_ata( + ¶ms.payer.pubkey(), + "e_mint, + "e_token_program, + ), get_user_volume_accumulator_pda(¶ms.payer.pubkey()), ) { - accounts.push(AccountMeta::new(wsol_ata, false)); + accounts.push(AccountMeta::new(quote_ata, false)); accounts.push(AccountMeta::new(accumulator, false)); } } - // Program upgrade: pool_v2 (readonly) at end of account list + // remainingAccounts: @pump-fun/pump-swap-sdk sell 要求末尾传 poolV2Pda(baseMint),勿删 accounts.push(AccountMeta::new_readonly( get_pool_v2_pda(&base_mint).unwrap(), false, diff --git a/src/instruction/utils/pumpswap.rs b/src/instruction/utils/pumpswap.rs index ddc9a0c..943e493 100644 --- a/src/instruction/utils/pumpswap.rs +++ b/src/instruction/utils/pumpswap.rs @@ -262,7 +262,7 @@ pub fn get_user_volume_accumulator_pda(user: &Pubkey) -> Option { ) } -/// WSOL ATA of UserVolumeAccumulator for Pump AMM (used for cashback remaining accounts). +/// WSOL ATA of UserVolumeAccumulator for Pump AMM (buy cashback: remaining_accounts[0] 官方用 NATIVE_MINT). pub fn get_user_volume_accumulator_wsol_ata(user: &Pubkey) -> Option { let accumulator = get_user_volume_accumulator_pda(user)?; Some(crate::common::fast_fn::get_associated_token_address_with_program_id_fast( @@ -272,6 +272,20 @@ pub fn get_user_volume_accumulator_wsol_ata(user: &Pubkey) -> Option { )) } +/// Quote-mint ATA of UserVolumeAccumulator(sell cashback 时官方用 quoteMint,非固定 WSOL). +pub fn get_user_volume_accumulator_quote_ata( + user: &Pubkey, + quote_mint: &Pubkey, + quote_token_program: &Pubkey, +) -> Option { + let accumulator = get_user_volume_accumulator_pda(user)?; + Some(crate::common::fast_fn::get_associated_token_address_with_program_id_fast( + &accumulator, + quote_mint, + quote_token_program, + )) +} + pub fn get_global_volume_accumulator_pda() -> Option { let seeds: &[&[u8]; 1] = &[&seeds::GLOBAL_VOLUME_ACCUMULATOR_SEED]; let program_id: &Pubkey = &&accounts::AMM_PROGRAM;