@@ -20,7 +20,9 @@ use spl_token_2022::ID as TOKEN_2022_PROGRAM_ID;
2020use std:: time:: { Duration , SystemTime , UNIX_EPOCH } ;
2121use std:: { collections:: HashMap , error:: Error } ;
2222
23- use crate :: { NativeMintWrappingStrategy , NATIVE_MINT_WRAPPING_STRATEGY } ;
23+ use crate :: {
24+ NativeMintWrappingStrategy , ENFORCE_TOKEN_BALANCE_CHECK , NATIVE_MINT_WRAPPING_STRATEGY ,
25+ } ;
2426
2527#[ derive( Debug , PartialEq , Eq , Hash ) ]
2628pub ( crate ) enum TokenAccountStrategy {
@@ -124,7 +126,8 @@ pub(crate) async fn prepare_token_accounts_instructions(
124126 0
125127 } ;
126128
127- if existing_balance < required_balance {
129+ let enforce_balance_check = * ENFORCE_TOKEN_BALANCE_CHECK . try_lock ( ) ?;
130+ if enforce_balance_check && existing_balance < required_balance {
128131 return Err ( format ! ( "Insufficient balance for mint {}" , mint_addresses[ i] ) . into ( ) ) ;
129132 }
130133 }
@@ -460,10 +463,10 @@ mod tests {
460463
461464 #[ tokio:: test]
462465 #[ serial]
463- async fn test_insufficient_balance ( ) {
466+ async fn test_insufficient_balance_check_not_enforced ( ) {
464467 let ctx = RpcContext :: new ( ) . await ;
465468
466- // Create a mint and token account with small balance using token.rs helpers
469+ // Create a mint and token account with small balance
467470 let mint = setup_mint ( & ctx) . await . unwrap ( ) ;
468471 let initial_amount = 1_000u64 ;
469472 let _ata = setup_ata_with_amount ( & ctx, mint, initial_amount)
@@ -479,12 +482,87 @@ mod tests {
479482 )
480483 . await ;
481484
482- // Should fail due to insufficient balance
485+ // Should succeed because balance checking is disabled
486+ assert ! ( result. is_ok( ) ) ;
487+ }
488+
489+ #[ tokio:: test]
490+ #[ serial]
491+ async fn test_insufficient_balance_check_enforced ( ) {
492+ let ctx = RpcContext :: new ( ) . await ;
493+ crate :: set_enforce_token_balance_check ( true ) . unwrap ( ) ;
494+
495+ // Create a mint and token account with small balance
496+ let mint = setup_mint ( & ctx) . await . unwrap ( ) ;
497+ let initial_amount = 1_000u64 ;
498+ let _ata = setup_ata_with_amount ( & ctx, mint, initial_amount)
499+ . await
500+ . unwrap ( ) ;
501+
502+ // Try to prepare instructions requiring more balance
503+ let required_amount = 2_000u64 ;
504+ let result = prepare_token_accounts_instructions (
505+ & ctx. rpc ,
506+ ctx. signer . pubkey ( ) ,
507+ vec ! [ TokenAccountStrategy :: WithBalance ( mint, required_amount) ] ,
508+ )
509+ . await ;
510+
511+ // Should fail due to insufficient balance when checking is enabled
512+ assert ! ( result. is_err( ) ) ;
513+ assert ! ( result
514+ . unwrap_err( )
515+ . to_string( )
516+ . contains( "Insufficient balance" ) ) ;
517+ crate :: reset_configuration ( ) . unwrap ( ) ;
518+ }
519+
520+ #[ tokio:: test]
521+ #[ serial]
522+ async fn test_nonexistent_token_account_balance_check_not_enforced ( ) {
523+ let ctx = RpcContext :: new ( ) . await ;
524+
525+ // Create a mint but no token account
526+ let mint = setup_mint ( & ctx) . await . unwrap ( ) ;
527+
528+ // Try to prepare instructions requiring balance for non-existent account
529+ let required_amount = 1_000u64 ;
530+ let result = prepare_token_accounts_instructions (
531+ & ctx. rpc ,
532+ ctx. signer . pubkey ( ) ,
533+ vec ! [ TokenAccountStrategy :: WithBalance ( mint, required_amount) ] ,
534+ )
535+ . await ;
536+
537+ // Should succeed because balance checking is disabled
538+ assert ! ( result. is_ok( ) ) ;
539+ }
540+
541+ #[ tokio:: test]
542+ #[ serial]
543+ async fn test_nonexistent_token_account_balance_check_enforced ( ) {
544+ let ctx = RpcContext :: new ( ) . await ;
545+ crate :: set_enforce_token_balance_check ( true ) . unwrap ( ) ;
546+
547+ // Create a mint but no token account
548+ let mint = setup_mint ( & ctx) . await . unwrap ( ) ;
549+
550+ // Try to prepare instructions requiring balance for non-existent account
551+ let required_amount = 1_000u64 ;
552+ let result = prepare_token_accounts_instructions (
553+ & ctx. rpc ,
554+ ctx. signer . pubkey ( ) ,
555+ vec ! [ TokenAccountStrategy :: WithBalance ( mint, required_amount) ] ,
556+ )
557+ . await ;
558+
559+ // Should fail due to insufficient balance (0) when checking is enabled
483560 assert ! ( result. is_err( ) ) ;
484561 assert ! ( result
485562 . unwrap_err( )
486563 . to_string( )
487564 . contains( "Insufficient balance" ) ) ;
565+ crate :: reset_configuration ( ) . unwrap ( ) ;
488566 }
489567
490568 #[ tokio:: test]
0 commit comments