|
66 | 66 | instruction::AssociatedTokenAccountInstruction,
|
67 | 67 | },
|
68 | 68 | spl_token::instruction::TokenInstruction,
|
| 69 | + spl_token_2022::instruction::TokenInstruction as Token2022Instruction, |
69 | 70 | std::{
|
70 | 71 | array,
|
71 | 72 | collections::VecDeque,
|
@@ -331,6 +332,20 @@ impl Service {
|
331 | 332 | ix_parsed
|
332 | 333 | ))),
|
333 | 334 | }
|
| 335 | + } else if *program_id == spl_token_2022::id() { |
| 336 | + let ix_parsed = Token2022Instruction::unpack(&ix.data) |
| 337 | + .map_err(InstructionError::InvalidSplTokenInstruction)?; |
| 338 | + match ix_parsed { |
| 339 | + // approve token program close account instructions |
| 340 | + Token2022Instruction::CloseAccount { .. } => Ok(()), |
| 341 | + // approve token program sync native (for WSOL) instructions |
| 342 | + Token2022Instruction::SyncNative { .. } => Ok(()), |
| 343 | + // other token program instructions are not approved |
| 344 | + _ => Err(InstructionError::UnsupportedSplTokenInstruction(format!( |
| 345 | + "{:?}", |
| 346 | + ix_parsed |
| 347 | + ))), |
| 348 | + } |
334 | 349 | } else if *program_id == spl_associated_token_account::id() {
|
335 | 350 | let ix_parsed =
|
336 | 351 | AssociatedTokenAccountInstruction::try_from_slice(&ix.data).map_err(|e| {
|
@@ -530,6 +545,7 @@ impl Service {
|
530 | 545 | Ok(result)
|
531 | 546 | }
|
532 | 547 |
|
| 548 | + /// TODO: need to adapt this to allow all transfers not including user account |
533 | 549 | async fn check_transfer_instruction(
|
534 | 550 | &self,
|
535 | 551 | tx: &VersionedTransaction,
|
@@ -2492,6 +2508,136 @@ mod tests {
|
2492 | 2508 | }
|
2493 | 2509 | }
|
2494 | 2510 |
|
| 2511 | + #[tokio::test] |
| 2512 | + async fn test_check_approved_program_when_unsupported_token_2022_instruction() { |
| 2513 | + let (service, opportunities) = get_service(true); |
| 2514 | + let opportunity = opportunities.user_token_specified.clone(); |
| 2515 | + let bid_amount = 1; |
| 2516 | + let searcher = Keypair::new(); |
| 2517 | + let swap_instruction = svm::Svm::get_swap_instruction(GetSwapInstructionParams { |
| 2518 | + searcher: searcher.pubkey(), |
| 2519 | + opportunity_params: get_opportunity_params(opportunity.clone()), |
| 2520 | + bid_amount, |
| 2521 | + deadline: (OffsetDateTime::now_utc() + Duration::seconds(30)).unix_timestamp(), |
| 2522 | + fee_receiver_relayer: Pubkey::new_unique(), |
| 2523 | + relayer_signer: service.config.chain_config.express_relay.relayer.pubkey(), |
| 2524 | + }) |
| 2525 | + .unwrap(); |
| 2526 | + let instructions = vec![ |
| 2527 | + spl_token_2022::instruction::initialize_account( |
| 2528 | + &spl_token_2022::id(), |
| 2529 | + &Pubkey::new_unique(), |
| 2530 | + &Pubkey::new_unique(), |
| 2531 | + &Pubkey::new_unique(), |
| 2532 | + ) |
| 2533 | + .unwrap(), |
| 2534 | + spl_token_2022::instruction::initialize_account2( |
| 2535 | + &spl_token_2022::id(), |
| 2536 | + &Pubkey::new_unique(), |
| 2537 | + &Pubkey::new_unique(), |
| 2538 | + &Pubkey::new_unique(), |
| 2539 | + ) |
| 2540 | + .unwrap(), |
| 2541 | + spl_token_2022::instruction::initialize_account3( |
| 2542 | + &spl_token_2022::id(), |
| 2543 | + &Pubkey::new_unique(), |
| 2544 | + &Pubkey::new_unique(), |
| 2545 | + &Pubkey::new_unique(), |
| 2546 | + ) |
| 2547 | + .unwrap(), |
| 2548 | + spl_token_2022::instruction::initialize_mint( |
| 2549 | + &spl_token_2022::id(), |
| 2550 | + &Pubkey::new_unique(), |
| 2551 | + &Pubkey::new_unique(), |
| 2552 | + None, |
| 2553 | + 0, |
| 2554 | + ) |
| 2555 | + .unwrap(), |
| 2556 | + spl_token_2022::instruction::initialize_mint2( |
| 2557 | + &spl_token_2022::id(), |
| 2558 | + &Pubkey::new_unique(), |
| 2559 | + &Pubkey::new_unique(), |
| 2560 | + None, |
| 2561 | + 0, |
| 2562 | + ) |
| 2563 | + .unwrap(), |
| 2564 | + spl_token_2022::instruction::transfer_checked( |
| 2565 | + &spl_token_2022::id(), |
| 2566 | + &Pubkey::new_unique(), |
| 2567 | + &Pubkey::new_unique(), |
| 2568 | + &Pubkey::new_unique(), |
| 2569 | + &Pubkey::new_unique(), |
| 2570 | + &[], |
| 2571 | + 0, |
| 2572 | + 0, |
| 2573 | + ) |
| 2574 | + .unwrap(), |
| 2575 | + spl_token_2022::instruction::approve( |
| 2576 | + &spl_token_2022::id(), |
| 2577 | + &Pubkey::new_unique(), |
| 2578 | + &Pubkey::new_unique(), |
| 2579 | + &Pubkey::new_unique(), |
| 2580 | + &[], |
| 2581 | + 0, |
| 2582 | + ) |
| 2583 | + .unwrap(), |
| 2584 | + spl_token_2022::instruction::revoke( |
| 2585 | + &spl_token_2022::id(), |
| 2586 | + &Pubkey::new_unique(), |
| 2587 | + &Pubkey::new_unique(), |
| 2588 | + &[], |
| 2589 | + ) |
| 2590 | + .unwrap(), |
| 2591 | + spl_token_2022::instruction::set_authority( |
| 2592 | + &spl_token_2022::id(), |
| 2593 | + &Pubkey::new_unique(), |
| 2594 | + None, |
| 2595 | + spl_token_2022::instruction::AuthorityType::AccountOwner, |
| 2596 | + &Pubkey::new_unique(), |
| 2597 | + &[], |
| 2598 | + ) |
| 2599 | + .unwrap(), |
| 2600 | + spl_token_2022::instruction::mint_to( |
| 2601 | + &spl_token_2022::id(), |
| 2602 | + &Pubkey::new_unique(), |
| 2603 | + &Pubkey::new_unique(), |
| 2604 | + &Pubkey::new_unique(), |
| 2605 | + &[], |
| 2606 | + 0, |
| 2607 | + ) |
| 2608 | + .unwrap(), |
| 2609 | + spl_token_2022::instruction::burn( |
| 2610 | + &spl_token_2022::id(), |
| 2611 | + &Pubkey::new_unique(), |
| 2612 | + &Pubkey::new_unique(), |
| 2613 | + &Pubkey::new_unique(), |
| 2614 | + &[], |
| 2615 | + 0, |
| 2616 | + ) |
| 2617 | + .unwrap(), |
| 2618 | + ]; |
| 2619 | + for instruction in instructions.into_iter() { |
| 2620 | + let data = instruction.data.clone(); |
| 2621 | + let ix_parsed = TokenInstruction::unpack(&data).unwrap(); |
| 2622 | + let program_id = instruction.program_id; |
| 2623 | + let transaction = Transaction::new_with_payer( |
| 2624 | + &[instruction.clone(), swap_instruction.clone()], |
| 2625 | + Some(&searcher.pubkey()), |
| 2626 | + ); |
| 2627 | + let instruction = transaction |
| 2628 | + .message() |
| 2629 | + .instructions |
| 2630 | + .first() |
| 2631 | + .expect("Expected at least one instruction") |
| 2632 | + .clone(); |
| 2633 | + let result = service.check_approved_program_instruction(&program_id, &instruction); |
| 2634 | + assert_eq!( |
| 2635 | + result.unwrap_err(), |
| 2636 | + InstructionError::UnsupportedSplTokenInstruction(format!("{:?}", ix_parsed)) |
| 2637 | + ); |
| 2638 | + } |
| 2639 | + } |
| 2640 | + |
2495 | 2641 | #[tokio::test]
|
2496 | 2642 | async fn test_check_approved_program_when_unsupported_associated_token_account_instruction() {
|
2497 | 2643 | let (service, opportunities) = get_service(true);
|
|
0 commit comments