From e0a37332089826aeb3e6b4609f80c13e38ef3e79 Mon Sep 17 00:00:00 2001 From: Nour Alharithi Date: Mon, 16 Dec 2024 11:44:48 -0800 Subject: [PATCH 1/3] remove swift messages from swift --- Anchor.toml | 2 +- programs/drift/src/instructions/keeper.rs | 44 ++-- programs/drift/src/lib.rs | 3 +- programs/drift/src/state/order_params.rs | 9 +- sdk/src/config.ts | 3 - sdk/src/driftClient.ts | 79 +------ sdk/src/driftClientConfig.ts | 1 - sdk/src/idl/drift.json | 43 +--- sdk/src/types.ts | 8 +- sdk/src/util/digest.ts | 5 + .../run-anchor-local-validator-tests.sh | 4 +- tests/placeAndMakeSwiftPerp.ts | 215 ++---------------- tests/placeAndMakeSwiftPerpBankrun.ts | 178 +++------------ 13 files changed, 86 insertions(+), 508 deletions(-) diff --git a/Anchor.toml b/Anchor.toml index dbaa02376..2ce0fc10c 100644 --- a/Anchor.toml +++ b/Anchor.toml @@ -7,7 +7,7 @@ exclude = ["programs/openbook_v2"] [scripts] # to run local validator tests, use "./test-scripts/run-ts-mocha" in "test" -test = "echo" # need to call anchor test to update metadata field in idl before running tests, so just do a noop +test = "./test-scripts/run-ts-mocha" # need to call anchor test to update metadata field in idl before running tests, so just do a noop lint = "yarn prettify:fix && cargo fmt" fulltest = 'cargo test && bash ./test-scripts/run-anchor-tests.sh' watch_ts = 'find ./programs/clearing_house/src/* ./tests ./sdk/src | entr -c bash ./test-scripts/single-anchor-test.sh' diff --git a/programs/drift/src/instructions/keeper.rs b/programs/drift/src/instructions/keeper.rs index c45c82d23..a50e2b765 100644 --- a/programs/drift/src/instructions/keeper.rs +++ b/programs/drift/src/instructions/keeper.rs @@ -40,9 +40,7 @@ use crate::state::fulfillment_params::serum::SerumFulfillmentParams; use crate::state::high_leverage_mode_config::HighLeverageModeConfig; use crate::state::insurance_fund_stake::InsuranceFundStake; use crate::state::oracle_map::OracleMap; -use crate::state::order_params::{ - OrderParams, PlaceOrderOptions, SwiftOrderParamsMessage, SwiftServerMessage, -}; +use crate::state::order_params::{OrderParams, PlaceOrderOptions, SwiftOrderParamsMessage}; use crate::state::paused_operations::PerpOperation; use crate::state::perp_market::{ContractType, MarketStatus, PerpMarket}; use crate::state::perp_market_map::{ @@ -603,11 +601,8 @@ pub fn handle_update_user_open_orders_count<'info>(ctx: Context) pub fn handle_place_swift_taker_order<'c: 'info, 'info>( ctx: Context<'_, '_, 'c, 'info, PlaceSwiftTakerOrder<'info>>, - swift_message_bytes: Vec, swift_order_params_message_bytes: Vec, ) -> Result<()> { - let swift_message: SwiftServerMessage = - SwiftServerMessage::deserialize(&mut &swift_message_bytes[..]).unwrap(); let taker_order_params_message: SwiftOrderParamsMessage = SwiftOrderParamsMessage::deserialize(&mut &swift_order_params_message_bytes[..]).unwrap(); @@ -634,7 +629,6 @@ pub fn handle_place_swift_taker_order<'c: 'info, 'info>( taker_key, &mut taker, &mut swift_taker, - swift_message, taker_order_params_message, &ctx.accounts.ix_sysvar.to_account_info(), &perp_market_map, @@ -649,7 +643,6 @@ pub fn place_swift_taker_order<'c: 'info, 'info>( taker_key: Pubkey, taker: &mut RefMut, swift_account: &mut SwiftUserOrdersZeroCopyMut, - swift_message: SwiftServerMessage, taker_order_params_message: SwiftOrderParamsMessage, ix_sysvar: &AccountInfo<'info>, perp_market_map: &PerpMarketMap, @@ -665,20 +658,12 @@ pub fn place_swift_taker_order<'c: 'info, 'info>( // Authenticate the swift param message let ix_idx = load_current_index_checked(ix_sysvar)?; validate!( - ix_idx > 1, + ix_idx > 0, ErrorCode::InvalidVerificationIxIndex, - "instruction index must be greater than 1 for two sig verifies" - )?; - - // Verify data from first verify ix - let ix: Instruction = load_instruction_at_checked(ix_idx as usize - 2, ix_sysvar)?; - verify_ed25519_msg( - &ix, - &swift_server::id().to_bytes(), - &digest_struct!(swift_message), + "instruction index must be greater than 0 for one sig verifies" )?; - // Verify data from second verify ix + // Verify data from verify ix let digest_hex = digest_struct_hex!(taker_order_params_message); let ix: Instruction = load_instruction_at_checked(ix_idx as usize - 1, ix_sysvar)?; verify_ed25519_msg( @@ -687,12 +672,7 @@ pub fn place_swift_taker_order<'c: 'info, 'info>( arrayref::array_ref!(digest_hex, 0, 64), )?; - // Verify that sig from swift server corresponds to order message - if swift_message.swift_order_signature != extract_ed25519_ix_signature(&ix.data)? { - msg!("Swift order signature does not match the order signature"); - return Err(ErrorCode::SigVerificationFailed.into()); - } - + let signature = extract_ed25519_ix_signature(&ix.data)?; let clock = &Clock::get()?; // First order must be a taker order @@ -715,7 +695,7 @@ pub fn place_swift_taker_order<'c: 'info, 'info>( } // Set max slot for the order early so we set correct swift order id - let order_slot = swift_message.slot; + let order_slot = taker_order_params_message.slot; let market_index = matching_taker_order_params.market_index; let max_slot = order_slot.safe_add( matching_taker_order_params @@ -735,7 +715,11 @@ pub fn place_swift_taker_order<'c: 'info, 'info>( } // Dont place order if swift order already exists - let swift_order_id = SwiftOrderId::new(swift_message.uuid, max_slot, taker.next_order_id); + let swift_order_id = SwiftOrderId::new( + taker_order_params_message.uuid, + max_slot, + taker.next_order_id, + ); if swift_account.check_exists_and_prune_stale_swift_order_ids(swift_order_id, clock.slot) { msg!("Swift order already exists for taker {}"); return Ok(()); @@ -757,10 +741,8 @@ pub fn place_swift_taker_order<'c: 'info, 'info>( }, )?; - let order_params_hash = base64::encode( - solana_program::hash::hash(&swift_message.swift_order_signature.try_to_vec().unwrap()) - .as_ref(), - ); + let order_params_hash = + base64::encode(solana_program::hash::hash(&signature.try_to_vec().unwrap()).as_ref()); emit!(SwiftOrderRecord { user: taker_key, diff --git a/programs/drift/src/lib.rs b/programs/drift/src/lib.rs index 444b11117..cde40ba8d 100644 --- a/programs/drift/src/lib.rs +++ b/programs/drift/src/lib.rs @@ -191,10 +191,9 @@ pub mod drift { pub fn place_swift_taker_order<'c: 'info, 'info>( ctx: Context<'_, '_, 'c, 'info, PlaceSwiftTakerOrder<'info>>, - swift_message_bytes: Vec, swift_order_params_message_bytes: Vec, ) -> Result<()> { - handle_place_swift_taker_order(ctx, swift_message_bytes, swift_order_params_message_bytes) + handle_place_swift_taker_order(ctx, swift_order_params_message_bytes) } pub fn place_and_match_rfq_orders<'c: 'info, 'info>( diff --git a/programs/drift/src/state/order_params.rs b/programs/drift/src/state/order_params.rs index 1564ed800..edad8fa02 100644 --- a/programs/drift/src/state/order_params.rs +++ b/programs/drift/src/state/order_params.rs @@ -706,17 +706,12 @@ impl OrderParams { } } -#[derive(AnchorSerialize, AnchorDeserialize, Clone, Eq, PartialEq, Debug)] -pub struct SwiftServerMessage { - pub uuid: [u8; 8], - pub swift_order_signature: [u8; 64], - pub slot: u64, -} - #[derive(AnchorSerialize, AnchorDeserialize, Clone, Default, Eq, PartialEq, Debug)] pub struct SwiftOrderParamsMessage { pub swift_order_params: OrderParams, pub sub_account_id: u16, + pub slot: u64, + pub uuid: [u8; 8], pub take_profit_order_params: Option, pub stop_loss_order_params: Option, } diff --git a/sdk/src/config.ts b/sdk/src/config.ts index bf4eea392..e32fced8d 100644 --- a/sdk/src/config.ts +++ b/sdk/src/config.ts @@ -44,9 +44,6 @@ export type DriftEnv = 'devnet' | 'mainnet-beta'; export const DRIFT_PROGRAM_ID = 'dRiftyHA39MWEi3m9aunc5MzRF1JYuBsbn6VPcn33UH'; export const DRIFT_ORACLE_RECEIVER_ID = 'G6EoTTTgpkNBtVXo96EQp2m6uwwVh2Kt6YidjkmQqoha'; -export const SWIFT_ID = 'SW1fThqrxLzVprnCMpiybiqYQfoNCdduC5uWsSUKChS'; -export const ANCHOR_TEST_SWIFT_ID = - 'DpaEdAPW3ZX67fnczT14AoX12Lx9VMkxvtT81nCHy3Nv'; export const PTYH_LAZER_PROGRAM_ID = 'pytd2yyk641x7ak7mkaasSJVXh6YYZnC7wTmtgAyxPt'; export const PYTH_LAZER_STORAGE_ACCOUNT_KEY = new PublicKey( diff --git a/sdk/src/driftClient.ts b/sdk/src/driftClient.ts index a0c433eb6..d6121acb1 100644 --- a/sdk/src/driftClient.ts +++ b/sdk/src/driftClient.ts @@ -54,7 +54,6 @@ import { StateAccount, SwapReduceOnly, SwiftOrderParamsMessage, - SwiftServerMessage, TakerInfo, TxParams, UserAccount, @@ -135,7 +134,6 @@ import { DRIFT_ORACLE_RECEIVER_ID, DEFAULT_CONFIRMATION_OPTS, DRIFT_PROGRAM_ID, - SWIFT_ID, DriftEnv, PYTH_LAZER_STORAGE_ACCOUNT_KEY, } from './config'; @@ -201,7 +199,6 @@ export class DriftClient { connection: Connection; wallet: IWallet; public program: Program; - public swiftID: PublicKey; provider: AnchorProvider; opts?: ConfirmOptions; users = new Map(); @@ -269,7 +266,6 @@ export class DriftClient { config.programID ?? new PublicKey(DRIFT_PROGRAM_ID), this.provider ); - this.swiftID = config.swiftID ?? new PublicKey(SWIFT_ID); this.authority = config.authority ?? this.wallet.publicKey; this.activeSubAccountId = config.activeSubAccountId ?? 0; @@ -5846,29 +5842,6 @@ export class DriftClient { ); } - public encodeSwiftServerMessage(message: SwiftServerMessage): Buffer { - return this.program.coder.types.encode('SwiftServerMessage', message); - } - - public decodeSwiftServerMessage(encodedMessage: Buffer): SwiftServerMessage { - const decodedSwiftMessage = this.program.coder.types.decode( - 'SwiftServerMessage', - encodedMessage - ); - return { - uuid: decodedSwiftMessage.uuid, - slot: decodedSwiftMessage.slot, - swiftOrderSignature: decodedSwiftMessage.swiftSignature, - }; - } - - public signSwiftServerMessage(message: SwiftServerMessage): Buffer { - const swiftServerMessage = Uint8Array.from( - digest(this.encodeSwiftServerMessage(message)) - ); - return this.signMessage(swiftServerMessage); - } - public signSwiftOrderParamsMessage( orderParamsMessage: SwiftOrderParamsMessage ): Buffer { @@ -5905,8 +5878,6 @@ export class DriftClient { } public async placeSwiftTakerOrder( - swiftServerMessage: Buffer, - swiftSignature: Buffer, swiftOrderParamsMessage: Buffer, swiftOrderParamsSignature: Buffer, marketIndex: number, @@ -5918,8 +5889,6 @@ export class DriftClient { txParams?: TxParams ): Promise { const ixs = await this.getPlaceSwiftTakerPerpOrderIxs( - swiftServerMessage, - swiftSignature, swiftOrderParamsMessage, swiftOrderParamsSignature, marketIndex, @@ -5934,8 +5903,6 @@ export class DriftClient { } public async getPlaceSwiftTakerPerpOrderIxs( - encodedSwiftServerMessage: Buffer, - swiftSignature: Buffer, encodedSwiftOrderParamsMessage: Buffer, swiftOrderParamsSignature: Buffer, marketIndex: number, @@ -5956,13 +5923,6 @@ export class DriftClient { readablePerpMarketIndex: marketIndex, }); - const swiftServerSignatureIx = - Ed25519Program.createInstructionWithPublicKey({ - publicKey: new PublicKey(this.swiftID).toBytes(), - signature: Uint8Array.from(swiftSignature), - message: Uint8Array.from(digest(encodedSwiftServerMessage)), - }); - const authorityToUse = authority || takerInfo.takerUserAccount.authority; const swiftOrderParamsSignatureIx = Ed25519Program.createInstructionWithPublicKey({ @@ -5975,7 +5935,6 @@ export class DriftClient { const placeTakerSwiftPerpOrderIx = await this.program.instruction.placeSwiftTakerOrder( - encodedSwiftServerMessage, encodedSwiftOrderParamsMessage, { accounts: { @@ -5993,16 +5952,10 @@ export class DriftClient { } ); - return [ - swiftServerSignatureIx, - swiftOrderParamsSignatureIx, - placeTakerSwiftPerpOrderIx, - ]; + return [swiftOrderParamsSignatureIx, placeTakerSwiftPerpOrderIx]; } public async placeAndMakeSwiftPerpOrder( - encodedSwiftMessage: Buffer, - swiftSignature: Buffer, encodedSwiftOrderParamsMessage: Buffer, swiftOrderParamsSignature: Buffer, swiftOrderUuid: Uint8Array, @@ -6017,8 +5970,6 @@ export class DriftClient { subAccountId?: number ): Promise { const ixs = await this.getPlaceAndMakeSwiftPerpOrderIxs( - encodedSwiftMessage, - swiftSignature, encodedSwiftOrderParamsMessage, swiftOrderParamsSignature, swiftOrderUuid, @@ -6038,8 +5989,6 @@ export class DriftClient { } public async getPlaceAndMakeSwiftPerpOrderIxs( - encodedSwiftMessage: Buffer, - swiftSignature: Buffer, encodedSwiftOrderParamsMessage: Buffer, swiftOrderParamsSignature: Buffer, swiftOrderUuid: Uint8Array, @@ -6052,18 +6001,13 @@ export class DriftClient { referrerInfo?: ReferrerInfo, subAccountId?: number ): Promise { - const [ - swiftServerSignatureIx, - swiftOrderSignatureIx, - placeTakerSwiftPerpOrderIx, - ] = await this.getPlaceSwiftTakerPerpOrderIxs( - encodedSwiftMessage, - swiftSignature, - encodedSwiftOrderParamsMessage, - swiftOrderParamsSignature, - orderParams.marketIndex, - takerInfo - ); + const [swiftOrderSignatureIx, placeTakerSwiftPerpOrderIx] = + await this.getPlaceSwiftTakerPerpOrderIxs( + encodedSwiftOrderParamsMessage, + swiftOrderParamsSignature, + orderParams.marketIndex, + takerInfo + ); orderParams = getOrderParams(orderParams, { marketType: MarketType.PERP }); const userStatsPublicKey = this.getUserStatsAccountPublicKey(); @@ -6112,12 +6056,7 @@ export class DriftClient { } ); - return [ - swiftServerSignatureIx, - swiftOrderSignatureIx, - placeTakerSwiftPerpOrderIx, - placeAndMakeIx, - ]; + return [swiftOrderSignatureIx, placeTakerSwiftPerpOrderIx, placeAndMakeIx]; } public encodeRFQMakerOrderParams(message: RFQMakerOrderParams): Buffer { diff --git a/sdk/src/driftClientConfig.ts b/sdk/src/driftClientConfig.ts index 5cf7f88ed..1b74de6ec 100644 --- a/sdk/src/driftClientConfig.ts +++ b/sdk/src/driftClientConfig.ts @@ -18,7 +18,6 @@ export type DriftClientConfig = { wallet: IWallet; env?: DriftEnv; programID?: PublicKey; - swiftID?: PublicKey; accountSubscription?: DriftClientSubscriptionConfig; opts?: ConfirmOptions; txSender?: TxSender; diff --git a/sdk/src/idl/drift.json b/sdk/src/idl/drift.json index 62b9efe71..22561a49b 100644 --- a/sdk/src/idl/drift.json +++ b/sdk/src/idl/drift.json @@ -813,10 +813,6 @@ } ], "args": [ - { - "name": "swiftMessageBytes", - "type": "bytes" - }, { "name": "swiftOrderParamsMessageBytes", "type": "bytes" @@ -9002,50 +8998,33 @@ } }, { - "name": "SwiftServerMessage", + "name": "SwiftOrderParamsMessage", "type": { "kind": "struct", "fields": [ { - "name": "uuid", + "name": "swiftOrderParams", "type": { - "array": [ - "u8", - 8 - ] + "defined": "OrderParams" } }, { - "name": "swiftOrderSignature", - "type": { - "array": [ - "u8", - 64 - ] - } + "name": "subAccountId", + "type": "u16" }, { "name": "slot", "type": "u64" - } - ] - } - }, - { - "name": "SwiftOrderParamsMessage", - "type": { - "kind": "struct", - "fields": [ + }, { - "name": "swiftOrderParams", + "name": "uuid", "type": { - "defined": "OrderParams" + "array": [ + "u8", + 8 + ] } }, - { - "name": "subAccountId", - "type": "u16" - }, { "name": "takeProfitOrderParams", "type": { diff --git a/sdk/src/types.ts b/sdk/src/types.ts index a61f6917e..055478e3f 100644 --- a/sdk/src/types.ts +++ b/sdk/src/types.ts @@ -1105,15 +1105,11 @@ export const DefaultOrderParams: OrderParams = { auctionEndPrice: null, }; -export type SwiftServerMessage = { - slot: BN; - swiftOrderSignature: Uint8Array; - uuid: Uint8Array; // From buffer of standard UUID string -}; - export type SwiftOrderParamsMessage = { swiftOrderParams: OptionalOrderParams; subAccountId: number; + uuid: Uint8Array; + slot: BN; takeProfitOrderParams: SwiftTriggerOrderParams | null; stopLossOrderParams: SwiftTriggerOrderParams | null; }; diff --git a/sdk/src/util/digest.ts b/sdk/src/util/digest.ts index fdb7f54fa..7a16c0143 100644 --- a/sdk/src/util/digest.ts +++ b/sdk/src/util/digest.ts @@ -1,4 +1,5 @@ import { createHash } from 'crypto'; +import { nanoid } from 'nanoid'; export function digest(data: Buffer): Buffer { const hash = createHash('sha256'); @@ -9,3 +10,7 @@ export function digest(data: Buffer): Buffer { export function digestSignature(signature: Uint8Array): string { return createHash('sha256').update(signature).digest('base64'); } + +export function generateSwiftUuid(): Uint8Array { + return Uint8Array.from(Buffer.from(nanoid(8))); +} diff --git a/test-scripts/run-anchor-local-validator-tests.sh b/test-scripts/run-anchor-local-validator-tests.sh index be7464abb..5678eb24c 100644 --- a/test-scripts/run-anchor-local-validator-tests.sh +++ b/test-scripts/run-anchor-local-validator-tests.sh @@ -6,8 +6,8 @@ fi export ANCHOR_WALLET=~/.config/solana/id.json test_files=( - #placeAndMakeSwiftPerp.ts, - pythLazer.ts + placeAndMakeSwiftPerp.ts + # pythLazer.ts ) diff --git a/tests/placeAndMakeSwiftPerp.ts b/tests/placeAndMakeSwiftPerp.ts index b9b4673cd..1b197c5bb 100644 --- a/tests/placeAndMakeSwiftPerp.ts +++ b/tests/placeAndMakeSwiftPerp.ts @@ -6,7 +6,6 @@ import { Program } from '@coral-xyz/anchor'; import { ComputeBudgetProgram, Keypair, - PublicKey, SendTransactionError, Transaction, TransactionMessage, @@ -26,12 +25,10 @@ import { OracleSource, BulkAccountLoader, SwiftOrderParamsMessage, - SwiftServerMessage, loadKeypair, getMarketOrderParams, MarketType, DriftClient, - ANCHOR_TEST_SWIFT_ID, } from '../sdk/src'; import { @@ -43,21 +40,14 @@ import { } from './testHelpersLocalValidator'; import { PEG_PRECISION, PostOnlyParams } from '../sdk/src'; import dotenv from 'dotenv'; -import { digest } from '../sdk/src/util/digest'; import { nanoid } from 'nanoid'; dotenv.config(); describe('place and make swift order', () => { - if (!process.env.SWIFT_PRIVATE_KEY) { - throw new Error('SWIFT_PRIVATE_KEY not set'); - } - if (!process.env.ANCHOR_WALLET) { throw new Error('ANCHOR_WALLET not set'); } - const swiftKeypair = loadKeypair(process.env.SWIFT_PRIVATE_KEY); - const provider = anchor.AnchorProvider.local(undefined, { commitment: 'confirmed', preflightCommitment: 'confirmed', @@ -128,7 +118,6 @@ describe('place and make swift order', () => { type: 'polling', accountLoader: bulkAccountLoader, }, - swiftID: new PublicKey(ANCHOR_TEST_SWIFT_ID), }); await makerDriftClient.initialize(usdcMint.publicKey, true); await makerDriftClient.subscribe(); @@ -193,7 +182,6 @@ describe('place and make swift order', () => { type: 'polling', accountLoader: bulkAccountLoader, }, - swiftID: new PublicKey(ANCHOR_TEST_SWIFT_ID), }); await takerDriftClient.subscribe(); @@ -230,9 +218,12 @@ describe('place and make swift order', () => { postOnly: PostOnlyParams.NONE, marketType: MarketType.PERP, }); + const uuid = Uint8Array.from(Buffer.from(nanoid(8))); const takerOrderParamsMessage: SwiftOrderParamsMessage = { swiftOrderParams: takerOrderParams, subAccountId: 0, + slot: new BN(await connection.getSlot()), + uuid, takeProfitOrderParams: null, stopLossOrderParams: null, }; @@ -253,26 +244,10 @@ describe('place and make swift order', () => { takerOrderParamsMessage ); - const swiftServerMessage: SwiftServerMessage = { - slot: new BN(await connection.getSlot()), - swiftOrderSignature: takerOrderParamsSig, - uuid: Uint8Array.from(Buffer.from(nanoid(8))), - }; - - const encodedSwiftServerMessage = - makerDriftClient.encodeSwiftServerMessage(swiftServerMessage); - - const swiftSignature = makerDriftClient.signMessage( - digest(encodedSwiftServerMessage), - swiftKeypair - ); - let ixs = await makerDriftClient.getPlaceAndMakeSwiftPerpOrderIxs( - encodedSwiftServerMessage, - swiftSignature, takerDriftClient.encodeSwiftOrderParamsMessage(takerOrderParamsMessage), takerOrderParamsSig, - swiftServerMessage.uuid, + uuid, { taker: await takerDriftClient.getUserAccountPublicKey(), takerUserAccount: takerDriftClient.getUserAccount(), @@ -374,37 +349,24 @@ describe('place and make swift order', () => { immediateOrCancel: true, }); + const uuid = Uint8Array.from(Buffer.from(nanoid(8))); const takerOrderParamsMessage: SwiftOrderParamsMessage = { swiftOrderParams: takerOrderParams, takeProfitOrderParams: null, subAccountId: 0, + slot: new BN(await connection.getSlot()), + uuid, stopLossOrderParams: null, }; const takerOrderParamsSig = makerDriftClient.signSwiftOrderParamsMessage( takerOrderParamsMessage ); - const swiftServerMessage: SwiftServerMessage = { - slot: new BN(await connection.getSlot()), - swiftOrderSignature: takerOrderParamsSig, - uuid: Uint8Array.from(Buffer.from(nanoid(8))), - }; - - const encodedSwiftServerMessage = - makerDriftClient.encodeSwiftServerMessage(swiftServerMessage); - - const swiftSignature = makerDriftClient.signMessage( - digest(encodedSwiftServerMessage), - swiftKeypair - ); - try { let ixs = await makerDriftClient.getPlaceAndMakeSwiftPerpOrderIxs( - encodedSwiftServerMessage, - swiftSignature, takerDriftClient.encodeSwiftOrderParamsMessage(takerOrderParamsMessage), takerOrderParamsSig, - swiftServerMessage.uuid, + uuid, { taker: await takerDriftClient.getUserAccountPublicKey(), takerUserAccount: takerDriftClient.getUserAccount(), @@ -428,122 +390,6 @@ describe('place and make swift order', () => { } }); - it('should fail on swift impersonator', async () => { - const keypair = new Keypair(); - await provider.connection.requestAirdrop(keypair.publicKey, 10 ** 9); - await sleep(1000); - const wallet = new Wallet(keypair); - const userUSDCAccount = await mockUserUSDCAccount( - usdcMint, - usdcAmount, - provider, - keypair.publicKey - ); - const takerDriftClient = new TestClient({ - connection, - wallet, - programID: chProgram.programId, - opts: { - commitment: 'confirmed', - }, - activeSubAccountId: 0, - perpMarketIndexes: marketIndexes, - spotMarketIndexes: spotMarketIndexes, - oracleInfos, - userStats: true, - accountSubscription: { - type: 'polling', - accountLoader: bulkAccountLoader, - }, - }); - await takerDriftClient.subscribe(); - await takerDriftClient.initializeUserAccountAndDepositCollateral( - usdcAmount, - userUSDCAccount.publicKey - ); - const takerDriftClientUser = new User({ - driftClient: takerDriftClient, - userAccountPublicKey: await takerDriftClient.getUserAccountPublicKey(), - accountSubscription: { - type: 'polling', - accountLoader: bulkAccountLoader, - }, - }); - await takerDriftClientUser.subscribe(); - await takerDriftClient.initializeSwiftUserOrders( - takerDriftClientUser.userAccountPublicKey, - 32 - ); - - const marketIndex = 0; - const baseAssetAmount = BASE_PRECISION; - const takerOrderParams = getLimitOrderParams({ - marketIndex, - direction: PositionDirection.LONG, - baseAssetAmount, - price: new BN(34).mul(PRICE_PRECISION), - auctionStartPrice: new BN(33).mul(PRICE_PRECISION), - auctionEndPrice: new BN(34).mul(PRICE_PRECISION), - auctionDuration: 10, - userOrderId: 1, - postOnly: PostOnlyParams.NONE, - }); - - await takerDriftClientUser.fetchAccounts(); - - // Auth part begins - const takerOrderParamsMessage: SwiftOrderParamsMessage = { - swiftOrderParams: takerOrderParams, - subAccountId: 0, - takeProfitOrderParams: null, - stopLossOrderParams: null, - }; - const takerOrderParamsSig = takerDriftClient.signSwiftOrderParamsMessage( - takerOrderParamsMessage - ); - - const swiftServerMessage: SwiftServerMessage = { - slot: new BN(await connection.getSlot()), - swiftOrderSignature: takerOrderParamsSig, - uuid: Uint8Array.from(Buffer.from(nanoid(8))), - }; - - const encodedSwiftServerMessage = - takerDriftClient.encodeSwiftServerMessage(swiftServerMessage); - - const swiftSignature = takerDriftClient.signMessage( - digest(encodedSwiftServerMessage) - ); - - try { - let ixs = await makerDriftClient.getPlaceSwiftTakerPerpOrderIxs( - encodedSwiftServerMessage, - swiftSignature, - takerDriftClient.encodeSwiftOrderParamsMessage(takerOrderParamsMessage), - takerOrderParamsSig, - marketIndex, - { - taker: await takerDriftClient.getUserAccountPublicKey(), - takerUserAccount: takerDriftClient.getUserAccount(), - takerStats: takerDriftClient.getUserStatsAccountPublicKey(), - } - ); - ixs = [ - ComputeBudgetProgram.setComputeUnitLimit({ - units: 10_000_000, - }), - ...ixs, - ]; - await makerDriftClient.sendTransaction(new Transaction().add(...ixs)); - assert.fail('Should have failed'); - } catch (error) { - assert.equal( - error.transactionMessage, - 'Transaction precompile verification failure InvalidAccountIndex' - ); - } - }); - it('should fail if diff signed message to verify ixs vs drift ixs', async () => { const keypair = new Keypair(); await provider.connection.requestAirdrop(keypair.publicKey, 10 ** 9); @@ -571,7 +417,6 @@ describe('place and make swift order', () => { type: 'polling', accountLoader: bulkAccountLoader, }, - swiftID: new PublicKey(ANCHOR_TEST_SWIFT_ID), }); await takerDriftClient.subscribe(); @@ -611,6 +456,8 @@ describe('place and make swift order', () => { const takerOrderParamsMessage: SwiftOrderParamsMessage = { swiftOrderParams: takerOrderParams, subAccountId: 0, + uuid: Uint8Array.from(Buffer.from(nanoid(8))), + slot: new BN(await connection.getSlot()), takeProfitOrderParams: null, stopLossOrderParams: null, }; @@ -622,20 +469,6 @@ describe('place and make swift order', () => { takerOrderParamsMessage ); - const swiftServerMessage: SwiftServerMessage = { - slot: new BN(await connection.getSlot()), - swiftOrderSignature: takerOrderParamsSig, - uuid: Uint8Array.from(Buffer.from(nanoid(8))), - }; - - const encodedSwiftServerMessage = - makerDriftClient.encodeSwiftServerMessage(swiftServerMessage); - - const swiftSignature = makerDriftClient.signMessage( - digest(encodedSwiftServerMessage), - swiftKeypair - ); - // Auth for non-legit order const takerOrderParamsMessage2: SwiftOrderParamsMessage = { swiftOrderParams: Object.assign({}, takerOrderParams, { @@ -647,33 +480,19 @@ describe('place and make swift order', () => { subAccountId: 0, takeProfitOrderParams: null, stopLossOrderParams: null, + uuid: Uint8Array.from(Buffer.from(nanoid(8))), + slot: new BN(await connection.getSlot()), }; const takerOrderParamsSig2 = takerDriftClient.signSwiftOrderParamsMessage( takerOrderParamsMessage2 ); - const swiftServerMessage2: SwiftServerMessage = { - slot: new BN(await connection.getSlot()), - swiftOrderSignature: takerOrderParamsSig2, - uuid: Uint8Array.from(Buffer.from(nanoid(8))), - }; - - const encodedSwiftServerMessage2 = - makerDriftClient.encodeSwiftServerMessage(swiftServerMessage2); - - const swiftSignature2 = makerDriftClient.signMessage( - digest(encodedSwiftServerMessage2), - swiftKeypair - ); - const computeBudgetIx = ComputeBudgetProgram.setComputeUnitLimit({ units: 10_000_000, }); const ixs = await makerDriftClient.getPlaceSwiftTakerPerpOrderIxs( - encodedSwiftServerMessage, - swiftSignature, takerDriftClient.encodeSwiftOrderParamsMessage(takerOrderParamsMessage), takerOrderParamsSig, 0, @@ -685,8 +504,6 @@ describe('place and make swift order', () => { ); const ixsForOrder2 = await makerDriftClient.getPlaceSwiftTakerPerpOrderIxs( - encodedSwiftServerMessage2, - swiftSignature2, takerDriftClient.encodeSwiftOrderParamsMessage(takerOrderParamsMessage2), takerOrderParamsSig2, 0, @@ -698,9 +515,7 @@ describe('place and make swift order', () => { ); const badOrderTx = new Transaction(); - badOrderTx.add( - ...[computeBudgetIx, ixs[0], ixsForOrder2[1], ixsForOrder2[2]] - ); + badOrderTx.add(...[computeBudgetIx, ixs[0], ixsForOrder2[1]]); try { await makerDriftClient.sendTransaction(badOrderTx); assert.fail('Should have failed'); @@ -714,9 +529,7 @@ describe('place and make swift order', () => { } const badSwiftTx = new Transaction(); - badSwiftTx.add( - ...[computeBudgetIx, ixsForOrder2[0], ixs[1], ixsForOrder2[2]] - ); + badSwiftTx.add(...[computeBudgetIx, ixsForOrder2[0], ixs[1]]); try { await makerDriftClient.sendTransaction(badSwiftTx); assert.fail('Should have failed'); diff --git a/tests/placeAndMakeSwiftPerpBankrun.ts b/tests/placeAndMakeSwiftPerpBankrun.ts index 88797108a..d94e86519 100644 --- a/tests/placeAndMakeSwiftPerpBankrun.ts +++ b/tests/placeAndMakeSwiftPerpBankrun.ts @@ -33,12 +33,8 @@ import { SwiftOrderParamsMessage, MarketType, getMarketOrderParams, - loadKeypair, - SwiftServerMessage, - ANCHOR_TEST_SWIFT_ID, SwiftOrderRecord, getSwiftUserAccountPublicKey, - digest, PYTH_LAZER_STORAGE_ACCOUNT_KEY, PTYH_LAZER_PROGRAM_ID, OrderType, @@ -80,13 +76,8 @@ const PYTH_STORAGE_ACCOUNT_INFO: AccountInfo = { describe('place and make swift order', () => { const chProgram = anchor.workspace.Drift as Program; - if (!process.env.SWIFT_PRIVATE_KEY) { - throw new Error('SWIFT_PRIVATE_KEY not set'); - } let slot: BN; - const swiftKeypair = loadKeypair(process.env.SWIFT_PRIVATE_KEY); - let makerDriftClient: TestClient; let makerDriftClientUser: User; let eventSubscriber: EventSubscriber; @@ -181,7 +172,6 @@ describe('place and make swift order', () => { type: 'polling', accountLoader: bulkAccountLoader, }, - swiftID: new PublicKey(ANCHOR_TEST_SWIFT_ID), }); await makerDriftClient.initialize(usdcMint.publicKey, true); await makerDriftClient.subscribe(); @@ -250,9 +240,12 @@ describe('place and make swift order', () => { postOnly: PostOnlyParams.NONE, marketType: MarketType.PERP, }); + const uuid = Uint8Array.from(Buffer.from(nanoid(8))); const takerOrderParamsMessage: SwiftOrderParamsMessage = { swiftOrderParams: takerOrderParams, subAccountId: 0, + slot, + uuid, takeProfitOrderParams: null, stopLossOrderParams: null, }; @@ -271,26 +264,10 @@ describe('place and make swift order', () => { takerOrderParamsMessage ); - const swiftServerMessage: SwiftServerMessage = { - slot, - swiftOrderSignature: takerOrderParamsSig, - uuid: Uint8Array.from(Buffer.from(nanoid(8))), - }; - - const encodedSwiftServerMessage = - makerDriftClient.encodeSwiftServerMessage(swiftServerMessage); - - const swiftSignature = makerDriftClient.signMessage( - digest(encodedSwiftServerMessage), - swiftKeypair - ); - const txSig = await makerDriftClient.placeAndMakeSwiftPerpOrder( - encodedSwiftServerMessage, - swiftSignature, takerDriftClient.encodeSwiftOrderParamsMessage(takerOrderParamsMessage), takerOrderParamsSig, - swiftServerMessage.uuid, + uuid, { taker: await takerDriftClient.getUserAccountPublicKey(), takerUserAccount: takerDriftClient.getUserAccount(), @@ -317,11 +294,9 @@ describe('place and make swift order', () => { ); await makerDriftClient.placeAndMakeSwiftPerpOrder( - encodedSwiftServerMessage, - swiftSignature, takerDriftClient.encodeSwiftOrderParamsMessage(takerOrderParamsMessage), takerOrderParamsSig, - swiftServerMessage.uuid, + uuid, { taker: await takerDriftClient.getUserAccountPublicKey(), takerUserAccount: takerDriftClient.getUserAccount(), @@ -424,9 +399,13 @@ describe('place and make swift order', () => { userOrderId: 1, postOnly: PostOnlyParams.NONE, }); + const uuid = nanoid(8); + const swiftSlot = slot.subn(15); const takerOrderParamsMessage: SwiftOrderParamsMessage = { swiftOrderParams: takerOrderParams, subAccountId: 0, + uuid: Uint8Array.from(Buffer.from(uuid)), + slot: swiftSlot, takeProfitOrderParams: null, stopLossOrderParams: null, }; @@ -434,22 +413,6 @@ describe('place and make swift order', () => { takerOrderParamsMessage ); - const uuid = nanoid(8); - const swiftSlot = slot.subn(15); - const swiftServerMessage: SwiftServerMessage = { - slot: swiftSlot, - swiftOrderSignature: takerOrderParamsSig, - uuid: Uint8Array.from(Buffer.from(uuid)), - }; - - const encodedSwiftServerMessage = - takerDriftClient.encodeSwiftServerMessage(swiftServerMessage); - - const swiftSignature = takerDriftClient.signMessage( - digest(encodedSwiftServerMessage), - swiftKeypair - ); - // Get pyth lazer instruction const pythLazerCrankIxs = makerDriftClient.getPostPythLazerOracleUpdateIxs( [6], @@ -460,8 +423,6 @@ describe('place and make swift order', () => { const placeSwiftTakerOrderIxs = await makerDriftClient.getPlaceSwiftTakerPerpOrderIxs( - encodedSwiftServerMessage, - swiftSignature, takerDriftClient.encodeSwiftOrderParamsMessage(takerOrderParamsMessage), takerOrderParamsSig, takerOrderParams.marketIndex, @@ -605,9 +566,12 @@ describe('place and make swift order', () => { marketType: MarketType.PERP, }); + const uuid = Uint8Array.from(Buffer.from(nanoid(8))); const takerOrderParamsMessage: SwiftOrderParamsMessage = { swiftOrderParams: takerOrderParams, subAccountId: 0, + slot, + uuid, stopLossOrderParams: { triggerPrice: stopLossTakerParams.triggerPrice, baseAssetAmount: stopLossTakerParams.baseAssetAmount, @@ -622,45 +586,10 @@ describe('place and make swift order', () => { takerOrderParamsMessage ); - const swiftDriftClient = new TestClient({ - connection: bankrunContextWrapper.connection.toConnection(), - wallet: new Wallet(swiftKeypair), - programID: chProgram.programId, - opts: { - commitment: 'confirmed', - }, - activeSubAccountId: 0, - perpMarketIndexes: marketIndexes, - spotMarketIndexes: spotMarketIndexes, - subAccountIds: [], - oracleInfos, - userStats: true, - accountSubscription: { - type: 'polling', - accountLoader: bulkAccountLoader, - }, - }); - - const swiftServerMessage: SwiftServerMessage = { - slot, - swiftOrderSignature: takerOrderParamsSig, - uuid: Uint8Array.from(Buffer.from(nanoid(8))), - }; - - const encodedSwiftServerMessage = - swiftDriftClient.encodeSwiftServerMessage(swiftServerMessage); - - const swiftSignature = swiftDriftClient.signMessage( - digest(encodedSwiftServerMessage), - swiftKeypair - ); - const ixs = await makerDriftClient.getPlaceAndMakeSwiftPerpOrderIxs( - encodedSwiftServerMessage, - swiftSignature, takerDriftClient.encodeSwiftOrderParamsMessage(takerOrderParamsMessage), takerOrderParamsSig, - swiftServerMessage.uuid, + uuid, { taker: await takerDriftClient.getUserAccountPublicKey(), takerUserAccount: takerDriftClient.getUserAccount(), @@ -749,9 +678,12 @@ describe('place and make swift order', () => { immediateOrCancel: true, }); + const uuid = Uint8Array.from(Buffer.from(nanoid(8))); const takerOrderParamsMessage: SwiftOrderParamsMessage = { swiftOrderParams: takerOrderParams, subAccountId: 0, + slot, + uuid, takeProfitOrderParams: null, stopLossOrderParams: null, }; @@ -760,27 +692,11 @@ describe('place and make swift order', () => { takerOrderParamsMessage ); - const swiftServerMessage: SwiftServerMessage = { - slot, - swiftOrderSignature: takerOrderParamsSig, - uuid: Uint8Array.from(Buffer.from(nanoid(8))), - }; - - const encodedSwiftServerMessage = - takerDriftClient.encodeSwiftServerMessage(swiftServerMessage); - - const swiftSignature = takerDriftClient.signMessage( - digest(encodedSwiftServerMessage), - swiftKeypair - ); - try { await makerDriftClient.placeAndMakeSwiftPerpOrder( - encodedSwiftServerMessage, - swiftSignature, takerDriftClient.encodeSwiftOrderParamsMessage(takerOrderParamsMessage), takerOrderParamsSig, - swiftServerMessage.uuid, + uuid, { taker: await takerDriftClient.getUserAccountPublicKey(), takerUserAccount: takerDriftClient.getUserAccount(), @@ -829,9 +745,13 @@ describe('place and make swift order', () => { userOrderId: 1, postOnly: PostOnlyParams.NONE, }); + const swiftSlot = slot.subn(5); + const uuid = Uint8Array.from(Buffer.from(nanoid(8))); const takerOrderParamsMessage: SwiftOrderParamsMessage = { swiftOrderParams: takerOrderParams, subAccountId: 0, + slot: swiftSlot, + uuid, takeProfitOrderParams: null, stopLossOrderParams: null, }; @@ -839,23 +759,7 @@ describe('place and make swift order', () => { takerOrderParamsMessage ); - const swiftServerMessage: SwiftServerMessage = { - slot: slot.subn(5), - swiftOrderSignature: takerOrderParamsSig, - uuid: Uint8Array.from(Buffer.from(nanoid(8))), - }; - - const encodedSwiftServerMessage = - takerDriftClient.encodeSwiftServerMessage(swiftServerMessage); - - const swiftSignature = takerDriftClient.signMessage( - digest(encodedSwiftServerMessage), - swiftKeypair - ); - await makerDriftClient.placeSwiftTakerOrder( - encodedSwiftServerMessage, - swiftSignature, takerDriftClient.encodeSwiftOrderParamsMessage(takerOrderParamsMessage), takerOrderParamsSig, takerOrderParams.marketIndex, @@ -878,11 +782,9 @@ describe('place and make swift order', () => { immediateOrCancel: true, }); await makerDriftClient.placeAndMakeSwiftPerpOrder( - encodedSwiftServerMessage, - swiftSignature, takerDriftClient.encodeSwiftOrderParamsMessage(takerOrderParamsMessage), takerOrderParamsSig, - swiftServerMessage.uuid, + uuid, { taker: await takerDriftClient.getUserAccountPublicKey(), takerUserAccount: takerDriftClient.getUserAccount(), @@ -929,6 +831,8 @@ describe('place and make swift order', () => { const takerOrderParamsMessage: SwiftOrderParamsMessage = { swiftOrderParams: takerOrderParams, subAccountId: 0, + slot, + uuid: Uint8Array.from(Buffer.from(nanoid(8))), takeProfitOrderParams: null, stopLossOrderParams: null, }; @@ -937,24 +841,8 @@ describe('place and make swift order', () => { takerOrderParamsMessage ); - const swiftServerMessage: SwiftServerMessage = { - slot, - swiftOrderSignature: takerOrderParamsSig, - uuid: Uint8Array.from(Buffer.from(nanoid(8))), - }; - - const encodedSwiftServerMessage = - makerDriftClient.encodeSwiftServerMessage(swiftServerMessage); - - const swiftSignature = makerDriftClient.signMessage( - digest(encodedSwiftServerMessage), - swiftKeypair - ); - try { await makerDriftClient.placeSwiftTakerOrder( - encodedSwiftServerMessage, - swiftSignature, takerDriftClient.encodeSwiftOrderParamsMessage(takerOrderParamsMessage), takerOrderParamsSig, 0, @@ -1006,6 +894,8 @@ describe('place and make swift order', () => { const takerOrderParamsMessage: SwiftOrderParamsMessage = { swiftOrderParams: takerOrderParams, subAccountId: 0, + slot, + uuid: Uint8Array.from(Buffer.from(nanoid(8))), takeProfitOrderParams: null, stopLossOrderParams: null, }; @@ -1014,23 +904,7 @@ describe('place and make swift order', () => { takerOrderParamsMessage ); - const swiftServerMessage: SwiftServerMessage = { - slot, - swiftOrderSignature: takerOrderParamsSig, - uuid: Uint8Array.from(Buffer.from(nanoid(8))), - }; - - const encodedSwiftServerMessage = - makerDriftClient.encodeSwiftServerMessage(swiftServerMessage); - - const swiftSignature = makerDriftClient.signMessage( - digest(encodedSwiftServerMessage), - swiftKeypair - ); - await makerDriftClient.placeSwiftTakerOrder( - encodedSwiftServerMessage, - swiftSignature, takerDriftClient.encodeSwiftOrderParamsMessage(takerOrderParamsMessage), takerOrderParamsSig, 0, From f84c60f846972244d60e7564f1499367d15a8910 Mon Sep 17 00:00:00 2001 From: Nour Alharithi Date: Mon, 16 Dec 2024 11:45:37 -0800 Subject: [PATCH 2/3] revert Anchor.toml changes --- Anchor.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Anchor.toml b/Anchor.toml index 2ce0fc10c..dbaa02376 100644 --- a/Anchor.toml +++ b/Anchor.toml @@ -7,7 +7,7 @@ exclude = ["programs/openbook_v2"] [scripts] # to run local validator tests, use "./test-scripts/run-ts-mocha" in "test" -test = "./test-scripts/run-ts-mocha" # need to call anchor test to update metadata field in idl before running tests, so just do a noop +test = "echo" # need to call anchor test to update metadata field in idl before running tests, so just do a noop lint = "yarn prettify:fix && cargo fmt" fulltest = 'cargo test && bash ./test-scripts/run-anchor-tests.sh' watch_ts = 'find ./programs/clearing_house/src/* ./tests ./sdk/src | entr -c bash ./test-scripts/single-anchor-test.sh' From 3ddee91e09f2db8fb3fd199aba8758c83aec16cd Mon Sep 17 00:00:00 2001 From: Nour Alharithi Date: Mon, 16 Dec 2024 11:55:04 -0800 Subject: [PATCH 3/3] add slot sanity check --- programs/drift/src/error.rs | 2 +- programs/drift/src/instructions/keeper.rs | 7 +++++++ 2 files changed, 8 insertions(+), 1 deletion(-) diff --git a/programs/drift/src/error.rs b/programs/drift/src/error.rs index 7a0705188..5c2d229ab 100644 --- a/programs/drift/src/error.rs +++ b/programs/drift/src/error.rs @@ -581,7 +581,7 @@ pub enum ErrorCode { SigVerificationFailed, #[msg("Market index mismatched b/w taker and maker swift order params")] MismatchedSwiftOrderParamsMarketIndex, - #[msg("Swift only available for market/oracle perp orders")] + #[msg("Invalid swift order param")] InvalidSwiftOrderParam, #[msg("Place and take order success condition failed")] PlaceAndTakeOrderSuccessConditionFailed, diff --git a/programs/drift/src/instructions/keeper.rs b/programs/drift/src/instructions/keeper.rs index a50e2b765..811777cd5 100644 --- a/programs/drift/src/instructions/keeper.rs +++ b/programs/drift/src/instructions/keeper.rs @@ -696,6 +696,13 @@ pub fn place_swift_taker_order<'c: 'info, 'info>( // Set max slot for the order early so we set correct swift order id let order_slot = taker_order_params_message.slot; + if order_slot < clock.slot - 500 { + msg!( + "Swift order slot {} is too old: must be within 500 slots of current slot", + order_slot + ); + return Err(print_error!(ErrorCode::InvalidSwiftOrderParam)().into()); + } let market_index = matching_taker_order_params.market_index; let max_slot = order_slot.safe_add( matching_taker_order_params