@drift-labs/sdk 2.42.0-beta.5 → 2.42.0-beta.7
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/VERSION +1 -1
- package/lib/driftClient.d.ts +1 -1
- package/lib/driftClient.js +16 -19
- package/lib/math/market.d.ts +1 -1
- package/lib/math/market.js +3 -2
- package/lib/math/spotMarket.d.ts +1 -1
- package/lib/math/spotMarket.js +9 -3
- package/lib/math/spotPosition.d.ts +3 -3
- package/lib/math/spotPosition.js +18 -7
- package/lib/user.d.ts +1 -1
- package/lib/user.js +29 -26
- package/package.json +1 -1
- package/src/driftClient.ts +20 -25
- package/src/math/market.ts +12 -7
- package/src/math/spotMarket.ts +13 -3
- package/src/math/spotPosition.ts +29 -7
- package/src/user.ts +64 -31
- package/tests/amm/test.ts +7 -5
- package/tests/auctions/test.ts +22 -11
- package/tests/dlob/helpers.ts +15 -13
- package/tests/tx/priorityFeeCalculator.ts +1 -1
- package/tests/user/test.ts +171 -24
package/VERSION
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
2.42.0-beta.
|
|
1
|
+
2.42.0-beta.7
|
package/lib/driftClient.d.ts
CHANGED
|
@@ -269,7 +269,7 @@ export declare class DriftClient {
|
|
|
269
269
|
* @param bracketOrdersParams
|
|
270
270
|
* @returns
|
|
271
271
|
*/
|
|
272
|
-
sendMarketOrderAndGetSignedFillTx(orderParams: OptionalOrderParams, userAccountPublicKey: PublicKey, userAccount: UserAccount, makerInfo?: MakerInfo | MakerInfo[], txParams?: TxParams, bracketOrdersParams?: OptionalOrderParams[], referrerInfo?: ReferrerInfo
|
|
272
|
+
sendMarketOrderAndGetSignedFillTx(orderParams: OptionalOrderParams, userAccountPublicKey: PublicKey, userAccount: UserAccount, makerInfo?: MakerInfo | MakerInfo[], txParams?: TxParams, bracketOrdersParams?: OptionalOrderParams[], referrerInfo?: ReferrerInfo): Promise<{
|
|
273
273
|
txSig: TransactionSignature;
|
|
274
274
|
signedFillTx: Transaction;
|
|
275
275
|
}>;
|
package/lib/driftClient.js
CHANGED
|
@@ -294,6 +294,7 @@ class DriftClient {
|
|
|
294
294
|
* @param includeDelegates
|
|
295
295
|
*/
|
|
296
296
|
async updateWallet(newWallet, subAccountIds, activeSubAccountId, includeDelegates, authoritySubaccountMap) {
|
|
297
|
+
var _a, _b;
|
|
297
298
|
const newProvider = new anchor_1.AnchorProvider(this.connection,
|
|
298
299
|
// @ts-ignore
|
|
299
300
|
newWallet, this.opts);
|
|
@@ -308,6 +309,10 @@ class DriftClient {
|
|
|
308
309
|
this.activeSubAccountId = activeSubAccountId;
|
|
309
310
|
this.userStatsAccountPublicKey = undefined;
|
|
310
311
|
this.includeDelegates = includeDelegates !== null && includeDelegates !== void 0 ? includeDelegates : false;
|
|
312
|
+
const walletSupportsVersionedTxns =
|
|
313
|
+
//@ts-ignore
|
|
314
|
+
(_b = (_a = this.wallet.supportedTransactionVersions) === null || _a === void 0 ? void 0 : _a.size) !== null && _b !== void 0 ? _b : 0 > 1;
|
|
315
|
+
this.txVersion = walletSupportsVersionedTxns ? 0 : 'legacy';
|
|
311
316
|
if (includeDelegates && subAccountIds) {
|
|
312
317
|
throw new Error('Can only pass one of includeDelegates or subAccountIds. If you want to specify subaccount ids for multiple authorities, pass authoritySubaccountMap instead');
|
|
313
318
|
}
|
|
@@ -939,28 +944,25 @@ class DriftClient {
|
|
|
939
944
|
* @param reduceOnly
|
|
940
945
|
*/
|
|
941
946
|
async deposit(amount, marketIndex, associatedTokenAccount, subAccountId, reduceOnly = false) {
|
|
942
|
-
const tx = new web3_js_1.Transaction();
|
|
943
|
-
tx.add(web3_js_1.ComputeBudgetProgram.setComputeUnitLimit({
|
|
944
|
-
units: 600000,
|
|
945
|
-
}));
|
|
946
947
|
const additionalSigners = [];
|
|
947
948
|
const spotMarketAccount = this.getSpotMarketAccount(marketIndex);
|
|
948
949
|
const isSolMarket = spotMarketAccount.mint.equals(spotMarkets_1.WRAPPED_SOL_MINT);
|
|
949
950
|
const signerAuthority = this.wallet.publicKey;
|
|
950
951
|
const createWSOLTokenAccount = isSolMarket && associatedTokenAccount.equals(signerAuthority);
|
|
952
|
+
const instructions = [];
|
|
951
953
|
if (createWSOLTokenAccount) {
|
|
952
954
|
const { ixs, pubkey } = await this.getWrappedSolAccountCreationIxs(amount, true);
|
|
953
955
|
associatedTokenAccount = pubkey;
|
|
954
|
-
|
|
955
|
-
tx.add(ix);
|
|
956
|
-
});
|
|
956
|
+
instructions.push(...ixs);
|
|
957
957
|
}
|
|
958
958
|
const depositCollateralIx = await this.getDepositInstruction(amount, marketIndex, associatedTokenAccount, subAccountId, reduceOnly, true);
|
|
959
|
-
|
|
959
|
+
instructions.push(depositCollateralIx);
|
|
960
960
|
// Close the wrapped sol account at the end of the transaction
|
|
961
961
|
if (createWSOLTokenAccount) {
|
|
962
|
-
|
|
962
|
+
instructions.push((0, spl_token_1.createCloseAccountInstruction)(associatedTokenAccount, signerAuthority, signerAuthority, []));
|
|
963
963
|
}
|
|
964
|
+
const txParams = { ...this.txParams, computeUnits: 600000 };
|
|
965
|
+
const tx = await this.buildTransaction(instructions, txParams);
|
|
964
966
|
const { txSig, slot } = await this.sendTransaction(tx, additionalSigners, this.opts);
|
|
965
967
|
this.spotMarketLastSlotCache.set(marketIndex, slot);
|
|
966
968
|
return txSig;
|
|
@@ -1363,8 +1365,7 @@ class DriftClient {
|
|
|
1363
1365
|
* @param bracketOrdersParams
|
|
1364
1366
|
* @returns
|
|
1365
1367
|
*/
|
|
1366
|
-
async sendMarketOrderAndGetSignedFillTx(orderParams, userAccountPublicKey, userAccount, makerInfo, txParams, bracketOrdersParams = new Array(), referrerInfo
|
|
1367
|
-
var _a, _b;
|
|
1368
|
+
async sendMarketOrderAndGetSignedFillTx(orderParams, userAccountPublicKey, userAccount, makerInfo, txParams, bracketOrdersParams = new Array(), referrerInfo) {
|
|
1368
1369
|
const marketIndex = orderParams.marketIndex;
|
|
1369
1370
|
const orderId = userAccount.nextOrderId;
|
|
1370
1371
|
const bracketOrderIxs = [];
|
|
@@ -1377,11 +1378,8 @@ class DriftClient {
|
|
|
1377
1378
|
orderId,
|
|
1378
1379
|
marketIndex,
|
|
1379
1380
|
}, makerInfo, referrerInfo);
|
|
1380
|
-
const walletSupportsVersionedTxns =
|
|
1381
|
-
//@ts-ignore
|
|
1382
|
-
(_b = (_a = this.wallet.supportedTransactionVersions) === null || _a === void 0 ? void 0 : _a.size) !== null && _b !== void 0 ? _b : 0 > 1;
|
|
1383
1381
|
// use versioned transactions if there is a lookup table account and wallet is compatible
|
|
1384
|
-
if (
|
|
1382
|
+
if (this.txVersion === 0) {
|
|
1385
1383
|
const versionedMarketOrderTx = await this.buildTransaction([placePerpOrderIx].concat(bracketOrderIxs), txParams, 0);
|
|
1386
1384
|
const versionedFillTx = await this.buildTransaction([fillPerpOrderIx], txParams, 0);
|
|
1387
1385
|
const [signedVersionedMarketOrderTx, signedVersionedFillTx] = await this.provider.wallet.signAllTransactions([
|
|
@@ -3252,12 +3250,11 @@ class DriftClient {
|
|
|
3252
3250
|
return undefined;
|
|
3253
3251
|
}
|
|
3254
3252
|
sendTransaction(tx, additionalSigners, opts, preSigned) {
|
|
3255
|
-
|
|
3256
|
-
|
|
3257
|
-
return this.txSender.send(tx, additionalSigners, opts, preSigned);
|
|
3253
|
+
if (tx instanceof web3_js_1.VersionedTransaction) {
|
|
3254
|
+
return this.txSender.sendVersionedTransaction(tx, additionalSigners, opts, preSigned);
|
|
3258
3255
|
}
|
|
3259
3256
|
else {
|
|
3260
|
-
return this.txSender.
|
|
3257
|
+
return this.txSender.send(tx, additionalSigners, opts, preSigned);
|
|
3261
3258
|
}
|
|
3262
3259
|
}
|
|
3263
3260
|
async buildTransaction(instructions, txParams, txVersion, lookupTables) {
|
package/lib/math/market.d.ts
CHANGED
|
@@ -26,7 +26,7 @@ export declare function calculateAskPrice(market: PerpMarketAccount, oraclePrice
|
|
|
26
26
|
export declare function calculateNewMarketAfterTrade(baseAssetAmount: BN, direction: PositionDirection, market: PerpMarketAccount): PerpMarketAccount;
|
|
27
27
|
export declare function calculateOracleReserveSpread(market: PerpMarketAccount, oraclePriceData: OraclePriceData): BN;
|
|
28
28
|
export declare function calculateOracleSpread(price: BN, oraclePriceData: OraclePriceData): BN;
|
|
29
|
-
export declare function calculateMarketMarginRatio(market: PerpMarketAccount, size: BN, marginCategory: MarginCategory): number;
|
|
29
|
+
export declare function calculateMarketMarginRatio(market: PerpMarketAccount, size: BN, marginCategory: MarginCategory, customMarginRatio?: number): number;
|
|
30
30
|
export declare function calculateUnrealizedAssetWeight(market: PerpMarketAccount, quoteSpotMarket: SpotMarketAccount, unrealizedPnl: BN, marginCategory: MarginCategory, oraclePriceData: OraclePriceData): BN;
|
|
31
31
|
export declare function calculateMarketAvailablePNL(perpMarket: PerpMarketAccount, spotMarket: SpotMarketAccount): BN;
|
|
32
32
|
export declare function calculateMarketMaxAvailableInsurance(perpMarket: PerpMarketAccount, spotMarket: SpotMarketAccount): BN;
|
package/lib/math/market.js
CHANGED
|
@@ -60,11 +60,12 @@ function calculateOracleSpread(price, oraclePriceData) {
|
|
|
60
60
|
return price.sub(oraclePriceData.price);
|
|
61
61
|
}
|
|
62
62
|
exports.calculateOracleSpread = calculateOracleSpread;
|
|
63
|
-
function calculateMarketMarginRatio(market, size, marginCategory) {
|
|
63
|
+
function calculateMarketMarginRatio(market, size, marginCategory, customMarginRatio = 0) {
|
|
64
64
|
let marginRatio;
|
|
65
65
|
switch (marginCategory) {
|
|
66
66
|
case 'Initial': {
|
|
67
|
-
|
|
67
|
+
// use lowest leverage between max allowed and optional user custom max
|
|
68
|
+
marginRatio = Math.max((0, margin_1.calculateSizePremiumLiabilityWeight)(size, new anchor_1.BN(market.imfFactor), new anchor_1.BN(market.marginRatioInitial), numericConstants_1.MARGIN_PRECISION).toNumber(), customMarginRatio);
|
|
68
69
|
break;
|
|
69
70
|
}
|
|
70
71
|
case 'Maintenance': {
|
package/lib/math/spotMarket.d.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
1
|
import { BN } from '@coral-xyz/anchor';
|
|
2
2
|
import { MarginCategory, SpotBalanceType, SpotMarketAccount } from '../types';
|
|
3
3
|
export declare function castNumberToSpotPrecision(value: number | BN, spotMarket: SpotMarketAccount): BN;
|
|
4
|
-
export declare function calculateSpotMarketMarginRatio(market: SpotMarketAccount, oraclePrice: BN, marginCategory: MarginCategory, size: BN, balanceType: SpotBalanceType): number;
|
|
4
|
+
export declare function calculateSpotMarketMarginRatio(market: SpotMarketAccount, oraclePrice: BN, marginCategory: MarginCategory, size: BN, balanceType: SpotBalanceType, customMarginRatio?: number): number;
|
package/lib/math/spotMarket.js
CHANGED
|
@@ -14,14 +14,20 @@ function castNumberToSpotPrecision(value, spotMarket) {
|
|
|
14
14
|
}
|
|
15
15
|
}
|
|
16
16
|
exports.castNumberToSpotPrecision = castNumberToSpotPrecision;
|
|
17
|
-
function calculateSpotMarketMarginRatio(market, oraclePrice, marginCategory, size, balanceType) {
|
|
17
|
+
function calculateSpotMarketMarginRatio(market, oraclePrice, marginCategory, size, balanceType, customMarginRatio = 0) {
|
|
18
|
+
let marginRatio;
|
|
18
19
|
if ((0, types_1.isVariant)(balanceType, 'deposit')) {
|
|
19
20
|
const assetWeight = (0, spotBalance_1.calculateAssetWeight)(size, oraclePrice, market, marginCategory);
|
|
20
|
-
|
|
21
|
+
marginRatio = numericConstants_1.MARGIN_PRECISION.sub(assetWeight).toNumber();
|
|
21
22
|
}
|
|
22
23
|
else {
|
|
23
24
|
const liabilityWeight = (0, spotBalance_1.calculateLiabilityWeight)(size, market, marginCategory);
|
|
24
|
-
|
|
25
|
+
marginRatio = liabilityWeight.sub(numericConstants_1.MARGIN_PRECISION).toNumber();
|
|
25
26
|
}
|
|
27
|
+
if (marginCategory === 'Initial') {
|
|
28
|
+
// use lowest leverage between max allowed and optional user custom max
|
|
29
|
+
return Math.max(marginRatio, customMarginRatio);
|
|
30
|
+
}
|
|
31
|
+
return marginRatio;
|
|
26
32
|
}
|
|
27
33
|
exports.calculateSpotMarketMarginRatio = calculateSpotMarketMarginRatio;
|
|
@@ -10,9 +10,9 @@ export type OrderFillSimulation = {
|
|
|
10
10
|
weightedTokenValue: BN;
|
|
11
11
|
freeCollateralContribution: any;
|
|
12
12
|
};
|
|
13
|
-
export declare function getWorstCaseTokenAmounts(spotPosition: SpotPosition, spotMarketAccount: SpotMarketAccount, strictOraclePrice: StrictOraclePrice, marginCategory: MarginCategory): OrderFillSimulation;
|
|
14
|
-
export declare function calculateWeightedTokenValue(tokenAmount: BN, tokenValue: BN, oraclePrice: BN, spotMarket: SpotMarketAccount, marginCategory: MarginCategory): {
|
|
13
|
+
export declare function getWorstCaseTokenAmounts(spotPosition: SpotPosition, spotMarketAccount: SpotMarketAccount, strictOraclePrice: StrictOraclePrice, marginCategory: MarginCategory, customMarginRatio?: number): OrderFillSimulation;
|
|
14
|
+
export declare function calculateWeightedTokenValue(tokenAmount: BN, tokenValue: BN, oraclePrice: BN, spotMarket: SpotMarketAccount, marginCategory: MarginCategory, customMarginRatio?: number): {
|
|
15
15
|
weight: BN;
|
|
16
16
|
weightedTokenValue: BN;
|
|
17
17
|
};
|
|
18
|
-
export declare function simulateOrderFill(tokenAmount: BN, tokenValue: BN, openOrders: BN, strictOraclePrice: StrictOraclePrice, spotMarket: SpotMarketAccount, marginCategory: MarginCategory): OrderFillSimulation;
|
|
18
|
+
export declare function simulateOrderFill(tokenAmount: BN, tokenValue: BN, openOrders: BN, strictOraclePrice: StrictOraclePrice, spotMarket: SpotMarketAccount, marginCategory: MarginCategory, customMarginRatio?: number): OrderFillSimulation;
|
package/lib/math/spotPosition.js
CHANGED
|
@@ -2,16 +2,17 @@
|
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.simulateOrderFill = exports.calculateWeightedTokenValue = exports.getWorstCaseTokenAmounts = exports.isSpotPositionAvailable = void 0;
|
|
4
4
|
const numericConstants_1 = require("../constants/numericConstants");
|
|
5
|
+
const anchor_1 = require("@coral-xyz/anchor");
|
|
5
6
|
const spotBalance_1 = require("./spotBalance");
|
|
6
7
|
function isSpotPositionAvailable(position) {
|
|
7
8
|
return position.scaledBalance.eq(numericConstants_1.ZERO) && position.openOrders === 0;
|
|
8
9
|
}
|
|
9
10
|
exports.isSpotPositionAvailable = isSpotPositionAvailable;
|
|
10
|
-
function getWorstCaseTokenAmounts(spotPosition, spotMarketAccount, strictOraclePrice, marginCategory) {
|
|
11
|
+
function getWorstCaseTokenAmounts(spotPosition, spotMarketAccount, strictOraclePrice, marginCategory, customMarginRatio) {
|
|
11
12
|
const tokenAmount = (0, spotBalance_1.getSignedTokenAmount)((0, spotBalance_1.getTokenAmount)(spotPosition.scaledBalance, spotMarketAccount, spotPosition.balanceType), spotPosition.balanceType);
|
|
12
13
|
const tokenValue = (0, spotBalance_1.getStrictTokenValue)(tokenAmount, spotMarketAccount.decimals, strictOraclePrice);
|
|
13
14
|
if (spotPosition.openBids.eq(numericConstants_1.ZERO) && spotPosition.openAsks.eq(numericConstants_1.ZERO)) {
|
|
14
|
-
const { weight, weightedTokenValue } = calculateWeightedTokenValue(tokenAmount, tokenValue, strictOraclePrice.current, spotMarketAccount, marginCategory);
|
|
15
|
+
const { weight, weightedTokenValue } = calculateWeightedTokenValue(tokenAmount, tokenValue, strictOraclePrice.current, spotMarketAccount, marginCategory, customMarginRatio);
|
|
15
16
|
return {
|
|
16
17
|
tokenAmount,
|
|
17
18
|
ordersValue: numericConstants_1.ZERO,
|
|
@@ -21,8 +22,8 @@ function getWorstCaseTokenAmounts(spotPosition, spotMarketAccount, strictOracleP
|
|
|
21
22
|
freeCollateralContribution: weightedTokenValue,
|
|
22
23
|
};
|
|
23
24
|
}
|
|
24
|
-
const bidsSimulation = simulateOrderFill(tokenAmount, tokenValue, spotPosition.openBids, strictOraclePrice, spotMarketAccount, marginCategory);
|
|
25
|
-
const asksSimulation = simulateOrderFill(tokenAmount, tokenValue, spotPosition.openAsks, strictOraclePrice, spotMarketAccount, marginCategory);
|
|
25
|
+
const bidsSimulation = simulateOrderFill(tokenAmount, tokenValue, spotPosition.openBids, strictOraclePrice, spotMarketAccount, marginCategory, customMarginRatio);
|
|
26
|
+
const asksSimulation = simulateOrderFill(tokenAmount, tokenValue, spotPosition.openAsks, strictOraclePrice, spotMarketAccount, marginCategory, customMarginRatio);
|
|
26
27
|
if (asksSimulation.freeCollateralContribution.lt(bidsSimulation.freeCollateralContribution)) {
|
|
27
28
|
return asksSimulation;
|
|
28
29
|
}
|
|
@@ -31,7 +32,7 @@ function getWorstCaseTokenAmounts(spotPosition, spotMarketAccount, strictOracleP
|
|
|
31
32
|
}
|
|
32
33
|
}
|
|
33
34
|
exports.getWorstCaseTokenAmounts = getWorstCaseTokenAmounts;
|
|
34
|
-
function calculateWeightedTokenValue(tokenAmount, tokenValue, oraclePrice, spotMarket, marginCategory) {
|
|
35
|
+
function calculateWeightedTokenValue(tokenAmount, tokenValue, oraclePrice, spotMarket, marginCategory, customMarginRatio) {
|
|
35
36
|
let weight;
|
|
36
37
|
if (tokenValue.gte(numericConstants_1.ZERO)) {
|
|
37
38
|
weight = (0, spotBalance_1.calculateAssetWeight)(tokenAmount, oraclePrice, spotMarket, marginCategory);
|
|
@@ -39,6 +40,16 @@ function calculateWeightedTokenValue(tokenAmount, tokenValue, oraclePrice, spotM
|
|
|
39
40
|
else {
|
|
40
41
|
weight = (0, spotBalance_1.calculateLiabilityWeight)(tokenAmount.abs(), spotMarket, marginCategory);
|
|
41
42
|
}
|
|
43
|
+
if (marginCategory === 'Initial' &&
|
|
44
|
+
customMarginRatio &&
|
|
45
|
+
spotMarket.marketIndex !== numericConstants_1.QUOTE_SPOT_MARKET_INDEX) {
|
|
46
|
+
const userCustomAssetWeight = tokenValue.gte(numericConstants_1.ZERO)
|
|
47
|
+
? anchor_1.BN.max(numericConstants_1.ZERO, numericConstants_1.SPOT_MARKET_WEIGHT_PRECISION.subn(customMarginRatio))
|
|
48
|
+
: numericConstants_1.SPOT_MARKET_WEIGHT_PRECISION.addn(customMarginRatio);
|
|
49
|
+
weight = tokenValue.gte(numericConstants_1.ZERO)
|
|
50
|
+
? anchor_1.BN.min(weight, userCustomAssetWeight)
|
|
51
|
+
: anchor_1.BN.max(weight, userCustomAssetWeight);
|
|
52
|
+
}
|
|
42
53
|
return {
|
|
43
54
|
weight: weight,
|
|
44
55
|
weightedTokenValue: tokenValue
|
|
@@ -47,13 +58,13 @@ function calculateWeightedTokenValue(tokenAmount, tokenValue, oraclePrice, spotM
|
|
|
47
58
|
};
|
|
48
59
|
}
|
|
49
60
|
exports.calculateWeightedTokenValue = calculateWeightedTokenValue;
|
|
50
|
-
function simulateOrderFill(tokenAmount, tokenValue, openOrders, strictOraclePrice, spotMarket, marginCategory) {
|
|
61
|
+
function simulateOrderFill(tokenAmount, tokenValue, openOrders, strictOraclePrice, spotMarket, marginCategory, customMarginRatio) {
|
|
51
62
|
const ordersValue = (0, spotBalance_1.getTokenValue)(openOrders.neg(), spotMarket.decimals, {
|
|
52
63
|
price: strictOraclePrice.max(),
|
|
53
64
|
});
|
|
54
65
|
const tokenAmountAfterFill = tokenAmount.add(openOrders);
|
|
55
66
|
const tokenValueAfterFill = tokenValue.add(ordersValue.neg());
|
|
56
|
-
const { weight, weightedTokenValue: weightedTokenValueAfterFill } = calculateWeightedTokenValue(tokenAmountAfterFill, tokenValueAfterFill, strictOraclePrice.current, spotMarket, marginCategory);
|
|
67
|
+
const { weight, weightedTokenValue: weightedTokenValueAfterFill } = calculateWeightedTokenValue(tokenAmountAfterFill, tokenValueAfterFill, strictOraclePrice.current, spotMarket, marginCategory, customMarginRatio);
|
|
57
68
|
const freeCollateralContribution = weightedTokenValueAfterFill.add(ordersValue);
|
|
58
69
|
return {
|
|
59
70
|
tokenAmount: tokenAmountAfterFill,
|
package/lib/user.d.ts
CHANGED
|
@@ -187,7 +187,7 @@ export declare class User {
|
|
|
187
187
|
spotAssetValue: BN;
|
|
188
188
|
spotLiabilityValue: BN;
|
|
189
189
|
}): BN;
|
|
190
|
-
getLeverageComponents(includeOpenOrders?: boolean): {
|
|
190
|
+
getLeverageComponents(includeOpenOrders?: boolean, marginCategory?: MarginCategory): {
|
|
191
191
|
perpLiabilityValue: BN;
|
|
192
192
|
perpPnl: BN;
|
|
193
193
|
spotAssetValue: BN;
|
package/lib/user.js
CHANGED
|
@@ -411,7 +411,7 @@ class User {
|
|
|
411
411
|
return this.getPerpBuyingPowerFromFreeCollateralAndBaseAssetAmount(marketIndex, freeCollateral, worstCaseBaseAssetAmount);
|
|
412
412
|
}
|
|
413
413
|
getPerpBuyingPowerFromFreeCollateralAndBaseAssetAmount(marketIndex, freeCollateral, baseAssetAmount) {
|
|
414
|
-
const marginRatio = (0, _1.calculateMarketMarginRatio)(this.driftClient.getPerpMarketAccount(marketIndex), baseAssetAmount, 'Initial');
|
|
414
|
+
const marginRatio = (0, _1.calculateMarketMarginRatio)(this.driftClient.getPerpMarketAccount(marketIndex), baseAssetAmount, 'Initial', this.getUserAccount().maxMarginRatio);
|
|
415
415
|
return freeCollateral.mul(numericConstants_1.MARGIN_PRECISION).div(new _1.BN(marginRatio));
|
|
416
416
|
}
|
|
417
417
|
/**
|
|
@@ -577,7 +577,7 @@ class User {
|
|
|
577
577
|
continue;
|
|
578
578
|
}
|
|
579
579
|
}
|
|
580
|
-
const { tokenAmount: worstCaseTokenAmount, ordersValue: worstCaseQuoteTokenAmount, } = (0, spotPosition_1.getWorstCaseTokenAmounts)(spotPosition, spotMarketAccount, strictOraclePrice, marginCategory
|
|
580
|
+
const { tokenAmount: worstCaseTokenAmount, ordersValue: worstCaseQuoteTokenAmount, } = (0, spotPosition_1.getWorstCaseTokenAmounts)(spotPosition, spotMarketAccount, strictOraclePrice, marginCategory, this.getUserAccount().maxMarginRatio);
|
|
581
581
|
if (worstCaseTokenAmount.gt(numericConstants_1.ZERO) && countForBase) {
|
|
582
582
|
const baseAssetValue = this.getSpotAssetValue(worstCaseTokenAmount, strictOraclePrice, spotMarketAccount, marginCategory);
|
|
583
583
|
totalAssetValue = totalAssetValue.add(baseAssetValue);
|
|
@@ -620,8 +620,9 @@ class User {
|
|
|
620
620
|
let liabilityValue = (0, _1.getStrictTokenValue)(tokenAmount, spotMarketAccount.decimals, strictOraclePrice);
|
|
621
621
|
if (marginCategory !== undefined) {
|
|
622
622
|
let weight = (0, spotBalance_1.calculateLiabilityWeight)(tokenAmount, spotMarketAccount, marginCategory);
|
|
623
|
-
if (marginCategory === 'Initial'
|
|
624
|
-
|
|
623
|
+
if (marginCategory === 'Initial' &&
|
|
624
|
+
spotMarketAccount.marketIndex !== numericConstants_1.QUOTE_SPOT_MARKET_INDEX) {
|
|
625
|
+
weight = _1.BN.max(weight, numericConstants_1.SPOT_MARKET_WEIGHT_PRECISION.addn(this.getUserAccount().maxMarginRatio));
|
|
625
626
|
}
|
|
626
627
|
if (liquidationBuffer !== undefined) {
|
|
627
628
|
weight = weight.add(liquidationBuffer);
|
|
@@ -639,7 +640,12 @@ class User {
|
|
|
639
640
|
getSpotAssetValue(tokenAmount, strictOraclePrice, spotMarketAccount, marginCategory) {
|
|
640
641
|
let assetValue = (0, _1.getStrictTokenValue)(tokenAmount, spotMarketAccount.decimals, strictOraclePrice);
|
|
641
642
|
if (marginCategory !== undefined) {
|
|
642
|
-
|
|
643
|
+
let weight = (0, spotBalance_1.calculateAssetWeight)(tokenAmount, strictOraclePrice.current, spotMarketAccount, marginCategory);
|
|
644
|
+
if (marginCategory === 'Initial' &&
|
|
645
|
+
spotMarketAccount.marketIndex !== numericConstants_1.QUOTE_SPOT_MARKET_INDEX) {
|
|
646
|
+
const userCustomAssetWeight = _1.BN.max(numericConstants_1.ZERO, numericConstants_1.SPOT_MARKET_WEIGHT_PRECISION.subn(this.getUserAccount().maxMarginRatio));
|
|
647
|
+
weight = _1.BN.min(weight, userCustomAssetWeight);
|
|
648
|
+
}
|
|
643
649
|
assetValue = assetValue.mul(weight).div(numericConstants_1.SPOT_MARKET_WEIGHT_PRECISION);
|
|
644
650
|
}
|
|
645
651
|
return assetValue;
|
|
@@ -702,10 +708,7 @@ class User {
|
|
|
702
708
|
.mul(valuationPrice)
|
|
703
709
|
.div(numericConstants_1.BASE_PRECISION);
|
|
704
710
|
if (marginCategory) {
|
|
705
|
-
let marginRatio = new _1.BN((0, _1.calculateMarketMarginRatio)(market, baseAssetAmount.abs(), marginCategory));
|
|
706
|
-
if (marginCategory === 'Initial') {
|
|
707
|
-
marginRatio = _1.BN.max(marginRatio, new _1.BN(this.getUserAccount().maxMarginRatio));
|
|
708
|
-
}
|
|
711
|
+
let marginRatio = new _1.BN((0, _1.calculateMarketMarginRatio)(market, baseAssetAmount.abs(), marginCategory, this.getUserAccount().maxMarginRatio));
|
|
709
712
|
if (liquidationBuffer !== undefined) {
|
|
710
713
|
marginRatio = marginRatio.add(liquidationBuffer);
|
|
711
714
|
}
|
|
@@ -834,10 +837,10 @@ class User {
|
|
|
834
837
|
}
|
|
835
838
|
return totalLiabilityValue.mul(numericConstants_1.TEN_THOUSAND).div(netAssetValue);
|
|
836
839
|
}
|
|
837
|
-
getLeverageComponents(includeOpenOrders = true) {
|
|
838
|
-
const perpLiability = this.getTotalPerpPositionValue(
|
|
839
|
-
const perpPnl = this.getUnrealizedPNL(true);
|
|
840
|
-
const { totalAssetValue: spotAssetValue, totalLiabilityValue: spotLiabilityValue, } = this.getSpotMarketAssetAndLiabilityValue(undefined,
|
|
840
|
+
getLeverageComponents(includeOpenOrders = true, marginCategory = undefined) {
|
|
841
|
+
const perpLiability = this.getTotalPerpPositionValue(marginCategory, undefined, includeOpenOrders);
|
|
842
|
+
const perpPnl = this.getUnrealizedPNL(true, undefined, marginCategory);
|
|
843
|
+
const { totalAssetValue: spotAssetValue, totalLiabilityValue: spotLiabilityValue, } = this.getSpotMarketAssetAndLiabilityValue(undefined, marginCategory, undefined, includeOpenOrders);
|
|
841
844
|
return {
|
|
842
845
|
perpLiabilityValue: perpLiability,
|
|
843
846
|
perpPnl,
|
|
@@ -889,7 +892,7 @@ class User {
|
|
|
889
892
|
let rawMarginRatio;
|
|
890
893
|
switch (marginCategory) {
|
|
891
894
|
case 'Initial':
|
|
892
|
-
rawMarginRatio = market.marginRatioInitial;
|
|
895
|
+
rawMarginRatio = Math.max(market.marginRatioInitial, this.getUserAccount().maxMarginRatio);
|
|
893
896
|
break;
|
|
894
897
|
case 'Maintenance':
|
|
895
898
|
rawMarginRatio = market.marginRatioMaintenance;
|
|
@@ -905,7 +908,7 @@ class User {
|
|
|
905
908
|
.mul(numericConstants_1.PRICE_PRECISION)
|
|
906
909
|
.div(marketPrice));
|
|
907
910
|
// margin ratio incorporting upper bound on size
|
|
908
|
-
let marginRatio = (0, _1.calculateMarketMarginRatio)(market, maxSize, marginCategory);
|
|
911
|
+
let marginRatio = (0, _1.calculateMarketMarginRatio)(market, maxSize, marginCategory, this.getUserAccount().maxMarginRatio);
|
|
909
912
|
// use more fesible size since imf factor activated
|
|
910
913
|
let attempts = 0;
|
|
911
914
|
while (marginRatio > rawMarginRatio + 1e-4 && attempts < 10) {
|
|
@@ -916,7 +919,7 @@ class User {
|
|
|
916
919
|
.mul(numericConstants_1.PRICE_PRECISION)
|
|
917
920
|
.div(marketPrice));
|
|
918
921
|
// margin ratio incorporting more fesible target size
|
|
919
|
-
marginRatio = (0, _1.calculateMarketMarginRatio)(market, targetSize, marginCategory);
|
|
922
|
+
marginRatio = (0, _1.calculateMarketMarginRatio)(market, targetSize, marginCategory, this.getUserAccount().maxMarginRatio);
|
|
920
923
|
attempts += 1;
|
|
921
924
|
}
|
|
922
925
|
// how much more liabilities can be opened w remaining free collateral
|
|
@@ -1277,19 +1280,19 @@ class User {
|
|
|
1277
1280
|
let freeCollateral = this.getFreeCollateral();
|
|
1278
1281
|
const marginRatio = (0, _1.calculateSpotMarketMarginRatio)(market, oraclePrice, 'Initial', numericConstants_1.ZERO, (0, types_1.isVariant)(direction, 'long')
|
|
1279
1282
|
? _1.SpotBalanceType.DEPOSIT
|
|
1280
|
-
: _1.SpotBalanceType.BORROW);
|
|
1283
|
+
: _1.SpotBalanceType.BORROW, this.getUserAccount().maxMarginRatio);
|
|
1281
1284
|
let tradeAmount = numericConstants_1.ZERO;
|
|
1282
1285
|
if (this.getUserAccount().isMarginTradingEnabled) {
|
|
1283
1286
|
// if the user is buying/selling and already short/long, need to account for closing out short/long
|
|
1284
1287
|
if ((0, types_1.isVariant)(direction, 'long') && currentSpotMarketNetValue.lt(numericConstants_1.ZERO)) {
|
|
1285
1288
|
tradeAmount = currentSpotMarketNetValue.abs();
|
|
1286
|
-
const marginRatio = (0, _1.calculateSpotMarketMarginRatio)(market, oraclePrice, 'Initial', this.getTokenAmount(targetMarketIndex).abs(), _1.SpotBalanceType.BORROW);
|
|
1289
|
+
const marginRatio = (0, _1.calculateSpotMarketMarginRatio)(market, oraclePrice, 'Initial', this.getTokenAmount(targetMarketIndex).abs(), _1.SpotBalanceType.BORROW, this.getUserAccount().maxMarginRatio);
|
|
1287
1290
|
freeCollateral = freeCollateral.add(tradeAmount.mul(new _1.BN(marginRatio)).div(numericConstants_1.MARGIN_PRECISION));
|
|
1288
1291
|
}
|
|
1289
1292
|
else if ((0, types_1.isVariant)(direction, 'short') &&
|
|
1290
1293
|
currentSpotMarketNetValue.gt(numericConstants_1.ZERO)) {
|
|
1291
1294
|
tradeAmount = currentSpotMarketNetValue;
|
|
1292
|
-
const marginRatio = (0, _1.calculateSpotMarketMarginRatio)(market, oraclePrice, 'Initial', this.getTokenAmount(targetMarketIndex), _1.SpotBalanceType.DEPOSIT);
|
|
1295
|
+
const marginRatio = (0, _1.calculateSpotMarketMarginRatio)(market, oraclePrice, 'Initial', this.getTokenAmount(targetMarketIndex), _1.SpotBalanceType.DEPOSIT, this.getUserAccount().maxMarginRatio);
|
|
1293
1296
|
freeCollateral = freeCollateral.add(tradeAmount.mul(new _1.BN(marginRatio)).div(numericConstants_1.MARGIN_PRECISION));
|
|
1294
1297
|
}
|
|
1295
1298
|
tradeAmount = tradeAmount.add(freeCollateral.mul(numericConstants_1.MARGIN_PRECISION).div(new _1.BN(marginRatio)));
|
|
@@ -1332,7 +1335,7 @@ class User {
|
|
|
1332
1335
|
const outContributionInitial = this.calculateSpotPositionFreeCollateralContribution(outSpotPosition, outStrictOraclePrice);
|
|
1333
1336
|
const { totalAssetValue: outTotalAssetValueInitial, totalLiabilityValue: outTotalLiabilityValueInitial, } = this.calculateSpotPositionLeverageContribution(outSpotPosition, outStrictOraclePrice);
|
|
1334
1337
|
const initialContribution = inContributionInitial.add(outContributionInitial);
|
|
1335
|
-
const { perpLiabilityValue, perpPnl, spotAssetValue, spotLiabilityValue } = this.getLeverageComponents();
|
|
1338
|
+
const { perpLiabilityValue, perpPnl, spotAssetValue, spotLiabilityValue } = this.getLeverageComponents(undefined, 'Initial');
|
|
1336
1339
|
if (!calculateSwap) {
|
|
1337
1340
|
calculateSwap = (inSwap) => {
|
|
1338
1341
|
return inSwap
|
|
@@ -1440,14 +1443,14 @@ class User {
|
|
|
1440
1443
|
calculateSpotPositionFreeCollateralContribution(spotPosition, strictOraclePrice) {
|
|
1441
1444
|
const marginCategory = 'Initial';
|
|
1442
1445
|
const spotMarketAccount = this.driftClient.getSpotMarketAccount(spotPosition.marketIndex);
|
|
1443
|
-
const { freeCollateralContribution } = (0, spotPosition_1.getWorstCaseTokenAmounts)(spotPosition, spotMarketAccount, strictOraclePrice, marginCategory);
|
|
1446
|
+
const { freeCollateralContribution } = (0, spotPosition_1.getWorstCaseTokenAmounts)(spotPosition, spotMarketAccount, strictOraclePrice, marginCategory, this.getUserAccount().maxMarginRatio);
|
|
1444
1447
|
return freeCollateralContribution;
|
|
1445
1448
|
}
|
|
1446
1449
|
calculateSpotPositionLeverageContribution(spotPosition, strictOraclePrice) {
|
|
1447
1450
|
let totalAssetValue = numericConstants_1.ZERO;
|
|
1448
1451
|
let totalLiabilityValue = numericConstants_1.ZERO;
|
|
1449
1452
|
const spotMarketAccount = this.driftClient.getSpotMarketAccount(spotPosition.marketIndex);
|
|
1450
|
-
const { tokenValue, ordersValue } = (0, spotPosition_1.getWorstCaseTokenAmounts)(spotPosition, spotMarketAccount, strictOraclePrice, 'Initial');
|
|
1453
|
+
const { tokenValue, ordersValue } = (0, spotPosition_1.getWorstCaseTokenAmounts)(spotPosition, spotMarketAccount, strictOraclePrice, 'Initial', this.getUserAccount().maxMarginRatio);
|
|
1451
1454
|
if (tokenValue.gte(numericConstants_1.ZERO)) {
|
|
1452
1455
|
totalAssetValue = tokenValue;
|
|
1453
1456
|
}
|
|
@@ -1487,7 +1490,7 @@ class User {
|
|
|
1487
1490
|
this.getEmptySpotPosition(outMarketIndex);
|
|
1488
1491
|
const { totalAssetValue: inTotalAssetValueInitial, totalLiabilityValue: inTotalLiabilityValueInitial, } = this.calculateSpotPositionLeverageContribution(inSpotPosition, inStrictOraclePrice);
|
|
1489
1492
|
const { totalAssetValue: outTotalAssetValueInitial, totalLiabilityValue: outTotalLiabilityValueInitial, } = this.calculateSpotPositionLeverageContribution(outSpotPosition, outStrictOraclePrice);
|
|
1490
|
-
const { perpLiabilityValue, perpPnl, spotAssetValue, spotLiabilityValue } = this.getLeverageComponents();
|
|
1493
|
+
const { perpLiabilityValue, perpPnl, spotAssetValue, spotLiabilityValue } = this.getLeverageComponents(undefined, 'Initial');
|
|
1491
1494
|
const inPositionAfter = this.cloneAndUpdateSpotPosition(inSpotPosition, inAmount.abs().neg(), inMarket);
|
|
1492
1495
|
const outPositionAfter = this.cloneAndUpdateSpotPosition(outSpotPosition, outAmount.abs(), outMarket);
|
|
1493
1496
|
const { totalAssetValue: inTotalAssetValueAfter, totalLiabilityValue: inTotalLiabilityValueAfter, } = this.calculateSpotPositionLeverageContribution(inPositionAfter, inStrictOraclePrice);
|
|
@@ -1801,7 +1804,7 @@ class User {
|
|
|
1801
1804
|
const oraclePriceData = this.driftClient.getOraclePriceDataAndSlot(perpMarket.amm.oracle).data;
|
|
1802
1805
|
const oraclePrice = oraclePriceData.price;
|
|
1803
1806
|
const worstCaseBaseAmount = (0, margin_1.calculateWorstCaseBaseAssetAmount)(perpPosition);
|
|
1804
|
-
const marginRatio = new _1.BN((0, _1.calculateMarketMarginRatio)(perpMarket, worstCaseBaseAmount.abs(), marginCategory));
|
|
1807
|
+
const marginRatio = new _1.BN((0, _1.calculateMarketMarginRatio)(perpMarket, worstCaseBaseAmount.abs(), marginCategory, this.getUserAccount().maxMarginRatio));
|
|
1805
1808
|
const quoteSpotMarket = this.driftClient.getSpotMarketAccount(perpMarket.quoteSpotMarketIndex);
|
|
1806
1809
|
const quoteOraclePriceData = this.driftClient.getOraclePriceDataAndSlot(quoteSpotMarket.oracle).data;
|
|
1807
1810
|
const baseAssetValue = worstCaseBaseAmount
|
|
@@ -1861,7 +1864,7 @@ class User {
|
|
|
1861
1864
|
netQuoteValue = netQuoteValue.add(tokenAmount);
|
|
1862
1865
|
continue;
|
|
1863
1866
|
}
|
|
1864
|
-
const { tokenAmount: worstCaseTokenAmount, tokenValue: tokenValue, weight, weightedTokenValue: weightedTokenValue, ordersValue: ordersValue, } = (0, spotPosition_1.getWorstCaseTokenAmounts)(spotPosition, spotMarketAccount, strictOraclePrice, marginCategory);
|
|
1867
|
+
const { tokenAmount: worstCaseTokenAmount, tokenValue: tokenValue, weight, weightedTokenValue: weightedTokenValue, ordersValue: ordersValue, } = (0, spotPosition_1.getWorstCaseTokenAmounts)(spotPosition, spotMarketAccount, strictOraclePrice, marginCategory, this.getUserAccount().maxMarginRatio);
|
|
1865
1868
|
netQuoteValue = netQuoteValue.add(ordersValue);
|
|
1866
1869
|
const baseAssetValue = tokenValue.abs();
|
|
1867
1870
|
const weightedValue = weightedTokenValue.abs();
|
|
@@ -1888,7 +1891,7 @@ class User {
|
|
|
1888
1891
|
const spotMarketAccount = this.driftClient.getQuoteSpotMarketAccount();
|
|
1889
1892
|
const oraclePriceData = this.getOracleDataForSpotMarket(numericConstants_1.QUOTE_SPOT_MARKET_INDEX);
|
|
1890
1893
|
const baseAssetValue = (0, _1.getTokenValue)(netQuoteValue, spotMarketAccount.decimals, oraclePriceData);
|
|
1891
|
-
const { weight, weightedTokenValue } = (0, spotPosition_1.calculateWeightedTokenValue)(netQuoteValue, baseAssetValue, oraclePriceData.price, spotMarketAccount, marginCategory);
|
|
1894
|
+
const { weight, weightedTokenValue } = (0, spotPosition_1.calculateWeightedTokenValue)(netQuoteValue, baseAssetValue, oraclePriceData.price, spotMarketAccount, marginCategory, this.getUserAccount().maxMarginRatio);
|
|
1892
1895
|
if (netQuoteValue.lt(numericConstants_1.ZERO)) {
|
|
1893
1896
|
healthComponents.borrows.push({
|
|
1894
1897
|
marketIndex: spotMarketAccount.marketIndex,
|
package/package.json
CHANGED
package/src/driftClient.ts
CHANGED
|
@@ -539,6 +539,10 @@ export class DriftClient {
|
|
|
539
539
|
this.activeSubAccountId = activeSubAccountId;
|
|
540
540
|
this.userStatsAccountPublicKey = undefined;
|
|
541
541
|
this.includeDelegates = includeDelegates ?? false;
|
|
542
|
+
const walletSupportsVersionedTxns =
|
|
543
|
+
//@ts-ignore
|
|
544
|
+
this.wallet.supportedTransactionVersions?.size ?? 0 > 1;
|
|
545
|
+
this.txVersion = walletSupportsVersionedTxns ? 0 : 'legacy';
|
|
542
546
|
|
|
543
547
|
if (includeDelegates && subAccountIds) {
|
|
544
548
|
throw new Error(
|
|
@@ -1574,13 +1578,6 @@ export class DriftClient {
|
|
|
1574
1578
|
subAccountId?: number,
|
|
1575
1579
|
reduceOnly = false
|
|
1576
1580
|
): Promise<TransactionSignature> {
|
|
1577
|
-
const tx = new Transaction();
|
|
1578
|
-
tx.add(
|
|
1579
|
-
ComputeBudgetProgram.setComputeUnitLimit({
|
|
1580
|
-
units: 600_000,
|
|
1581
|
-
})
|
|
1582
|
-
);
|
|
1583
|
-
|
|
1584
1581
|
const additionalSigners: Array<Signer> = [];
|
|
1585
1582
|
|
|
1586
1583
|
const spotMarketAccount = this.getSpotMarketAccount(marketIndex);
|
|
@@ -1592,6 +1589,8 @@ export class DriftClient {
|
|
|
1592
1589
|
const createWSOLTokenAccount =
|
|
1593
1590
|
isSolMarket && associatedTokenAccount.equals(signerAuthority);
|
|
1594
1591
|
|
|
1592
|
+
const instructions = [];
|
|
1593
|
+
|
|
1595
1594
|
if (createWSOLTokenAccount) {
|
|
1596
1595
|
const { ixs, pubkey } = await this.getWrappedSolAccountCreationIxs(
|
|
1597
1596
|
amount,
|
|
@@ -1600,9 +1599,7 @@ export class DriftClient {
|
|
|
1600
1599
|
|
|
1601
1600
|
associatedTokenAccount = pubkey;
|
|
1602
1601
|
|
|
1603
|
-
|
|
1604
|
-
tx.add(ix);
|
|
1605
|
-
});
|
|
1602
|
+
instructions.push(...ixs);
|
|
1606
1603
|
}
|
|
1607
1604
|
|
|
1608
1605
|
const depositCollateralIx = await this.getDepositInstruction(
|
|
@@ -1614,11 +1611,11 @@ export class DriftClient {
|
|
|
1614
1611
|
true
|
|
1615
1612
|
);
|
|
1616
1613
|
|
|
1617
|
-
|
|
1614
|
+
instructions.push(depositCollateralIx);
|
|
1618
1615
|
|
|
1619
1616
|
// Close the wrapped sol account at the end of the transaction
|
|
1620
1617
|
if (createWSOLTokenAccount) {
|
|
1621
|
-
|
|
1618
|
+
instructions.push(
|
|
1622
1619
|
createCloseAccountInstruction(
|
|
1623
1620
|
associatedTokenAccount,
|
|
1624
1621
|
signerAuthority,
|
|
@@ -1628,6 +1625,10 @@ export class DriftClient {
|
|
|
1628
1625
|
);
|
|
1629
1626
|
}
|
|
1630
1627
|
|
|
1628
|
+
const txParams = { ...this.txParams, computeUnits: 600_000 };
|
|
1629
|
+
|
|
1630
|
+
const tx = await this.buildTransaction(instructions, txParams);
|
|
1631
|
+
|
|
1631
1632
|
const { txSig, slot } = await this.sendTransaction(
|
|
1632
1633
|
tx,
|
|
1633
1634
|
additionalSigners,
|
|
@@ -2442,8 +2443,7 @@ export class DriftClient {
|
|
|
2442
2443
|
makerInfo?: MakerInfo | MakerInfo[],
|
|
2443
2444
|
txParams?: TxParams,
|
|
2444
2445
|
bracketOrdersParams = new Array<OptionalOrderParams>(),
|
|
2445
|
-
referrerInfo?: ReferrerInfo
|
|
2446
|
-
useVersionedTx = true
|
|
2446
|
+
referrerInfo?: ReferrerInfo
|
|
2447
2447
|
): Promise<{ txSig: TransactionSignature; signedFillTx: Transaction }> {
|
|
2448
2448
|
const marketIndex = orderParams.marketIndex;
|
|
2449
2449
|
const orderId = userAccount.nextOrderId;
|
|
@@ -2469,12 +2469,8 @@ export class DriftClient {
|
|
|
2469
2469
|
referrerInfo
|
|
2470
2470
|
);
|
|
2471
2471
|
|
|
2472
|
-
const walletSupportsVersionedTxns =
|
|
2473
|
-
//@ts-ignore
|
|
2474
|
-
this.wallet.supportedTransactionVersions?.size ?? 0 > 1;
|
|
2475
|
-
|
|
2476
2472
|
// use versioned transactions if there is a lookup table account and wallet is compatible
|
|
2477
|
-
if (
|
|
2473
|
+
if (this.txVersion === 0) {
|
|
2478
2474
|
const versionedMarketOrderTx = await this.buildTransaction(
|
|
2479
2475
|
[placePerpOrderIx].concat(bracketOrderIxs),
|
|
2480
2476
|
txParams,
|
|
@@ -5852,17 +5848,16 @@ export class DriftClient {
|
|
|
5852
5848
|
opts?: ConfirmOptions,
|
|
5853
5849
|
preSigned?: boolean
|
|
5854
5850
|
): Promise<TxSigAndSlot> {
|
|
5855
|
-
|
|
5856
|
-
|
|
5857
|
-
|
|
5858
|
-
tx as Transaction,
|
|
5851
|
+
if (tx instanceof VersionedTransaction) {
|
|
5852
|
+
return this.txSender.sendVersionedTransaction(
|
|
5853
|
+
tx as VersionedTransaction,
|
|
5859
5854
|
additionalSigners,
|
|
5860
5855
|
opts,
|
|
5861
5856
|
preSigned
|
|
5862
5857
|
);
|
|
5863
5858
|
} else {
|
|
5864
|
-
return this.txSender.
|
|
5865
|
-
tx as
|
|
5859
|
+
return this.txSender.send(
|
|
5860
|
+
tx as Transaction,
|
|
5866
5861
|
additionalSigners,
|
|
5867
5862
|
opts,
|
|
5868
5863
|
preSigned
|
package/src/math/market.ts
CHANGED
|
@@ -129,17 +129,22 @@ export function calculateOracleSpread(
|
|
|
129
129
|
export function calculateMarketMarginRatio(
|
|
130
130
|
market: PerpMarketAccount,
|
|
131
131
|
size: BN,
|
|
132
|
-
marginCategory: MarginCategory
|
|
132
|
+
marginCategory: MarginCategory,
|
|
133
|
+
customMarginRatio = 0
|
|
133
134
|
): number {
|
|
134
135
|
let marginRatio;
|
|
135
136
|
switch (marginCategory) {
|
|
136
137
|
case 'Initial': {
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
138
|
+
// use lowest leverage between max allowed and optional user custom max
|
|
139
|
+
marginRatio = Math.max(
|
|
140
|
+
calculateSizePremiumLiabilityWeight(
|
|
141
|
+
size,
|
|
142
|
+
new BN(market.imfFactor),
|
|
143
|
+
new BN(market.marginRatioInitial),
|
|
144
|
+
MARGIN_PRECISION
|
|
145
|
+
).toNumber(),
|
|
146
|
+
customMarginRatio
|
|
147
|
+
);
|
|
143
148
|
break;
|
|
144
149
|
}
|
|
145
150
|
case 'Maintenance': {
|
package/src/math/spotMarket.ts
CHANGED
|
@@ -24,8 +24,11 @@ export function calculateSpotMarketMarginRatio(
|
|
|
24
24
|
oraclePrice: BN,
|
|
25
25
|
marginCategory: MarginCategory,
|
|
26
26
|
size: BN,
|
|
27
|
-
balanceType: SpotBalanceType
|
|
27
|
+
balanceType: SpotBalanceType,
|
|
28
|
+
customMarginRatio = 0
|
|
28
29
|
): number {
|
|
30
|
+
let marginRatio;
|
|
31
|
+
|
|
29
32
|
if (isVariant(balanceType, 'deposit')) {
|
|
30
33
|
const assetWeight = calculateAssetWeight(
|
|
31
34
|
size,
|
|
@@ -33,13 +36,20 @@ export function calculateSpotMarketMarginRatio(
|
|
|
33
36
|
market,
|
|
34
37
|
marginCategory
|
|
35
38
|
);
|
|
36
|
-
|
|
39
|
+
marginRatio = MARGIN_PRECISION.sub(assetWeight).toNumber();
|
|
37
40
|
} else {
|
|
38
41
|
const liabilityWeight = calculateLiabilityWeight(
|
|
39
42
|
size,
|
|
40
43
|
market,
|
|
41
44
|
marginCategory
|
|
42
45
|
);
|
|
43
|
-
|
|
46
|
+
marginRatio = liabilityWeight.sub(MARGIN_PRECISION).toNumber();
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
if (marginCategory === 'Initial') {
|
|
50
|
+
// use lowest leverage between max allowed and optional user custom max
|
|
51
|
+
return Math.max(marginRatio, customMarginRatio);
|
|
44
52
|
}
|
|
53
|
+
|
|
54
|
+
return marginRatio;
|
|
45
55
|
}
|