Skip to content

Commit

Permalink
solana: fix beneficiary in add history entry
Browse files Browse the repository at this point in the history
  • Loading branch information
a5-pickle committed Aug 14, 2024
1 parent c0d0308 commit c6bd633
Show file tree
Hide file tree
Showing 4 changed files with 20 additions and 91 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,6 @@ use crate::{
},
};
use anchor_lang::{prelude::*, system_program};
use anchor_spl::token;

#[derive(Accounts)]
pub struct AddAuctionHistoryEntry<'info> {
Expand Down Expand Up @@ -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>,
}
Expand Down
5 changes: 1 addition & 4 deletions solana/ts/src/idl/json/matching_engine.json
Original file line number Diff line number Diff line change
Expand Up @@ -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"
}
Expand Down
5 changes: 1 addition & 4 deletions solana/ts/src/idl/ts/matching_engine.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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"
}
Expand Down
82 changes: 13 additions & 69 deletions solana/ts/tests/01__matchingEngine.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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(
{
Expand All @@ -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" },
);
});

Expand Down Expand Up @@ -4161,7 +4133,6 @@ describe("Matching Engine", function () {
auction?: PublicKey;
history: PublicKey;
beneficiary?: PublicKey;
beneficiaryToken?: PublicKey;
},
opts: ForTestOpts &
ObserveCctpOrderVaasOpts &
Expand Down Expand Up @@ -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 {
Expand All @@ -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,
})
Expand Down Expand Up @@ -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;
Expand Down

0 comments on commit c6bd633

Please sign in to comment.