@@ -78,11 +78,11 @@ impl Processor {
78
78
account. delegated_amount = 0 ;
79
79
account. state = AccountState :: Initialized ;
80
80
if * mint_info. key == crate :: native_mint:: id ( ) {
81
- account . is_native = true ;
82
- account. amount = new_account_info . lamports ( ) ;
83
- account. rent_exempt_reserve = rent . minimum_balance ( new_account_info_data_len ) ;
81
+ let rent_exempt_reserve = rent . minimum_balance ( new_account_info_data_len ) ;
82
+ account. is_native = COption :: Some ( rent_exempt_reserve ) ;
83
+ account. amount = new_account_info . lamports ( ) - rent_exempt_reserve ;
84
84
} else {
85
- account. is_native = false ;
85
+ account. is_native = COption :: None ;
86
86
account. amount = 0 ;
87
87
} ;
88
88
@@ -183,11 +183,7 @@ impl Processor {
183
183
. checked_add ( amount)
184
184
. ok_or ( TokenError :: Overflow ) ?;
185
185
186
- if source_account. is_native {
187
- // Ensure that wrapped SOL accounts remain rent-exempt
188
- if source_account_info. lamports ( ) < source_account. rent_exempt_reserve + amount {
189
- return Err ( TokenError :: InsufficientFunds . into ( ) ) ;
190
- }
186
+ if source_account. is_native ( ) {
191
187
* * source_account_info. lamports . borrow_mut ( ) -= amount;
192
188
* * dest_account_info. lamports . borrow_mut ( ) += amount;
193
189
}
@@ -362,7 +358,7 @@ impl Processor {
362
358
return Err ( TokenError :: AccountFrozen . into ( ) ) ;
363
359
}
364
360
365
- if dest_account. is_native {
361
+ if dest_account. is_native ( ) {
366
362
return Err ( TokenError :: NativeNotSupported . into ( ) ) ;
367
363
}
368
364
if mint_info. key != & dest_account. mint {
@@ -407,7 +403,7 @@ impl Processor {
407
403
let mut source_data = source_account_info. data . borrow_mut ( ) ;
408
404
let source_account: & mut Account = state:: unpack ( & mut source_data) ?;
409
405
410
- if source_account. is_native {
406
+ if source_account. is_native ( ) {
411
407
return Err ( TokenError :: NativeNotSupported . into ( ) ) ;
412
408
}
413
409
if source_account. amount < amount {
@@ -457,7 +453,7 @@ impl Processor {
457
453
let mut source_data = source_account_info. data . borrow_mut ( ) ;
458
454
let source_account: & mut Account = state:: unpack ( & mut source_data) ?;
459
455
460
- if !source_account. is_native && source_account. amount != 0 {
456
+ if !source_account. is_native ( ) && source_account. amount != 0 {
461
457
return Err ( TokenError :: NonNativeHasBalance . into ( ) ) ;
462
458
}
463
459
@@ -493,7 +489,7 @@ impl Processor {
493
489
let mut source_data = source_account_info. data . borrow_mut ( ) ;
494
490
let source_account: & mut Account = state:: unpack ( & mut source_data) ?;
495
491
496
- if source_account. is_native {
492
+ if source_account. is_native ( ) {
497
493
return Err ( TokenError :: NativeNotSupported . into ( ) ) ;
498
494
}
499
495
if mint_info. key != & source_account. mint {
@@ -2626,8 +2622,11 @@ mod tests {
2626
2622
let mut account_account =
2627
2623
SolanaAccount :: new ( account_minimum_balance ( ) , size_of :: < Account > ( ) , & program_id) ;
2628
2624
let account2_key = pubkey_rand ( ) ;
2629
- let mut account2_account =
2630
- SolanaAccount :: new ( account_minimum_balance ( ) , size_of :: < Account > ( ) , & program_id) ;
2625
+ let mut account2_account = SolanaAccount :: new (
2626
+ account_minimum_balance ( ) + 42 ,
2627
+ size_of :: < Account > ( ) ,
2628
+ & program_id,
2629
+ ) ;
2631
2630
let account3_key = pubkey_rand ( ) ;
2632
2631
let mut account3_account =
2633
2632
SolanaAccount :: new ( account_minimum_balance ( ) , size_of :: < Account > ( ) , & program_id) ;
@@ -2697,8 +2696,8 @@ mod tests {
2697
2696
)
2698
2697
. unwrap ( ) ;
2699
2698
let account: & mut Account = state:: unpack ( & mut account2_account. data ) . unwrap ( ) ;
2700
- assert ! ( account. is_native) ;
2701
- assert_eq ! ( account. amount, account_minimum_balance ( ) ) ;
2699
+ assert ! ( account. is_native( ) ) ;
2700
+ assert_eq ! ( account. amount, 42 ) ;
2702
2701
2703
2702
// close non-native account with balance
2704
2703
assert_eq ! (
@@ -2820,10 +2819,13 @@ mod tests {
2820
2819
)
2821
2820
. unwrap ( ) ;
2822
2821
let account: & mut Account = state:: unpack_unchecked ( & mut account2_account. data ) . unwrap ( ) ;
2823
- assert ! ( account. is_native) ;
2822
+ assert ! ( account. is_native( ) ) ;
2824
2823
assert_eq ! ( account_account. lamports, 0 ) ;
2825
2824
assert_eq ! ( account. amount, 0 ) ;
2826
- assert_eq ! ( account3_account. lamports, 3 * account_minimum_balance( ) + 2 ) ;
2825
+ assert_eq ! (
2826
+ account3_account. lamports,
2827
+ 3 * account_minimum_balance( ) + 2 + 42
2828
+ ) ;
2827
2829
}
2828
2830
2829
2831
#[ test]
@@ -2864,8 +2866,8 @@ mod tests {
2864
2866
)
2865
2867
. unwrap ( ) ;
2866
2868
let account: & mut Account = state:: unpack ( & mut account_account. data ) . unwrap ( ) ;
2867
- assert ! ( account. is_native) ;
2868
- assert_eq ! ( account. amount, account_minimum_balance ( ) + 40 ) ;
2869
+ assert ! ( account. is_native( ) ) ;
2870
+ assert_eq ! ( account. amount, 40 ) ;
2869
2871
2870
2872
// initialize native account
2871
2873
do_process_instruction (
@@ -2885,8 +2887,8 @@ mod tests {
2885
2887
)
2886
2888
. unwrap ( ) ;
2887
2889
let account: & mut Account = state:: unpack ( & mut account2_account. data ) . unwrap ( ) ;
2888
- assert ! ( account. is_native) ;
2889
- assert_eq ! ( account. amount, account_minimum_balance ( ) ) ;
2890
+ assert ! ( account. is_native( ) ) ;
2891
+ assert_eq ! ( account. amount, 0 ) ;
2890
2892
2891
2893
// mint_to unsupported
2892
2894
assert_eq ! (
@@ -2914,7 +2916,28 @@ mod tests {
2914
2916
)
2915
2917
) ;
2916
2918
2917
- // initialize native account
2919
+ // ensure can't transfer below rent-exempt reserve
2920
+ assert_eq ! (
2921
+ Err ( TokenError :: InsufficientFunds . into( ) ) ,
2922
+ do_process_instruction(
2923
+ transfer(
2924
+ & program_id,
2925
+ & account_key,
2926
+ & account2_key,
2927
+ & owner_key,
2928
+ & [ ] ,
2929
+ 50 ,
2930
+ )
2931
+ . unwrap( ) ,
2932
+ vec![
2933
+ & mut account_account,
2934
+ & mut account2_account,
2935
+ & mut owner_account,
2936
+ ] ,
2937
+ )
2938
+ ) ;
2939
+
2940
+ // transfer between native accounts
2918
2941
do_process_instruction (
2919
2942
transfer (
2920
2943
& program_id,
@@ -2934,13 +2957,13 @@ mod tests {
2934
2957
. unwrap ( ) ;
2935
2958
2936
2959
let account: & mut Account = state:: unpack ( & mut account_account. data ) . unwrap ( ) ;
2937
- assert ! ( account. is_native) ;
2960
+ assert ! ( account. is_native( ) ) ;
2938
2961
assert_eq ! ( account_account. lamports, account_minimum_balance( ) ) ;
2939
- assert_eq ! ( account. amount, account_minimum_balance ( ) ) ;
2962
+ assert_eq ! ( account. amount, 0 ) ;
2940
2963
let account: & mut Account = state:: unpack ( & mut account2_account. data ) . unwrap ( ) ;
2941
- assert ! ( account. is_native) ;
2964
+ assert ! ( account. is_native( ) ) ;
2942
2965
assert_eq ! ( account2_account. lamports, account_minimum_balance( ) + 40 ) ;
2943
- assert_eq ! ( account. amount, account_minimum_balance ( ) + 40 ) ;
2966
+ assert_eq ! ( account. amount, 40 ) ;
2944
2967
2945
2968
// close native account
2946
2969
do_process_instruction (
@@ -2953,7 +2976,7 @@ mod tests {
2953
2976
)
2954
2977
. unwrap ( ) ;
2955
2978
let account: & mut Account = state:: unpack_unchecked ( & mut account_account. data ) . unwrap ( ) ;
2956
- assert ! ( account. is_native) ;
2979
+ assert ! ( account. is_native( ) ) ;
2957
2980
assert_eq ! ( account_account. lamports, 0 ) ;
2958
2981
assert_eq ! ( account. amount, 0 ) ;
2959
2982
assert_eq ! ( account3_account. lamports, 2 * account_minimum_balance( ) ) ;
0 commit comments