use solana_sdk::signer::Signer;
use access_protocol::state::FeeRecipient;
use access_protocol::state::{MAX_FEE_RECIPIENTS, MAX_FEE_SPLIT_SETUP_DELAY};
use crate::common::test_runner::TestRunner;
pub mod common;
#[tokio::test]
async fn fee_split() {
let mut tr = TestRunner::new(1_000_000).await.unwrap();
tr.sleep(1).await.unwrap();
let token_stats = tr.token_stats().await.unwrap();
assert_eq!(token_stats.supply, 100_000_000_000_000_000);
let pool_owner = tr.create_user_with_ata().await.unwrap();
tr.create_pool(&pool_owner, 200_000_000)
.await
.unwrap();
tr.activate_stake_pool(&pool_owner.pubkey()).await.unwrap();
let staker = tr.create_user_with_ata().await.unwrap();
tr.get_tokens_from_supply(&staker.pubkey(), 100_000_000_000).await.unwrap();
tr.create_stake_account(&pool_owner.pubkey(), &staker.pubkey())
.await
.unwrap();
tr.stake(&pool_owner.pubkey(), &staker, 5_000_000_000)
.await
.unwrap();
let central_state_stats = tr.central_state_stats().await.unwrap();
assert_eq!(central_state_stats.balance, 100_000_000);
assert_eq!(central_state_stats.account.recipients.len(), 0);
tr.distribute_fees().await.unwrap();
let central_state_stats = tr.central_state_stats().await.unwrap();
assert_eq!(central_state_stats.balance, 0);
assert_eq!(central_state_stats.account.recipients.len(), 0);
let token_stats = tr.token_stats().await.unwrap();
assert_eq!(token_stats.supply, 100_000_000_000_000_000 - 100_000_000);
let mut recipients = vec![];
for _ in 0..MAX_FEE_RECIPIENTS {
recipients.push(tr.create_user_with_ata().await.unwrap());
}
let recipient_percentages = (0..MAX_FEE_RECIPIENTS - 1)
.map(|_| rand::random::<u64>() % 5 + 1)
.collect::<Vec<_>>();
let recipient_percentages = {
let mut recipient_percentages = recipient_percentages;
recipient_percentages.push(99 - recipient_percentages.iter().sum::<u64>());
recipient_percentages
};
let fee_recipients = recipients
.iter()
.zip(recipient_percentages.iter())
.map(|(r, p)| FeeRecipient {
owner: r.pubkey(),
percentage: *p,
})
.collect::<Vec<_>>();
tr.setup_fee_split(fee_recipients).await.unwrap();
tr.stake(&pool_owner.pubkey(), &staker, 4_999_999_949)
.await
.unwrap();
let central_state_stats = tr.central_state_stats().await.unwrap();
assert_eq!(central_state_stats.balance, 99_999_999);
assert_eq!(central_state_stats.account.recipients.len(), MAX_FEE_RECIPIENTS);
println!("central_state_stats: {:?}", central_state_stats);
tr.distribute_fees().await.unwrap_err();
tr.stake(&pool_owner.pubkey(), &staker, 1).await.unwrap();
let central_state_stats = tr.central_state_stats().await.unwrap();
assert_eq!(central_state_stats.balance, 100_000_000);
assert_eq!(central_state_stats.account.recipients.len(), MAX_FEE_RECIPIENTS);
tr.sleep(1).await.unwrap();
tr.distribute_fees().await.unwrap();
for (recipient, percentage) in recipients.iter().zip(recipient_percentages.iter()) {
let recipient_stats = tr.staker_stats(recipient.pubkey()).await.unwrap();
assert_eq!(recipient_stats.balance, 100_000_000 * percentage / 100);
}
tr.sleep(1).await.unwrap();
tr.distribute_fees().await.unwrap_err();
for (recipient, percentage) in recipients.iter().zip(recipient_percentages.iter()) {
let recipient_stats = tr.staker_stats(recipient.pubkey()).await.unwrap();
assert_eq!(recipient_stats.balance, 100_000_000 * percentage / 100);
}
let token_stats = tr.token_stats().await.unwrap();
assert_eq!(token_stats.supply, 100_000_000_000_000_000 - 100_000_000 - 1_000_000);
let new_recipient1 = tr.create_user_with_ata().await.unwrap();
let new_recipient2 = tr.create_user_with_ata().await.unwrap();
tr.setup_fee_split(vec![
FeeRecipient {
owner: new_recipient1.pubkey(),
percentage: 30,
},
FeeRecipient {
owner: new_recipient2.pubkey(),
percentage: 70,
},
])
.await
.unwrap();
tr.setup_fee_split(vec![
FeeRecipient {
owner: new_recipient1.pubkey(),
percentage: 50,
},
FeeRecipient {
owner: new_recipient2.pubkey(),
percentage: 51,
},
])
.await
.unwrap_err();
tr.stake(&pool_owner.pubkey(), &staker, 11_234_567_891)
.await
.unwrap();
let central_state_stats = tr.central_state_stats().await.unwrap();
assert_eq!(central_state_stats.balance, 224691358);
tr.sleep(MAX_FEE_SPLIT_SETUP_DELAY + 1).await.unwrap();
tr.setup_fee_split(vec![FeeRecipient {
owner: new_recipient1.pubkey(),
percentage: 3,
}])
.await
.unwrap_err();
tr.distribute_fees().await.unwrap();
let recipient1_stats = tr.staker_stats(new_recipient1.pubkey()).await.unwrap();
assert_eq!(recipient1_stats.balance, 224691358 * 30 / 100);
let recipient2_stats = tr.staker_stats(new_recipient2.pubkey()).await.unwrap();
assert_eq!(recipient2_stats.balance, 224691358 * 70 / 100);
let central_state_stats = tr.central_state_stats().await.unwrap();
assert_eq!(central_state_stats.balance, 0);
let token_stats = tr.token_stats().await.unwrap();
assert_eq!(token_stats.supply, 100_000_000_000_000_000 - 100_000_000 - 1_000_000 - 1);
tr.sleep(1).await.unwrap();
tr.setup_fee_split(vec![FeeRecipient {
owner: new_recipient1.pubkey(),
percentage: 3,
}])
.await
.unwrap();
tr.sleep(1).await.unwrap();
tr.setup_fee_split(vec![]).await.unwrap();
tr.stake(&pool_owner.pubkey(), &staker, 5_000_000_000)
.await
.unwrap();
let central_state_stats = tr.central_state_stats().await.unwrap();
assert_eq!(central_state_stats.balance, 100_000_000);
assert_eq!(central_state_stats.account.recipients.len(), 0);
tr.distribute_fees().await.unwrap();
let central_state_stats = tr.central_state_stats().await.unwrap();
assert_eq!(central_state_stats.balance, 0);
assert_eq!(central_state_stats.account.recipients.len(), 0);
let token_stats = tr.token_stats().await.unwrap();
assert_eq!(token_stats.supply, 100_000_000_000_000_000 - 100_000_000 - 1_000_000 - 1 - 100_000_000);
}