diff --git a/programs/mpl-staking/tests/test_claim.rs b/programs/mpl-staking/tests/test_claim.rs index 4ac6a478..065bf250 100644 --- a/programs/mpl-staking/tests/test_claim.rs +++ b/programs/mpl-staking/tests/test_claim.rs @@ -6,11 +6,28 @@ use solana_program_test::*; use solana_sdk::{signature::Keypair, signer::Signer, transport::TransportError}; use spl_governance::state::vote_record::get_vote_record_address; use std::str::FromStr; +use mplx_staking_states::error::MplStakingError; +use crate::program_test::utils::assert_custom_on_chain_error::AssertCustomOnChainErr; mod program_test; -#[tokio::test] -async fn successeful_claim() -> Result<(), TransportError> { +struct CLaimSetup { + context: TestContext, + realm: GovernanceRealmCookie, + mint_governance: MintGovernanceCookie, + proposal: ProposalCookie, + voter: VoterCookie, + voter_authority: Keypair, + registrar: RegistrarCookie, + rewards_pool: Pubkey, + reward_mint: Pubkey, + deposit_mining: Pubkey, + voter_authority_ata: Pubkey, + realm_authority: Keypair, + payer: Keypair, +} + +async fn setup(realm_name: &str) -> Result { let context = TestContext::new().await; let payer = &context.users[0].key; @@ -18,7 +35,7 @@ async fn successeful_claim() -> Result<(), TransportError> { let realm = context .governance .create_realm( - REALM_NAME, + realm_name, realm_authority.pubkey(), &context.mints[0], payer, @@ -208,44 +225,66 @@ async fn successeful_claim() -> Result<(), TransportError> { ) .await .unwrap(); - realm + + Ok(CLaimSetup { + voter_authority: clone_keypair(voter_authority), + payer: clone_keypair(payer), + context, + realm, + mint_governance, + proposal, + voter, + registrar, + rewards_pool, + reward_mint: *reward_mint, + deposit_mining, + voter_authority_ata, + realm_authority, + }) +} + +#[tokio::test] +async fn successeful_claim() -> Result<(), TransportError> { + let claim_setup = setup(REALM_NAME).await?; + + claim_setup.realm .cast_vote( - mint_governance.address, - &proposal, - &voter, - voter_authority, - payer, - context + claim_setup.mint_governance.address, + &claim_setup.proposal, + &claim_setup.voter, + &claim_setup.voter_authority, + &claim_setup.payer, + claim_setup.context .addin - .update_voter_weight_record_instruction(®istrar, &voter), + .update_voter_weight_record_instruction(&claim_setup.registrar, &claim_setup.voter), ) .await .unwrap(); let vote_record = get_vote_record_address( &Pubkey::from_str(GOVERNANCE_PROGRAM_ID).unwrap(), - &proposal.address, - &proposal.owner_token_owner_record, + &claim_setup.proposal.address, + &claim_setup.proposal.owner_token_owner_record, ); - context + claim_setup.context .addin .claim( - &rewards_pool, - reward_mint, - &deposit_mining, - voter_authority, - &voter_authority_ata, - &context.rewards.program_id, - ®istrar, - &mint_governance.address, - &proposal.address, + &claim_setup.rewards_pool, + &claim_setup.reward_mint, + &claim_setup.deposit_mining, + &claim_setup.voter_authority, + &claim_setup.voter_authority_ata, + &claim_setup.context.rewards.program_id, + &claim_setup.registrar, + &claim_setup.mint_governance.address, + &claim_setup.proposal.address, &vote_record, ) .await?; - let claimed_amount = context + let claimed_amount = claim_setup.context .solana - .token_account_balance(voter_authority_ata) + .token_account_balance(claim_setup.voter_authority_ata) .await; assert_eq!(100, claimed_amount); @@ -254,247 +293,52 @@ async fn successeful_claim() -> Result<(), TransportError> { #[tokio::test] async fn claim_is_restricted() -> Result<(), TransportError> { - let context = TestContext::new().await; - - let payer = &context.users[0].key; - let realm_authority = Keypair::new(); - let realm = context - .governance - .create_realm( - REALM_NAME, - realm_authority.pubkey(), - &context.mints[0], - payer, - &context.addin.program_id, - ) - .await; - - let deposit_authority = &context.users[1].key; - let token_owner_record = realm - .create_token_owner_record(deposit_authority.pubkey(), payer) - .await; - - let fill_authority = Keypair::from_bytes(&context.users[3].key.to_bytes()).unwrap(); - let distribution_authority = Keypair::new(); - let (registrar, rewards_pool) = context - .addin - .create_registrar( - &realm, - &realm_authority, - payer, - &fill_authority.pubkey(), - &distribution_authority.pubkey(), - &context.rewards.program_id, - ) - .await; - context - .addin - .configure_voting_mint( - ®istrar, - &realm_authority, - payer, - 0, - &context.mints[0], - None, - None, - ) - .await; - let mngo_voting_mint = context - .addin - .configure_voting_mint( - ®istrar, - &realm_authority, - payer, - 0, - &context.mints[0], - None, - None, - ) - .await; + let claim_setup = setup(REALM_NAME).await?; - // TODO: ??? voter_authority == deposit_authority ??? - let voter_authority = deposit_authority; - let (deposit_mining, _) = find_deposit_mining_addr( - &context.rewards.program_id, - &voter_authority.pubkey(), - &rewards_pool, - ); - let voter_authority_ata = context - .rewards - .solana - .create_spl_ata( - &voter_authority.pubkey(), - &mngo_voting_mint.mint.pubkey.unwrap(), - payer, - ) - .await; - let voter = context - .addin - .create_voter( - ®istrar, - &token_owner_record, - voter_authority, - payer, - &rewards_pool, - &deposit_mining, - &context.rewards.program_id, - ) - .await; - - let depositer_token_account = context.users[1].token_accounts[0]; - - context - .addin - .create_deposit_entry( - ®istrar, - &voter, - &voter, - &mngo_voting_mint, - 0, - LockupKind::None, - LockupPeriod::None, - ) - .await?; - context - .addin - .create_deposit_entry( - ®istrar, - &voter, - &voter, - &mngo_voting_mint, - 1, - LockupKind::Constant, - LockupPeriod::ThreeMonths, - ) - .await?; - - context - .addin - .deposit( - ®istrar, - &voter, - &mngo_voting_mint, - deposit_authority, - depositer_token_account, - 0, - 10000, - ) - .await?; - - context - .addin - .stake( - ®istrar, - &voter, - voter.authority.pubkey(), - &context.rewards.program_id, - 0, - 1, - 10000, - ) - .await?; - - let rewards_source_ata = context.users[3].token_accounts[0]; - let amount = 100; - let distribution_ends_at = context - .solana - .context - .borrow_mut() - .banks_client - .get_sysvar::() - .await - .unwrap() - .unix_timestamp as u64 - + 86400; - - let reward_mint = &realm.community_token_mint.pubkey.unwrap(); - context - .rewards - .fill_vault( - &rewards_pool, - reward_mint, - &fill_authority, - &rewards_source_ata, - amount, - distribution_ends_at, - ) - .await - .unwrap(); - - context - .rewards - .distribute_rewards(&rewards_pool, &distribution_authority) - .await?; - - let mint_governance = realm - .create_mint_governance( - context.mints[0].pubkey.unwrap(), - &context.mints[0].authority, - &voter, - voter_authority, - payer, - context - .addin - .update_voter_weight_record_instruction(®istrar, &voter), - ) - .await; - - let proposal = realm - .create_proposal( - mint_governance.address, - voter_authority, - &voter, - payer, - context - .addin - .update_voter_weight_record_instruction(®istrar, &voter), - ) - .await - .unwrap(); - realm + claim_setup.realm .cast_vote( - mint_governance.address, - &proposal, - &voter, - voter_authority, - payer, - context + claim_setup.mint_governance.address, + &claim_setup.proposal, + &claim_setup.voter, + &claim_setup.voter_authority, + &claim_setup.payer, + claim_setup.context .addin - .update_voter_weight_record_instruction(®istrar, &voter), + .update_voter_weight_record_instruction(&claim_setup.registrar, &claim_setup.voter), ) .await .unwrap(); let vote_record = get_vote_record_address( &Pubkey::from_str(GOVERNANCE_PROGRAM_ID).unwrap(), - &proposal.address, - &proposal.owner_token_owner_record, + &claim_setup.proposal.address, + &claim_setup.proposal.owner_token_owner_record, ); - context + claim_setup.context .addin .restrict_tokenflow( - &rewards_pool, - &deposit_mining, - ®istrar, - &realm_authority, - &voter_authority.pubkey(), - &context.rewards.program_id, + &claim_setup.rewards_pool, + &claim_setup.deposit_mining, + &claim_setup.registrar, + &claim_setup.realm_authority, + &claim_setup.voter_authority.pubkey(), + &claim_setup.context.rewards.program_id, ) .await .unwrap(); - context + claim_setup.context .addin .claim( - &rewards_pool, - reward_mint, - &deposit_mining, - voter_authority, - &voter_authority_ata, - &context.rewards.program_id, - ®istrar, - &mint_governance.address, - &proposal.address, + &claim_setup.rewards_pool, + &claim_setup.reward_mint, + &claim_setup.deposit_mining, + &claim_setup.voter_authority, + &claim_setup.voter_authority_ata, + &claim_setup.context.rewards.program_id, + &claim_setup.registrar, + &claim_setup.mint_governance.address, + &claim_setup.proposal.address, &vote_record, ) .await @@ -505,284 +349,135 @@ async fn claim_is_restricted() -> Result<(), TransportError> { #[tokio::test] async fn claim_is_allowed() -> Result<(), TransportError> { - let context = TestContext::new().await; - - let payer = &context.users[0].key; - let realm_authority = Keypair::new(); - let realm = context - .governance - .create_realm( - REALM_NAME, - realm_authority.pubkey(), - &context.mints[0], - payer, - &context.addin.program_id, - ) - .await; - - let deposit_authority = &context.users[1].key; - let token_owner_record = realm - .create_token_owner_record(deposit_authority.pubkey(), payer) - .await; - - let fill_authority = Keypair::from_bytes(&context.users[3].key.to_bytes()).unwrap(); - let distribution_authority = Keypair::new(); - let (registrar, rewards_pool) = context - .addin - .create_registrar( - &realm, - &realm_authority, - payer, - &fill_authority.pubkey(), - &distribution_authority.pubkey(), - &context.rewards.program_id, - ) - .await; - context - .addin - .configure_voting_mint( - ®istrar, - &realm_authority, - payer, - 0, - &context.mints[0], - None, - None, - ) - .await; - let mngo_voting_mint = context - .addin - .configure_voting_mint( - ®istrar, - &realm_authority, - payer, - 0, - &context.mints[0], - None, - None, - ) - .await; - - // TODO: ??? voter_authority == deposit_authority ??? - let voter_authority = deposit_authority; - let (deposit_mining, _) = find_deposit_mining_addr( - &context.rewards.program_id, - &voter_authority.pubkey(), - &rewards_pool, - ); - let voter_authority_ata = context - .rewards - .solana - .create_spl_ata( - &voter_authority.pubkey(), - &mngo_voting_mint.mint.pubkey.unwrap(), - payer, - ) - .await; - let voter = context - .addin - .create_voter( - ®istrar, - &token_owner_record, - voter_authority, - payer, - &rewards_pool, - &deposit_mining, - &context.rewards.program_id, - ) - .await; - - let depositer_token_account = context.users[1].token_accounts[0]; + let claim_setup = setup(REALM_NAME).await?; - context - .addin - .create_deposit_entry( - ®istrar, - &voter, - &voter, - &mngo_voting_mint, - 0, - LockupKind::None, - LockupPeriod::None, - ) - .await?; - context - .addin - .create_deposit_entry( - ®istrar, - &voter, - &voter, - &mngo_voting_mint, - 1, - LockupKind::Constant, - LockupPeriod::ThreeMonths, - ) - .await?; - - context - .addin - .deposit( - ®istrar, - &voter, - &mngo_voting_mint, - deposit_authority, - depositer_token_account, - 0, - 10000, - ) - .await?; - - context - .addin - .stake( - ®istrar, - &voter, - voter.authority.pubkey(), - &context.rewards.program_id, - 0, - 1, - 10000, - ) - .await?; - - let rewards_source_ata = context.users[3].token_accounts[0]; - let amount = 100; - let distribution_ends_at = context - .solana - .context - .borrow_mut() - .banks_client - .get_sysvar::() - .await - .unwrap() - .unix_timestamp as u64 - + 86400; - - let reward_mint = &realm.community_token_mint.pubkey.unwrap(); - context - .rewards - .fill_vault( - &rewards_pool, - reward_mint, - &fill_authority, - &rewards_source_ata, - amount, - distribution_ends_at, - ) - .await - .unwrap(); - - context - .rewards - .distribute_rewards(&rewards_pool, &distribution_authority) - .await?; - - let mint_governance = realm - .create_mint_governance( - context.mints[0].pubkey.unwrap(), - &context.mints[0].authority, - &voter, - voter_authority, - payer, - context - .addin - .update_voter_weight_record_instruction(®istrar, &voter), - ) - .await; - - let proposal = realm - .create_proposal( - mint_governance.address, - voter_authority, - &voter, - payer, - context - .addin - .update_voter_weight_record_instruction(®istrar, &voter), - ) - .await - .unwrap(); - realm + claim_setup.realm .cast_vote( - mint_governance.address, - &proposal, - &voter, - voter_authority, - payer, - context + claim_setup.mint_governance.address, + &claim_setup.proposal, + &claim_setup.voter, + &claim_setup.voter_authority, + &claim_setup.payer, + claim_setup.context .addin - .update_voter_weight_record_instruction(®istrar, &voter), + .update_voter_weight_record_instruction(&claim_setup.registrar, &claim_setup.voter), ) .await .unwrap(); let vote_record = get_vote_record_address( &Pubkey::from_str(GOVERNANCE_PROGRAM_ID).unwrap(), - &proposal.address, - &proposal.owner_token_owner_record, + &claim_setup.proposal.address, + &claim_setup.proposal.owner_token_owner_record, ); - context + claim_setup.context .addin .restrict_tokenflow( - &rewards_pool, - &deposit_mining, - ®istrar, - &realm_authority, - &voter_authority.pubkey(), - &context.rewards.program_id, + &claim_setup.rewards_pool, + &claim_setup.deposit_mining, + &claim_setup.registrar, + &claim_setup.realm_authority, + &claim_setup.voter_authority.pubkey(), + &claim_setup.context.rewards.program_id, ) .await?; - context + claim_setup.context .addin .claim( - &rewards_pool, - reward_mint, - &deposit_mining, - voter_authority, - &voter_authority_ata, - &context.rewards.program_id, - ®istrar, - &mint_governance.address, - &proposal.address, + &claim_setup.rewards_pool, + &claim_setup.reward_mint, + &claim_setup.deposit_mining, + &claim_setup.voter_authority, + &claim_setup.voter_authority_ata, + &claim_setup.context.rewards.program_id, + &claim_setup.registrar, + &claim_setup.mint_governance.address, + &claim_setup.proposal.address, &vote_record, ) .await .expect_err("Claiming is restricted by Rewards program"); - context + claim_setup.context .addin .allow_tokenflow( - &rewards_pool, - &deposit_mining, - ®istrar, - &realm_authority, - &voter_authority.pubkey(), - &context.rewards.program_id, + &claim_setup.rewards_pool, + &claim_setup.deposit_mining, + &claim_setup.registrar, + &claim_setup.realm_authority, + &claim_setup.voter_authority.pubkey(), + &claim_setup.context.rewards.program_id, ) .await?; - context + claim_setup.context .addin .claim( - &rewards_pool, - reward_mint, - &deposit_mining, - voter_authority, - &voter_authority_ata, - &context.rewards.program_id, - ®istrar, - &mint_governance.address, - &proposal.address, + &claim_setup.rewards_pool, + &claim_setup.reward_mint, + &claim_setup.deposit_mining, + &claim_setup.voter_authority, + &claim_setup.voter_authority_ata, + &claim_setup.context.rewards.program_id, + &claim_setup.registrar, + &claim_setup.mint_governance.address, + &claim_setup.proposal.address, &vote_record, ) .await?; - let claimed_amount = context + let claimed_amount = claim_setup.context .solana - .token_account_balance(voter_authority_ata) + .token_account_balance(claim_setup.voter_authority_ata) .await; assert_eq!(100, claimed_amount); Ok(()) } + +#[tokio::test] +async fn claim_without_dao_vote_fail() -> Result<(), TransportError> { + // Create realm wi th invalid seed + let claim_setup = setup("Realm").await?; + + // DAO with invalid seed vote + claim_setup.realm + .cast_vote( + claim_setup.mint_governance.address, + &claim_setup.proposal, + &claim_setup.voter, + &claim_setup.voter_authority, + &claim_setup.payer, + claim_setup.context + .addin + .update_voter_weight_record_instruction(&claim_setup.registrar, &claim_setup.voter), + ) + .await + .unwrap(); + let vote_record = get_vote_record_address( + &Pubkey::from_str(GOVERNANCE_PROGRAM_ID).unwrap(), + &claim_setup.proposal.address, + &claim_setup.proposal.owner_token_owner_record, + ); + + // Check do we voted into valid DAO, but we dont + claim_setup.context + .addin + .claim( + &claim_setup.rewards_pool, + &claim_setup.reward_mint, + &claim_setup.deposit_mining, + &claim_setup.voter_authority, + &claim_setup.voter_authority_ata, + &claim_setup.context.rewards.program_id, + &claim_setup.registrar, + &claim_setup.mint_governance.address, + &claim_setup.proposal.address, + &vote_record, + ) + .await + .assert_on_chain_err(MplStakingError::NoDaoInteractionFound); + + Ok(()) +} \ No newline at end of file