use solana_sdk::signer::Signer;
use solana_test_framework::*;
use access_protocol::state::STAKE_BUFFER_LEN;
use crate::common::test_runner::TestRunner;
pub mod common;
const DAY: u64 = 86400;
const DAILY_INFLATION: u64 = 10_000_000_000_000_000;
mod rewards_wrap {
use super::*;
#[tokio::test]
async fn rewards_long_time() {
let mut tr = TestRunner::new(DAILY_INFLATION).await.unwrap();
let pool_owner = tr.create_user_with_ata().await.unwrap();
let pool_owner2 = tr.create_user_with_ata().await.unwrap();
tr.create_pool(&pool_owner, 1_000_000_000)
.await
.unwrap();
tr.create_pool(&pool_owner2, 1_000_000_000)
.await
.unwrap();
tr.activate_stake_pool(&pool_owner.pubkey()).await.unwrap();
tr.activate_stake_pool(&pool_owner2.pubkey()).await.unwrap();
let staker = tr.create_user_with_ata().await.unwrap();
tr.mint(&staker.pubkey(), 5_100_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();
tr.create_bond(
&pool_owner2.pubkey(),
&staker.pubkey(),
5_000_000_000,
1,
8 * DAY as i64,
1,
)
.await
.unwrap();
tr.claim_bond(&pool_owner2.pubkey(), &staker.pubkey())
.await
.unwrap();
for _ in 0..2 * STAKE_BUFFER_LEN + 3 {
tr.sleep(DAY).await.unwrap();
tr.crank_pool(&pool_owner.pubkey()).await.unwrap();
tr.crank_pool(&pool_owner2.pubkey()).await.unwrap();
}
tr.claim_pool_rewards(&pool_owner).await.unwrap();
let pool_stats = tr.pool_stats(pool_owner.pubkey()).await.unwrap();
assert_eq!(pool_stats.balance, STAKE_BUFFER_LEN * DAILY_INFLATION / 4);
tr.claim_staker_rewards(&pool_owner.pubkey(), &staker)
.await
.unwrap();
let staker_stats = tr.staker_stats(staker.pubkey()).await.unwrap();
assert_eq!(staker_stats.balance, STAKE_BUFFER_LEN * DAILY_INFLATION / 4);
tr.claim_pool_rewards(&pool_owner2).await.unwrap();
let pool_stats = tr.pool_stats(pool_owner2.pubkey()).await.unwrap();
assert_eq!(pool_stats.balance, STAKE_BUFFER_LEN * DAILY_INFLATION / 4);
tr.claim_bond_rewards(&pool_owner2.pubkey(), &staker)
.await
.unwrap();
let staker_stats = tr.staker_stats(staker.pubkey()).await.unwrap();
assert_eq!(
staker_stats.balance,
2 * (STAKE_BUFFER_LEN * DAILY_INFLATION / 4)
);
}
#[tokio::test]
async fn rewards_on_bound() {
let mut tr = TestRunner::new(DAILY_INFLATION).await.unwrap();
let pool_owner = tr.create_user_with_ata().await.unwrap();
let pool_owner2 = tr.create_user_with_ata().await.unwrap();
tr.create_pool(&pool_owner, 1_000_000_000)
.await
.unwrap();
tr.create_pool(&pool_owner2, 1_000_000_000)
.await
.unwrap();
tr.activate_stake_pool(&pool_owner.pubkey()).await.unwrap();
tr.activate_stake_pool(&pool_owner2.pubkey()).await.unwrap();
let staker = tr.create_user_with_ata().await.unwrap();
tr.mint(&staker.pubkey(), 5_100_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();
tr.create_bond(
&pool_owner2.pubkey(),
&staker.pubkey(),
5_000_000_000,
1,
8 * DAY as i64,
1,
)
.await
.unwrap();
tr.claim_bond(&pool_owner2.pubkey(), &staker.pubkey())
.await
.unwrap();
for i in 0..STAKE_BUFFER_LEN + 10 {
tr.sleep(DAY).await.unwrap();
tr.crank_pool(&pool_owner.pubkey()).await.unwrap();
tr.crank_pool(&pool_owner2.pubkey()).await.unwrap();
tr.claim_pool_rewards(&pool_owner).await.unwrap();
let pool_stats = tr.pool_stats(pool_owner.pubkey()).await.unwrap();
assert_eq!(pool_stats.balance, (i + 1) * DAILY_INFLATION / 4);
tr.claim_staker_rewards(&pool_owner.pubkey(), &staker)
.await
.unwrap();
let staker_stats = tr.staker_stats(staker.pubkey()).await.unwrap();
assert_eq!(
staker_stats.balance,
(2 * i + 1) * DAILY_INFLATION / 4
);
tr.claim_pool_rewards(&pool_owner2).await.unwrap();
let pool_stats = tr.pool_stats(pool_owner2.pubkey()).await.unwrap();
assert_eq!(pool_stats.balance, (i + 1) * DAILY_INFLATION / 4);
tr.claim_bond_rewards(&pool_owner2.pubkey(), &staker)
.await
.unwrap();
let staker_stats = tr.staker_stats(staker.pubkey()).await.unwrap();
assert_eq!(staker_stats.balance, (i + 1) * DAILY_INFLATION / 2);
}
}
#[tokio::test]
async fn rewards_over_bound() {
let mut tr = TestRunner::new(DAILY_INFLATION).await.unwrap();
let pool_owner = tr.create_user_with_ata().await.unwrap();
let pool_owner2 = tr.create_user_with_ata().await.unwrap();
tr.create_pool(&pool_owner, 1_000_000_000)
.await
.unwrap();
tr.create_pool(&pool_owner2, 1_000_000_000)
.await
.unwrap();
tr.activate_stake_pool(&pool_owner.pubkey()).await.unwrap();
tr.activate_stake_pool(&pool_owner2.pubkey()).await.unwrap();
let staker = tr.create_user_with_ata().await.unwrap();
tr.mint(&staker.pubkey(), 5_100_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();
tr.create_bond(
&pool_owner2.pubkey(),
&staker.pubkey(),
5_000_000_000,
1,
8 * DAY as i64,
1,
)
.await
.unwrap();
tr.claim_bond(&pool_owner2.pubkey(), &staker.pubkey())
.await
.unwrap();
for i in 0..STAKE_BUFFER_LEN - 5 {
tr.sleep(DAY).await.unwrap();
tr.crank_pool(&pool_owner.pubkey()).await.unwrap();
tr.crank_pool(&pool_owner2.pubkey()).await.unwrap();
tr.claim_pool_rewards(&pool_owner).await.unwrap();
let pool_stats = tr.pool_stats(pool_owner.pubkey()).await.unwrap();
assert_eq!(pool_stats.balance, (i + 1) * DAILY_INFLATION / 4);
tr.claim_staker_rewards(&pool_owner.pubkey(), &staker)
.await
.unwrap();
let staker_stats = tr.staker_stats(staker.pubkey()).await.unwrap();
assert_eq!(
staker_stats.balance,
2 * i * DAILY_INFLATION / 4 + DAILY_INFLATION / 4
);
tr.claim_pool_rewards(&pool_owner2).await.unwrap();
let pool_stats = tr.pool_stats(pool_owner2.pubkey()).await.unwrap();
assert_eq!(pool_stats.balance, (i + 1) * DAILY_INFLATION / 4);
tr.claim_bond_rewards(&pool_owner2.pubkey(), &staker)
.await
.unwrap();
let staker_stats = tr.staker_stats(staker.pubkey()).await.unwrap();
assert_eq!(staker_stats.balance, 2 * (i + 1) * DAILY_INFLATION / 4);
}
for _ in 0..10 {
tr.sleep(DAY).await.unwrap();
tr.crank_pool(&pool_owner.pubkey()).await.unwrap();
tr.crank_pool(&pool_owner2.pubkey()).await.unwrap();
}
tr.claim_pool_rewards(&pool_owner).await.unwrap();
let pool_stats = tr.pool_stats(pool_owner.pubkey()).await.unwrap();
assert_eq!(
pool_stats.balance,
(STAKE_BUFFER_LEN + 5) * DAILY_INFLATION / 4
);
tr.claim_staker_rewards(&pool_owner.pubkey(), &staker)
.await
.unwrap();
let staker_stats = tr.staker_stats(staker.pubkey()).await.unwrap();
assert_eq!(
staker_stats.balance,
(STAKE_BUFFER_LEN - 5) * DAILY_INFLATION / 2 + 10 * DAILY_INFLATION / 4
);
tr.claim_pool_rewards(&pool_owner2).await.unwrap();
let pool_stats = tr.pool_stats(pool_owner2.pubkey()).await.unwrap();
assert_eq!(
pool_stats.balance,
(STAKE_BUFFER_LEN + 5) * DAILY_INFLATION / 4
);
tr.claim_bond_rewards(&pool_owner2.pubkey(), &staker)
.await
.unwrap();
let staker_stats = tr.staker_stats(staker.pubkey()).await.unwrap();
assert_eq!(
staker_stats.balance,
(STAKE_BUFFER_LEN + 5) * DAILY_INFLATION / 2
);
let pool_owner3 = tr.create_user_with_ata().await.unwrap();
tr.create_pool(&pool_owner3, 1_000_000_000)
.await
.unwrap();
tr.activate_stake_pool(&pool_owner3.pubkey()).await.unwrap();
let pool_stats = tr.pool_stats(pool_owner3.pubkey()).await.unwrap();
assert_eq!(pool_stats.balance, 0);
assert_eq!(pool_stats.header.last_claimed_offset, STAKE_BUFFER_LEN + 5);
tr.create_stake_account(&pool_owner3.pubkey(), &staker.pubkey())
.await
.unwrap();
tr.mint(&staker.pubkey(), 5_100_000_000).await.unwrap();
tr.stake(&pool_owner3.pubkey(), &staker, 5_000_000_000)
.await
.unwrap();
tr.sleep(DAY).await.unwrap();
tr.crank_pool(&pool_owner3.pubkey()).await.unwrap();
tr.claim_pool_rewards(&pool_owner3).await.unwrap();
let pool_stats = tr.pool_stats(pool_owner3.pubkey()).await.unwrap();
assert_eq!(pool_stats.balance, DAILY_INFLATION / 6 + 1); assert_eq!(
pool_stats.header.current_day_idx as u64,
STAKE_BUFFER_LEN + 5 + 1
);
}
}