1use crate::PROGRAM_ID;
2
3use super::PumpfunDecoder;
4pub mod buy;
5pub mod complete_event;
6pub mod complete_pump_amm_migration_event;
7pub mod create;
8pub mod create_event;
9pub mod extend_account;
10pub mod extend_account_event;
11pub mod initialize;
12pub mod migrate;
13pub mod sell;
14pub mod set_params;
15pub mod set_params_event;
16pub mod trade_event;
17pub mod update_global_authority;
18pub mod update_global_authority_event;
19pub mod withdraw;
20
21#[derive(
22 carbon_core::InstructionType,
23 serde::Serialize,
24 serde::Deserialize,
25 PartialEq,
26 Eq,
27 Debug,
28 Clone,
29 Hash,
30)]
31pub enum PumpfunInstruction {
32 Buy(buy::Buy),
33 Create(create::Create),
34 ExtendAccount(extend_account::ExtendAccount),
35 Initialize(initialize::Initialize),
36 Migrate(migrate::Migrate),
37 Sell(sell::Sell),
38 SetParams(set_params::SetParams),
39 UpdateGlobalAuthority(update_global_authority::UpdateGlobalAuthority),
40 Withdraw(withdraw::Withdraw),
41 CompleteEvent(complete_event::CompleteEvent),
42 CompletePumpAmmMigrationEvent(complete_pump_amm_migration_event::CompletePumpAmmMigrationEvent),
43 CreateEvent(create_event::CreateEvent),
44 ExtendAccountEvent(extend_account_event::ExtendAccountEvent),
45 SetParamsEvent(set_params_event::SetParamsEvent),
46 TradeEvent(trade_event::TradeEvent),
47 UpdateGlobalAuthorityEvent(update_global_authority_event::UpdateGlobalAuthorityEvent),
48}
49
50impl carbon_core::instruction::InstructionDecoder<'_> for PumpfunDecoder {
51 type InstructionType = PumpfunInstruction;
52
53 fn decode_instruction(
54 &self,
55 instruction: &solana_instruction::Instruction,
56 ) -> Option<carbon_core::instruction::DecodedInstruction<Self::InstructionType>> {
57 if !instruction.program_id.eq(&PROGRAM_ID) {
58 return None;
59 }
60
61 carbon_core::try_decode_instructions!(instruction,
62 PumpfunInstruction::Buy => buy::Buy,
63 PumpfunInstruction::Create => create::Create,
64 PumpfunInstruction::ExtendAccount => extend_account::ExtendAccount,
65 PumpfunInstruction::Initialize => initialize::Initialize,
66 PumpfunInstruction::Migrate => migrate::Migrate,
67 PumpfunInstruction::Sell => sell::Sell,
68 PumpfunInstruction::SetParams => set_params::SetParams,
69 PumpfunInstruction::UpdateGlobalAuthority => update_global_authority::UpdateGlobalAuthority,
70 PumpfunInstruction::Withdraw => withdraw::Withdraw,
71 PumpfunInstruction::CompleteEvent => complete_event::CompleteEvent,
72 PumpfunInstruction::CompletePumpAmmMigrationEvent => complete_pump_amm_migration_event::CompletePumpAmmMigrationEvent,
73 PumpfunInstruction::CreateEvent => create_event::CreateEvent,
74 PumpfunInstruction::ExtendAccountEvent => extend_account_event::ExtendAccountEvent,
75 PumpfunInstruction::SetParamsEvent => set_params_event::SetParamsEvent,
76 PumpfunInstruction::TradeEvent => trade_event::TradeEvent,
77 PumpfunInstruction::UpdateGlobalAuthorityEvent => update_global_authority_event::UpdateGlobalAuthorityEvent,
78 )
79 }
80}
81
82#[cfg(test)]
83mod tests {
84 use alloc::{borrow::ToOwned, vec};
85 use carbon_core::{deserialize::ArrangeAccounts, instruction::InstructionDecoder};
86 use solana_instruction::AccountMeta;
87 use solana_pubkey::Pubkey;
88
89 use super::*;
90
91 #[test]
92 fn test_decode_buy() {
93 let expected_ix = PumpfunInstruction::Buy(buy::Buy {
95 amount: 2712969161192,
96 max_sol_cost: 204000000,
97 });
98 let expected_accounts = vec![
99 AccountMeta::new_readonly(
100 Pubkey::from_str_const("4wTV1YmiEkRvAtNtsSGPtUrqRYQMe5SKy2uB4Jjaxnjf"),
101 false,
102 ),
103 AccountMeta::new(
104 Pubkey::from_str_const("62qc2CNXwrYqQScmEdiZFFAnJR262PxWEuNQtxfafNgV"),
105 false,
106 ),
107 AccountMeta::new_readonly(
108 Pubkey::from_str_const("9p1PMtto471A7GvnRJVmDcuqUz3xDd1Lhu8vzrmpump"),
109 false,
110 ),
111 AccountMeta::new(
112 Pubkey::from_str_const("HWxwYxr4AV5ytUyT8pvjCEiUrXhwpbx365VpvQ6Bd6MZ"),
113 false,
114 ),
115 AccountMeta::new(
116 Pubkey::from_str_const("AUfg9aTAix7YarkHXSBMUyQPCTq55Gg1Z2NTe6utwwzG"),
117 false,
118 ),
119 AccountMeta::new(
120 Pubkey::from_str_const("4FLYmjhLuUb5ofNBo1PA9enF7HrPUSYUA1t55tUSFYa5"),
121 false,
122 ),
123 AccountMeta::new(
124 Pubkey::from_str_const("5ztadiszGPmBeGVcvmtPyqiHRA8SpU8mqNzPV1WeV88F"),
125 true,
126 ),
127 AccountMeta::new_readonly(
128 Pubkey::from_str_const("11111111111111111111111111111111"),
129 false,
130 ),
131 AccountMeta::new_readonly(
132 Pubkey::from_str_const("TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA"),
133 false,
134 ),
135 AccountMeta::new_readonly(
136 Pubkey::from_str_const("SysvarRent111111111111111111111111111111111"),
137 false,
138 ),
139 AccountMeta::new_readonly(
140 Pubkey::from_str_const("Ce6TQqeHC9p8KetsN6JsjHK7UTZk7nasjjnr7XxXp9F1"),
141 false,
142 ),
143 AccountMeta::new_readonly(
144 Pubkey::from_str_const("6EF8rrecthR5Dkzon8Nwu78hRvfCKubJ14M5uBEwF6P"),
145 false,
146 ),
147 ];
148 let expected_arranged_accounts = buy::BuyInstructionAccounts {
149 global: Pubkey::from_str_const("4wTV1YmiEkRvAtNtsSGPtUrqRYQMe5SKy2uB4Jjaxnjf"),
150 fee_recipient: Pubkey::from_str_const("62qc2CNXwrYqQScmEdiZFFAnJR262PxWEuNQtxfafNgV"),
151 mint: Pubkey::from_str_const("9p1PMtto471A7GvnRJVmDcuqUz3xDd1Lhu8vzrmpump"),
152 bonding_curve: Pubkey::from_str_const("HWxwYxr4AV5ytUyT8pvjCEiUrXhwpbx365VpvQ6Bd6MZ"),
153 associated_bonding_curve: Pubkey::from_str_const(
154 "AUfg9aTAix7YarkHXSBMUyQPCTq55Gg1Z2NTe6utwwzG",
155 ),
156 associated_user: Pubkey::from_str_const("4FLYmjhLuUb5ofNBo1PA9enF7HrPUSYUA1t55tUSFYa5"),
157 user: Pubkey::from_str_const("5ztadiszGPmBeGVcvmtPyqiHRA8SpU8mqNzPV1WeV88F"),
158 system_program: Pubkey::from_str_const("11111111111111111111111111111111"),
159 token_program: Pubkey::from_str_const("TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA"),
160 rent: Pubkey::from_str_const("SysvarRent111111111111111111111111111111111"),
161 event_authority: Pubkey::from_str_const("Ce6TQqeHC9p8KetsN6JsjHK7UTZk7nasjjnr7XxXp9F1"),
162 program: Pubkey::from_str_const("6EF8rrecthR5Dkzon8Nwu78hRvfCKubJ14M5uBEwF6P"),
163 };
164
165 let decoder = PumpfunDecoder;
167 let instruction = carbon_test_utils::read_instruction("tests/fixtures/buy_ix.json")
168 .expect("read fixture");
169 let decoded = decoder
170 .decode_instruction(&instruction)
171 .expect("decode instruction");
172 let decoded_arranged_accounts =
173 buy::Buy::arrange_accounts(&instruction.accounts).expect("aranage accounts");
174
175 assert_eq!(decoded.data, expected_ix);
177 assert_eq!(decoded.accounts, expected_accounts);
178 assert_eq!(decoded.program_id, PROGRAM_ID);
179 assert_eq!(decoded_arranged_accounts, expected_arranged_accounts);
180 }
181
182 #[test]
183 fn test_decode_sell() {
184 let expected_ix = PumpfunInstruction::Sell(sell::Sell {
186 amount: 26705394300,
187 min_sol_output: 724522,
188 });
189 let expected_accounts = vec![
190 AccountMeta::new_readonly(
191 Pubkey::from_str_const("4wTV1YmiEkRvAtNtsSGPtUrqRYQMe5SKy2uB4Jjaxnjf"),
192 false,
193 ),
194 AccountMeta::new(
195 Pubkey::from_str_const("62qc2CNXwrYqQScmEdiZFFAnJR262PxWEuNQtxfafNgV"),
196 false,
197 ),
198 AccountMeta::new_readonly(
199 Pubkey::from_str_const("HXfFC4G1aJJo17KW56jJ2iaDLFXq6T8XZjPbQfhspump"),
200 false,
201 ),
202 AccountMeta::new(
203 Pubkey::from_str_const("8f12Y6z6CkMmcBqduvThRG2V873CP3eu2iBydqKGDX6y"),
204 false,
205 ),
206 AccountMeta::new(
207 Pubkey::from_str_const("GkSscwZJBhcFeB6hpWrnfrE73e5SawPmMuT55U1W4uqz"),
208 false,
209 ),
210 AccountMeta::new(
211 Pubkey::from_str_const("Bi6H7WPrZoJmqSauP38NuBaEttGraZkceR4p17ekoTwh"),
212 false,
213 ),
214 AccountMeta::new(
215 Pubkey::from_str_const("3bApZNQrP3T6Q1GvK1n1nUPHHnpnsbrEmdGyQyYLEbkP"),
216 true,
217 ),
218 AccountMeta::new_readonly(
219 Pubkey::from_str_const("11111111111111111111111111111111"),
220 false,
221 ),
222 AccountMeta::new_readonly(
223 Pubkey::from_str_const("ATokenGPvbdGVxr1b2hvZbsiqW5xWH25efTNsLJA8knL"),
224 false,
225 ),
226 AccountMeta::new_readonly(
227 Pubkey::from_str_const("TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA"),
228 false,
229 ),
230 AccountMeta::new_readonly(
231 Pubkey::from_str_const("Ce6TQqeHC9p8KetsN6JsjHK7UTZk7nasjjnr7XxXp9F1"),
232 false,
233 ),
234 AccountMeta::new_readonly(
235 Pubkey::from_str_const("6EF8rrecthR5Dkzon8Nwu78hRvfCKubJ14M5uBEwF6P"),
236 false,
237 ),
238 ];
239 let expected_arranged_accounts = sell::SellInstructionAccounts {
240 global: Pubkey::from_str_const("4wTV1YmiEkRvAtNtsSGPtUrqRYQMe5SKy2uB4Jjaxnjf"),
241 fee_recipient: Pubkey::from_str_const("62qc2CNXwrYqQScmEdiZFFAnJR262PxWEuNQtxfafNgV"),
242 mint: Pubkey::from_str_const("HXfFC4G1aJJo17KW56jJ2iaDLFXq6T8XZjPbQfhspump"),
243 bonding_curve: Pubkey::from_str_const("8f12Y6z6CkMmcBqduvThRG2V873CP3eu2iBydqKGDX6y"),
244 associated_bonding_curve: Pubkey::from_str_const(
245 "GkSscwZJBhcFeB6hpWrnfrE73e5SawPmMuT55U1W4uqz",
246 ),
247 associated_user: Pubkey::from_str_const("Bi6H7WPrZoJmqSauP38NuBaEttGraZkceR4p17ekoTwh"),
248 user: Pubkey::from_str_const("3bApZNQrP3T6Q1GvK1n1nUPHHnpnsbrEmdGyQyYLEbkP"),
249 system_program: Pubkey::from_str_const("11111111111111111111111111111111"),
250 associated_token_program: Pubkey::from_str_const(
251 "ATokenGPvbdGVxr1b2hvZbsiqW5xWH25efTNsLJA8knL",
252 ),
253 token_program: Pubkey::from_str_const("TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA"),
254 event_authority: Pubkey::from_str_const("Ce6TQqeHC9p8KetsN6JsjHK7UTZk7nasjjnr7XxXp9F1"),
255 program: Pubkey::from_str_const("6EF8rrecthR5Dkzon8Nwu78hRvfCKubJ14M5uBEwF6P"),
256 };
257
258 let decoder = PumpfunDecoder;
260 let instruction = carbon_test_utils::read_instruction("tests/fixtures/sell_ix.json")
261 .expect("read fixture");
262 let decoded = decoder
263 .decode_instruction(&instruction)
264 .expect("decode instruction");
265 let decoded_arranged_accounts =
266 sell::Sell::arrange_accounts(&instruction.accounts).expect("aranage accounts");
267
268 assert_eq!(decoded.data, expected_ix);
270 assert_eq!(decoded.accounts, expected_accounts);
271 assert_eq!(decoded.program_id, PROGRAM_ID);
272 assert_eq!(decoded_arranged_accounts, expected_arranged_accounts);
273 }
274
275 #[test]
276 fn test_decode_create() {
277 let expected_ix = PumpfunInstruction::Create(create::Create {
279 name: "Super Elon Bros ".to_owned(),
280 symbol: "SEB".to_owned(),
281 uri: "https://ipfs.io/ipfs/QmVnjMrWqhMBsmeFnaje87XVxMKY9y7BRL2DtFYJazTGM5".to_owned(),
282 creator: Pubkey::from_str_const("7a9xQF38YVW58TPeHavvXiVpqynCxY2GcohsZxdUZCX1"),
283 });
284 let expected_accounts = vec![
285 AccountMeta::new(
286 Pubkey::from_str_const("5PweXK19JD4PkafHm9BmpgiTaMoQgKq9EXVkDagwpump"),
287 true,
288 ),
289 AccountMeta::new_readonly(
290 Pubkey::from_str_const("TSLvdd1pWpHVjahSpsvCXUbgwsL3JAcvokwaKt1eokM"),
291 false,
292 ),
293 AccountMeta::new(
294 Pubkey::from_str_const("Chau1rGA8w4L43rAMUAKXGwq8hpPfGjUoHsiZJEyziKz"),
295 false,
296 ),
297 AccountMeta::new(
298 Pubkey::from_str_const("7JxriSri8PukwVQ6VQZ6ErpJ3Km1x6eWMnQeJ2Cd2148"),
299 false,
300 ),
301 AccountMeta::new_readonly(
302 Pubkey::from_str_const("4wTV1YmiEkRvAtNtsSGPtUrqRYQMe5SKy2uB4Jjaxnjf"),
303 false,
304 ),
305 AccountMeta::new_readonly(
306 Pubkey::from_str_const("metaqbxxUerdq28cj1RbAWkYQm3ybzjb6a8bt518x1s"),
307 false,
308 ),
309 AccountMeta::new(
310 Pubkey::from_str_const("Dzp1H2K6sNR8VAqXE9Q6eSdZckp7uQSJKR1FKY9SzFoS"),
311 false,
312 ),
313 AccountMeta::new(
314 Pubkey::from_str_const("7a9xQF38YVW58TPeHavvXiVpqynCxY2GcohsZxdUZCX1"),
315 true,
316 ),
317 AccountMeta::new_readonly(
318 Pubkey::from_str_const("11111111111111111111111111111111"),
319 false,
320 ),
321 AccountMeta::new_readonly(
322 Pubkey::from_str_const("TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA"),
323 false,
324 ),
325 AccountMeta::new_readonly(
326 Pubkey::from_str_const("ATokenGPvbdGVxr1b2hvZbsiqW5xWH25efTNsLJA8knL"),
327 false,
328 ),
329 AccountMeta::new_readonly(
330 Pubkey::from_str_const("SysvarRent111111111111111111111111111111111"),
331 false,
332 ),
333 AccountMeta::new_readonly(
334 Pubkey::from_str_const("Ce6TQqeHC9p8KetsN6JsjHK7UTZk7nasjjnr7XxXp9F1"),
335 false,
336 ),
337 AccountMeta::new_readonly(
338 Pubkey::from_str_const("6EF8rrecthR5Dkzon8Nwu78hRvfCKubJ14M5uBEwF6P"),
339 false,
340 ),
341 ];
342 let expected_arranged_accounts = create::CreateInstructionAccounts {
343 mint: Pubkey::from_str_const("5PweXK19JD4PkafHm9BmpgiTaMoQgKq9EXVkDagwpump"),
344 mint_authority: Pubkey::from_str_const("TSLvdd1pWpHVjahSpsvCXUbgwsL3JAcvokwaKt1eokM"),
345 bonding_curve: Pubkey::from_str_const("Chau1rGA8w4L43rAMUAKXGwq8hpPfGjUoHsiZJEyziKz"),
346 associated_bonding_curve: Pubkey::from_str_const(
347 "7JxriSri8PukwVQ6VQZ6ErpJ3Km1x6eWMnQeJ2Cd2148",
348 ),
349 global: Pubkey::from_str_const("4wTV1YmiEkRvAtNtsSGPtUrqRYQMe5SKy2uB4Jjaxnjf"),
350 mpl_token_metadata: Pubkey::from_str_const(
351 "metaqbxxUerdq28cj1RbAWkYQm3ybzjb6a8bt518x1s",
352 ),
353 metadata: Pubkey::from_str_const("Dzp1H2K6sNR8VAqXE9Q6eSdZckp7uQSJKR1FKY9SzFoS"),
354 user: Pubkey::from_str_const("7a9xQF38YVW58TPeHavvXiVpqynCxY2GcohsZxdUZCX1"),
355 system_program: Pubkey::from_str_const("11111111111111111111111111111111"),
356 token_program: Pubkey::from_str_const("TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA"),
357 associated_token_program: Pubkey::from_str_const(
358 "ATokenGPvbdGVxr1b2hvZbsiqW5xWH25efTNsLJA8knL",
359 ),
360 rent: Pubkey::from_str_const("SysvarRent111111111111111111111111111111111"),
361 event_authority: Pubkey::from_str_const("Ce6TQqeHC9p8KetsN6JsjHK7UTZk7nasjjnr7XxXp9F1"),
362 program: Pubkey::from_str_const("6EF8rrecthR5Dkzon8Nwu78hRvfCKubJ14M5uBEwF6P"),
363 };
364
365 let decoder = PumpfunDecoder;
367 let instruction = carbon_test_utils::read_instruction("tests/fixtures/create_ix.json")
368 .expect("read fixture");
369 let decoded = decoder
370 .decode_instruction(&instruction)
371 .expect("decode instruction");
372 let decoded_arranged_accounts =
373 create::Create::arrange_accounts(&instruction.accounts).expect("aranage accounts");
374
375 assert_eq!(decoded.data, expected_ix);
377 assert_eq!(decoded.accounts, expected_accounts);
378 assert_eq!(decoded.program_id, PROGRAM_ID);
379 assert_eq!(decoded_arranged_accounts, expected_arranged_accounts);
380 }
381
382 #[test]
383 fn test_decode_withdraw() {
384 let expected_ix = PumpfunInstruction::Withdraw(withdraw::Withdraw {});
386 let expected_accounts = vec![
387 AccountMeta::new_readonly(
388 Pubkey::from_str_const("4wTV1YmiEkRvAtNtsSGPtUrqRYQMe5SKy2uB4Jjaxnjf"),
389 false,
390 ),
391 AccountMeta::new(
392 Pubkey::from_str_const("EGqbBGXmDA9QYd1XJkf3GDFoerQYeFW3FrQZZXRza9JL"),
393 false,
394 ),
395 AccountMeta::new_readonly(
396 Pubkey::from_str_const("8f8inBUeF6GCPQvN2qxu95uZMTjidZfS2RbYBrFSpump"),
397 false,
398 ),
399 AccountMeta::new(
400 Pubkey::from_str_const("DfcyEVHECKF9U14EzYqxeovufnndbN8qrDurVdJbkUwY"),
401 false,
402 ),
403 AccountMeta::new(
404 Pubkey::from_str_const("EQtzJCRiCpbEmKqZndvCQgGAXCFuGtP2FAZ2HYpH8F6F"),
405 false,
406 ),
407 AccountMeta::new(
408 Pubkey::from_str_const("7ngNZs9Ax61KJ8MKmQKFao73LB4jRRgrg4SZU3YsAbfY"),
409 false,
410 ),
411 AccountMeta::new(
412 Pubkey::from_str_const("39azUYFWPz3VHgKCf3VChUwbpURdCHRxjWVowf5jUJjg"),
413 true,
414 ),
415 AccountMeta::new_readonly(
416 Pubkey::from_str_const("11111111111111111111111111111111"),
417 false,
418 ),
419 AccountMeta::new_readonly(
420 Pubkey::from_str_const("TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA"),
421 false,
422 ),
423 AccountMeta::new_readonly(
424 Pubkey::from_str_const("SysvarRent111111111111111111111111111111111"),
425 false,
426 ),
427 AccountMeta::new_readonly(
428 Pubkey::from_str_const("Ce6TQqeHC9p8KetsN6JsjHK7UTZk7nasjjnr7XxXp9F1"),
429 false,
430 ),
431 AccountMeta::new_readonly(
432 Pubkey::from_str_const("6EF8rrecthR5Dkzon8Nwu78hRvfCKubJ14M5uBEwF6P"),
433 false,
434 ),
435 ];
436 let expected_arranged_accounts = withdraw::WithdrawInstructionAccounts {
437 global: Pubkey::from_str_const("4wTV1YmiEkRvAtNtsSGPtUrqRYQMe5SKy2uB4Jjaxnjf"),
438 last_withdraw: Pubkey::from_str_const("EGqbBGXmDA9QYd1XJkf3GDFoerQYeFW3FrQZZXRza9JL"),
439 mint: Pubkey::from_str_const("8f8inBUeF6GCPQvN2qxu95uZMTjidZfS2RbYBrFSpump"),
440 bonding_curve: Pubkey::from_str_const("DfcyEVHECKF9U14EzYqxeovufnndbN8qrDurVdJbkUwY"),
441 associated_bonding_curve: Pubkey::from_str_const(
442 "EQtzJCRiCpbEmKqZndvCQgGAXCFuGtP2FAZ2HYpH8F6F",
443 ),
444 associated_user: Pubkey::from_str_const("7ngNZs9Ax61KJ8MKmQKFao73LB4jRRgrg4SZU3YsAbfY"),
445 user: Pubkey::from_str_const("39azUYFWPz3VHgKCf3VChUwbpURdCHRxjWVowf5jUJjg"),
446 system_program: Pubkey::from_str_const("11111111111111111111111111111111"),
447 token_program: Pubkey::from_str_const("TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA"),
448 rent: Pubkey::from_str_const("SysvarRent111111111111111111111111111111111"),
449 event_authority: Pubkey::from_str_const("Ce6TQqeHC9p8KetsN6JsjHK7UTZk7nasjjnr7XxXp9F1"),
450 program: Pubkey::from_str_const("6EF8rrecthR5Dkzon8Nwu78hRvfCKubJ14M5uBEwF6P"),
451 };
452
453 let decoder = PumpfunDecoder;
455 let instruction = carbon_test_utils::read_instruction("tests/fixtures/withdraw_ix.json")
456 .expect("read fixture");
457 let decoded = decoder
458 .decode_instruction(&instruction)
459 .expect("decode instruction");
460 let decoded_arranged_accounts =
461 withdraw::Withdraw::arrange_accounts(&instruction.accounts).expect("aranage accounts");
462
463 assert_eq!(decoded.data, expected_ix);
465 assert_eq!(decoded.accounts, expected_accounts);
466 assert_eq!(decoded.program_id, PROGRAM_ID);
467 assert_eq!(decoded_arranged_accounts, expected_arranged_accounts);
468 }
469}