#![cfg(feature = "test-bpf")] mod test_factory; use test_factory::*; use agsol_gold_contract::pda::*; use agsol_gold_contract::state::*; use agsol_gold_contract::AuctionContractError; use agsol_gold_contract::ID as CONTRACT_ID; use agsol_testbench::tokio; use solana_program::pubkey::Pubkey; use solana_sdk::signer::Signer; const CLOSE_AUCTION_CYCLE_COST_EXISTING_MARKER: u64 = 16_557_840; #[tokio::test] async fn test_process_claim_funds() { let (mut testbench, auction_owner) = test_factory::testbench_setup().await.unwrap().unwrap(); let auction_id = [1; 32]; let auction_config = AuctionConfig { cycle_period: 60, encore_period: 1, minimum_bid_amount: 50_000_000, // lamports number_of_cycles: Some(2), }; let user_1 = TestUser::new(&mut testbench).await.unwrap().unwrap(); let auction_cycle_payer = TestUser::new(&mut testbench) .await .unwrap() .unwrap() .keypair; initialize_new_auction( &mut testbench, &auction_owner.keypair, &auction_config, auction_id, TokenType::Nft, ) .await .unwrap() .unwrap(); let (auction_root_state_pubkey, _) = Pubkey::find_program_address(&auction_root_state_seeds(&auction_id), &CONTRACT_ID); let (auction_bank_pubkey, _) = Pubkey::find_program_address(&auction_bank_seeds(&auction_id), &CONTRACT_ID); // Invalid use case // Trying to claim from an auction with insufficient treasury let claim_amount = 1_000_000; let not_enough_funds_to_claim_error = claim_funds_transaction( &mut testbench, auction_id, &auction_owner.keypair, claim_amount, ) .await .unwrap() .err() .unwrap(); assert_eq!( not_enough_funds_to_claim_error, AuctionContractError::InvalidClaimAmount ); // Test single bid let bid_amount = 50_000_000; place_bid_transaction(&mut testbench, auction_id, &user_1.keypair, bid_amount) .await .unwrap() .unwrap(); // Invalid use case // Trying to claim funds from the current auction cycle let current_bid_claim_error = claim_funds_transaction( &mut testbench, auction_id, &auction_owner.keypair, claim_amount, ) .await .unwrap() .err() .unwrap(); assert_eq!( current_bid_claim_error, AuctionContractError::InvalidClaimAmount ); // Make the auction cycle reach end time warp_to_cycle_end(&mut testbench, auction_id).await.unwrap(); // Close auction cycle so that we can claim funds let balance_change = close_cycle_transaction( &mut testbench, &auction_cycle_payer, auction_id, &auction_owner.keypair.pubkey(), TokenType::Nft, ) .await .unwrap() .unwrap(); assert_eq!( -balance_change as u64, CLOSE_AUCTION_CYCLE_COST_EXISTING_MARKER + TRANSACTION_FEE, ); // claim all treasury from not ended auction should be prohibited due to rent let claim_all = testbench .get_account_lamports(&auction_bank_pubkey) .await .unwrap(); let error = claim_funds_transaction( &mut testbench, auction_id, &auction_owner.keypair, claim_all, ) .await .unwrap() .err() .unwrap(); assert_eq!(error, AuctionContractError::InvalidClaimAmount); let auction_root_state = testbench .get_and_deserialize_account_data::(&auction_root_state_pubkey) .await .unwrap(); assert_eq!(auction_root_state.available_funds, bid_amount); assert_eq!(auction_root_state.all_time_treasury, bid_amount); // This should be successful because the auction cycle of the bid has ended let owner_balance_change = claim_funds_transaction( &mut testbench, auction_id, &auction_owner.keypair, claim_amount, ) .await .unwrap() .unwrap(); assert_eq!( claim_amount / 20 * 19 - TRANSACTION_FEE, owner_balance_change as u64 ); let auction_root_state = testbench .get_and_deserialize_account_data::(&auction_root_state_pubkey) .await .unwrap(); assert_eq!( auction_root_state.available_funds, bid_amount - claim_amount ); assert_eq!(auction_root_state.all_time_treasury, bid_amount); // Closing last (second) auction cycle will only extend it because there was // no bid warp_to_cycle_end(&mut testbench, auction_id).await.unwrap(); close_cycle_transaction( &mut testbench, &auction_cycle_payer, auction_id, &auction_owner.keypair.pubkey(), TokenType::Nft, ) .await .unwrap() .unwrap(); // Claim funds from the ended auction let owner_balance_change = claim_funds_transaction( &mut testbench, auction_id, &auction_owner.keypair, claim_amount, ) .await .unwrap() .unwrap(); assert_eq!( claim_amount / 20 * 19 - TRANSACTION_FEE, owner_balance_change as u64 ); // Claiming ALL funds from the auction should be an error because it has not ended yet. let claim_all = testbench .get_account_lamports(&auction_bank_pubkey) .await .unwrap(); let error = claim_funds_transaction( &mut testbench, auction_id, &auction_owner.keypair, claim_all, ) .await .unwrap() .err() .unwrap(); assert_eq!(error, AuctionContractError::InvalidClaimAmount); let (contract_bank_pubkey, _) = Pubkey::find_program_address(&contract_bank_seeds(), &CONTRACT_ID); let contract_balance_before = testbench .get_account_lamports(&contract_bank_pubkey) .await .unwrap(); let owner_balance_change = claim_funds_transaction( &mut testbench, auction_id, &auction_owner.keypair, claim_amount, ) .await .unwrap() .unwrap(); let contract_balance_after = testbench .get_account_lamports(&contract_bank_pubkey) .await .unwrap(); assert_eq!( claim_amount / 20 * 19 - TRANSACTION_FEE, owner_balance_change as u64 ); assert_eq!( claim_amount - (claim_amount / 20 * 19), contract_balance_after - contract_balance_before ); // second bid place_bid_transaction(&mut testbench, auction_id, &user_1.keypair, bid_amount) .await .unwrap() .unwrap(); warp_to_cycle_end(&mut testbench, auction_id).await.unwrap(); // close second cycle for real close_cycle_transaction( &mut testbench, &auction_cycle_payer, auction_id, &auction_owner.keypair.pubkey(), TokenType::Nft, ) .await .unwrap() .unwrap(); let auction_root_state = testbench .get_and_deserialize_account_data::(&auction_root_state_pubkey) .await .unwrap(); assert!(!auction_root_state.status.is_frozen); assert!(auction_root_state.status.is_finished); // claim all treasury from ended auction let claim_all = testbench .get_account_lamports(&auction_bank_pubkey) .await .unwrap(); claim_funds_transaction( &mut testbench, auction_id, &auction_owner.keypair, claim_all, ) .await .unwrap() .unwrap(); }