Skip to content

Commit 788bdef

Browse files
committed
feat: zero out account withdraw from perp position
1 parent afd9fee commit 788bdef

File tree

1 file changed

+53
-2
lines changed

1 file changed

+53
-2
lines changed

sdk/src/driftClient.ts

Lines changed: 53 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -46,6 +46,7 @@ import {
4646
PhoenixV1FulfillmentConfigAccount,
4747
PlaceAndTakeOrderSuccessCondition,
4848
PositionDirection,
49+
PositionFlag,
4950
ReferrerInfo,
5051
ReferrerNameAccount,
5152
SerumV3FulfillmentConfigAccount,
@@ -264,6 +265,51 @@ export class DriftClient {
264265
return this._isSubscribed && this.accountSubscriber.isSubscribed;
265266
}
266267

268+
private async getPostIxsForIsolatedWithdrawAfterMarketOrder(
269+
orderParams: OptionalOrderParams,
270+
userAccount: UserAccount
271+
): Promise<TransactionInstruction[]> {
272+
const postIxs: TransactionInstruction[] = [];
273+
const perpPosition = userAccount.perpPositions.find(
274+
(p) => p.marketIndex === orderParams.marketIndex
275+
);
276+
if (!perpPosition) return postIxs;
277+
278+
const isIsolated =
279+
(perpPosition.positionFlag & PositionFlag.IsolatedPosition) !== 0;
280+
if (!isIsolated) return postIxs;
281+
282+
const currentBase = perpPosition.baseAssetAmount;
283+
if (currentBase.eq(ZERO)) return postIxs;
284+
285+
const signedOrderBase =
286+
orderParams.direction === PositionDirection.LONG
287+
? orderParams.baseAssetAmount
288+
: (orderParams.baseAssetAmount as BN).neg();
289+
const postBase = currentBase.add(signedOrderBase as BN);
290+
if (!postBase.eq(ZERO)) return postIxs;
291+
292+
const withdrawAmount = this.getIsolatedPerpPositionTokenAmount(
293+
orderParams.marketIndex,
294+
userAccount.subAccountId
295+
);
296+
if (withdrawAmount.lte(ZERO)) return postIxs;
297+
298+
const userTokenAccount = await this.getAssociatedTokenAccount(
299+
QUOTE_SPOT_MARKET_INDEX
300+
);
301+
postIxs.push(
302+
await this.getWithdrawFromIsolatedPerpPositionIx(
303+
withdrawAmount,
304+
orderParams.marketIndex,
305+
userTokenAccount,
306+
userAccount.subAccountId
307+
)
308+
);
309+
310+
return postIxs;
311+
}
312+
267313
public set isSubscribed(val: boolean) {
268314
this._isSubscribed = val;
269315
}
@@ -4303,13 +4349,18 @@ export class DriftClient {
43034349
);
43044350
}
43054351

4352+
// Build post-order instructions for perp (e.g., withdraw isolated margin on close)
4353+
const postIxs: TransactionInstruction[] = isVariant(orderParams.marketType, 'perp')
4354+
? await this.getPostIxsForIsolatedWithdrawAfterMarketOrder(orderParams, userAccount)
4355+
: [];
4356+
43064357
ixPromisesForTxs.marketOrderTx = (async () => {
43074358
const placeOrdersIx = await this.getPlaceOrdersIx(
43084359
[orderParams, ...bracketOrdersParams],
43094360
userAccount.subAccountId
43104361
);
4311-
if (preIxs.length) {
4312-
return [...preIxs, placeOrdersIx] as unknown as TransactionInstruction;
4362+
if (preIxs.length || postIxs.length) {
4363+
return [...preIxs, placeOrdersIx, ...postIxs] as unknown as TransactionInstruction;
43134364
}
43144365
return placeOrdersIx;
43154366
})();

0 commit comments

Comments
 (0)