Skip to content

Commit

Permalink
Add tests
Browse files Browse the repository at this point in the history
  • Loading branch information
KartikSoneji committed Mar 24, 2023
1 parent 2e87911 commit 159ce1b
Showing 1 changed file with 287 additions and 3 deletions.
290 changes: 287 additions & 3 deletions auctioneer/program/tests/execute_sale.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,11 +7,16 @@ use utils::setup_functions::*;

use anchor_lang::{InstructionData, ToAccountMetas};
use mpl_testing_utils::{solana::airdrop, utils::Metadata};
use solana_sdk::{compute_budget::ComputeBudgetInstruction, signer::Signer};
use solana_sdk::{
account::Account as SolanaAccount, compute_budget::ComputeBudgetInstruction, signer::Signer,
};

use std::{assert_eq, time::SystemTime};

use solana_program::{instruction::Instruction, system_program, sysvar};
use solana_program::{
instruction::{AccountMeta, Instruction},
system_program, sysvar,
};

use solana_program::program_pack::Pack;

Expand All @@ -20,7 +25,8 @@ use mpl_auction_house::pda::{
find_trade_state_address,
};
use mpl_auctioneer::pda::find_auctioneer_authority_seeds;
use solana_sdk::{signature::Keypair, transaction::Transaction};
use mpl_token_metadata::state::Creator;
use solana_sdk::{pubkey::Pubkey, signature::Keypair, transaction::Transaction};
use spl_associated_token_account::get_associated_token_address;
use spl_token::state::Account;

Expand Down Expand Up @@ -782,3 +788,281 @@ async fn execute_sale_two_bids_failure() {

assert_error!(result, NOT_HIGH_BIDDER)
}

#[tokio::test]
async fn execute_sale_one_creator() {
execute_sale_with_creators(vec![(Pubkey::new_unique(), 100)]).await;
}

#[tokio::test]
async fn execute_sale_two_creator() {
execute_sale_with_creators(vec![(Pubkey::new_unique(), 25), (Pubkey::new_unique(), 75)]).await;
}

