@drift-labs/sdk 2.131.0-beta.8 → 2.131.0

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/src/user.ts CHANGED
@@ -662,7 +662,7 @@ export class User {
662
662
  public getPerpBuyingPower(
663
663
  marketIndex: number,
664
664
  collateralBuffer = ZERO,
665
- enterHighLeverageMode = false
665
+ enterHighLeverageMode = undefined
666
666
  ): BN {
667
667
  const perpPosition = this.getPerpPositionWithLPSettle(
668
668
  marketIndex,
@@ -697,7 +697,7 @@ export class User {
697
697
  marketIndex: number,
698
698
  freeCollateral: BN,
699
699
  baseAssetAmount: BN,
700
- enterHighLeverageMode = false
700
+ enterHighLeverageMode = undefined
701
701
  ): BN {
702
702
  const marginRatio = calculateMarketMarginRatio(
703
703
  this.driftClient.getPerpMarketAccount(marketIndex),
@@ -716,7 +716,7 @@ export class User {
716
716
  */
717
717
  public getFreeCollateral(
718
718
  marginCategory: MarginCategory = 'Initial',
719
- enterHighLeverageMode = false
719
+ enterHighLeverageMode = undefined
720
720
  ): BN {
721
721
  const totalCollateral = this.getTotalCollateral(marginCategory, true);
722
722
  const marginRequirement =
@@ -735,7 +735,7 @@ export class User {
735
735
  liquidationBuffer?: BN,
736
736
  strict = false,
737
737
  includeOpenOrders = true,
738
- enteringHighLeverage = false
738
+ enteringHighLeverage = undefined
739
739
  ): BN {
740
740
  return this.getTotalPerpPositionLiability(
741
741
  marginCategory,
@@ -757,7 +757,7 @@ export class User {
757
757
  /**
758
758
  * @returns The initial margin requirement in USDC. : QUOTE_PRECISION
759
759
  */
760
- public getInitialMarginRequirement(enterHighLeverageMode = false): BN {
760
+ public getInitialMarginRequirement(enterHighLeverageMode = undefined): BN {
761
761
  return this.getMarginRequirement(
762
762
  'Initial',
763
763
  undefined,
@@ -1432,7 +1432,7 @@ export class User {
1432
1432
  liquidationBuffer?: BN,
1433
1433
  includeOpenOrders?: boolean,
1434
1434
  strict = false,
1435
- enteringHighLeverage = false
1435
+ enteringHighLeverage = undefined
1436
1436
  ): BN {
1437
1437
  const market = this.driftClient.getPerpMarketAccount(
1438
1438
  perpPosition.marketIndex
@@ -1476,13 +1476,17 @@ export class User {
1476
1476
  }
1477
1477
 
1478
1478
  if (marginCategory) {
1479
+ const userCustomMargin = this.getUserAccount().maxMarginRatio;
1479
1480
  let marginRatio = new BN(
1480
1481
  calculateMarketMarginRatio(
1481
1482
  market,
1482
1483
  baseAssetAmount.abs(),
1483
1484
  marginCategory,
1484
- this.getUserAccount().maxMarginRatio,
1485
- this.isHighLeverageMode(marginCategory) || enteringHighLeverage
1485
+ enteringHighLeverage === false
1486
+ ? Math.max(market.marginRatioInitial, userCustomMargin)
1487
+ : userCustomMargin,
1488
+ this.isHighLeverageMode(marginCategory) ||
1489
+ enteringHighLeverage === true
1486
1490
  )
1487
1491
  );
1488
1492
 
@@ -1570,7 +1574,7 @@ export class User {
1570
1574
  liquidationBuffer?: BN,
1571
1575
  includeOpenOrders?: boolean,
1572
1576
  strict = false,
1573
- enteringHighLeverage = false
1577
+ enteringHighLeverage = undefined
1574
1578
  ): BN {
1575
1579
  return this.getActivePerpPositions().reduce(
1576
1580
  (totalPerpValue, perpPosition) => {
@@ -1594,7 +1598,7 @@ export class User {
1594
1598
  */
1595
1599
  public getPerpPositionValue(
1596
1600
  marketIndex: number,
1597
- oraclePriceData: OraclePriceData,
1601
+ oraclePriceData: Pick<OraclePriceData, 'price'>,
1598
1602
  includeOpenOrders = false
1599
1603
  ): BN {
1600
1604
  const userPosition =
@@ -1894,7 +1898,7 @@ export class User {
1894
1898
  perpMarketIndex: number,
1895
1899
  _marginCategory: MarginCategory = 'Initial',
1896
1900
  isLp = false,
1897
- enterHighLeverageMode = false
1901
+ enterHighLeverageMode = undefined
1898
1902
  ): BN {
1899
1903
  const market = this.driftClient.getPerpMarketAccount(perpMarketIndex);
1900
1904
  const marketPrice =
@@ -2245,7 +2249,7 @@ export class User {
2245
2249
  marginCategory: MarginCategory = 'Maintenance',
2246
2250
  includeOpenOrders = false,
2247
2251
  offsetCollateral = ZERO,
2248
- enteringHighLeverage = false
2252
+ enteringHighLeverage = undefined
2249
2253
  ): BN {
2250
2254
  const totalCollateral = this.getTotalCollateral(
2251
2255
  marginCategory,
@@ -2370,7 +2374,7 @@ export class User {
2370
2374
  positionBaseSizeChange: BN,
2371
2375
  estimatedEntryPrice: BN,
2372
2376
  includeOpenOrders: boolean,
2373
- enteringHighLeverage = false,
2377
+ enteringHighLeverage = undefined,
2374
2378
  marginCategory: MarginCategory = 'Maintenance'
2375
2379
  ): BN {
2376
2380
  let freeCollateralChange = ZERO;
@@ -2423,12 +2427,15 @@ export class User {
2423
2427
  );
2424
2428
  }
2425
2429
 
2430
+ const userCustomMargin = this.getUserAccount().maxMarginRatio;
2426
2431
  const marginRatio = calculateMarketMarginRatio(
2427
2432
  market,
2428
2433
  baseAssetAmount.abs(),
2429
2434
  marginCategory,
2430
- this.getUserAccount().maxMarginRatio,
2431
- this.isHighLeverageMode(marginCategory) || enteringHighLeverage
2435
+ enteringHighLeverage === false
2436
+ ? Math.max(market.marginRatioInitial, userCustomMargin)
2437
+ : userCustomMargin,
2438
+ this.isHighLeverageMode(marginCategory) || enteringHighLeverage === true
2432
2439
  );
2433
2440
 
2434
2441
  return liabilityValue.mul(new BN(marginRatio)).div(MARGIN_PRECISION);
@@ -2457,7 +2464,7 @@ export class User {
2457
2464
  oraclePrice: BN,
2458
2465
  marginCategory: MarginCategory = 'Maintenance',
2459
2466
  includeOpenOrders = false,
2460
- enteringHighLeverage = false
2467
+ enteringHighLeverage = undefined
2461
2468
  ): BN | undefined {
2462
2469
  const baseAssetAmount = includeOpenOrders
2463
2470
  ? calculateWorstCaseBaseAssetAmount(perpPosition, market, oraclePrice)
@@ -2470,12 +2477,16 @@ export class User {
2470
2477
 
2471
2478
  const proposedBaseAssetAmount = baseAssetAmount.add(positionBaseSizeChange);
2472
2479
 
2480
+ const userCustomMargin = this.getUserAccount().maxMarginRatio;
2481
+
2473
2482
  const marginRatio = calculateMarketMarginRatio(
2474
2483
  market,
2475
2484
  proposedBaseAssetAmount.abs(),
2476
2485
  marginCategory,
2477
- this.getUserAccount().maxMarginRatio,
2478
- this.isHighLeverageMode(marginCategory) || enteringHighLeverage
2486
+ enteringHighLeverage === false
2487
+ ? Math.max(market.marginRatioInitial, userCustomMargin)
2488
+ : userCustomMargin,
2489
+ this.isHighLeverageMode(marginCategory) || enteringHighLeverage === true
2479
2490
  );
2480
2491
 
2481
2492
  const marginRatioQuotePrecision = new BN(marginRatio)
@@ -2631,7 +2642,7 @@ export class User {
2631
2642
  targetMarketIndex: number,
2632
2643
  tradeSide: PositionDirection,
2633
2644
  isLp = false,
2634
- enterHighLeverageMode = false
2645
+ enterHighLeverageMode = undefined
2635
2646
  ): { tradeSize: BN; oppositeSideTradeSize: BN } {
2636
2647
  let tradeSize = ZERO;
2637
2648
  let oppositeSideTradeSize = ZERO;
@@ -3484,7 +3495,7 @@ export class User {
3484
3495
  public getUserFeeTier(marketType: MarketType, now?: BN) {
3485
3496
  const state = this.driftClient.getStateAccount();
3486
3497
 
3487
- let feeTierIndex = 0;
3498
+ const feeTierIndex = 0;
3488
3499
  if (isVariant(marketType, 'perp')) {
3489
3500
  if (this.isHighLeverageMode('Initial')) {
3490
3501
  return state.perpFeeStructure.feeTiers[0];
@@ -3498,34 +3509,52 @@ export class User {
3498
3509
  userStatsAccount,
3499
3510
  now
3500
3511
  );
3501
-
3502
3512
  const stakedGovAssetAmount = userStatsAccount.ifStakedGovTokenAmount;
3503
- const volumeTiers = [
3504
- new BN(100_000_000).mul(QUOTE_PRECISION),
3505
- new BN(50_000_000).mul(QUOTE_PRECISION),
3513
+
3514
+ const volumeThresholds = [
3515
+ new BN(2_000_000).mul(QUOTE_PRECISION),
3506
3516
  new BN(10_000_000).mul(QUOTE_PRECISION),
3507
- new BN(5_000_000).mul(QUOTE_PRECISION),
3508
- new BN(1_000_000).mul(QUOTE_PRECISION),
3517
+ new BN(20_000_000).mul(QUOTE_PRECISION),
3518
+ new BN(100_000_000).mul(QUOTE_PRECISION),
3519
+ new BN(200_000_000).mul(QUOTE_PRECISION),
3509
3520
  ];
3510
- const stakedTiers = [
3511
- new BN(120000 - 1).mul(QUOTE_PRECISION),
3512
- new BN(100000 - 1).mul(QUOTE_PRECISION),
3513
- new BN(25000 - 1).mul(QUOTE_PRECISION),
3514
- new BN(10000 - 1).mul(QUOTE_PRECISION),
3515
- new BN(1000 - 1).mul(QUOTE_PRECISION),
3521
+ const stakeThresholds = [
3522
+ new BN(1_000 - 1).mul(QUOTE_PRECISION),
3523
+ new BN(10_000 - 1).mul(QUOTE_PRECISION),
3524
+ new BN(50_000 - 1).mul(QUOTE_PRECISION),
3525
+ new BN(100_000 - 1).mul(QUOTE_PRECISION),
3526
+ new BN(250_000 - 5).mul(QUOTE_PRECISION),
3516
3527
  ];
3528
+ const stakeBenefitFrac = [0, 5, 10, 20, 30, 40];
3517
3529
 
3518
- for (let i = 0; i < volumeTiers.length; i++) {
3519
- if (
3520
- total30dVolume.gte(volumeTiers[i]) ||
3521
- stakedGovAssetAmount.gte(stakedTiers[i])
3522
- ) {
3523
- feeTierIndex = 5 - i;
3530
+ let feeTierIndex = 5;
3531
+ for (let i = 0; i < volumeThresholds.length; i++) {
3532
+ if (total30dVolume.lt(volumeThresholds[i])) {
3533
+ feeTierIndex = i;
3524
3534
  break;
3525
3535
  }
3526
3536
  }
3527
3537
 
3528
- return state.perpFeeStructure.feeTiers[feeTierIndex];
3538
+ let stakeBenefitIndex = 5;
3539
+ for (let i = 0; i < stakeThresholds.length; i++) {
3540
+ if (stakedGovAssetAmount.lt(stakeThresholds[i])) {
3541
+ stakeBenefitIndex = i;
3542
+ break;
3543
+ }
3544
+ }
3545
+
3546
+ const stakeBenefit = stakeBenefitFrac[stakeBenefitIndex];
3547
+
3548
+ const tier = { ...state.perpFeeStructure.feeTiers[feeTierIndex] };
3549
+
3550
+ if (stakeBenefit > 0) {
3551
+ tier.feeNumerator = (tier.feeNumerator * (100 - stakeBenefit)) / 100;
3552
+
3553
+ tier.makerRebateNumerator =
3554
+ (tier.makerRebateNumerator * (100 + stakeBenefit)) / 100;
3555
+ }
3556
+
3557
+ return tier;
3529
3558
  }
3530
3559
 
3531
3560
  return state.spotFeeStructure.feeTiers[feeTierIndex];