Skip to content
This repository was archived by the owner on Mar 11, 2025. It is now read-only.

Commit 1f77ba0

Browse files
authored
token-2022: DRY out the transfer fee tests (#2845)
1 parent 37ba32f commit 1f77ba0

File tree

1 file changed

+109
-173
lines changed

1 file changed

+109
-173
lines changed

token/program-2022/tests/transfer_fee.rs

Lines changed: 109 additions & 173 deletions
Original file line numberDiff line numberDiff line change
@@ -22,11 +22,14 @@ use {
2222
std::convert::TryInto,
2323
};
2424

25+
const TEST_MAXIMUM_FEE: u64 = 10_000_000;
26+
const TEST_FEE_BASIS_POINTS: u16 = 250;
27+
2528
fn test_transfer_fee() -> TransferFee {
2629
TransferFee {
2730
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(),
3033
}
3134
}
3235

@@ -69,6 +72,73 @@ fn test_transfer_fee_config_with_keypairs() -> TransferFeeConfigWithKeypairs {
6972
}
7073
}
7174

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+
72142
#[tokio::test]
73143
async fn success_init() {
74144
let TransferFeeConfig {
@@ -585,54 +655,17 @@ async fn set_withdraw_withheld_authority() {
585655

586656
#[tokio::test]
587657
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 {
613661
token,
662+
transfer_fee_config,
614663
alice,
615-
bob,
664+
alice_account,
665+
bob_account,
666+
decimals,
616667
..
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;
636669

637670
// fail unchecked always
638671
let error = token
@@ -722,8 +755,12 @@ async fn transfer_checked() {
722755
assert_eq!(extension.withheld_amount, withheld_amount.into());
723756

724757
// 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);
727764
let fee = transfer_fee_config
728765
.calculate_epoch_fee(0, transfer_amount)
729766
.unwrap();
@@ -791,54 +828,17 @@ async fn transfer_checked() {
791828

792829
#[tokio::test]
793830
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 {
819834
token,
835+
transfer_fee_config,
820836
alice,
821-
bob,
837+
alice_account,
838+
bob_account,
839+
decimals,
822840
..
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;
842842

843843
// incorrect fee, too high
844844
let transfer_amount = maximum_fee;
@@ -946,48 +946,16 @@ async fn transfer_checked_with_fee() {
946946

947947
#[tokio::test]
948948
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 {
974952
token,
953+
transfer_fee_config,
975954
alice,
955+
alice_account,
956+
decimals,
976957
..
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;
991959

992960
// self transfer, no fee assessed
993961
let fee = transfer_fee_config.calculate_epoch_fee(0, amount).unwrap();
@@ -1003,7 +971,7 @@ async fn no_fees_from_self_transfer() {
1003971
.await
1004972
.unwrap();
1005973
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);
1007975
let extension = alice_state.get_extension::<TransferFeeAmount>().unwrap();
1008976
assert_eq!(extension.withheld_amount, 0.into());
1009977
}
@@ -1145,49 +1113,17 @@ async fn harvest_withheld_tokens_to_mint() {
11451113

11461114
#[tokio::test]
11471115
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 {
11731119
token,
1120+
transfer_fee_config,
11741121
alice,
1122+
alice_account,
1123+
decimals,
11751124
..
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;
11831126

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();
11911127
// harvest from max accounts, which is around 35, AKA 34 accounts + 1 mint
11921128
// see https://docs.solana.com/proposals/transactions-v2#problem
11931129
let mut accounts = vec![];

0 commit comments

Comments
 (0)