diff --git a/auctioneer/program/src/cancel/mod.rs b/auctioneer/program/src/cancel/mod.rs index 8849d91211..049e7e605a 100644 --- a/auctioneer/program/src/cancel/mod.rs +++ b/auctioneer/program/src/cancel/mod.rs @@ -156,7 +156,7 @@ pub fn auctioneer_cancel<'info>( // Close the Listing Config account if the seller is canceling their listing. if ctx.accounts.token_account.owner == ctx.accounts.wallet.key() - && ctx.accounts.wallet.is_signer + && ctx.accounts.wallet.is_signer && buyer_price == AUCTIONEER_BUYER_PRICE { let listing_config = &ctx.accounts.listing_config.to_account_info(); let seller = &ctx.accounts.seller.to_account_info(); diff --git a/auctioneer/program/tests/cancel.rs b/auctioneer/program/tests/cancel.rs index b54652c364..0bd76a771d 100644 --- a/auctioneer/program/tests/cancel.rs +++ b/auctioneer/program/tests/cancel.rs @@ -467,3 +467,127 @@ async fn cancel_highest_bid() { ); context.banks_client.process_transaction(tx2).await.unwrap(); } + +#[tokio::test] +async fn cancel_seller_bid() { + let mut context = auctioneer_program_test().start_with_context().await; + // Payer Wallet + let (ah, ahkey, _) = existing_auction_house_test_context(&mut context) + .await + .unwrap(); + let test_metadata = Metadata::new(); + airdrop(&mut context, &test_metadata.token.pubkey(), 1000000000) + .await + .unwrap(); + test_metadata + .create( + &mut context, + "Tests".to_string(), + "TST".to_string(), + "uri".to_string(), + None, + 10, + false, + 1, + ) + .await + .unwrap(); + + let price = 1000000000; + + 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, + Some(true), + ); + context + .banks_client + .process_transaction(sell_tx) + .await + .unwrap(); + + context.warp_to_slot(100).unwrap(); + // Buyer = Seller : The seller bids on its own listing. + // Derive Auction House Key + airdrop(&mut context, &test_metadata.token.pubkey(), 2000000000) + .await + .unwrap(); + let (acc, buy_tx) = buy( + &mut context, + &ahkey, + &ah, + &test_metadata, + &test_metadata.token.pubkey(), + &test_metadata.token, + &sell_acc.wallet, + &listing_config_address, + price, + ); + + context + .banks_client + .process_transaction(buy_tx) + .await + .unwrap(); + let (auctioneer_authority, aa_bump) = find_auctioneer_authority_seeds(&ahkey); + let (auctioneer_pda, _) = find_auctioneer_pda(&ahkey, &auctioneer_authority); + let accounts = mpl_auctioneer::accounts::AuctioneerCancel { + auction_house_program: mpl_auction_house::id(), + listing_config: listing_config_address, + seller: sell_acc.wallet, + auction_house: ahkey, + wallet: test_metadata.token.pubkey(), + token_account: acc.token_account, + authority: ah.authority, + trade_state: acc.buyer_trade_state, + token_program: spl_token::id(), + token_mint: test_metadata.mint.pubkey(), + auction_house_fee_account: ah.auction_house_fee_account, + auctioneer_authority, + ah_auctioneer_pda: auctioneer_pda, + } + .to_account_metas(None); + let instruction = Instruction { + program_id: mpl_auctioneer::id(), + data: mpl_auctioneer::instruction::Cancel { + auctioneer_authority_bump: aa_bump, + buyer_price: price, + token_size: 1, + } + .data(), + accounts, + }; + + let tx = Transaction::new_signed_with_payer( + &[instruction], + Some(&test_metadata.token.pubkey()), + &[&test_metadata.token], + context.last_blockhash, + ); + context.banks_client.process_transaction(tx).await.unwrap(); + + // Make sure the trade state wasn't erroneously closed. + let listing_config_closed = context + .banks_client + .get_account(listing_config_address) + .await + .unwrap(); + + assert!(listing_config_closed.is_some()); +} \ No newline at end of file