carbon_pumpfun_decoder/instructions/
mod.rs

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        // Arrange
94        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        // Act
166        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
176        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        // Arrange
185        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        // Act
259        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
269        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        // Arrange
278        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        // Act
366        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
376        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        // Arrange
385        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        // Act
454        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
464        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}