use crate::{TestMintWrapper, quarry_mine, quarry_mint_wrapper};
use testsvm::prelude::*;
pub struct TestRewarder {
pub label: String,
pub rewarder: AccountRef<quarry_mine::accounts::Rewarder>,
pub mint_wrapper: TestMintWrapper,
pub minter: AccountRef<quarry_mint_wrapper::accounts::Minter>,
pub claim_fee_token_account: AccountRef<anchor_spl::token::TokenAccount>,
pub authority: Pubkey,
pub rewarder_base: Keypair,
}
impl TestRewarder {
pub fn new_rewarder(env: &mut TestSVM, label: &str, authority: &Keypair) -> Result<Self> {
let mint_wrapper = TestMintWrapper::new(env, &format!("rewarder[{label}]"), authority)?;
let rewarder_base = env.new_wallet(&format!("rewarder[{label}].rewarder_base"))?;
let rewarder = env.get_pda(
&format!("rewarder[{label}].rewarder"),
&[b"Rewarder", rewarder_base.pubkey().as_ref()],
quarry_mine::ID,
)?;
let (create_ata_ix, claim_fee_token_account) = env.create_ata_ix(
&format!("rewarder[{label}].claim_fee_tokens"),
&rewarder.key,
&mint_wrapper.reward_token_mint.key,
)?;
env.execute_ixs(&[create_ata_ix])?;
let create_rewarder_ix = anchor_instruction(
quarry_mine::ID,
quarry_mine::client::accounts::NewRewarderV2 {
base: rewarder_base.pubkey(),
rewarder: rewarder.key,
initial_authority: authority.pubkey(),
payer: env.default_fee_payer(),
system_program: solana_sdk::system_program::ID,
mint_wrapper: mint_wrapper.mint_wrapper.key,
rewards_token_mint: mint_wrapper.reward_token_mint.key,
claim_fee_token_account: claim_fee_token_account.key,
},
quarry_mine::client::args::NewRewarderV2 {},
);
env.execute_ixs_with_signers(&[create_rewarder_ix], &[&rewarder_base])?;
let minter = mint_wrapper.create_minter(env, &rewarder.key, u64::MAX, authority)?;
Ok(TestRewarder {
label: label.to_string(),
rewarder,
mint_wrapper,
minter,
authority: authority.pubkey(),
rewarder_base,
claim_fee_token_account,
})
}
pub fn create_quarry(
&self,
env: &mut TestSVM,
quarry_name: &str,
staked_token_mint: &Pubkey,
authority: &Keypair,
) -> Result<crate::TestQuarry> {
let quarry_label = format!("rewarder[{}].quarry[{}]", self.label, quarry_name);
let quarry = env.get_pda(
&format!("{quarry_label}.quarry"),
&[
b"Quarry",
self.rewarder.key.as_ref(),
staked_token_mint.as_ref(),
],
quarry_mine::ID,
)?;
use quarry_mine::client::accounts::TransferAuthority;
let create_quarry_ix = anchor_instruction(
quarry_mine::ID,
quarry_mine::client::accounts::CreateQuarryV2 {
quarry: quarry.key,
auth: TransferAuthority {
authority: authority.pubkey(),
rewarder: self.rewarder.key,
},
token_mint: *staked_token_mint,
payer: env.default_fee_payer(),
system_program: solana_sdk::system_program::ID,
},
quarry_mine::client::args::CreateQuarryV2 {},
);
let set_shares_ix = anchor_instruction(
quarry_mine::ID,
quarry_mine::client::accounts::SetRewardsShare {
auth: TransferAuthority {
authority: authority.pubkey(),
rewarder: self.rewarder.key,
},
quarry: quarry.key,
},
quarry_mine::client::args::SetRewardsShare { new_share: 1 },
);
env.execute_ixs_with_signers(&[create_quarry_ix, set_shares_ix], &[authority])?;
Ok(crate::TestQuarry {
label: quarry_label,
quarry,
rewarder: self.rewarder.key,
staked_token_mint: AccountRef::new(*staked_token_mint),
})
}
pub fn create_primary_quarry(
&self,
env: &mut TestSVM,
quarry_name: &str,
staked_token_mint: &Pubkey,
authority: &Keypair,
) -> Result<crate::TestQuarry> {
self.create_quarry(env, quarry_name, staked_token_mint, authority)
}
pub fn create_replica_quarry(
&self,
env: &mut TestSVM,
quarry_name: &str,
merge_pool: &crate::TestMergePool,
authority: &Keypair,
) -> Result<crate::TestQuarry> {
self.create_quarry(env, quarry_name, &merge_pool.replica_mint.key, authority)
}
pub fn fetch_rewarder(&self, env: &TestSVM) -> Result<quarry_mine::accounts::Rewarder> {
self.rewarder.load(env)
}
pub fn fetch_mint_wrapper(
&self,
env: &TestSVM,
) -> Result<quarry_mint_wrapper::accounts::MintWrapper> {
self.mint_wrapper.mint_wrapper.load(env)
}
pub fn set_annual_rewards_rate(
&self,
env: &mut TestSVM,
annual_rate: u64,
authority: &Keypair,
) -> TXResult {
let set_rewards_ix = anchor_instruction(
quarry_mine::ID,
quarry_mine::client::accounts::SetAnnualRewards {
auth: quarry_mine::client::accounts::TransferAuthority {
authority: authority.pubkey(),
rewarder: self.rewarder.key,
},
},
quarry_mine::client::args::SetAnnualRewards {
new_rate: annual_rate,
},
);
env.execute_ixs_with_signers(&[set_rewards_ix], &[authority])
}
pub fn new_minter(
&self,
env: &mut TestSVM,
label: &str,
authority: &Keypair,
) -> Result<TXResult> {
let (minter, minter_bump) = Pubkey::find_program_address(
&[
b"MintWrapperMinter",
self.mint_wrapper.mint_wrapper.key.as_ref(),
self.rewarder.key.as_ref(),
],
&quarry_mint_wrapper::ID,
);
let new_minter_ix = anchor_instruction(
quarry_mint_wrapper::ID,
quarry_mint_wrapper::client::accounts::NewMinter {
new_minter_auth: quarry_mint_wrapper::client::accounts::NewMinterAuth {
mint_wrapper: self.mint_wrapper.mint_wrapper.key,
admin: authority.pubkey(),
},
new_minter_authority: self.rewarder.key,
minter,
payer: env.default_fee_payer(),
system_program: solana_sdk::system_program::ID,
},
quarry_mint_wrapper::client::args::NewMinter { bump: minter_bump },
);
let result = env.execute_ixs_with_signers(&[new_minter_ix], &[authority]);
if result.is_ok() {
env.address_book.add_pda(
minter,
format!("rewarder[{}].minter[{}]", self.label, label),
vec![
"MintWrapperMinter".to_string(),
self.mint_wrapper.mint_wrapper.key.to_string(),
self.rewarder.key.to_string(),
],
quarry_mint_wrapper::ID,
minter_bump,
)?;
}
Ok(result)
}
}