Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
13 changes: 12 additions & 1 deletion common-ts/src/common-ui-utils/user.ts
Original file line number Diff line number Diff line change
Expand Up @@ -154,7 +154,18 @@ const getOpenPositionData = (
markPrice,
entryPrice,
exitPrice: estExitPrice,
liqPrice: user.liquidationPrice(position.marketIndex, ZERO),
liqPrice: user.isPerpPositionIsolated(position)
? user.liquidationPrice(
position.marketIndex,
ZERO,
undefined,
undefined,
undefined,
undefined,
undefined,
'Isolated'
)
: user.liquidationPrice(position.marketIndex, ZERO),
quoteAssetNotionalAmount: position.quoteAssetAmount,
quoteEntryAmount: position.quoteEntryAmount,
quoteBreakEvenAmount: position.quoteBreakEvenAmount,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -467,6 +467,7 @@ export class DriftOperations {
params.orderConfig.optionalAuctionParamsInputs,
builderParams: params.builderParams,
positionMaxLeverage: params.positionMaxLeverage,
isolatedPositionDeposit: params.isolatedPositionDeposit,
});

return swiftOrderResult;
Expand All @@ -484,6 +485,7 @@ export class DriftOperations {
dlobServerHttpUrl: this.dlobServerHttpUrl,
useSwift: false,
positionMaxLeverage: params.positionMaxLeverage,
isolatedPositionDeposit: params.isolatedPositionDeposit,
});

const { txSig } = await this.driftClient.sendTransaction(result);
Expand Down Expand Up @@ -527,6 +529,7 @@ export class DriftOperations {
},
builderParams: params.builderParams,
positionMaxLeverage: params.positionMaxLeverage,
isolatedPositionDeposit: params.isolatedPositionDeposit,
});

return swiftOrderResult;
Expand All @@ -548,6 +551,7 @@ export class DriftOperations {
useSwift: false,
txParams: this.getTxParams(),
positionMaxLeverage: params.positionMaxLeverage,
isolatedPositionDeposit: params.isolatedPositionDeposit,
});

