@@ -22,11 +22,14 @@ use {
22
22
std:: convert:: TryInto ,
23
23
} ;
24
24
25
+ const TEST_MAXIMUM_FEE : u64 = 10_000_000 ;
26
+ const TEST_FEE_BASIS_POINTS : u16 = 250 ;
27
+
25
28
fn test_transfer_fee ( ) -> TransferFee {
26
29
TransferFee {
27
30
epoch : 0 . into ( ) ,
28
- transfer_fee_basis_points : 250 . into ( ) ,
29
- maximum_fee : 10_000_000 . into ( ) ,
31
+ transfer_fee_basis_points : TEST_FEE_BASIS_POINTS . into ( ) ,
32
+ maximum_fee : TEST_MAXIMUM_FEE . into ( ) ,
30
33
}
31
34
}
32
35
@@ -69,6 +72,73 @@ fn test_transfer_fee_config_with_keypairs() -> TransferFeeConfigWithKeypairs {
69
72
}
70
73
}
71
74
75
+ struct TokenWithAccounts {
76
+ token : Token < ProgramBanksClientProcessTransaction , Keypair > ,
77
+ transfer_fee_config : TransferFeeConfig ,
78
+ alice : Keypair ,
79
+ alice_account : Pubkey ,
80
+ bob_account : Pubkey ,
81
+ decimals : u8 ,
82
+ }
83
+
84
+ async fn create_mint_with_accounts ( alice_amount : u64 ) -> TokenWithAccounts {
85
+ let TransferFeeConfigWithKeypairs {
86
+ transfer_fee_config_authority,
87
+ withdraw_withheld_authority,
88
+ transfer_fee_config,
89
+ ..
90
+ } = test_transfer_fee_config_with_keypairs ( ) ;
91
+ let mut context = TestContext :: new ( ) . await ;
92
+ let transfer_fee_basis_points = u16:: from (
93
+ transfer_fee_config
94
+ . newer_transfer_fee
95
+ . transfer_fee_basis_points ,
96
+ ) ;
97
+ let maximum_fee = u64:: from ( transfer_fee_config. newer_transfer_fee . maximum_fee ) ;
98
+ context
99
+ . init_token_with_mint ( vec ! [ ExtensionInitializationParams :: TransferFeeConfig {
100
+ transfer_fee_config_authority: transfer_fee_config_authority. pubkey( ) . into( ) ,
101
+ withdraw_withheld_authority: withdraw_withheld_authority. pubkey( ) . into( ) ,
102
+ transfer_fee_basis_points,
103
+ maximum_fee,
104
+ } ] )
105
+ . await
106
+ . unwrap ( ) ;
107
+ let TokenContext {
108
+ decimals,
109
+ mint_authority,
110
+ token,
111
+ alice,
112
+ bob,
113
+ ..
114
+ } = context. token_context . unwrap ( ) ;
115
+
116
+ // token account is self-owned just to test another case
117
+ let alice_account = token
118
+ . create_auxiliary_token_account ( & alice, & alice. pubkey ( ) )
119
+ . await
120
+ . unwrap ( ) ;
121
+ let bob_account = Keypair :: new ( ) ;
122
+ let bob_account = token
123
+ . create_auxiliary_token_account ( & bob_account, & bob. pubkey ( ) )
124
+ . await
125
+ . unwrap ( ) ;
126
+
127
+ // mint tokens
128
+ token
129
+ . mint_to ( & alice_account, & mint_authority, alice_amount)
130
+ . await
131
+ . unwrap ( ) ;
132
+ TokenWithAccounts {
133
+ token,
134
+ transfer_fee_config,
135
+ alice,
136
+ alice_account,
137
+ bob_account,
138
+ decimals,
139
+ }
140
+ }
141
+
72
142
#[ tokio:: test]
73
143
async fn success_init ( ) {
74
144
let TransferFeeConfig {
@@ -585,54 +655,17 @@ async fn set_withdraw_withheld_authority() {
585
655
586
656
#[ tokio:: test]
587
657
async fn transfer_checked ( ) {
588
- let TransferFeeConfigWithKeypairs {
589
- transfer_fee_config_authority,
590
- withdraw_withheld_authority,
591
- transfer_fee_config,
592
- ..
593
- } = test_transfer_fee_config_with_keypairs ( ) ;
594
- let mut context = TestContext :: new ( ) . await ;
595
- let transfer_fee_basis_points = u16:: from (
596
- transfer_fee_config
597
- . newer_transfer_fee
598
- . transfer_fee_basis_points ,
599
- ) ;
600
- let maximum_fee = u64:: from ( transfer_fee_config. newer_transfer_fee . maximum_fee ) ;
601
- context
602
- . init_token_with_mint ( vec ! [ ExtensionInitializationParams :: TransferFeeConfig {
603
- transfer_fee_config_authority: transfer_fee_config_authority. pubkey( ) . into( ) ,
604
- withdraw_withheld_authority: withdraw_withheld_authority. pubkey( ) . into( ) ,
605
- transfer_fee_basis_points,
606
- maximum_fee,
607
- } ] )
608
- . await
609
- . unwrap ( ) ;
610
- let TokenContext {
611
- decimals,
612
- mint_authority,
658
+ let maximum_fee = TEST_MAXIMUM_FEE ;
659
+ let mut alice_amount = maximum_fee * 100 ;
660
+ let TokenWithAccounts {
613
661
token,
662
+ transfer_fee_config,
614
663
alice,
615
- bob,
664
+ alice_account,
665
+ bob_account,
666
+ decimals,
616
667
..
617
- } = context. token_context . unwrap ( ) ;
618
-
619
- // token account is self-owned just to test another case
620
- let alice_account = token
621
- . create_auxiliary_token_account ( & alice, & alice. pubkey ( ) )
622
- . await
623
- . unwrap ( ) ;
624
- let bob_account = Keypair :: new ( ) ;
625
- let bob_account = token
626
- . create_auxiliary_token_account ( & bob_account, & bob. pubkey ( ) )
627
- . await
628
- . unwrap ( ) ;
629
-
630
- // mint a lot of tokens, 100x max fee
631
- let mut alice_amount = maximum_fee * 100 ;
632
- token
633
- . mint_to ( & alice_account, & mint_authority, alice_amount)
634
- . await
635
- . unwrap ( ) ;
668
+ } = create_mint_with_accounts ( alice_amount) . await ;
636
669
637
670
// fail unchecked always
638
671
let error = token
@@ -722,8 +755,12 @@ async fn transfer_checked() {
722
755
assert_eq ! ( extension. withheld_amount, withheld_amount. into( ) ) ;
723
756
724
757
// success, maximum fee kicks in
725
- let transfer_amount =
726
- 1 + maximum_fee * ( MAX_FEE_BASIS_POINTS as u64 ) / ( transfer_fee_basis_points as u64 ) ;
758
+ let transfer_amount = 1 + maximum_fee * ( MAX_FEE_BASIS_POINTS as u64 )
759
+ / ( u16:: from (
760
+ transfer_fee_config
761
+ . newer_transfer_fee
762
+ . transfer_fee_basis_points ,
763
+ ) as u64 ) ;
727
764
let fee = transfer_fee_config
728
765
. calculate_epoch_fee ( 0 , transfer_amount)
729
766
. unwrap ( ) ;
@@ -791,54 +828,17 @@ async fn transfer_checked() {
791
828
792
829
#[ tokio:: test]
793
830
async fn transfer_checked_with_fee ( ) {
794
- let TransferFeeConfigWithKeypairs {
795
- transfer_fee_config_authority,
796
- withdraw_withheld_authority,
797
- transfer_fee_config,
798
- ..
799
- } = test_transfer_fee_config_with_keypairs ( ) ;
800
- let mut context = TestContext :: new ( ) . await ;
801
- let transfer_fee_basis_points = u16:: from (
802
- transfer_fee_config
803
- . newer_transfer_fee
804
- . transfer_fee_basis_points ,
805
- ) ;
806
- let maximum_fee = u64:: from ( transfer_fee_config. newer_transfer_fee . maximum_fee ) ;
807
- context
808
- . init_token_with_mint ( vec ! [ ExtensionInitializationParams :: TransferFeeConfig {
809
- transfer_fee_config_authority: transfer_fee_config_authority. pubkey( ) . into( ) ,
810
- withdraw_withheld_authority: withdraw_withheld_authority. pubkey( ) . into( ) ,
811
- transfer_fee_basis_points,
812
- maximum_fee,
813
- } ] )
814
- . await
815
- . unwrap ( ) ;
816
- let TokenContext {
817
- decimals,
818
- mint_authority,
831
+ let maximum_fee = TEST_MAXIMUM_FEE ;
832
+ let alice_amount = maximum_fee * 100 ;
833
+ let TokenWithAccounts {
819
834
token,
835
+ transfer_fee_config,
820
836
alice,
821
- bob,
837
+ alice_account,
838
+ bob_account,
839
+ decimals,
822
840
..
823
- } = context. token_context . unwrap ( ) ;
824
-
825
- let alice_account = Keypair :: new ( ) ;
826
- let alice_account = token
827
- . create_auxiliary_token_account ( & alice_account, & alice. pubkey ( ) )
828
- . await
829
- . unwrap ( ) ;
830
- let bob_account = Keypair :: new ( ) ;
831
- let bob_account = token
832
- . create_auxiliary_token_account ( & bob_account, & bob. pubkey ( ) )
833
- . await
834
- . unwrap ( ) ;
835
-
836
- // mint a lot of tokens, 100x max fee
837
- let alice_amount = maximum_fee * 100 ;
838
- token
839
- . mint_to ( & alice_account, & mint_authority, alice_amount)
840
- . await
841
- . unwrap ( ) ;
841
+ } = create_mint_with_accounts ( alice_amount) . await ;
842
842
843
843
// incorrect fee, too high
844
844
let transfer_amount = maximum_fee;
@@ -946,48 +946,16 @@ async fn transfer_checked_with_fee() {
946
946
947
947
#[ tokio:: test]
948
948
async fn no_fees_from_self_transfer ( ) {
949
- let TransferFeeConfigWithKeypairs {
950
- transfer_fee_config_authority,
951
- withdraw_withheld_authority,
952
- transfer_fee_config,
953
- ..
954
- } = test_transfer_fee_config_with_keypairs ( ) ;
955
- let mut context = TestContext :: new ( ) . await ;
956
- let transfer_fee_basis_points = u16:: from (
957
- transfer_fee_config
958
- . newer_transfer_fee
959
- . transfer_fee_basis_points ,
960
- ) ;
961
- let maximum_fee = u64:: from ( transfer_fee_config. newer_transfer_fee . maximum_fee ) ;
962
- context
963
- . init_token_with_mint ( vec ! [ ExtensionInitializationParams :: TransferFeeConfig {
964
- transfer_fee_config_authority: transfer_fee_config_authority. pubkey( ) . into( ) ,
965
- withdraw_withheld_authority: withdraw_withheld_authority. pubkey( ) . into( ) ,
966
- transfer_fee_basis_points,
967
- maximum_fee,
968
- } ] )
969
- . await
970
- . unwrap ( ) ;
971
- let TokenContext {
972
- decimals,
973
- mint_authority,
949
+ let amount = TEST_MAXIMUM_FEE ;
950
+ let alice_amount = amount * 100 ;
951
+ let TokenWithAccounts {
974
952
token,
953
+ transfer_fee_config,
975
954
alice,
955
+ alice_account,
956
+ decimals,
976
957
..
977
- } = context. token_context . unwrap ( ) ;
978
-
979
- let alice_account = Keypair :: new ( ) ;
980
- let alice_account = token
981
- . create_auxiliary_token_account ( & alice_account, & alice. pubkey ( ) )
982
- . await
983
- . unwrap ( ) ;
984
-
985
- // mint some tokens
986
- let amount = maximum_fee;
987
- token
988
- . mint_to ( & alice_account, & mint_authority, amount)
989
- . await
990
- . unwrap ( ) ;
958
+ } = create_mint_with_accounts ( alice_amount) . await ;
991
959
992
960
// self transfer, no fee assessed
993
961
let fee = transfer_fee_config. calculate_epoch_fee ( 0 , amount) . unwrap ( ) ;
@@ -1003,7 +971,7 @@ async fn no_fees_from_self_transfer() {
1003
971
. await
1004
972
. unwrap ( ) ;
1005
973
let alice_state = token. get_account_info ( & alice_account) . await . unwrap ( ) ;
1006
- assert_eq ! ( alice_state. base. amount, amount ) ;
974
+ assert_eq ! ( alice_state. base. amount, alice_amount ) ;
1007
975
let extension = alice_state. get_extension :: < TransferFeeAmount > ( ) . unwrap ( ) ;
1008
976
assert_eq ! ( extension. withheld_amount, 0 . into( ) ) ;
1009
977
}
@@ -1145,49 +1113,17 @@ async fn harvest_withheld_tokens_to_mint() {
1145
1113
1146
1114
#[ tokio:: test]
1147
1115
async fn max_harvest_withheld_tokens_to_mint ( ) {
1148
- let TransferFeeConfigWithKeypairs {
1149
- transfer_fee_config_authority,
1150
- withdraw_withheld_authority,
1151
- transfer_fee_config,
1152
- ..
1153
- } = test_transfer_fee_config_with_keypairs ( ) ;
1154
- let mut context = TestContext :: new ( ) . await ;
1155
- let transfer_fee_basis_points = u16:: from (
1156
- transfer_fee_config
1157
- . newer_transfer_fee
1158
- . transfer_fee_basis_points ,
1159
- ) ;
1160
- let maximum_fee = u64:: from ( transfer_fee_config. newer_transfer_fee . maximum_fee ) ;
1161
- context
1162
- . init_token_with_mint ( vec ! [ ExtensionInitializationParams :: TransferFeeConfig {
1163
- transfer_fee_config_authority: transfer_fee_config_authority. pubkey( ) . into( ) ,
1164
- withdraw_withheld_authority: withdraw_withheld_authority. pubkey( ) . into( ) ,
1165
- transfer_fee_basis_points,
1166
- maximum_fee,
1167
- } ] )
1168
- . await
1169
- . unwrap ( ) ;
1170
- let TokenContext {
1171
- decimals,
1172
- mint_authority,
1116
+ let amount = TEST_MAXIMUM_FEE ;
1117
+ let alice_amount = amount * 100 ;
1118
+ let TokenWithAccounts {
1173
1119
token,
1120
+ transfer_fee_config,
1174
1121
alice,
1122
+ alice_account,
1123
+ decimals,
1175
1124
..
1176
- } = context. token_context . unwrap ( ) ;
1177
-
1178
- let alice_account = Keypair :: new ( ) ;
1179
- let alice_account = token
1180
- . create_auxiliary_token_account ( & alice_account, & alice. pubkey ( ) )
1181
- . await
1182
- . unwrap ( ) ;
1125
+ } = create_mint_with_accounts ( alice_amount) . await ;
1183
1126
1184
- // mint a lot of tokens
1185
- let amount = maximum_fee;
1186
- let alice_amount = amount * 100 ;
1187
- token
1188
- . mint_to ( & alice_account, & mint_authority, alice_amount)
1189
- . await
1190
- . unwrap ( ) ;
1191
1127
// harvest from max accounts, which is around 35, AKA 34 accounts + 1 mint
1192
1128
// see https://docs.solana.com/proposals/transactions-v2#problem
1193
1129
let mut accounts = vec ! [ ] ;
0 commit comments