1use crate::PROGRAM_ID;
2
3use super::MoonshotDecoder;
4pub mod buy;
5pub mod config_init;
6pub mod config_update;
7pub mod migrate_funds;
8pub mod migration_event;
9pub mod sell;
10pub mod token_mint;
11pub mod trade_event;
12
13#[derive(
14 carbon_core::InstructionType, serde::Serialize, serde::Deserialize, PartialEq, Eq, Debug, Clone,
15)]
16pub enum MoonshotInstruction {
17 TokenMint(token_mint::TokenMint),
18 Buy(buy::Buy),
19 Sell(sell::Sell),
20 MigrateFunds(migrate_funds::MigrateFunds),
21 ConfigInit(config_init::ConfigInit),
22 ConfigUpdate(config_update::ConfigUpdate),
23 TradeEvent(trade_event::TradeEvent),
24 MigrationEvent(migration_event::MigrationEvent),
25}
26
27impl carbon_core::instruction::InstructionDecoder<'_> for MoonshotDecoder {
28 type InstructionType = MoonshotInstruction;
29
30 fn decode_instruction(
31 &self,
32 instruction: &solana_instruction::Instruction,
33 ) -> Option<carbon_core::instruction::DecodedInstruction<Self::InstructionType>> {
34 if !instruction.program_id.eq(&PROGRAM_ID) {
35 return None;
36 }
37
38 carbon_core::try_decode_instructions!(instruction,
39 MoonshotInstruction::TokenMint => token_mint::TokenMint,
40 MoonshotInstruction::Buy => buy::Buy,
41 MoonshotInstruction::Sell => sell::Sell,
42 MoonshotInstruction::MigrateFunds => migrate_funds::MigrateFunds,
43 MoonshotInstruction::ConfigInit => config_init::ConfigInit,
44 MoonshotInstruction::ConfigUpdate => config_update::ConfigUpdate,
45 MoonshotInstruction::TradeEvent => trade_event::TradeEvent,
46 MoonshotInstruction::MigrationEvent => migration_event::MigrationEvent,
47 )
48 }
49}
50
51#[cfg(test)]
52mod tests {
53 use alloc::{string::ToString, vec};
54 use carbon_core::{
55 deserialize::{ArrangeAccounts, PrefixString},
56 instruction::InstructionDecoder,
57 };
58 use solana_instruction::AccountMeta;
59
60 use crate::types::{TokenMintParams, TradeParams};
61
62 use super::*;
63
64 #[test]
65 fn test_decode_token_mint() {
66 let expected_ix = MoonshotInstruction::TokenMint(token_mint::TokenMint {
68 mint_params: TokenMintParams {
69 name: PrefixString("Gamestop".to_string()),
70 symbol: PrefixString("$GME".to_string()),
71 uri: PrefixString(
72 "https://cdn.dexscreener.com/cms/tokens/metadata/UgnNvayhAu8K97aoT3B8"
73 .to_string(),
74 ),
75 decimals: 9,
76 collateral_currency: 0,
77 amount: 1000000000000000000,
78 curve_type: 1,
79 migration_target: 0,
80 ..TokenMintParams::default()
81 },
82 });
83 let expected_accounts = vec![
84 AccountMeta::new(
85 solana_pubkey::Pubkey::from_str_const(
86 "AiG8HZSRociZpmHGmFnHQ3eQvFxVq4HUwxXcZKZJaEr1",
87 ),
88 true,
89 ),
90 AccountMeta::new_readonly(
91 solana_pubkey::Pubkey::from_str_const(
92 "Cb8Fnhp95f9dLxB3sYkNCbN3Mjxuc3v2uQZ7uVeqvNGB",
93 ),
94 true,
95 ),
96 AccountMeta::new(
97 solana_pubkey::Pubkey::from_str_const(
98 "ALPoEBuBD9GMWRQrMmWd81By5GCH8X9i9HiPWBf68n8C",
99 ),
100 false,
101 ),
102 AccountMeta::new(
103 solana_pubkey::Pubkey::from_str_const(
104 "HkzfucJHWykNPSpKpduLVg2j45zafYhA1G51xPLumoon",
105 ),
106 true,
107 ),
108 AccountMeta::new(
109 solana_pubkey::Pubkey::from_str_const(
110 "Do7VSKZ6yz1eJMg5N8GpZ5Me12jfXVTTaWTi6tgo3vFr",
111 ),
112 false,
113 ),
114 AccountMeta::new(
115 solana_pubkey::Pubkey::from_str_const(
116 "6oGTJKhWPZQ1ixiguEDvbHQJLizqUmbyL9isRvNUEGR",
117 ),
118 false,
119 ),
120 AccountMeta::new_readonly(
121 solana_pubkey::Pubkey::from_str_const(
122 "36Eru7v11oU5Pfrojyn5oY3nETA1a1iqsw2WUu6afkM9",
123 ),
124 false,
125 ),
126 AccountMeta::new_readonly(
127 solana_pubkey::Pubkey::from_str_const(
128 "TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA",
129 ),
130 false,
131 ),
132 AccountMeta::new_readonly(
133 solana_pubkey::Pubkey::from_str_const(
134 "ATokenGPvbdGVxr1b2hvZbsiqW5xWH25efTNsLJA8knL",
135 ),
136 false,
137 ),
138 AccountMeta::new_readonly(
139 solana_pubkey::Pubkey::from_str_const(
140 "metaqbxxUerdq28cj1RbAWkYQm3ybzjb6a8bt518x1s",
141 ),
142 false,
143 ),
144 AccountMeta::new_readonly(
145 solana_pubkey::Pubkey::from_str_const("11111111111111111111111111111111"),
146 false,
147 ),
148 ];
149 let expected_arranged_accounts = token_mint::TokenMintInstructionAccounts {
150 sender: solana_pubkey::Pubkey::from_str_const(
151 "AiG8HZSRociZpmHGmFnHQ3eQvFxVq4HUwxXcZKZJaEr1",
152 ),
153 backend_authority: solana_pubkey::Pubkey::from_str_const(
154 "Cb8Fnhp95f9dLxB3sYkNCbN3Mjxuc3v2uQZ7uVeqvNGB",
155 ),
156 curve_account: solana_pubkey::Pubkey::from_str_const(
157 "ALPoEBuBD9GMWRQrMmWd81By5GCH8X9i9HiPWBf68n8C",
158 ),
159 mint: solana_pubkey::Pubkey::from_str_const(
160 "HkzfucJHWykNPSpKpduLVg2j45zafYhA1G51xPLumoon",
161 ),
162 mint_metadata: solana_pubkey::Pubkey::from_str_const(
163 "Do7VSKZ6yz1eJMg5N8GpZ5Me12jfXVTTaWTi6tgo3vFr",
164 ),
165 curve_token_account: solana_pubkey::Pubkey::from_str_const(
166 "6oGTJKhWPZQ1ixiguEDvbHQJLizqUmbyL9isRvNUEGR",
167 ),
168 config_account: solana_pubkey::Pubkey::from_str_const(
169 "36Eru7v11oU5Pfrojyn5oY3nETA1a1iqsw2WUu6afkM9",
170 ),
171 token_program: solana_pubkey::Pubkey::from_str_const(
172 "TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA",
173 ),
174 associated_token_program: solana_pubkey::Pubkey::from_str_const(
175 "ATokenGPvbdGVxr1b2hvZbsiqW5xWH25efTNsLJA8knL",
176 ),
177 mpl_token_metadata: solana_pubkey::Pubkey::from_str_const(
178 "metaqbxxUerdq28cj1RbAWkYQm3ybzjb6a8bt518x1s",
179 ),
180 system_program: solana_pubkey::Pubkey::from_str_const(
181 "11111111111111111111111111111111",
182 ),
183 };
184
185 let decoder = MoonshotDecoder;
187 let instruction = carbon_test_utils::read_instruction("tests/fixtures/token_mint_ix.json")
188 .expect("read fixture");
189 let decoded = decoder
190 .decode_instruction(&instruction)
191 .expect("decode instruction");
192 let decoded_arranged_accounts =
193 token_mint::TokenMint::arrange_accounts(&instruction.accounts)
194 .expect("aranage accounts");
195
196 assert_eq!(decoded.data, expected_ix);
198 assert_eq!(decoded.accounts, expected_accounts);
199 assert_eq!(decoded.program_id, PROGRAM_ID);
200 assert_eq!(decoded_arranged_accounts, expected_arranged_accounts);
201 }
202
203 #[test]
204 fn test_decode_buy() {
205 let expected_ix = MoonshotInstruction::Buy(buy::Buy {
207 data: TradeParams {
208 token_amount: 5430576418647,
209 collateral_amount: 1640000,
210 fixed_side: 1,
211 slippage_bps: 9999,
212 },
213 });
214 let expected_accounts = vec![
215 AccountMeta::new(
216 solana_pubkey::Pubkey::from_str_const(
217 "Ezug1uk7oTEULvBcXCngdZuJDmZ8Ed2TKY4oov4GmLLm",
218 ),
219 true,
220 ),
221 AccountMeta::new(
222 solana_pubkey::Pubkey::from_str_const(
223 "6FqNPPA4W1nuvL1BHGhusSHjdNa4qJBoXyRKggAh9pb9",
224 ),
225 false,
226 ),
227 AccountMeta::new(
228 solana_pubkey::Pubkey::from_str_const(
229 "4CYhuDhT4c9ATZpJceoQG8Du4vCjf5ZKvxsyXpJoVub4",
230 ),
231 false,
232 ),
233 AccountMeta::new(
234 solana_pubkey::Pubkey::from_str_const(
235 "5Zg9kJdzYFKwS4hLzF1QvvNBYyUNpn9YWxYp6HVMknJt",
236 ),
237 false,
238 ),
239 AccountMeta::new(
240 solana_pubkey::Pubkey::from_str_const(
241 "3udvfL24waJcLhskRAsStNMoNUvtyXdxrWQz4hgi953N",
242 ),
243 false,
244 ),
245 AccountMeta::new(
246 solana_pubkey::Pubkey::from_str_const(
247 "5K5RtTWzzLp4P8Npi84ocf7F1vBsAu29N1irG4iiUnzt",
248 ),
249 false,
250 ),
251 AccountMeta::new_readonly(
252 solana_pubkey::Pubkey::from_str_const(
253 "3cBFsM1wosTJi9yun6kcHhYHyJcut1MNQY28zjC4moon",
254 ),
255 false,
256 ),
257 AccountMeta::new_readonly(
258 solana_pubkey::Pubkey::from_str_const(
259 "36Eru7v11oU5Pfrojyn5oY3nETA1a1iqsw2WUu6afkM9",
260 ),
261 false,
262 ),
263 AccountMeta::new_readonly(
264 solana_pubkey::Pubkey::from_str_const(
265 "TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA",
266 ),
267 false,
268 ),
269 AccountMeta::new_readonly(
270 solana_pubkey::Pubkey::from_str_const(
271 "ATokenGPvbdGVxr1b2hvZbsiqW5xWH25efTNsLJA8knL",
272 ),
273 false,
274 ),
275 AccountMeta::new_readonly(
276 solana_pubkey::Pubkey::from_str_const("11111111111111111111111111111111"),
277 false,
278 ),
279 ];
280 let expected_arranged_accounts = buy::BuyInstructionAccounts {
281 sender: solana_pubkey::Pubkey::from_str_const(
282 "Ezug1uk7oTEULvBcXCngdZuJDmZ8Ed2TKY4oov4GmLLm",
283 ),
284 sender_token_account: solana_pubkey::Pubkey::from_str_const(
285 "6FqNPPA4W1nuvL1BHGhusSHjdNa4qJBoXyRKggAh9pb9",
286 ),
287 curve_account: solana_pubkey::Pubkey::from_str_const(
288 "4CYhuDhT4c9ATZpJceoQG8Du4vCjf5ZKvxsyXpJoVub4",
289 ),
290 curve_token_account: solana_pubkey::Pubkey::from_str_const(
291 "5Zg9kJdzYFKwS4hLzF1QvvNBYyUNpn9YWxYp6HVMknJt",
292 ),
293 dex_fee: solana_pubkey::Pubkey::from_str_const(
294 "3udvfL24waJcLhskRAsStNMoNUvtyXdxrWQz4hgi953N",
295 ),
296 helio_fee: solana_pubkey::Pubkey::from_str_const(
297 "5K5RtTWzzLp4P8Npi84ocf7F1vBsAu29N1irG4iiUnzt",
298 ),
299 mint: solana_pubkey::Pubkey::from_str_const(
300 "3cBFsM1wosTJi9yun6kcHhYHyJcut1MNQY28zjC4moon",
301 ),
302 config_account: solana_pubkey::Pubkey::from_str_const(
303 "36Eru7v11oU5Pfrojyn5oY3nETA1a1iqsw2WUu6afkM9",
304 ),
305 token_program: solana_pubkey::Pubkey::from_str_const(
306 "TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA",
307 ),
308 associated_token_program: solana_pubkey::Pubkey::from_str_const(
309 "ATokenGPvbdGVxr1b2hvZbsiqW5xWH25efTNsLJA8knL",
310 ),
311 system_program: solana_pubkey::Pubkey::from_str_const(
312 "11111111111111111111111111111111",
313 ),
314 };
315
316 let decoder = MoonshotDecoder;
318 let instruction = carbon_test_utils::read_instruction("tests/fixtures/buy_ix.json")
319 .expect("read fixture");
320 let decoded = decoder
321 .decode_instruction(&instruction)
322 .expect("decode instruction");
323 let decoded_arranged_accounts =
324 buy::Buy::arrange_accounts(&instruction.accounts).expect("aranage accounts");
325
326 assert_eq!(decoded.data, expected_ix);
328 assert_eq!(decoded.accounts, expected_accounts);
329 assert_eq!(decoded.program_id, PROGRAM_ID);
330 assert_eq!(decoded_arranged_accounts, expected_arranged_accounts);
331 }
332
333 #[test]
334 fn test_decode_sell() {
335 let expected_ix = MoonshotInstruction::Sell(sell::Sell {
337 data: TradeParams {
338 token_amount: 157227000000000,
339 collateral_amount: 20990579,
340 fixed_side: 0,
341 slippage_bps: 100,
342 },
343 });
344 let expected_accounts = vec![
345 AccountMeta::new(
346 solana_pubkey::Pubkey::from_str_const(
347 "93fdoNBQF6t7aBPuPv3SGGpXyWmJVfvWPpPsBXrGqEK7",
348 ),
349 true,
350 ),
351 AccountMeta::new(
352 solana_pubkey::Pubkey::from_str_const(
353 "H4QJQ3mm865pMW7Ufvq6BiSXn2P8xUCv2xFd1sWYpmmK",
354 ),
355 false,
356 ),
357 AccountMeta::new(
358 solana_pubkey::Pubkey::from_str_const(
359 "DnTTm5JdDoZS9pY5JxxJJ9LUQx5L3MmcR5DdvHyEDruQ",
360 ),
361 false,
362 ),
363 AccountMeta::new(
364 solana_pubkey::Pubkey::from_str_const(
365 "FNkJw68x21iyHrbA7yyUYyzFMmtdsNzxHWy7WwnaorEd",
366 ),
367 false,
368 ),
369 AccountMeta::new(
370 solana_pubkey::Pubkey::from_str_const(
371 "3udvfL24waJcLhskRAsStNMoNUvtyXdxrWQz4hgi953N",
372 ),
373 false,
374 ),
375 AccountMeta::new(
376 solana_pubkey::Pubkey::from_str_const(
377 "5K5RtTWzzLp4P8Npi84ocf7F1vBsAu29N1irG4iiUnzt",
378 ),
379 false,
380 ),
381 AccountMeta::new_readonly(
382 solana_pubkey::Pubkey::from_str_const(
383 "3hrY3mte6rpea8UDSm4Be6D1sUJyLyLpGxFfRBvVmoon",
384 ),
385 false,
386 ),
387 AccountMeta::new_readonly(
388 solana_pubkey::Pubkey::from_str_const(
389 "36Eru7v11oU5Pfrojyn5oY3nETA1a1iqsw2WUu6afkM9",
390 ),
391 false,
392 ),
393 AccountMeta::new_readonly(
394 solana_pubkey::Pubkey::from_str_const(
395 "TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA",
396 ),
397 false,
398 ),
399 AccountMeta::new_readonly(
400 solana_pubkey::Pubkey::from_str_const(
401 "ATokenGPvbdGVxr1b2hvZbsiqW5xWH25efTNsLJA8knL",
402 ),
403 false,
404 ),
405 AccountMeta::new_readonly(
406 solana_pubkey::Pubkey::from_str_const("11111111111111111111111111111111"),
407 false,
408 ),
409 ];
410 let expected_arranged_accounts = sell::SellInstructionAccounts {
411 sender: solana_pubkey::Pubkey::from_str_const(
412 "93fdoNBQF6t7aBPuPv3SGGpXyWmJVfvWPpPsBXrGqEK7",
413 ),
414 sender_token_account: solana_pubkey::Pubkey::from_str_const(
415 "H4QJQ3mm865pMW7Ufvq6BiSXn2P8xUCv2xFd1sWYpmmK",
416 ),
417 curve_account: solana_pubkey::Pubkey::from_str_const(
418 "DnTTm5JdDoZS9pY5JxxJJ9LUQx5L3MmcR5DdvHyEDruQ",
419 ),
420 curve_token_account: solana_pubkey::Pubkey::from_str_const(
421 "FNkJw68x21iyHrbA7yyUYyzFMmtdsNzxHWy7WwnaorEd",
422 ),
423 dex_fee: solana_pubkey::Pubkey::from_str_const(
424 "3udvfL24waJcLhskRAsStNMoNUvtyXdxrWQz4hgi953N",
425 ),
426 helio_fee: solana_pubkey::Pubkey::from_str_const(
427 "5K5RtTWzzLp4P8Npi84ocf7F1vBsAu29N1irG4iiUnzt",
428 ),
429 mint: solana_pubkey::Pubkey::from_str_const(
430 "3hrY3mte6rpea8UDSm4Be6D1sUJyLyLpGxFfRBvVmoon",
431 ),
432 config_account: solana_pubkey::Pubkey::from_str_const(
433 "36Eru7v11oU5Pfrojyn5oY3nETA1a1iqsw2WUu6afkM9",
434 ),
435 token_program: solana_pubkey::Pubkey::from_str_const(
436 "TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA",
437 ),
438 associated_token_program: solana_pubkey::Pubkey::from_str_const(
439 "ATokenGPvbdGVxr1b2hvZbsiqW5xWH25efTNsLJA8knL",
440 ),
441 system_program: solana_pubkey::Pubkey::from_str_const(
442 "11111111111111111111111111111111",
443 ),
444 };
445
446 let decoder = MoonshotDecoder;
448 let instruction = carbon_test_utils::read_instruction("tests/fixtures/sell_ix.json")
449 .expect("read fixture");
450 let decoded = decoder
451 .decode_instruction(&instruction)
452 .expect("decode instruction");
453 let decoded_arranged_accounts =
454 sell::Sell::arrange_accounts(&instruction.accounts).expect("aranage accounts");
455
456 assert_eq!(decoded.data, expected_ix);
458 assert_eq!(decoded.accounts, expected_accounts);
459 assert_eq!(decoded.program_id, PROGRAM_ID);
460 assert_eq!(decoded_arranged_accounts, expected_arranged_accounts);
461 }
462
463 #[test]
464 fn test_decode_migrate_funds() {
465 let expected_ix = MoonshotInstruction::MigrateFunds(migrate_funds::MigrateFunds {});
467 let expected_accounts = vec![
468 AccountMeta::new_readonly(
469 solana_pubkey::Pubkey::from_str_const(
470 "Cb8Fnhp95f9dLxB3sYkNCbN3Mjxuc3v2uQZ7uVeqvNGB",
471 ),
472 true,
473 ),
474 AccountMeta::new(
475 solana_pubkey::Pubkey::from_str_const(
476 "CGsqR7CTqTwbmAUTPnfg9Bj9GLJgkrUD9rhjh3vHEYvh",
477 ),
478 true,
479 ),
480 AccountMeta::new(
481 solana_pubkey::Pubkey::from_str_const(
482 "AwxvCNVa16VfZZdxtSZ2DJ8VDQ17J27FYMMJc9KoWkZt",
483 ),
484 false,
485 ),
486 AccountMeta::new(
487 solana_pubkey::Pubkey::from_str_const(
488 "5JKuvPWQuYXAvvkCs7cvBFgmUdhPbaTW3ii7zGPknnHW",
489 ),
490 false,
491 ),
492 AccountMeta::new(
493 solana_pubkey::Pubkey::from_str_const(
494 "HzxySmjxfbV8nthWw7qogXZ9qH4LFUxSZVpU91n48xFf",
495 ),
496 false,
497 ),
498 AccountMeta::new(
499 solana_pubkey::Pubkey::from_str_const(
500 "5JZUMLtHBzG4PaQ6UAhVWnh2pZ1BMMKRWWpCbMxxe148",
501 ),
502 false,
503 ),
504 AccountMeta::new(
505 solana_pubkey::Pubkey::from_str_const(
506 "3udvfL24waJcLhskRAsStNMoNUvtyXdxrWQz4hgi953N",
507 ),
508 false,
509 ),
510 AccountMeta::new(
511 solana_pubkey::Pubkey::from_str_const(
512 "5K5RtTWzzLp4P8Npi84ocf7F1vBsAu29N1irG4iiUnzt",
513 ),
514 false,
515 ),
516 AccountMeta::new_readonly(
517 solana_pubkey::Pubkey::from_str_const(
518 "36Eru7v11oU5Pfrojyn5oY3nETA1a1iqsw2WUu6afkM9",
519 ),
520 false,
521 ),
522 AccountMeta::new_readonly(
523 solana_pubkey::Pubkey::from_str_const("11111111111111111111111111111111"),
524 false,
525 ),
526 AccountMeta::new_readonly(
527 solana_pubkey::Pubkey::from_str_const(
528 "TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA",
529 ),
530 false,
531 ),
532 AccountMeta::new_readonly(
533 solana_pubkey::Pubkey::from_str_const(
534 "ATokenGPvbdGVxr1b2hvZbsiqW5xWH25efTNsLJA8knL",
535 ),
536 false,
537 ),
538 ];
539 let expected_arranged_accounts = migrate_funds::MigrateFundsInstructionAccounts {
540 backend_authority: solana_pubkey::Pubkey::from_str_const(
541 "Cb8Fnhp95f9dLxB3sYkNCbN3Mjxuc3v2uQZ7uVeqvNGB",
542 ),
543 migration_authority: solana_pubkey::Pubkey::from_str_const(
544 "CGsqR7CTqTwbmAUTPnfg9Bj9GLJgkrUD9rhjh3vHEYvh",
545 ),
546 curve_account: solana_pubkey::Pubkey::from_str_const(
547 "AwxvCNVa16VfZZdxtSZ2DJ8VDQ17J27FYMMJc9KoWkZt",
548 ),
549 curve_token_account: solana_pubkey::Pubkey::from_str_const(
550 "5JKuvPWQuYXAvvkCs7cvBFgmUdhPbaTW3ii7zGPknnHW",
551 ),
552 migration_authority_token_account: solana_pubkey::Pubkey::from_str_const(
553 "HzxySmjxfbV8nthWw7qogXZ9qH4LFUxSZVpU91n48xFf",
554 ),
555 mint: solana_pubkey::Pubkey::from_str_const(
556 "5JZUMLtHBzG4PaQ6UAhVWnh2pZ1BMMKRWWpCbMxxe148",
557 ),
558 dex_fee_account: solana_pubkey::Pubkey::from_str_const(
559 "3udvfL24waJcLhskRAsStNMoNUvtyXdxrWQz4hgi953N",
560 ),
561 helio_fee_account: solana_pubkey::Pubkey::from_str_const(
562 "5K5RtTWzzLp4P8Npi84ocf7F1vBsAu29N1irG4iiUnzt",
563 ),
564 config_account: solana_pubkey::Pubkey::from_str_const(
565 "36Eru7v11oU5Pfrojyn5oY3nETA1a1iqsw2WUu6afkM9",
566 ),
567 system_program: solana_pubkey::Pubkey::from_str_const(
568 "11111111111111111111111111111111",
569 ),
570 token_program: solana_pubkey::Pubkey::from_str_const(
571 "TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA",
572 ),
573 associated_token_program: solana_pubkey::Pubkey::from_str_const(
574 "ATokenGPvbdGVxr1b2hvZbsiqW5xWH25efTNsLJA8knL",
575 ),
576 };
577
578 let decoder = MoonshotDecoder;
580 let instruction =
581 carbon_test_utils::read_instruction("tests/fixtures/migrate_funds_ix.json")
582 .expect("read fixture");
583 let decoded = decoder
584 .decode_instruction(&instruction)
585 .expect("decode instruction");
586 let decoded_arranged_accounts =
587 migrate_funds::MigrateFunds::arrange_accounts(&instruction.accounts)
588 .expect("aranage accounts");
589
590 assert_eq!(decoded.data, expected_ix);
592 assert_eq!(decoded.accounts, expected_accounts);
593 assert_eq!(decoded.program_id, PROGRAM_ID);
594 assert_eq!(decoded_arranged_accounts, expected_arranged_accounts);
595 }
596}