@drift-labs/sdk 2.97.0-beta.2 → 2.97.0-beta.20

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.
@@ -187,20 +187,20 @@ export function calculateWorstCasePerpLiabilityValue(
187
187
 
188
188
  export function calculatePerpLiabilityValue(
189
189
  baseAssetAmount: BN,
190
- oraclePrice: BN,
190
+ price: BN,
191
191
  isPredictionMarket: boolean
192
192
  ): BN {
193
193
  if (isPredictionMarket) {
194
194
  if (baseAssetAmount.gt(ZERO)) {
195
- return baseAssetAmount.mul(oraclePrice).div(BASE_PRECISION);
195
+ return baseAssetAmount.mul(price).div(BASE_PRECISION);
196
196
  } else {
197
197
  return baseAssetAmount
198
198
  .abs()
199
- .mul(MAX_PREDICTION_PRICE.sub(oraclePrice))
199
+ .mul(MAX_PREDICTION_PRICE.sub(price))
200
200
  .div(BASE_PRECISION);
201
201
  }
202
202
  } else {
203
- return baseAssetAmount.abs().mul(oraclePrice).div(BASE_PRECISION);
203
+ return baseAssetAmount.abs().mul(price).div(BASE_PRECISION);
204
204
  }
205
205
  }
206
206
 
@@ -214,16 +214,19 @@ export function calculateMarginUSDCRequiredForTrade(
214
214
  driftClient: DriftClient,
215
215
  targetMarketIndex: number,
216
216
  baseSize: BN,
217
- userMaxMarginRatio?: number
217
+ userMaxMarginRatio?: number,
218
+ userHighLeverageMode?: boolean,
219
+ entryPrice?: BN
218
220
  ): BN {
219
221
  const targetMarket = driftClient.getPerpMarketAccount(targetMarketIndex);
220
- const oracleData = driftClient.getOracleDataForPerpMarket(
221
- targetMarket.marketIndex
222
- );
222
+
223
+ const price =
224
+ entryPrice ??
225
+ driftClient.getOracleDataForPerpMarket(targetMarket.marketIndex).price;
223
226
 
224
227
  const perpLiabilityValue = calculatePerpLiabilityValue(
225
228
  baseSize,
226
- oracleData.price,
229
+ price,
227
230
  isVariant(targetMarket.contractType, 'prediction')
228
231
  );
229
232
 
@@ -232,7 +235,8 @@ export function calculateMarginUSDCRequiredForTrade(
232
235
  targetMarket,
233
236
  baseSize.abs(),
234
237
  'Initial',
235
- userMaxMarginRatio
238
+ userMaxMarginRatio,
239
+ userHighLeverageMode
236
240
  )
237
241
  )
238
242
  .mul(perpLiabilityValue)
@@ -251,13 +255,17 @@ export function calculateCollateralDepositRequiredForTrade(
251
255
  targetMarketIndex: number,
252
256
  baseSize: BN,
253
257
  collateralIndex: number,
254
- userMaxMarginRatio?: number
258
+ userMaxMarginRatio?: number,
259
+ userHighLeverageMode?: boolean,
260
+ estEntryPrice?: BN
255
261
  ): BN {
256
262
  const marginRequiredUsdc = calculateMarginUSDCRequiredForTrade(
257
263
  driftClient,
258
264
  targetMarketIndex,
259
265
  baseSize,
260
- userMaxMarginRatio
266
+ userMaxMarginRatio,
267
+ userHighLeverageMode,
268
+ estEntryPrice
261
269
  );
262
270
 
263
271
  const collateralMarket = driftClient.getSpotMarketAccount(collateralIndex);
@@ -130,8 +130,24 @@ export function calculateMarketMarginRatio(
130
130
  market: PerpMarketAccount,
131
131
  size: BN,
132
132
  marginCategory: MarginCategory,
133
- customMarginRatio = 0
133
+ customMarginRatio = 0,
134
+ userHighLeverageMode = false
134
135
  ): number {
136
+ let marginRationInitial;
137
+ let marginRatioMaintenance;
138
+
139
+ if (
140
+ userHighLeverageMode &&
141
+ market.highLeverageMarginRatioInitial > 0 &&
142
+ market.highLeverageMarginRatioMaintenance
143
+ ) {
144
+ marginRationInitial = market.highLeverageMarginRatioInitial;
145
+ marginRatioMaintenance = market.highLeverageMarginRatioMaintenance;
146
+ } else {
147
+ marginRationInitial = market.marginRatioInitial;
148
+ marginRatioMaintenance = market.marginRatioMaintenance;
149
+ }
150
+
135
151
  let marginRatio;
136
152
  switch (marginCategory) {
137
153
  case 'Initial': {
@@ -140,7 +156,7 @@ export function calculateMarketMarginRatio(
140
156
  calculateSizePremiumLiabilityWeight(
141
157
  size,
142
158
  new BN(market.imfFactor),
143
- new BN(market.marginRatioInitial),
159
+ new BN(marginRationInitial),
144
160
  MARGIN_PRECISION
145
161
  ).toNumber(),
146
162
  customMarginRatio
@@ -151,7 +167,7 @@ export function calculateMarketMarginRatio(
151
167
  marginRatio = calculateSizePremiumLiabilityWeight(
152
168
  size,
153
169
  new BN(market.imfFactor),
154
- new BN(market.marginRatioMaintenance),
170
+ new BN(marginRatioMaintenance),
155
171
  MARGIN_PRECISION
156
172
  ).toNumber();
157
173
  break;
package/src/types.ts CHANGED
@@ -68,6 +68,11 @@ export enum UserStatus {
68
68
  ADVANCED_LP = 8,
69
69
  }
70
70
 
71
+ export class MarginMode {
72
+ static readonly DEFAULT = { default: {} };
73
+ static readonly HIGH_LEVERAGE = { highLeverage: {} };
74
+ }
75
+
71
76
  export class ContractType {
72
77
  static readonly PERPETUAL = { perpetual: {} };
73
78
  static readonly FUTURE = { future: {} };
@@ -661,6 +666,9 @@ export type PerpMarketAccount = {
661
666
  fuelBoostTaker: number;
662
667
  fuelBoostMaker: number;
663
668
  fuelBoostPosition: number;
669
+
670
+ highLeverageMarginRatioInitial: number;
671
+ highLeverageMarginRatioMaintenance: number;
664
672
  };
665
673
 
666
674
  export type HistoricalOracleData = {
@@ -950,6 +958,7 @@ export type UserAccount = {
950
958
  openAuctions: number;
951
959
  hasOpenAuction: boolean;
952
960
  lastFuelBonusUpdateTs: number;
961
+ marginMode: MarginMode;
953
962
  };
954
963
 
955
964
  export type SpotPosition = {
@@ -1301,3 +1310,9 @@ export type SignedTxData = {
1301
1310
  lastValidBlockHeight?: number;
1302
1311
  blockHash: string;
1303
1312
  };
1313
+
1314
+ export type HighLeverageModeConfig = {
1315
+ maxUsers: number;
1316
+ currentUsers: number;
1317
+ reduceOnly: boolean;
1318
+ };
package/src/user.ts CHANGED
@@ -676,7 +676,8 @@ export class User {
676
676
  this.driftClient.getPerpMarketAccount(marketIndex),
677
677
  baseAssetAmount,
678
678
  'Initial',
679
- this.getUserAccount().maxMarginRatio
679
+ this.getUserAccount().maxMarginRatio,
680
+ this.isHighLeverageMode()
680
681
  );
681
682
 
682
683
  return freeCollateral.mul(MARGIN_PRECISION).div(new BN(marginRatio));
@@ -1507,7 +1508,8 @@ export class User {
1507
1508
  market,
1508
1509
  baseAssetAmount.abs(),
1509
1510
  marginCategory,
1510
- this.getUserAccount().maxMarginRatio
1511
+ this.getUserAccount().maxMarginRatio,
1512
+ this.isHighLeverageMode()
1511
1513
  )
1512
1514
  );
1513
1515
 
@@ -1972,7 +1974,8 @@ export class User {
1972
1974
  market,
1973
1975
  maxSize,
1974
1976
  marginCategory,
1975
- this.getUserAccount().maxMarginRatio
1977
+ this.getUserAccount().maxMarginRatio,
1978
+ this.isHighLeverageMode()
1976
1979
  );
1977
1980
 
1978
1981
  // use more fesible size since imf factor activated
@@ -1993,7 +1996,8 @@ export class User {
1993
1996
  market,
1994
1997
  targetSize,
1995
1998
  marginCategory,
1996
- this.getUserAccount().maxMarginRatio
1999
+ this.getUserAccount().maxMarginRatio,
2000
+ this.isHighLeverageMode()
1997
2001
  );
1998
2002
  attempts += 1;
1999
2003
  }
@@ -2154,6 +2158,10 @@ export class User {
2154
2158
  return (this.getUserAccount().status & UserStatus.BANKRUPT) > 0;
2155
2159
  }
2156
2160
 
2161
+ public isHighLeverageMode(): boolean {
2162
+ return isVariant(this.getUserAccount().marginMode, 'highLeverage');
2163
+ }
2164
+
2157
2165
  /**
2158
2166
  * Checks if any user position cumulative funding differs from respective market cumulative funding
2159
2167
  * @returns
@@ -2443,7 +2451,9 @@ export class User {
2443
2451
  const marginRatio = calculateMarketMarginRatio(
2444
2452
  market,
2445
2453
  baseAssetAmount.abs(),
2446
- 'Maintenance'
2454
+ 'Maintenance',
2455
+ this.getUserAccount().maxMarginRatio,
2456
+ this.isHighLeverageMode()
2447
2457
  );
2448
2458
 
2449
2459
  return liabilityValue.mul(new BN(marginRatio)).div(MARGIN_PRECISION);
@@ -2488,7 +2498,8 @@ export class User {
2488
2498
  market,
2489
2499
  proposedBaseAssetAmount.abs(),
2490
2500
  marginCategory,
2491
- this.getUserAccount().maxMarginRatio
2501
+ this.getUserAccount().maxMarginRatio,
2502
+ this.isHighLeverageMode()
2492
2503
  );
2493
2504
  const marginRatioQuotePrecision = new BN(marginRatio)
2494
2505
  .mul(QUOTE_PRECISION)
@@ -2602,13 +2613,16 @@ export class User {
2602
2613
 
2603
2614
  public getMarginUSDCRequiredForTrade(
2604
2615
  targetMarketIndex: number,
2605
- baseSize: BN
2616
+ baseSize: BN,
2617
+ estEntryPrice?: BN
2606
2618
  ): BN {
2607
2619
  return calculateMarginUSDCRequiredForTrade(
2608
2620
  this.driftClient,
2609
2621
  targetMarketIndex,
2610
2622
  baseSize,
2611
- this.getUserAccount().maxMarginRatio
2623
+ this.getUserAccount().maxMarginRatio,
2624
+ undefined,
2625
+ estEntryPrice
2612
2626
  );
2613
2627
  }
2614
2628
 
@@ -2622,7 +2636,8 @@ export class User {
2622
2636
  targetMarketIndex,
2623
2637
  baseSize,
2624
2638
  collateralIndex,
2625
- this.getUserAccount().maxMarginRatio
2639
+ this.getUserAccount().maxMarginRatio,
2640
+ false // assume user cant be high leverage if they havent created user account ?
2626
2641
  );
2627
2642
  }
2628
2643
 
@@ -3771,7 +3786,8 @@ export class User {
3771
3786
  perpMarket,
3772
3787
  worstCaseBaseAmount.abs(),
3773
3788
  marginCategory,
3774
- this.getUserAccount().maxMarginRatio
3789
+ this.getUserAccount().maxMarginRatio,
3790
+ this.isHighLeverageMode()
3775
3791
  )
3776
3792
  );
3777
3793