Skip to content
This repository was archived by the owner on Jun 16, 2025. It is now read-only.

Commit 200f5bd

Browse files
committed
settle order in test
1 parent 0b9c764 commit 200f5bd

File tree

3 files changed

+60
-81
lines changed

3 files changed

+60
-81
lines changed

solana/ts/src/protocol/matchingEngine.ts

Lines changed: 26 additions & 55 deletions
Original file line numberDiff line numberDiff line change
@@ -169,7 +169,7 @@ export class SolanaMatchingEngine<N extends Network, C extends SolanaChains>
169169

170170
async *placeInitialOffer(
171171
sender: AnySolanaAddress,
172-
vaa: FastTransfer.VAA,
172+
vaa: VAA<"FastTransfer:FastMarketOrder">,
173173
offerPrice: bigint,
174174
totalDeposit?: bigint,
175175
) {
@@ -189,7 +189,11 @@ export class SolanaMatchingEngine<N extends Network, C extends SolanaChains>
189189
yield this.createUnsignedTx({ transaction }, "MatchingEngine.placeInitialOffer");
190190
}
191191

192-
async *improveOffer(sender: AnySolanaAddress, vaa: FastTransfer.VAA, offer: bigint) {
192+
async *improveOffer(
193+
sender: AnySolanaAddress,
194+
vaa: VAA<"FastTransfer:FastMarketOrder">,
195+
offer: bigint,
196+
) {
193197
const participant = new SolanaAddress(sender).unwrap();
194198
const auction = this.auctionAddress(keccak256(vaa.hash));
195199

@@ -201,11 +205,9 @@ export class SolanaMatchingEngine<N extends Network, C extends SolanaChains>
201205

202206
async *executeFastOrder(
203207
sender: AnySolanaAddress,
204-
vaa: FastTransfer.VAA,
208+
vaa: VAA<"FastTransfer:FastMarketOrder">,
205209
participant?: AnySolanaAddress,
206210
) {
207-
if (vaa.payloadLiteral !== "FastTransfer:FastMarketOrder") throw new Error("Invalid VAA");
208-
209211
const payer = new SolanaAddress(sender).unwrap();
210212

211213
const initialParticipant = participant
@@ -219,6 +221,8 @@ export class SolanaMatchingEngine<N extends Network, C extends SolanaChains>
219221

220222
const digest = keccak256(vaa.hash);
221223
const auction = this.auctionAddress(digest);
224+
225+
// TODO: make sure this has already been done, or do it here
222226
const reservedSequence = this.reservedFastFillSequenceAddress(digest);
223227

224228
const { targetChain } = vaa.payload;
@@ -272,6 +276,14 @@ export class SolanaMatchingEngine<N extends Network, C extends SolanaChains>
272276
Buffer.from(finalized.hash),
273277
);
274278

279+
const preparedAddress = this.preparedOrderResponseAddress(keccak256(fast.hash));
280+
281+
try {
282+
// Check if its already been prepared
283+
await this.fetchPreparedOrderResponse({ address: preparedAddress });
284+
return;
285+
} catch {}
286+
275287
const ix = await this.prepareOrderResponseCctpIx(
276288
{ payer, fastVaa, finalizedVaa },
277289
{
@@ -288,75 +300,34 @@ export class SolanaMatchingEngine<N extends Network, C extends SolanaChains>
288300
yield this.createUnsignedTx({ transaction }, "MatchingEngine.prepareOrderResponse");
289301
}
290302

291-
async *settleAuctionComplete(
303+
async *settleOrder(
292304
sender: AnySolanaAddress,
293305
fast: VAA<"FastTransfer:FastMarketOrder">,
294-
finalized: VAA<"FastTransfer:CctpDeposit">,
295-
cctp: {
306+
finalized?: VAA<"FastTransfer:CctpDeposit">,
307+
cctp?: {
296308
message: CircleBridge.Message;
297309
attestation: CircleAttestation;
298310
},
299311
lookupTables?: AddressLookupTableAccount[],
300312
) {
301-
const payer = new SolanaAddress(sender).unwrap();
302-
303-
const fastVaa = coreUtils.derivePostedVaaKey(
304-
this.coreBridgeProgramId(),
305-
Buffer.from(fast.hash),
306-
);
307-
308-
const finalizedVaa = coreUtils.derivePostedVaaKey(
309-
this.coreBridgeProgramId(),
310-
Buffer.from(finalized.hash),
311-
);
312-
313-
const prepareIx = await this.prepareOrderResponseCctpIx(
314-
{ payer, fastVaa, finalizedVaa },
315-
{
316-
encodedCctpMessage: Buffer.from(CircleBridge.serialize(cctp.message)),
317-
cctpAttestation: Buffer.from(cctp.attestation, "hex"),
318-
},
319-
);
313+
// If the finalized VAA and CCTP message/attestation are passed
314+
// we may try to prepare the order response
315+
if (finalized && cctp)
316+
yield* this.prepareOrderResponse(sender, fast, finalized, cctp, lookupTables);
320317

318+
const executor = new SolanaAddress(sender).unwrap();
321319
const preparedAddress = this.preparedOrderResponseAddress(keccak256(fast.hash));
322320

323-
const computeIx = ComputeBudgetProgram.setComputeUnitLimit({
324-
units: 300_000,
325-
});
326-
327-
const executor = new SolanaAddress(sender).unwrap();
328321
const settleIx = await this.settleAuctionCompleteIx({
329322
executor,
330323
preparedOrderResponse: preparedAddress,
331324
});
332325

333-
const transaction = await this.createTx(
334-
executor,
335-
[prepareIx, settleIx, computeIx],
336-
undefined,
337-
lookupTables,
338-
);
326+
const transaction = await this.createTx(executor, [settleIx], undefined, lookupTables);
339327

340328
yield this.createUnsignedTx({ transaction }, "MatchingEngine.settleAuctionComplete");
341329
}
342330

343-
settleAuction(): AsyncGenerator<UnsignedTransaction<N, C>, any, unknown> {
344-
throw new Error("Method not implemented.");
345-
}
346-
347-
getAuctionGracePeriod(): Promise<number> {
348-
throw new Error("Method not implemented.");
349-
}
350-
getAuctionDuration(): Promise<number> {
351-
throw new Error("Method not implemented.");
352-
}
353-
getPenaltyBlocks(): Promise<number> {
354-
throw new Error("Method not implemented.");
355-
}
356-
getInitialPenaltyBps(): Promise<number> {
357-
throw new Error("Method not implemented.");
358-
}
359-
360331
private async createTx(
361332
payerKey: PublicKey,
362333
instructions: TransactionInstruction[],

solana/ts/tests/01__matchingEngine.ts

Lines changed: 11 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -4304,7 +4304,7 @@ describe("Matching Engine", function () {
43044304
);
43054305

43064306
// Improve the bid with offer one.
4307-
const { signer } = getSdkSigner<"Devnet">(connection, participant);
4307+
const { signer } = getSdkSigner(connection, participant);
43084308
await expectTxsOk(signer, txs);
43094309

43104310
const auctionDataBefore = await engine.fetchAuction({ address: auction });
@@ -4549,9 +4549,8 @@ describe("Matching Engine", function () {
45494549
let { executorIsPreparer, prepareSigners, preparedInSameTransaction } = excludedForTestOpts;
45504550
executorIsPreparer ??= true;
45514551
prepareSigners ??= [playerOneSigner];
4552+
preparedInSameTransaction ??= false; // TODO: do something with this
45524553

4553-
//
4554-
preparedInSameTransaction ??= false; // TODO: do something with this (like what?)
45554554
if (preparedInSameTransaction) {
45564555
throw new Error("preparedInSameTransaction not implemented");
45574556
}
@@ -4599,7 +4598,6 @@ describe("Matching Engine", function () {
45994598
}
46004599

46014600
const fastVaaAccount = await VaaAccount.fetch(connection, fastVaa);
4602-
46034601
const auction = accounts.auction ?? engine.auctionAddress(fastVaaAccount.digest());
46044602
const { info, status: statusBefore } = await engine.fetchAuction({
46054603
address: auction,
@@ -4640,7 +4638,13 @@ describe("Matching Engine", function () {
46404638
.getAccountInfo(preparedCustodyToken)
46414639
.then((info) => info!.lamports);
46424640

4643-
await expectIxOk(connection, [ix], [payer]);
4641+
const txs = engine.settleOrder(
4642+
executor,
4643+
fastVaaAccount.vaa("FastTransfer:FastMarketOrder"),
4644+
);
4645+
4646+
const signer = executorIsPreparer ? prepareSigners[0] : payerSigner;
4647+
await expectTxsOk(signer, txs);
46444648

46454649
{
46464650
const accInfo = await connection.getAccountInfo(preparedCustodyToken);
@@ -4655,6 +4659,7 @@ describe("Matching Engine", function () {
46554659
connection,
46564660
bestOfferToken,
46574661
);
4662+
46584663
const finalizedVaaAccount = await VaaAccount.fetch(connection, finalizedVaa);
46594664
const { deposit } = LiquidityLayerMessage.decode(finalizedVaaAccount.payload());
46604665
const { baseFee } = deposit!.message.payload! as SlowOrderResponse;
@@ -4677,7 +4682,7 @@ describe("Matching Engine", function () {
46774682

46784683
const authorityLamportsAfter = await connection.getBalance(executor);
46794684
expect(authorityLamportsAfter).equals(
4680-
authorityLamportsBefore + preparedOrderLamports + preparedCustodyLamports,
4685+
authorityLamportsBefore + preparedOrderLamports + preparedCustodyLamports - 5000,
46814686
);
46824687

46834688
const { status: statusAfter } = await engine.fetchAuction({

universal/ts/src/protocol.ts

Lines changed: 23 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -38,12 +38,6 @@ export interface FastTransfer<N extends Network, C extends Chain> {
3838

3939
// matching engine: this is only on solana and where the auctions happen
4040
export interface MatchingEngine<N extends Network, C extends Chain> {
41-
// Read methods
42-
getAuctionGracePeriod(): Promise<number>;
43-
getAuctionDuration(): Promise<number>;
44-
getPenaltyBlocks(): Promise<number>;
45-
getInitialPenaltyBps(): Promise<number>;
46-
4741
// Admin methods
4842
registerRouter<RC extends Chain>(
4943
sender: AccountAddress<C>,
@@ -52,6 +46,19 @@ export interface MatchingEngine<N extends Network, C extends Chain> {
5246
router: AccountAddress<RC>,
5347
tokenAccount?: AccountAddress<C>,
5448
): AsyncGenerator<UnsignedTransaction<N, C>>;
49+
updateRouter<RC extends Chain>(
50+
sender: AccountAddress<C>,
51+
chain: RC,
52+
cctpDomain: number, // TODO: should be typed?
53+
router: AccountAddress<RC>,
54+
tokenAccount?: AccountAddress<C>,
55+
): AsyncGenerator<UnsignedTransaction<N, C>>;
56+
disableRouter<RC extends Chain>(
57+
sender: AccountAddress<C>,
58+
chain: RC,
59+
): AsyncGenerator<UnsignedTransaction<N, C>>;
60+
61+
setPause(sender: AccountAddress<C>, pause: boolean): AsyncGenerator<UnsignedTransaction<N, C>>;
5562
setConfiguration(config: {
5663
enabled: boolean;
5764
maxAmount: bigint;
@@ -68,29 +75,26 @@ export interface MatchingEngine<N extends Network, C extends Chain> {
6875
offerPrice: bigint,
6976
totalDeposit?: bigint,
7077
): AsyncGenerator<UnsignedTransaction<N, C>>;
71-
72-
// improves the offer TODO: alias for bid id?
7378
improveOffer(
7479
sender: AccountAddress<C>,
7580
vaa: VAA<"FastTransfer:FastMarketOrder">,
7681
offer: bigint,
7782
): AsyncGenerator<UnsignedTransaction<N, C>>;
78-
79-
//this basically fulfills the fast order like sending the cctp message to dst chain
8083
executeFastOrder(
8184
sender: AccountAddress<C>,
8285
vaa: VAA<"FastTransfer:FastMarketOrder">,
8386
): AsyncGenerator<UnsignedTransaction<N, C>>;
84-
85-
// cleans up a fast order by transferring funds/closing account/executing penalty
86-
settleAuctionComplete(
87+
prepareOrderResponse(
88+
sender: AccountAddress<C>,
89+
vaa: VAA<"FastTransfer:FastMarketOrder">,
90+
deposit: VAA<"FastTransfer:CctpDeposit">,
91+
cctp: CircleBridge.Attestation,
92+
): AsyncGenerator<UnsignedTransaction<N, C>>;
93+
settleOrder(
8794
sender: AccountAddress<C>,
8895
fast: VAA<"FastTransfer:FastMarketOrder">,
89-
finalized: VAA<"FastTransfer:CctpDeposit">,
90-
cctp: {
91-
message: CircleBridge.Message;
92-
attestation: CircleAttestation;
93-
},
96+
deposit?: VAA<"FastTransfer:CctpDeposit">,
97+
cctp?: CircleBridge.Attestation,
9498
): AsyncGenerator<UnsignedTransaction<N, C>>;
9599
}
96100

@@ -118,8 +122,7 @@ export interface TokenRouter<N extends Network = Network, C extends Chain = Chai
118122

119123
redeemFill(
120124
vaa: FastTransfer.VAA,
121-
circleBridgeMessage: CircleTransferMessage,
122-
circleAttestation: CircleAttestation,
125+
cctp: CircleBridge.Attestation,
123126
): AsyncGenerator<UnsignedTransaction<N, C>>;
124127
}
125128

0 commit comments

Comments
 (0)