token-2022: DRY out the transfer fee tests (#2845)

This commit is contained in:
Jon Cinque 2022-01-31 22:08:44 +01:00 committed by GitHub
parent 37ba32f7c8
commit 1f77ba09ed
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
1 changed files with 116 additions and 180 deletions

View File

@ -22,11 +22,14 @@ use {
std::convert::TryInto, std::convert::TryInto,
}; };
const TEST_MAXIMUM_FEE: u64 = 10_000_000;
const TEST_FEE_BASIS_POINTS: u16 = 250;
fn test_transfer_fee() -> TransferFee { fn test_transfer_fee() -> TransferFee {
TransferFee { TransferFee {
epoch: 0.into(), epoch: 0.into(),
transfer_fee_basis_points: 250.into(), transfer_fee_basis_points: TEST_FEE_BASIS_POINTS.into(),
maximum_fee: 10_000_000.into(), maximum_fee: TEST_MAXIMUM_FEE.into(),
} }
} }
@ -69,6 +72,73 @@ fn test_transfer_fee_config_with_keypairs() -> TransferFeeConfigWithKeypairs {
} }
} }
struct TokenWithAccounts {
token: Token<ProgramBanksClientProcessTransaction, Keypair>,
transfer_fee_config: TransferFeeConfig,
alice: Keypair,
alice_account: Pubkey,
bob_account: Pubkey,
decimals: u8,
}
async fn create_mint_with_accounts(alice_amount: u64) -> TokenWithAccounts {
let TransferFeeConfigWithKeypairs {
transfer_fee_config_authority,
withdraw_withheld_authority,
transfer_fee_config,
..
} = test_transfer_fee_config_with_keypairs();
let mut context = TestContext::new().await;
let transfer_fee_basis_points = u16::from(
transfer_fee_config
.newer_transfer_fee
.transfer_fee_basis_points,
);
let maximum_fee = u64::from(transfer_fee_config.newer_transfer_fee.maximum_fee);
context
.init_token_with_mint(vec![ExtensionInitializationParams::TransferFeeConfig {
transfer_fee_config_authority: transfer_fee_config_authority.pubkey().into(),
withdraw_withheld_authority: withdraw_withheld_authority.pubkey().into(),
transfer_fee_basis_points,
maximum_fee,
}])
.await
.unwrap();
let TokenContext {
decimals,
mint_authority,
token,
alice,
bob,
..
} = context.token_context.unwrap();
// token account is self-owned just to test another case
let alice_account = token
.create_auxiliary_token_account(&alice, &alice.pubkey())
.await
.unwrap();
let bob_account = Keypair::new();
let bob_account = token
.create_auxiliary_token_account(&bob_account, &bob.pubkey())
.await
.unwrap();
// mint tokens
token
.mint_to(&alice_account, &mint_authority, alice_amount)
.await
.unwrap();
TokenWithAccounts {
token,
transfer_fee_config,
alice,
alice_account,
bob_account,
decimals,
}
}
#[tokio::test] #[tokio::test]
async fn success_init() { async fn success_init() {
let TransferFeeConfig { let TransferFeeConfig {
@ -585,54 +655,17 @@ async fn set_withdraw_withheld_authority() {
#[tokio::test] #[tokio::test]
async fn transfer_checked() { async fn transfer_checked() {
let TransferFeeConfigWithKeypairs { let maximum_fee = TEST_MAXIMUM_FEE;
transfer_fee_config_authority,
withdraw_withheld_authority,
transfer_fee_config,
..
} = test_transfer_fee_config_with_keypairs();
let mut context = TestContext::new().await;
let transfer_fee_basis_points = u16::from(
transfer_fee_config
.newer_transfer_fee
.transfer_fee_basis_points,
);
let maximum_fee = u64::from(transfer_fee_config.newer_transfer_fee.maximum_fee);
context
.init_token_with_mint(vec![ExtensionInitializationParams::TransferFeeConfig {
transfer_fee_config_authority: transfer_fee_config_authority.pubkey().into(),
withdraw_withheld_authority: withdraw_withheld_authority.pubkey().into(),
transfer_fee_basis_points,
maximum_fee,
}])
.await
.unwrap();
let TokenContext {
decimals,
mint_authority,
token,
alice,
bob,
..
} = context.token_context.unwrap();
// token account is self-owned just to test another case
let alice_account = token
.create_auxiliary_token_account(&alice, &alice.pubkey())
.await
.unwrap();
let bob_account = Keypair::new();
let bob_account = token
.create_auxiliary_token_account(&bob_account, &bob.pubkey())
.await
.unwrap();
// mint a lot of tokens, 100x max fee
let mut alice_amount = maximum_fee * 100; let mut alice_amount = maximum_fee * 100;
token let TokenWithAccounts {
.mint_to(&alice_account, &mint_authority, alice_amount) token,
.await transfer_fee_config,
.unwrap(); alice,
alice_account,
bob_account,
decimals,
..
} = create_mint_with_accounts(alice_amount).await;
// fail unchecked always // fail unchecked always
let error = token let error = token
@ -722,8 +755,12 @@ async fn transfer_checked() {
assert_eq!(extension.withheld_amount, withheld_amount.into()); assert_eq!(extension.withheld_amount, withheld_amount.into());
// success, maximum fee kicks in // success, maximum fee kicks in
let transfer_amount = let transfer_amount = 1 + maximum_fee * (MAX_FEE_BASIS_POINTS as u64)
1 + maximum_fee * (MAX_FEE_BASIS_POINTS as u64) / (transfer_fee_basis_points as u64); / (u16::from(
transfer_fee_config
.newer_transfer_fee
.transfer_fee_basis_points,
) as u64);
let fee = transfer_fee_config let fee = transfer_fee_config
.calculate_epoch_fee(0, transfer_amount) .calculate_epoch_fee(0, transfer_amount)
.unwrap(); .unwrap();
@ -791,54 +828,17 @@ async fn transfer_checked() {
#[tokio::test] #[tokio::test]
async fn transfer_checked_with_fee() { async fn transfer_checked_with_fee() {
let TransferFeeConfigWithKeypairs { let maximum_fee = TEST_MAXIMUM_FEE;
transfer_fee_config_authority,
withdraw_withheld_authority,
transfer_fee_config,
..
} = test_transfer_fee_config_with_keypairs();
let mut context = TestContext::new().await;
let transfer_fee_basis_points = u16::from(
transfer_fee_config
.newer_transfer_fee
.transfer_fee_basis_points,
);
let maximum_fee = u64::from(transfer_fee_config.newer_transfer_fee.maximum_fee);
context
.init_token_with_mint(vec![ExtensionInitializationParams::TransferFeeConfig {
transfer_fee_config_authority: transfer_fee_config_authority.pubkey().into(),
withdraw_withheld_authority: withdraw_withheld_authority.pubkey().into(),
transfer_fee_basis_points,
maximum_fee,
}])
.await
.unwrap();
let TokenContext {
decimals,
mint_authority,
token,
alice,
bob,
..
} = context.token_context.unwrap();
let alice_account = Keypair::new();
let alice_account = token
.create_auxiliary_token_account(&alice_account, &alice.pubkey())
.await
.unwrap();
let bob_account = Keypair::new();
let bob_account = token
.create_auxiliary_token_account(&bob_account, &bob.pubkey())
.await
.unwrap();
// mint a lot of tokens, 100x max fee
let alice_amount = maximum_fee * 100; let alice_amount = maximum_fee * 100;
token let TokenWithAccounts {
.mint_to(&alice_account, &mint_authority, alice_amount) token,
.await transfer_fee_config,
.unwrap(); alice,
alice_account,
bob_account,
decimals,
..
} = create_mint_with_accounts(alice_amount).await;
// incorrect fee, too high // incorrect fee, too high
let transfer_amount = maximum_fee; let transfer_amount = maximum_fee;
@ -946,48 +946,16 @@ async fn transfer_checked_with_fee() {
#[tokio::test] #[tokio::test]
async fn no_fees_from_self_transfer() { async fn no_fees_from_self_transfer() {
let TransferFeeConfigWithKeypairs { let amount = TEST_MAXIMUM_FEE;
transfer_fee_config_authority, let alice_amount = amount * 100;
withdraw_withheld_authority, let TokenWithAccounts {
transfer_fee_config,
..
} = test_transfer_fee_config_with_keypairs();
let mut context = TestContext::new().await;
let transfer_fee_basis_points = u16::from(
transfer_fee_config
.newer_transfer_fee
.transfer_fee_basis_points,
);
let maximum_fee = u64::from(transfer_fee_config.newer_transfer_fee.maximum_fee);
context
.init_token_with_mint(vec![ExtensionInitializationParams::TransferFeeConfig {
transfer_fee_config_authority: transfer_fee_config_authority.pubkey().into(),
withdraw_withheld_authority: withdraw_withheld_authority.pubkey().into(),
transfer_fee_basis_points,
maximum_fee,
}])
.await
.unwrap();
let TokenContext {
decimals,
mint_authority,
token, token,
transfer_fee_config,
alice, alice,
alice_account,
decimals,
.. ..
} = context.token_context.unwrap(); } = create_mint_with_accounts(alice_amount).await;
let alice_account = Keypair::new();
let alice_account = token
.create_auxiliary_token_account(&alice_account, &alice.pubkey())
.await
.unwrap();
// mint some tokens
let amount = maximum_fee;
token
.mint_to(&alice_account, &mint_authority, amount)
.await
.unwrap();
// self transfer, no fee assessed // self transfer, no fee assessed
let fee = transfer_fee_config.calculate_epoch_fee(0, amount).unwrap(); let fee = transfer_fee_config.calculate_epoch_fee(0, amount).unwrap();
@ -1003,7 +971,7 @@ async fn no_fees_from_self_transfer() {
.await .await
.unwrap(); .unwrap();
let alice_state = token.get_account_info(&alice_account).await.unwrap(); let alice_state = token.get_account_info(&alice_account).await.unwrap();
assert_eq!(alice_state.base.amount, amount); assert_eq!(alice_state.base.amount, alice_amount);
let extension = alice_state.get_extension::<TransferFeeAmount>().unwrap(); let extension = alice_state.get_extension::<TransferFeeAmount>().unwrap();
assert_eq!(extension.withheld_amount, 0.into()); assert_eq!(extension.withheld_amount, 0.into());
} }
@ -1145,49 +1113,17 @@ async fn harvest_withheld_tokens_to_mint() {
#[tokio::test] #[tokio::test]
async fn max_harvest_withheld_tokens_to_mint() { async fn max_harvest_withheld_tokens_to_mint() {
let TransferFeeConfigWithKeypairs { let amount = TEST_MAXIMUM_FEE;
transfer_fee_config_authority,
withdraw_withheld_authority,
transfer_fee_config,
..
} = test_transfer_fee_config_with_keypairs();
let mut context = TestContext::new().await;
let transfer_fee_basis_points = u16::from(
transfer_fee_config
.newer_transfer_fee
.transfer_fee_basis_points,
);
let maximum_fee = u64::from(transfer_fee_config.newer_transfer_fee.maximum_fee);
context
.init_token_with_mint(vec![ExtensionInitializationParams::TransferFeeConfig {
transfer_fee_config_authority: transfer_fee_config_authority.pubkey().into(),
withdraw_withheld_authority: withdraw_withheld_authority.pubkey().into(),
transfer_fee_basis_points,
maximum_fee,
}])
.await
.unwrap();
let TokenContext {
decimals,
mint_authority,
token,
alice,
..
} = context.token_context.unwrap();
let alice_account = Keypair::new();
let alice_account = token
.create_auxiliary_token_account(&alice_account, &alice.pubkey())
.await
.unwrap();
// mint a lot of tokens
let amount = maximum_fee;
let alice_amount = amount * 100; let alice_amount = amount * 100;
token let TokenWithAccounts {
.mint_to(&alice_account, &mint_authority, alice_amount) token,
.await transfer_fee_config,
.unwrap(); alice,
alice_account,
decimals,
..
} = create_mint_with_accounts(alice_amount).await;
// harvest from max accounts, which is around 35, AKA 34 accounts + 1 mint // harvest from max accounts, which is around 35, AKA 34 accounts + 1 mint
// see https://docs.solana.com/proposals/transactions-v2#problem // see https://docs.solana.com/proposals/transactions-v2#problem
let mut accounts = vec![]; let mut accounts = vec![];