diff --git a/solana/programs/matching-engine/src/processor/auction/history/add_entry.rs b/solana/programs/matching-engine/src/processor/auction/history/add_entry.rs index d49ac2a0..502dd097 100644 --- a/solana/programs/matching-engine/src/processor/auction/history/add_entry.rs +++ b/solana/programs/matching-engine/src/processor/auction/history/add_entry.rs @@ -8,7 +8,6 @@ use crate::{ }, }; use anchor_lang::{prelude::*, system_program}; -use anchor_spl::token; #[derive(Accounts)] pub struct AddAuctionHistoryEntry<'info> { @@ -62,21 +61,13 @@ pub struct AddAuctionHistoryEntry<'info> { )] auction: Account<'info, Auction>, - /// CHECK: This account will either be the owner of the fee recipient token account (if there - /// was no auction) or the owner of the initial offer token account. - #[account(mut)] - beneficiary: UncheckedAccount<'info>, - + /// CHECK: This account is whoever originally created the auction account (see + /// [Auction::prepared_by]. #[account( - token::authority = beneficiary, - address = { - match &auction.info { - Some(info) => info.initial_offer_token, - None => custodian.fee_recipient_token, - } - } + mut, + address = auction.prepared_by, )] - beneficiary_token: Account<'info, token::TokenAccount>, + beneficiary: UncheckedAccount<'info>, system_program: Program<'info, system_program::System>, } diff --git a/solana/ts/src/idl/json/matching_engine.json b/solana/ts/src/idl/json/matching_engine.json index b913f336..a94b37b8 100644 --- a/solana/ts/src/idl/json/matching_engine.json +++ b/solana/ts/src/idl/json/matching_engine.json @@ -65,13 +65,10 @@ { "name": "beneficiary", "docs": [ - "was no auction) or the owner of the initial offer token account." + "[Auction::prepared_by]." ], "writable": true }, - { - "name": "beneficiary_token" - }, { "name": "system_program" } diff --git a/solana/ts/src/idl/ts/matching_engine.ts b/solana/ts/src/idl/ts/matching_engine.ts index abf9df3a..75ce8915 100644 --- a/solana/ts/src/idl/ts/matching_engine.ts +++ b/solana/ts/src/idl/ts/matching_engine.ts @@ -71,13 +71,10 @@ export type MatchingEngine = { { "name": "beneficiary", "docs": [ - "was no auction) or the owner of the initial offer token account." + "[Auction::prepared_by]." ], "writable": true }, - { - "name": "beneficiaryToken" - }, { "name": "systemProgram" } diff --git a/solana/ts/tests/01__matchingEngine.ts b/solana/ts/tests/01__matchingEngine.ts index cf5fb49f..57461d0f 100644 --- a/solana/ts/tests/01__matchingEngine.ts +++ b/solana/ts/tests/01__matchingEngine.ts @@ -3881,35 +3881,20 @@ describe("Matching Engine", function () { ); }); - it("Cannot Add Entry from Settled Complete Auction with Beneficiary Token != Initial Offer Token", async function () { + it("Cannot Add Entry from Settled Complete Auction with Beneficiary != Auction's Preparer", async function () { await addAuctionHistoryEntryForTest( { payer: payer.publicKey, history: engine.auctionHistoryAddress(0), - beneficiary: payer.publicKey, + beneficiary: Keypair.generate().publicKey, }, { settlementType: "complete", - errorMsg: "beneficiary_token. Error Code: ConstraintAddress", + errorMsg: "beneficiary. Error Code: ConstraintAddress", }, ); }); - it("Cannot Add Entry from Settled Complete Auction with Beneficiary != Initial Offer Token Owner", async function () { - await addAuctionHistoryEntryForTest( - { - payer: payer.publicKey, - history: engine.auctionHistoryAddress(0), - beneficiary: payer.publicKey, - beneficiaryToken: splToken.getAssociatedTokenAddressSync( - USDC_MINT_ADDRESS, - playerOne.publicKey, - ), - }, - { settlementType: "complete", errorMsg: "Error Code: ConstraintTokenOwner" }, - ); - }); - it("Add Entry from Settled Complete Auction After Expiration Time", async function () { await addAuctionHistoryEntryForTest( { @@ -3936,30 +3921,17 @@ describe("Matching Engine", function () { ); }); - it("Cannot Close Auction Account from Settled Auction None with Beneficiary Token != Fee Recipient Token", async function () { + it("Cannot Close Auction Account from Settled Auction None with Beneficiary != Auction's Preparer", async function () { await addAuctionHistoryEntryForTest( { payer: payer.publicKey, history: engine.auctionHistoryAddress(0), - beneficiary: payer.publicKey, + beneficiary: Keypair.generate().publicKey, }, { settlementType: "none", - errorMsg: "beneficiary_token. Error Code: ConstraintAddress", - }, - ); - }); - - it("Cannot Close Auction Account from Settled Auction None with Beneficiary != Fee Recipient", async function () { - const { feeRecipientToken } = await engine.fetchCustodian(); - await addAuctionHistoryEntryForTest( - { - payer: payer.publicKey, - history: engine.auctionHistoryAddress(0), - beneficiary: payer.publicKey, - beneficiaryToken: feeRecipientToken, + errorMsg: "beneficiary. Error Code: ConstraintAddress", }, - { settlementType: "none", errorMsg: "Error Code: ConstraintTokenOwner" }, ); }); @@ -4161,7 +4133,6 @@ describe("Matching Engine", function () { auction?: PublicKey; history: PublicKey; beneficiary?: PublicKey; - beneficiaryToken?: PublicKey; }, opts: ForTestOpts & ObserveCctpOrderVaasOpts & @@ -4194,8 +4165,8 @@ describe("Matching Engine", function () { return result!.auction; } else if (settlementType == "none") { const result = await settleAuctionNoneCctpForTest( - { payer: payer.publicKey }, - { vaaTimestamp }, + { payer: playerOne.publicKey }, + { vaaTimestamp, signers: [playerOne] }, ); return result!.auction; } else { @@ -4209,47 +4180,19 @@ describe("Matching Engine", function () { await waitUntilTimestamp(connection, current + timeToWait); } - const { beneficiary, beneficiaryToken } = await (async () => { - if (accounts.beneficiary !== undefined) { - return { - beneficiary: accounts.beneficiary, - beneficiaryToken: - accounts.beneficiaryToken ?? - splToken.getAssociatedTokenAddressSync( - USDC_MINT_ADDRESS, - accounts.beneficiary, - ), - }; - } else { - const { info } = await engine.fetchAuction({ address: auction }); - const beneficiaryToken = await (async () => { - if (info === null) { - const custodian = await engine.fetchCustodian(); - return custodian.feeRecipientToken; - } else { - return info!.initialOfferToken; - } - })(); - const { owner } = await splToken.getAccount(connection, beneficiaryToken); - return { - beneficiary: owner, - beneficiaryToken: accounts.beneficiaryToken ?? beneficiaryToken, - }; - } - })(); - - const { vaaHash, vaaTimestamp, info } = await engine.fetchAuction({ + const { vaaHash, vaaTimestamp, info, preparedBy } = await engine.fetchAuction({ address: auction, }); expect(info === null).equals(settlementType === "none"); + const beneficiary = accounts.beneficiary ?? preparedBy; + const ix = await engine.program.methods .addAuctionHistoryEntry() .accounts({ ...accounts, auction, beneficiary, - beneficiaryToken, custodian: engine.checkedCustodianComposite(), systemProgram: SystemProgram.programId, }) @@ -4964,11 +4907,12 @@ describe("Matching Engine", function () { } else { const result = await prepareOrderResponseCctpForTest( { - payer: payer.publicKey, + payer: accounts.payer, }, { ...excludedForTestOpts, placeInitialOffer: false, + signers, }, ); expect(typeof result == "object" && "preparedOrderResponse" in result).is.true;