async fn execute_sale_with_creators(metadata_creators: Vec<(Pubkey, u8)>) {
let mut context = auctioneer_program_test().start_with_context().await;
// Payer Wallet
let (ah, ahkey, authority) = existing_auction_house_test_context(&mut context)
.await
.unwrap();
let test_metadata = Metadata::new();
airdrop(&mut context, &test_metadata.token.pubkey(), 10_000_000_000)
.await
.unwrap();

for (creator, _) in &metadata_creators {
// airdrop 0.1 sol to ensure rent-exempt minimum
airdrop(&mut context, &creator, 100_000_000).await.unwrap();
}
test_metadata
.create(
&mut context,
"Test".to_string(),
"TST".to_string(),
"uri".to_string(),
Some(
metadata_creators
.clone()
.iter()
.map(|(address, share)| Creator {
address: *address,
verified: false,
share: *share,
})
.collect(),
),
1000,
false,
1,
)
.await
.unwrap();
let ((sell_acc, listing_config_address), sell_tx) = sell(
&mut context,
&ahkey,
&ah,
&test_metadata,
(SystemTime::now()
.duration_since(SystemTime::UNIX_EPOCH)
.expect("Time went backwards")
.as_secs()
- 60) as i64,
(SystemTime::now()
.duration_since(SystemTime::UNIX_EPOCH)
.expect("Time went backwards")
.as_secs()
+ 60) as i64,
None,
None,
None,
None,
None,
);
context
.banks_client
.process_transaction(sell_tx)
.await
.unwrap();

let buyer = Keypair::new();
airdrop(&mut context, &buyer.pubkey(), 10_000_000_000)
.await
.unwrap();
let (bid_acc, buy_tx) = buy(
&mut context,
&ahkey,
&ah,
&test_metadata,
&test_metadata.token.pubkey(),
&buyer,
&sell_acc.wallet,
&listing_config_address,
100_000_000,
);
context
.banks_client
.process_transaction(buy_tx)
.await
.unwrap();
let buyer_token_account =
get_associated_token_address(&buyer.pubkey(), &test_metadata.mint.pubkey());

context.warp_to_slot(120 * 400).unwrap();

let (auctioneer_authority, _aa_bump) = find_auctioneer_authority_seeds(&ahkey);
let (auctioneer_pda, _) = find_auctioneer_pda(&ahkey, &auctioneer_authority);
let mut accounts = mpl_auctioneer::accounts::AuctioneerExecuteSale {
auction_house_program: mpl_auction_house::id(),
listing_config: listing_config_address,
buyer: buyer.pubkey(),
seller: test_metadata.token.pubkey(),
authority: ah.authority,
auction_house: ahkey,
metadata: test_metadata.pubkey,
token_account: sell_acc.token_account,
seller_trade_state: sell_acc.seller_trade_state,
buyer_trade_state: bid_acc.buyer_trade_state,
token_program: spl_token::id(),
free_trade_state: sell_acc.free_seller_trade_state,
seller_payment_receipt_account: test_metadata.token.pubkey(),
buyer_receipt_token_account: buyer_token_account,
escrow_payment_account: bid_acc.escrow_payment_account,
token_mint: test_metadata.mint.pubkey(),
auction_house_fee_account: ah.auction_house_fee_account,
auction_house_treasury: ah.auction_house_treasury,
treasury_mint: ah.treasury_mint,
program_as_signer: sell_acc.program_as_signer,
system_program: system_program::id(),
ata_program: spl_associated_token_account::id(),
rent: sysvar::rent::id(),
auctioneer_authority,
ah_auctioneer_pda: auctioneer_pda,
}
.to_account_metas(None);
for (pubkey, _) in &metadata_creators {
accounts.push(AccountMeta {
pubkey: *pubkey,
is_signer: false,
is_writable: true,
});
}

let (_, free_sts_bump) = find_trade_state_address(
&test_metadata.token.pubkey(),
&ahkey,
&sell_acc.token_account,
&ah.treasury_mint,
&test_metadata.mint.pubkey(),
0,
1,
);
let (_, escrow_bump) = find_escrow_payment_address(&ahkey, &buyer.pubkey());
let (_, pas_bump) = find_program_as_signer_address();
let (_, aa_bump) = find_auctioneer_authority_seeds(&ahkey);

let instruction = Instruction {
program_id: mpl_auctioneer::id(),
data: mpl_auctioneer::instruction::ExecuteSale {
escrow_payment_bump: escrow_bump,
free_trade_state_bump: free_sts_bump,
program_as_signer_bump: pas_bump,
auctioneer_authority_bump: aa_bump,
token_size: 1,
buyer_price: 100_000_000,
}
.data(),
accounts,
};
airdrop(&mut context, &ah.auction_house_fee_account, 10_000_000_000)
.await
.unwrap();

let compute_ix = ComputeBudgetInstruction::set_compute_unit_limit(350_000);

let tx = Transaction::new_signed_with_payer(
&[compute_ix, instruction],
Some(&authority.pubkey()),
&[&authority],
context.last_blockhash,
);
let seller_before = context
.banks_client
.get_account(test_metadata.token.pubkey())
.await
.unwrap()
.unwrap();
let mut metadata_creators_before: Vec<SolanaAccount> = Vec::new();
for (creator, _) in &metadata_creators {
metadata_creators_before.push(
context
.banks_client
.get_account(*creator)
.await
.unwrap()
.unwrap(),
);
}
let buyer_token_before = &context
.banks_client
.get_account(buyer_token_account)
.await
.unwrap();
assert!(buyer_token_before.is_none());

let listing_config_account = context
.banks_client
.get_account(listing_config_address)
.await
.unwrap()
.unwrap();

context.banks_client.process_transaction(tx).await.unwrap();

let seller_after = context
.banks_client
.get_account(test_metadata.token.pubkey())
.await
.unwrap()
.unwrap();
let mut metadata_creators_after: Vec<SolanaAccount> = Vec::new();
for (creator, _) in &metadata_creators {
metadata_creators_after.push(
context
.banks_client
.get_account(*creator)
.await
.unwrap()
.unwrap(),
);
}
let buyer_token_after = Account::unpack_from_slice(
context
.banks_client
.get_account(buyer_token_account)
.await
.unwrap()
.unwrap()
.data
.as_slice(),
)
.unwrap();

let royalty = (test_metadata
.get_data(&mut context)
.await
.data
.seller_fee_basis_points as u64
* 100_000_000)
/ 10000;
let fee_minus: u64 =
100_000_000 - royalty - ((ah.seller_fee_basis_points as u64 * (100_000_000)) / 10000);
assert!(seller_before.lamports < seller_after.lamports);
assert_eq!(buyer_token_after.amount, 1);

let rent = context.banks_client.get_rent().await.unwrap();
let rent_exempt_min: u64 = rent.minimum_balance(listing_config_account.data.len());

for (((_, share), creator_before), creator_after) in metadata_creators
.iter()
.zip(metadata_creators_before.iter())
.zip(metadata_creators_after.iter())
{
assert_eq!(
creator_before.lamports + (royalty * (*share as u64)) / 100,
creator_after.lamports
);
}

assert_eq!(
seller_before.lamports + fee_minus + rent_exempt_min,
seller_after.lamports
);

let listing_config_closed = context
.banks_client
.get_account(listing_config_address)
.await
.unwrap();

assert!(listing_config_closed.is_none());
}

0 comments on commit 159ce1b

Please sign in to comment.