From ecbe2bb40a75a80fc92740f9c201c91318aef0ad Mon Sep 17 00:00:00 2001 From: Hardhat Chad Date: Fri, 16 Feb 2024 19:26:15 +0000 Subject: [PATCH] claim test --- src/instruction.rs | 10 ++++++--- src/processor/claim.rs | 13 ++++++----- tests/test_mine.rs | 51 +++++++++++++++++++++++++++++++++++++----- 3 files changed, 60 insertions(+), 14 deletions(-) diff --git a/src/instruction.rs b/src/instruction.rs index 8e5d585..6e8c747 100644 --- a/src/instruction.rs +++ b/src/instruction.rs @@ -121,7 +121,7 @@ pub struct MineArgs { #[repr(C)] #[derive(Clone, Copy, Debug, Pod, Zeroable)] pub struct ClaimArgs { - pub amount: u64, + pub amount: [u8; 8], } #[repr(C)] @@ -209,11 +209,11 @@ pub fn initialize(signer: Pubkey) -> Instruction { } pub fn claim(signer: Pubkey, beneficiary: Pubkey, amount: u64) -> Instruction { + let proof = Pubkey::find_program_address(&[PROOF, signer.as_ref()], &crate::id()).0; let treasury_tokens = spl_associated_token_account::get_associated_token_address( &TREASURY_ADDRESS, &MINT_ADDRESS, ); - let proof = Pubkey::find_program_address(&[PROOF, signer.as_ref()], &crate::id()).0; Instruction { program_id: crate::id(), accounts: vec![ @@ -227,7 +227,11 @@ pub fn claim(signer: Pubkey, beneficiary: Pubkey, amount: u64) -> Instruction { ], data: [ OreInstruction::Claim.to_vec(), - ClaimArgs { amount }.to_bytes().to_vec(), + ClaimArgs { + amount: amount.to_le_bytes(), + } + .to_bytes() + .to_vec(), ] .concat(), } diff --git a/src/processor/claim.rs b/src/processor/claim.rs index 41b4dc7..fc7f8a5 100644 --- a/src/processor/claim.rs +++ b/src/processor/claim.rs @@ -19,6 +19,7 @@ pub fn process_claim<'a, 'info>( ) -> ProgramResult { // Parse args let args = ClaimArgs::try_from_bytes(data)?; + let amount = u64::from_le_bytes(args.amount); // Load accounts let [signer, beneficiary_info, mint_info, proof_info, treasury_info, treasury_tokens_info, token_program] = accounts else { @@ -39,19 +40,21 @@ pub fn process_claim<'a, 'info>( // Validate claim amout let mut proof_data = proof_info.data.borrow_mut(); let mut proof = Proof::try_from_bytes_mut(&mut proof_data)?; - if proof.claimable_rewards.lt(&args.amount) { + if proof.claimable_rewards.lt(&amount) { return Err(OreError::InvalidClaimAmount.into()); } // Update claimable amount - proof.claimable_rewards = proof.claimable_rewards.saturating_sub(args.amount); + proof.claimable_rewards = proof.claimable_rewards.saturating_sub(amount); // Update lifetime status let mut treasury_data = treasury_info.data.borrow_mut(); let mut treasury = Treasury::try_from_bytes_mut(&mut treasury_data)?; - treasury.total_claimed_rewards = treasury.total_claimed_rewards.saturating_add(args.amount); + treasury.total_claimed_rewards = treasury.total_claimed_rewards.saturating_add(amount); // Distribute tokens from treasury to beneficiary + let treasury_bump = treasury.bump; + drop(treasury_data); solana_program::program::invoke_signed( &spl_token::instruction::transfer( &spl_token::id(), @@ -59,7 +62,7 @@ pub fn process_claim<'a, 'info>( beneficiary_info.key, treasury_info.key, &[treasury_info.key], - args.amount, + amount, )?, &[ token_program.clone(), @@ -67,7 +70,7 @@ pub fn process_claim<'a, 'info>( beneficiary_info.clone(), treasury_info.clone(), ], - &[&[TREASURY, &[treasury.bump as u8]]], + &[&[TREASURY, &[treasury_bump as u8]]], )?; Ok(()) diff --git a/tests/test_mine.rs b/tests/test_mine.rs index ef126fd..fbab19a 100644 --- a/tests/test_mine.rs +++ b/tests/test_mine.rs @@ -21,6 +21,9 @@ use solana_sdk::{ signature::{Keypair, Signer}, transaction::Transaction, }; +use spl_associated_token_account::{ + get_associated_token_address, instruction::create_associated_token_account, +}; use spl_token::state::{AccountState, Mint}; #[tokio::test] @@ -45,15 +48,10 @@ async fn test_mine() { assert_eq!(proof.total_hashes, 0); assert_eq!(proof.total_rewards, 0); - // Assert proof state - let treasury_pda = Pubkey::find_program_address(&[TREASURY], &ore::id()); - let treasury_account = banks.get_account(treasury_pda.0).await.unwrap().unwrap(); - let treasury = Treasury::try_from_bytes(&treasury_account.data).unwrap(); - // Find next hash let (next_hash, nonce) = find_next_hash( proof.hash.into(), - treasury.difficulty.into(), + KeccakHash::new_from_array([u8::MAX; 32]), payer.pubkey(), ); @@ -81,6 +79,47 @@ async fn test_mine() { ); assert_eq!(proof.total_hashes, 1); assert_eq!(proof.total_rewards, INITIAL_REWARD_RATE); + + // Submit claim tx + let amount = proof.claimable_rewards; + let beneficiary_address = get_associated_token_address(&payer.pubkey(), &ore::MINT_ADDRESS); + let token_ix = create_associated_token_account( + &payer.pubkey(), + &payer.pubkey(), + &ore::MINT_ADDRESS, + &spl_token::id(), + ); + let ix = ore::instruction::claim(payer.pubkey(), beneficiary_address, amount); + let tx = + Transaction::new_signed_with_payer(&[token_ix, ix], Some(&payer.pubkey()), &[&payer], hash); + let res = banks.process_transaction(tx).await; + assert!(res.is_ok()); + + // Assert proof state + let proof_account = banks.get_account(proof_pda.0).await.unwrap().unwrap(); + let proof_ = Proof::try_from_bytes(&proof_account.data).unwrap(); + assert_eq!(proof_.authority, proof.authority); + assert_eq!(proof_.claimable_rewards, 0); + assert_eq!(proof_.hash, proof.hash); + assert_eq!(proof_.total_hashes, proof.total_hashes); + assert_eq!(proof_.total_rewards, proof.total_rewards); + + // Assert beneficiary state + let beneficiary_account = banks + .get_account(beneficiary_address) + .await + .unwrap() + .unwrap(); + assert_eq!(beneficiary_account.owner, spl_token::id()); + let beneficiary = spl_token::state::Account::unpack(&beneficiary_account.data).unwrap(); + assert_eq!(beneficiary.mint, ore::MINT_ADDRESS); + assert_eq!(beneficiary.owner, payer.pubkey()); + assert_eq!(beneficiary.amount, amount); + assert_eq!(beneficiary.delegate, COption::None); + assert_eq!(beneficiary.state, AccountState::Initialized); + assert_eq!(beneficiary.is_native, COption::None); + assert_eq!(beneficiary.delegated_amount, 0); + assert_eq!(beneficiary.close_authority, COption::None); } fn find_next_hash(hash: KeccakHash, difficulty: KeccakHash, signer: Pubkey) -> (KeccakHash, u64) {