const { txSig } = await this.driftClient.sendTransaction(txn);
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import {
BigNum,
BN,
PositionDirection,
PostOnlyParams,
PublicKey,
Expand Down Expand Up @@ -60,6 +61,7 @@ export type PerpOrderParams = {
assetType: 'base' | 'quote';
size: BigNum;
positionMaxLeverage: number;
isolatedPositionDeposit?: BN;
reduceOnly?: boolean;
postOnly?: PostOnlyParams;
isMaxLeverage?: boolean;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,3 +4,4 @@ export * from './openSwiftOrder';
export * from './dlobServer';
export * from './types';
export * from './positionMaxLeverage';
export * from './isolatedPositionDeposit';
Original file line number Diff line number Diff line change
@@ -0,0 +1,115 @@
import {
BN,
DriftClient,
User,
calculateMarginUSDCRequiredForTrade,
OptionalOrderParams,
PositionDirection,
MarketType,
OrderType,
} from '@drift-labs/sdk';
import { PublicKey, TransactionInstruction } from '@solana/web3.js';

export const ISOLATED_POSITION_DEPOSIT_BUFFER_BPS = 300;

export interface ComputeIsolatedPositionDepositParams {
driftClient: DriftClient;
user: User;
marketIndex: number;
baseAssetAmount: BN;
/**
* Optional direction of the order.
* If provided, we will check if the order will increase the position.
* If the order will not increase the position, we will return 0.
*/
direction?: PositionDirection;
/**
* Margin ratio to use for the position (e.g. 2000 for 5x leverage).
*/
marginRatio: number;
/**
* Optional estimated entry price to use for the margin calculation.
*/
entryPrice?: BN;
/**
* Number of open high leverage spots available to the user (if any).
* If greater than 0, we will consider the trade as entering high leverage mode.
*/
numOfOpenHighLeverageSpots?: number;
}

/**
* Computes the isolated position deposit required for opening an isolated perp position.
* Returns a BN in QUOTE_PRECISION (USDC).
*/
export function computeIsolatedPositionDepositForTrade({
driftClient,
user,
marketIndex,
baseAssetAmount,
direction,
marginRatio,
entryPrice,
numOfOpenHighLeverageSpots,
}: ComputeIsolatedPositionDepositParams): BN | null {
// Only require isolated deposit if the order will increase the position (when direction is provided)
if (direction !== undefined) {
const maybeOrderParams: OptionalOrderParams = {
marketIndex,
marketType: MarketType.PERP,
orderType: OrderType.MARKET,
direction,
baseAssetAmount,
};
const subAccountId = user.getUserAccount().subAccountId;
const isIncreasing = driftClient.isOrderIncreasingPosition(
maybeOrderParams,
subAccountId
);
if (!isIncreasing) {
return null;
}
}

const userIsInHighLeverageMode = user.isHighLeverageMode('Initial') ?? false;
const hasOpenHighLeverageSpots =
numOfOpenHighLeverageSpots !== undefined && numOfOpenHighLeverageSpots > 0;
const enteringHighLeverageMode =
userIsInHighLeverageMode || hasOpenHighLeverageSpots;

const marginRequired = calculateMarginUSDCRequiredForTrade(
driftClient,
marketIndex,
baseAssetAmount,
marginRatio,
enteringHighLeverageMode,
entryPrice
);

return marginRequired.add(
marginRequired.div(new BN(ISOLATED_POSITION_DEPOSIT_BUFFER_BPS))
); // buffer in basis points
}

export async function getIsolatedPositionDepositIxIfNeeded(
driftClient: DriftClient,
user: User,
marketIndex: number,
isolatedPositionDeposit?: BN,
signingAuthority?: PublicKey
): Promise<TransactionInstruction | undefined> {
if (!isolatedPositionDeposit) {
return undefined;
}
if (isolatedPositionDeposit.isZero()) {
return undefined;
}

return driftClient.getTransferIsolatedPerpPositionDepositIx(
isolatedPositionDeposit,
marketIndex,
user.getUserAccount().subAccountId,
undefined, // noAmountBuffer
signingAuthority
);
}
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,7 @@ import { NoTopMakersError } from '../../../../../Drift/constants/errors';
import { PlaceAndTakeParams, OptionalTriggerOrderParams } from '../types';
import { getPositionMaxLeverageIxIfNeeded } from '../positionMaxLeverage';
import { AuctionParamsFetchedCallback } from '../../../../../utils/auctionParamsResponseMapper';
import { getIsolatedPositionDepositIxIfNeeded } from '../isolatedPositionDeposit';

export interface OpenPerpMarketOrderBaseParams {
driftClient: DriftClient;
Expand All @@ -61,6 +62,12 @@ export interface OpenPerpMarketOrderBaseParams {
* Example: 5 for 5x leverage, 10 for 10x leverage
*/
positionMaxLeverage: number;
/**
* Optional isolated position deposit amount.
* If provided, it will be added to the order params as isolatedPositionDeposit.
* This field is used for opening isolated positions.
*/
isolatedPositionDeposit?: BN;
/**
* If provided, will override the main signer for the order. Otherwise, the main signer will be the user's authority.
* This is only applicable for non-SWIFT orders.
Expand Down Expand Up @@ -139,6 +146,7 @@ export async function createSwiftMarketOrder({
swiftOptions,
userOrderId = 0,
positionMaxLeverage,
isolatedPositionDeposit,
builderParams,
highLeverageOptions,
callbacks,
Expand Down Expand Up @@ -190,6 +198,7 @@ export async function createSwiftMarketOrder({
takeProfit: bracketOrders?.takeProfit,
stopLoss: bracketOrders?.stopLoss,
positionMaxLeverage,
isolatedPositionDeposit,
},
builderParams,
});
Expand Down Expand Up @@ -337,6 +346,7 @@ export const createOpenPerpMarketOrderIxs = async ({
positionMaxLeverage,
mainSignerOverride,
highLeverageOptions,
isolatedPositionDeposit,
callbacks,
}: OpenPerpMarketOrderBaseParams): Promise<TransactionInstruction[]> => {
if (!amount || amount.isZero()) {
Expand All @@ -357,6 +367,18 @@ export const createOpenPerpMarketOrderIxs = async ({
allIxs.push(leverageIx);
}

const isolatedPositionDepositIx = await getIsolatedPositionDepositIxIfNeeded(
driftClient,
user,
marketIndex,
isolatedPositionDeposit,
mainSignerOverride
);

if (isolatedPositionDepositIx) {
allIxs.push(isolatedPositionDepositIx);
}

if (placeAndTake?.enable) {
try {
const placeAndTakeIx = await createPlaceAndTakePerpMarketOrderIx({
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,7 @@ import {
import { WithTxnParams } from '../../../../types';
import { getPositionMaxLeverageIxIfNeeded } from '../positionMaxLeverage';
import { getLimitAuctionOrderParams } from '../auction';
import { getIsolatedPositionDepositIxIfNeeded } from '../isolatedPositionDeposit';

export interface OpenPerpNonMarketOrderBaseParams
extends Omit<NonMarketOrderParamsConfig, 'marketType' | 'baseAssetAmount'> {
Expand Down Expand Up @@ -141,6 +142,7 @@ export const createOpenPerpNonMarketOrderIxs = async (
orderConfig,
userOrderId = 0,
positionMaxLeverage,
isolatedPositionDeposit,
mainSignerOverride,
highLeverageOptions,
} = params;
Expand Down Expand Up @@ -174,6 +176,18 @@ export const createOpenPerpNonMarketOrderIxs = async (
allIxs.push(leverageIx);
}

const isolatedPositionDepositIx: TransactionInstruction | undefined =
await getIsolatedPositionDepositIxIfNeeded(
driftClient,
user,
marketIndex,
isolatedPositionDeposit,
mainSignerOverride
);
if (isolatedPositionDepositIx) {
allIxs.push(isolatedPositionDepositIx);
}

// handle limit auction
if (
orderConfig.orderType === 'limit' &&
Expand Down Expand Up @@ -359,7 +373,7 @@ export const createSwiftLimitOrder = async (
reduceOnly: params.reduceOnly,
postOnly: params.postOnly,
userOrderId: params.userOrderId,
positionMaxLeverage: params.positionMaxLeverage,
positionMaxLeverage: params.positionMaxLeverage, // TODO: this isn't referenced in the function... do we need it?
});

const userAccount = user.getUserAccount();
Expand All @@ -376,6 +390,7 @@ export const createSwiftLimitOrder = async (
takeProfit: orderConfig.bracketOrders?.takeProfit,
stopLoss: orderConfig.bracketOrders?.stopLoss,
positionMaxLeverage: params.positionMaxLeverage,
isolatedPositionDeposit: params.isolatedPositionDeposit,
},
builderParams: params.builderParams,
});
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -128,6 +128,8 @@ interface PrepSwiftOrderParams {
takeProfit?: OptionalTriggerOrderParams;
/** Optional max leverage for the position */
positionMaxLeverage?: number;
/** Optional isolated position deposit amount */
isolatedPositionDeposit?: BN;
};
/**
* Buffer slots to account for the user to sign the message. Affects the auction start slot.
Expand Down Expand Up @@ -222,6 +224,11 @@ export const prepSwiftOrder = ({

const signedMsgOrderUuid = generateSignedMsgUuid();

console.log(
'DEBUG swift prep orderParams.isolatedPositionDeposit',
orderParams.isolatedPositionDeposit?.toString()
);

const baseSignedMsgOrderParamsMessage = {
signedMsgOrderParams: mainOrderParams,
uuid: signedMsgOrderUuid,
Expand All @@ -243,6 +250,7 @@ export const prepSwiftOrder = ({
orderParams.positionMaxLeverage
)
: null,
isolatedPositionDeposit: orderParams.isolatedPositionDeposit ?? null,
// Include builder params if provided
builderIdx: builderParams?.builderIdx ?? null,
builderFeeTenthBps: builderParams?.builderFeeTenthBps ?? null,
Expand Down Expand Up @@ -461,6 +469,10 @@ type PrepSignAndSendSwiftOrderParams = {
* Adjusts the max leverage of a position.
*/
positionMaxLeverage?: number;
/**
* Optional isolated position deposit amount for isolated positions.
*/
isolatedPositionDeposit?: BN;
};
/**
* Optional builder code parameters for revenue sharing.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -80,6 +80,7 @@ export interface NonMarketOrderParamsConfig {
* Example: 5 for 5x leverage, 10 for 10x leverage
*/
positionMaxLeverage: number;
isolatedPositionDeposit?: BN;
orderConfig:
| LimitOrderParamsOrderConfig
| {
Expand Down
1 change: 1 addition & 0 deletions common-ts/tsconfig.json
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@
"@drift-labs/sdk": ["../protocol/sdk"]
},
"outDir": "./lib"
// "strictNullChecks": true // TODO: we should enable this
},
"include": ["src/**/*"],
"exclude": ["node_modules"]
Expand Down
2 changes: 1 addition & 1 deletion protocol
Submodule protocol updated 2 files
+1 −1 sdk/VERSION
+1 −1 sdk/package.json
Loading
Loading