@drift-labs/sdk 2.97.0-beta.5 → 2.97.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 CHANGED
@@ -1 +1 @@
1
- 2.97.0-beta.5
1
+ 2.97.0-beta.7
@@ -26,3 +26,4 @@ export declare function getProtocolIfSharesTransferConfigPublicKey(programId: Pu
26
26
  export declare function getPrelaunchOraclePublicKey(programId: PublicKey, marketIndex: number): PublicKey;
27
27
  export declare function getPythPullOraclePublicKey(progarmId: PublicKey, feedId: Uint8Array): PublicKey;
28
28
  export declare function getTokenProgramForSpotMarket(spotMarketAccount: SpotMarketAccount): PublicKey;
29
+ export declare function getHighLeverageModeConfigPublicKey(programId: PublicKey): PublicKey;
@@ -23,7 +23,7 @@ var __importStar = (this && this.__importStar) || function (mod) {
23
23
  return result;
24
24
  };
25
25
  Object.defineProperty(exports, "__esModule", { value: true });
26
- exports.getTokenProgramForSpotMarket = exports.getPythPullOraclePublicKey = exports.getPrelaunchOraclePublicKey = exports.getProtocolIfSharesTransferConfigPublicKey = exports.getReferrerNamePublicKeySync = exports.getOpenbookV2FulfillmentConfigPublicKey = exports.getPhoenixFulfillmentConfigPublicKey = exports.getSerumFulfillmentConfigPublicKey = exports.getSerumSignerPublicKey = exports.getSerumOpenOrdersPublicKey = exports.getDriftSignerPublicKey = exports.getInsuranceFundStakeAccountPublicKey = exports.getInsuranceFundVaultPublicKey = exports.getSpotMarketVaultPublicKey = exports.getSpotMarketPublicKeySync = exports.getSpotMarketPublicKey = exports.getPerpMarketPublicKeySync = exports.getPerpMarketPublicKey = exports.getUserStatsAccountPublicKey = exports.getUserAccountPublicKeySync = exports.getUserAccountPublicKey = exports.getUserAccountPublicKeyAndNonce = exports.getDriftStateAccountPublicKey = exports.getDriftStateAccountPublicKeyAndNonce = void 0;
26
+ exports.getHighLeverageModeConfigPublicKey = exports.getTokenProgramForSpotMarket = exports.getPythPullOraclePublicKey = exports.getPrelaunchOraclePublicKey = exports.getProtocolIfSharesTransferConfigPublicKey = exports.getReferrerNamePublicKeySync = exports.getOpenbookV2FulfillmentConfigPublicKey = exports.getPhoenixFulfillmentConfigPublicKey = exports.getSerumFulfillmentConfigPublicKey = exports.getSerumSignerPublicKey = exports.getSerumOpenOrdersPublicKey = exports.getDriftSignerPublicKey = exports.getInsuranceFundStakeAccountPublicKey = exports.getInsuranceFundVaultPublicKey = exports.getSpotMarketVaultPublicKey = exports.getSpotMarketPublicKeySync = exports.getSpotMarketPublicKey = exports.getPerpMarketPublicKeySync = exports.getPerpMarketPublicKey = exports.getUserStatsAccountPublicKey = exports.getUserAccountPublicKeySync = exports.getUserAccountPublicKey = exports.getUserAccountPublicKeyAndNonce = exports.getDriftStateAccountPublicKey = exports.getDriftStateAccountPublicKeyAndNonce = void 0;
27
27
  const web3_js_1 = require("@solana/web3.js");
28
28
  const anchor = __importStar(require("@coral-xyz/anchor"));
29
29
  const spl_token_1 = require("@solana/spl-token");
@@ -180,3 +180,7 @@ function getTokenProgramForSpotMarket(spotMarketAccount) {
180
180
  return spl_token_1.TOKEN_PROGRAM_ID;
181
181
  }
182
182
  exports.getTokenProgramForSpotMarket = getTokenProgramForSpotMarket;
183
+ function getHighLeverageModeConfigPublicKey(programId) {
184
+ return web3_js_1.PublicKey.findProgramAddressSync([Buffer.from(anchor.utils.bytes.utf8.encode('high_leverage_mode_config'))], programId)[0];
185
+ }
186
+ exports.getHighLeverageModeConfigPublicKey = getHighLeverageModeConfigPublicKey;
@@ -55,6 +55,8 @@ export declare class AdminClient extends DriftClient {
55
55
  getUpdatePerpMarketTargetBaseAssetAmountPerLpIx(perpMarketIndex: number, targetBaseAssetAmountPerLP: number): Promise<TransactionInstruction>;
56
56
  updatePerpMarketMarginRatio(perpMarketIndex: number, marginRatioInitial: number, marginRatioMaintenance: number): Promise<TransactionSignature>;
57
57
  getUpdatePerpMarketMarginRatioIx(perpMarketIndex: number, marginRatioInitial: number, marginRatioMaintenance: number): Promise<TransactionInstruction>;
58
+ updatePerpMarketHighLeverageMarginRatio(perpMarketIndex: number, marginRatioInitial: number, marginRatioMaintenance: number): Promise<TransactionSignature>;
59
+ getUpdatePerpMarketHighLeverageMarginRatioIx(perpMarketIndex: number, marginRatioInitial: number, marginRatioMaintenance: number): Promise<TransactionInstruction>;
58
60
  updatePerpMarketImfFactor(perpMarketIndex: number, imfFactor: number, unrealizedPnlImfFactor: number): Promise<TransactionSignature>;
59
61
  getUpdatePerpMarketImfFactorIx(perpMarketIndex: number, imfFactor: number, unrealizedPnlImfFactor: number): Promise<TransactionInstruction>;
60
62
  updatePerpMarketBaseSpread(perpMarketIndex: number, baseSpread: number): Promise<TransactionSignature>;
@@ -193,4 +195,8 @@ export declare class AdminClient extends DriftClient {
193
195
  getInitUserFuelIx(user: PublicKey, authority: PublicKey, fuelBonusDeposits?: number, fuelBonusBorrows?: number, fuelBonusTaker?: number, fuelBonusMaker?: number, fuelBonusInsurance?: number): Promise<TransactionInstruction>;
194
196
  initializePythPullOracle(feedId: string): Promise<TransactionSignature>;
195
197
  getInitializePythPullOracleIx(feedId: string): Promise<TransactionInstruction>;
198
+ initializeHighLeverageModeConfig(maxUsers: number): Promise<TransactionSignature>;
199
+ getInitializeHighLeverageModeConfigIx(maxUsers: number): Promise<TransactionInstruction>;
200
+ updateUpdateHighLeverageModeConfig(maxUsers: number, reduceOnly: boolean): Promise<TransactionSignature>;
201
+ getUpdateHighLeverageModeConfigIx(maxUsers: number, reduceOnly: boolean): Promise<TransactionInstruction>;
196
202
  }
@@ -561,6 +561,23 @@ class AdminClient extends driftClient_1.DriftClient {
561
561
  },
562
562
  });
563
563
  }
564
+ async updatePerpMarketHighLeverageMarginRatio(perpMarketIndex, marginRatioInitial, marginRatioMaintenance) {
565
+ const updatePerpMarketHighLeverageMarginRatioIx = await this.getUpdatePerpMarketHighLeverageMarginRatioIx(perpMarketIndex, marginRatioInitial, marginRatioMaintenance);
566
+ const tx = await this.buildTransaction(updatePerpMarketHighLeverageMarginRatioIx);
567
+ const { txSig } = await this.sendTransaction(tx, [], this.opts);
568
+ return txSig;
569
+ }
570
+ async getUpdatePerpMarketHighLeverageMarginRatioIx(perpMarketIndex, marginRatioInitial, marginRatioMaintenance) {
571
+ return await this.program.instruction.updatePerpMarketHighLeverageMarginRatio(marginRatioInitial, marginRatioMaintenance, {
572
+ accounts: {
573
+ admin: this.isSubscribed
574
+ ? this.getStateAccount().admin
575
+ : this.wallet.publicKey,
576
+ state: await this.getStatePublicKey(),
577
+ perpMarket: await (0, pda_1.getPerpMarketPublicKey)(this.program.programId, perpMarketIndex),
578
+ },
579
+ });
580
+ }
564
581
  async updatePerpMarketImfFactor(perpMarketIndex, imfFactor, unrealizedPnlImfFactor) {
565
582
  const updatePerpMarketImfFactorIx = await this.getUpdatePerpMarketImfFactorIx(perpMarketIndex, imfFactor, unrealizedPnlImfFactor);
566
583
  const tx = await this.buildTransaction(updatePerpMarketImfFactorIx);
@@ -1769,5 +1786,41 @@ class AdminClient extends driftClient_1.DriftClient {
1769
1786
  },
1770
1787
  });
1771
1788
  }
1789
+ async initializeHighLeverageModeConfig(maxUsers) {
1790
+ const initializeHighLeverageModeConfigIx = await this.getInitializeHighLeverageModeConfigIx(maxUsers);
1791
+ const tx = await this.buildTransaction(initializeHighLeverageModeConfigIx);
1792
+ const { txSig } = await this.sendTransaction(tx, [], this.opts);
1793
+ return txSig;
1794
+ }
1795
+ async getInitializeHighLeverageModeConfigIx(maxUsers) {
1796
+ return await this.program.instruction.initializeHighLeverageModeConfig(maxUsers, {
1797
+ accounts: {
1798
+ admin: this.isSubscribed
1799
+ ? this.getStateAccount().admin
1800
+ : this.wallet.publicKey,
1801
+ state: await this.getStatePublicKey(),
1802
+ rent: web3_js_1.SYSVAR_RENT_PUBKEY,
1803
+ systemProgram: anchor.web3.SystemProgram.programId,
1804
+ highLeverageModeConfig: (0, pda_1.getHighLeverageModeConfigPublicKey)(this.program.programId),
1805
+ },
1806
+ });
1807
+ }
1808
+ async updateUpdateHighLeverageModeConfig(maxUsers, reduceOnly) {
1809
+ const updateHighLeverageModeConfigIx = await this.getUpdateHighLeverageModeConfigIx(maxUsers, reduceOnly);
1810
+ const tx = await this.buildTransaction(updateHighLeverageModeConfigIx);
1811
+ const { txSig } = await this.sendTransaction(tx, [], this.opts);
1812
+ return txSig;
1813
+ }
1814
+ async getUpdateHighLeverageModeConfigIx(maxUsers, reduceOnly) {
1815
+ return await this.program.instruction.updateHighLeverageModeConfig(maxUsers, reduceOnly, {
1816
+ accounts: {
1817
+ admin: this.isSubscribed
1818
+ ? this.getStateAccount().admin
1819
+ : this.wallet.publicKey,
1820
+ state: await this.getStatePublicKey(),
1821
+ highLeverageModeConfig: (0, pda_1.getHighLeverageModeConfigPublicKey)(this.program.programId),
1822
+ },
1823
+ });
1824
+ }
1772
1825
  }
1773
1826
  exports.AdminClient = AdminClient;
package/lib/config.d.ts CHANGED
@@ -43,7 +43,7 @@ export declare const initialize: (props: {
43
43
  env: DriftEnv;
44
44
  overrideEnv?: Partial<DriftConfig>;
45
45
  }) => DriftConfig;
46
- export declare function getMarketsAndOraclesForSubscription(env: DriftEnv): {
46
+ export declare function getMarketsAndOraclesForSubscription(env: DriftEnv, perpMarkets?: PerpMarketConfig[], spotMarkets?: SpotMarketConfig[]): {
47
47
  perpMarketIndexes: number[];
48
48
  spotMarketIndexes: number[];
49
49
  oracleInfos: OracleInfo[];
package/lib/config.js CHANGED
@@ -66,18 +66,20 @@ const initialize = (props) => {
66
66
  return currentConfig;
67
67
  };
68
68
  exports.initialize = initialize;
69
- function getMarketsAndOraclesForSubscription(env) {
69
+ function getMarketsAndOraclesForSubscription(env, perpMarkets, spotMarkets) {
70
+ const perpMarketsToUse = (perpMarkets === null || perpMarkets === void 0 ? void 0 : perpMarkets.length) > 0 ? perpMarkets : perpMarkets_1.PerpMarkets[env];
71
+ const spotMarketsToUse = (spotMarkets === null || spotMarkets === void 0 ? void 0 : spotMarkets.length) > 0 ? spotMarkets : spotMarkets_1.SpotMarkets[env];
70
72
  const perpMarketIndexes = [];
71
73
  const spotMarketIndexes = [];
72
74
  const oracleInfos = new Map();
73
- for (const market of perpMarkets_1.PerpMarkets[env]) {
75
+ for (const market of perpMarketsToUse) {
74
76
  perpMarketIndexes.push(market.marketIndex);
75
77
  oracleInfos.set(market.oracle.toString(), {
76
78
  publicKey: market.oracle,
77
79
  source: market.oracleSource,
78
80
  });
79
81
  }
80
- for (const spotMarket of spotMarkets_1.SpotMarkets[env]) {
82
+ for (const spotMarket of spotMarketsToUse) {
81
83
  spotMarketIndexes.push(spotMarket.marketIndex);
82
84
  oracleInfos.set(spotMarket.oracle.toString(), {
83
85
  publicKey: spotMarket.oracle,
@@ -789,6 +789,10 @@ export declare class DriftClient {
789
789
  getPostSwitchboardOnDemandUpdateAtomicIx(feed: PublicKey, numSignatures?: number): Promise<TransactionInstruction | undefined>;
790
790
  postSwitchboardOnDemandUpdate(feed: PublicKey, numSignatures?: number): Promise<TransactionSignature>;
791
791
  private getBuildEncodedVaaIxs;
792
+ enableUserHighLeverageMode(subAccountId: number, txParams?: TxParams): Promise<TransactionSignature>;
793
+ getEnableHighLeverageModeIx(subAccountId: number): Promise<anchor.web3.TransactionInstruction>;
794
+ disableUserHighLeverageMode(user: PublicKey, txParams?: TxParams): Promise<TransactionSignature>;
795
+ getDisableHighLeverageModeIx(user: PublicKey): Promise<anchor.web3.TransactionInstruction>;
792
796
  private handleSignedTransaction;
793
797
  private handlePreSignedTransaction;
794
798
  private isVersionedTransaction;
@@ -4254,6 +4254,36 @@ class DriftClient {
4254
4254
  .instruction());
4255
4255
  return [postIxs, encodedVaaKeypair];
4256
4256
  }
4257
+ async enableUserHighLeverageMode(subAccountId, txParams) {
4258
+ const { txSig } = await this.sendTransaction(await this.buildTransaction(await this.getEnableHighLeverageModeIx(subAccountId), txParams), [], this.opts);
4259
+ return txSig;
4260
+ }
4261
+ async getEnableHighLeverageModeIx(subAccountId) {
4262
+ const ix = await this.program.instruction.enableHighLeverageMode(subAccountId, {
4263
+ accounts: {
4264
+ state: await this.getStatePublicKey(),
4265
+ user: (0, pda_1.getUserAccountPublicKeySync)(this.program.programId, this.wallet.publicKey, subAccountId),
4266
+ authority: this.wallet.publicKey,
4267
+ highLeverageModeConfig: (0, pda_1.getHighLeverageModeConfigPublicKey)(this.program.programId),
4268
+ },
4269
+ });
4270
+ return ix;
4271
+ }
4272
+ async disableUserHighLeverageMode(user, txParams) {
4273
+ const { txSig } = await this.sendTransaction(await this.buildTransaction(await this.getDisableHighLeverageModeIx(user), txParams), [], this.opts);
4274
+ return txSig;
4275
+ }
4276
+ async getDisableHighLeverageModeIx(user) {
4277
+ const ix = await this.program.instruction.disableHighLeverageMode({
4278
+ accounts: {
4279
+ state: await this.getStatePublicKey(),
4280
+ user,
4281
+ authority: this.wallet.publicKey,
4282
+ highLeverageModeConfig: (0, pda_1.getHighLeverageModeConfigPublicKey)(this.program.programId),
4283
+ },
4284
+ });
4285
+ return ix;
4286
+ }
4257
4287
  handleSignedTransaction(signedTxs) {
4258
4288
  if (this.enableMetricsEvents && this.metricsEventEmitter) {
4259
4289
  this.metricsEventEmitter.emit('txSigned', signedTxs);
@@ -28,12 +28,12 @@ export declare function calculatePerpLiabilityValue(baseAssetAmount: BN, oracleP
28
28
  * @param baseSize
29
29
  * @returns
30
30
  */
31
- export declare function calculateMarginUSDCRequiredForTrade(driftClient: DriftClient, targetMarketIndex: number, baseSize: BN, userMaxMarginRatio?: number): BN;
31
+ export declare function calculateMarginUSDCRequiredForTrade(driftClient: DriftClient, targetMarketIndex: number, baseSize: BN, userMaxMarginRatio?: number, userHighLeverageMode?: boolean): BN;
32
32
  /**
33
33
  * Similar to calculatetMarginUSDCRequiredForTrade, but calculates how much of a given collateral is required to cover the margin requirements for a given trade. Basically does the same thing as getMarginUSDCRequiredForTrade but also accounts for asset weight of the selected collateral.
34
34
  *
35
35
  * Returns collateral required in the precision of the target collateral market.
36
36
  */
37
- export declare function calculateCollateralDepositRequiredForTrade(driftClient: DriftClient, targetMarketIndex: number, baseSize: BN, collateralIndex: number, userMaxMarginRatio?: number): BN;
37
+ export declare function calculateCollateralDepositRequiredForTrade(driftClient: DriftClient, targetMarketIndex: number, baseSize: BN, collateralIndex: number, userMaxMarginRatio?: number, userHighLeverageMode?: boolean): BN;
38
38
  export declare function calculateCollateralValueOfDeposit(driftClient: DriftClient, collateralIndex: number, baseSize: BN): BN;
39
39
  export declare function calculateLiquidationPrice(freeCollateral: BN, freeCollateralDelta: BN, oraclePrice: BN): BN;
@@ -123,11 +123,11 @@ exports.calculatePerpLiabilityValue = calculatePerpLiabilityValue;
123
123
  * @param baseSize
124
124
  * @returns
125
125
  */
126
- function calculateMarginUSDCRequiredForTrade(driftClient, targetMarketIndex, baseSize, userMaxMarginRatio) {
126
+ function calculateMarginUSDCRequiredForTrade(driftClient, targetMarketIndex, baseSize, userMaxMarginRatio, userHighLeverageMode) {
127
127
  const targetMarket = driftClient.getPerpMarketAccount(targetMarketIndex);
128
128
  const oracleData = driftClient.getOracleDataForPerpMarket(targetMarket.marketIndex);
129
129
  const perpLiabilityValue = calculatePerpLiabilityValue(baseSize, oracleData.price, (0, types_1.isVariant)(targetMarket.contractType, 'prediction'));
130
- const marginRequired = new anchor_1.BN((0, __1.calculateMarketMarginRatio)(targetMarket, baseSize.abs(), 'Initial', userMaxMarginRatio))
130
+ const marginRequired = new anchor_1.BN((0, __1.calculateMarketMarginRatio)(targetMarket, baseSize.abs(), 'Initial', userMaxMarginRatio, userHighLeverageMode))
131
131
  .mul(perpLiabilityValue)
132
132
  .div(numericConstants_1.MARGIN_PRECISION);
133
133
  return marginRequired;
@@ -138,8 +138,8 @@ exports.calculateMarginUSDCRequiredForTrade = calculateMarginUSDCRequiredForTrad
138
138
  *
139
139
  * Returns collateral required in the precision of the target collateral market.
140
140
  */
141
- function calculateCollateralDepositRequiredForTrade(driftClient, targetMarketIndex, baseSize, collateralIndex, userMaxMarginRatio) {
142
- const marginRequiredUsdc = calculateMarginUSDCRequiredForTrade(driftClient, targetMarketIndex, baseSize, userMaxMarginRatio);
141
+ function calculateCollateralDepositRequiredForTrade(driftClient, targetMarketIndex, baseSize, collateralIndex, userMaxMarginRatio, userHighLeverageMode) {
142
+ const marginRequiredUsdc = calculateMarginUSDCRequiredForTrade(driftClient, targetMarketIndex, baseSize, userMaxMarginRatio, userHighLeverageMode);
143
143
  const collateralMarket = driftClient.getSpotMarketAccount(collateralIndex);
144
144
  const collateralOracleData = driftClient.getOracleDataForSpotMarket(collateralIndex);
145
145
  const scaledAssetWeight = (0, __1.calculateScaledInitialAssetWeight)(collateralMarket, collateralOracleData.price);
@@ -27,7 +27,7 @@ export declare function calculateAskPrice(market: PerpMarketAccount, oraclePrice
27
27
  export declare function calculateNewMarketAfterTrade(baseAssetAmount: BN, direction: PositionDirection, market: PerpMarketAccount): PerpMarketAccount;
28
28
  export declare function calculateOracleReserveSpread(market: PerpMarketAccount, oraclePriceData: OraclePriceData): BN;
29
29
  export declare function calculateOracleSpread(price: BN, oraclePriceData: OraclePriceData): BN;
30
- export declare function calculateMarketMarginRatio(market: PerpMarketAccount, size: BN, marginCategory: MarginCategory, customMarginRatio?: number): number;
30
+ export declare function calculateMarketMarginRatio(market: PerpMarketAccount, size: BN, marginCategory: MarginCategory, customMarginRatio?: number, userHighLeverageMode?: boolean): number;
31
31
  export declare function calculateUnrealizedAssetWeight(market: PerpMarketAccount, quoteSpotMarket: SpotMarketAccount, unrealizedPnl: BN, marginCategory: MarginCategory, oraclePriceData: OraclePriceData): BN;
32
32
  export declare function calculateMarketAvailablePNL(perpMarket: PerpMarketAccount, spotMarket: SpotMarketAccount): BN;
33
33
  export declare function calculateMarketMaxAvailableInsurance(perpMarket: PerpMarketAccount, spotMarket: SpotMarketAccount): BN;
@@ -60,16 +60,28 @@ function calculateOracleSpread(price, oraclePriceData) {
60
60
  return price.sub(oraclePriceData.price);
61
61
  }
62
62
  exports.calculateOracleSpread = calculateOracleSpread;
63
- function calculateMarketMarginRatio(market, size, marginCategory, customMarginRatio = 0) {
63
+ function calculateMarketMarginRatio(market, size, marginCategory, customMarginRatio = 0, userHighLeverageMode = false) {
64
+ let marginRationInitial;
65
+ let marginRatioMaintenance;
66
+ if (userHighLeverageMode &&
67
+ market.highLeverageMarginRatioInitial > 0 &&
68
+ market.highLeverageMarginRatioMaintenance) {
69
+ marginRationInitial = market.highLeverageMarginRatioInitial;
70
+ marginRatioMaintenance = market.highLeverageMarginRatioMaintenance;
71
+ }
72
+ else {
73
+ marginRationInitial = market.marginRatioInitial;
74
+ marginRatioMaintenance = market.marginRatioMaintenance;
75
+ }
64
76
  let marginRatio;
65
77
  switch (marginCategory) {
66
78
  case 'Initial': {
67
79
  // 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);
80
+ marginRatio = Math.max((0, margin_1.calculateSizePremiumLiabilityWeight)(size, new anchor_1.BN(market.imfFactor), new anchor_1.BN(marginRationInitial), numericConstants_1.MARGIN_PRECISION).toNumber(), customMarginRatio);
69
81
  break;
70
82
  }
71
83
  case 'Maintenance': {
72
- marginRatio = (0, margin_1.calculateSizePremiumLiabilityWeight)(size, new anchor_1.BN(market.imfFactor), new anchor_1.BN(market.marginRatioMaintenance), numericConstants_1.MARGIN_PRECISION).toNumber();
84
+ marginRatio = (0, margin_1.calculateSizePremiumLiabilityWeight)(size, new anchor_1.BN(market.imfFactor), new anchor_1.BN(marginRatioMaintenance), numericConstants_1.MARGIN_PRECISION).toNumber();
73
85
  break;
74
86
  }
75
87
  }
package/lib/types.d.ts CHANGED
@@ -71,6 +71,14 @@ export declare enum UserStatus {
71
71
  REDUCE_ONLY = 4,
72
72
  ADVANCED_LP = 8
73
73
  }
74
+ export declare class MarginMode {
75
+ static readonly DEFAULT: {
76
+ default: {};
77
+ };
78
+ static readonly HIGH_LEVERAGE: {
79
+ highLeverage: {};
80
+ };
81
+ }
74
82
  export declare class ContractType {
75
83
  static readonly PERPETUAL: {
76
84
  perpetual: {};
@@ -753,6 +761,8 @@ export type PerpMarketAccount = {
753
761
  fuelBoostTaker: number;
754
762
  fuelBoostMaker: number;
755
763
  fuelBoostPosition: number;
764
+ highLeverageMarginRatioInitial: number;
765
+ highLeverageMarginRatioMaintenance: number;
756
766
  };
757
767
  export type HistoricalOracleData = {
758
768
  lastOraclePrice: BN;
@@ -1004,6 +1014,7 @@ export type UserAccount = {
1004
1014
  openAuctions: number;
1005
1015
  hasOpenAuction: boolean;
1006
1016
  lastFuelBonusUpdateTs: number;
1017
+ marginMode: MarginMode;
1007
1018
  };
1008
1019
  export type SpotPosition = {
1009
1020
  marketIndex: number;
package/lib/types.js CHANGED
@@ -1,6 +1,6 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.SwapReduceOnly = exports.PlaceAndTakeOrderSuccessCondition = exports.DefaultOrderParams = exports.ModifyOrderPolicy = exports.PostOnlyParams = exports.LiquidationType = exports.LPAction = exports.TradeSide = exports.getVariant = exports.isOneOfVariant = exports.isVariant = exports.SettlePnlMode = exports.StakeAction = exports.SpotFulfillmentConfigStatus = exports.SettlePnlExplanation = exports.DepositExplanation = exports.SpotFulfillmentStatus = exports.SpotFulfillmentType = exports.OrderTriggerCondition = exports.OrderActionExplanation = exports.OrderAction = exports.OrderStatus = exports.MarketType = exports.OrderType = exports.OracleSource = exports.DepositDirection = exports.PositionDirection = exports.SpotBalanceType = exports.SwapDirection = exports.AssetTier = exports.ContractTier = exports.ContractType = exports.UserStatus = exports.InsuranceFundOperation = exports.SpotOperation = exports.PerpOperation = exports.MarketStatus = exports.ExchangeStatus = void 0;
3
+ exports.SwapReduceOnly = exports.PlaceAndTakeOrderSuccessCondition = exports.DefaultOrderParams = exports.ModifyOrderPolicy = exports.PostOnlyParams = exports.LiquidationType = exports.LPAction = exports.TradeSide = exports.getVariant = exports.isOneOfVariant = exports.isVariant = exports.SettlePnlMode = exports.StakeAction = exports.SpotFulfillmentConfigStatus = exports.SettlePnlExplanation = exports.DepositExplanation = exports.SpotFulfillmentStatus = exports.SpotFulfillmentType = exports.OrderTriggerCondition = exports.OrderActionExplanation = exports.OrderAction = exports.OrderStatus = exports.MarketType = exports.OrderType = exports.OracleSource = exports.DepositDirection = exports.PositionDirection = exports.SpotBalanceType = exports.SwapDirection = exports.AssetTier = exports.ContractTier = exports.ContractType = exports.MarginMode = exports.UserStatus = exports.InsuranceFundOperation = exports.SpotOperation = exports.PerpOperation = exports.MarketStatus = exports.ExchangeStatus = void 0;
4
4
  const _1 = require(".");
5
5
  // # Utility Types / Enums / Constants
6
6
  var ExchangeStatus;
@@ -58,6 +58,11 @@ var UserStatus;
58
58
  UserStatus[UserStatus["REDUCE_ONLY"] = 4] = "REDUCE_ONLY";
59
59
  UserStatus[UserStatus["ADVANCED_LP"] = 8] = "ADVANCED_LP";
60
60
  })(UserStatus = exports.UserStatus || (exports.UserStatus = {}));
61
+ class MarginMode {
62
+ }
63
+ exports.MarginMode = MarginMode;
64
+ MarginMode.DEFAULT = { default: {} };
65
+ MarginMode.HIGH_LEVERAGE = { highLeverage: {} };
61
66
  class ContractType {
62
67
  }
63
68
  exports.ContractType = ContractType;
package/lib/user.d.ts CHANGED
@@ -247,6 +247,7 @@ export declare class User {
247
247
  isBeingLiquidated(): boolean;
248
248
  hasStatus(status: UserStatus): boolean;
249
249
  isBankrupt(): boolean;
250
+ isHighLeverageMode(): boolean;
250
251
  /**
251
252
  * Checks if any user position cumulative funding differs from respective market cumulative funding
252
253
  * @returns
package/lib/user.js CHANGED
@@ -420,7 +420,7 @@ class User {
420
420
  return this.getPerpBuyingPowerFromFreeCollateralAndBaseAssetAmount(marketIndex, freeCollateral, worstCaseBaseAssetAmount);
421
421
  }
422
422
  getPerpBuyingPowerFromFreeCollateralAndBaseAssetAmount(marketIndex, freeCollateral, baseAssetAmount) {
423
- const marginRatio = (0, _1.calculateMarketMarginRatio)(this.driftClient.getPerpMarketAccount(marketIndex), baseAssetAmount, 'Initial', this.getUserAccount().maxMarginRatio);
423
+ const marginRatio = (0, _1.calculateMarketMarginRatio)(this.driftClient.getPerpMarketAccount(marketIndex), baseAssetAmount, 'Initial', this.getUserAccount().maxMarginRatio, this.isHighLeverageMode());
424
424
  return freeCollateral.mul(numericConstants_1.MARGIN_PRECISION).div(new _1.BN(marginRatio));
425
425
  }
426
426
  /**
@@ -787,7 +787,7 @@ class User {
787
787
  liabilityValue = (0, _1.calculatePerpLiabilityValue)(baseAssetAmount, valuationPrice, (0, types_1.isVariant)(market.contractType, 'prediction'));
788
788
  }
789
789
  if (marginCategory) {
790
- let marginRatio = new _1.BN((0, _1.calculateMarketMarginRatio)(market, baseAssetAmount.abs(), marginCategory, this.getUserAccount().maxMarginRatio));
790
+ let marginRatio = new _1.BN((0, _1.calculateMarketMarginRatio)(market, baseAssetAmount.abs(), marginCategory, this.getUserAccount().maxMarginRatio, this.isHighLeverageMode()));
791
791
  if (liquidationBuffer !== undefined) {
792
792
  marginRatio = marginRatio.add(liquidationBuffer);
793
793
  }
@@ -1032,7 +1032,7 @@ class User {
1032
1032
  .mul(numericConstants_1.PRICE_PRECISION)
1033
1033
  .div(marketPrice));
1034
1034
  // margin ratio incorporting upper bound on size
1035
- let marginRatio = (0, _1.calculateMarketMarginRatio)(market, maxSize, marginCategory, this.getUserAccount().maxMarginRatio);
1035
+ let marginRatio = (0, _1.calculateMarketMarginRatio)(market, maxSize, marginCategory, this.getUserAccount().maxMarginRatio, this.isHighLeverageMode());
1036
1036
  // use more fesible size since imf factor activated
1037
1037
  let attempts = 0;
1038
1038
  while (marginRatio > rawMarginRatio + 1e-4 && attempts < 10) {
@@ -1043,7 +1043,7 @@ class User {
1043
1043
  .mul(numericConstants_1.PRICE_PRECISION)
1044
1044
  .div(marketPrice));
1045
1045
  // margin ratio incorporting more fesible target size
1046
- marginRatio = (0, _1.calculateMarketMarginRatio)(market, targetSize, marginCategory, this.getUserAccount().maxMarginRatio);
1046
+ marginRatio = (0, _1.calculateMarketMarginRatio)(market, targetSize, marginCategory, this.getUserAccount().maxMarginRatio, this.isHighLeverageMode());
1047
1047
  attempts += 1;
1048
1048
  }
1049
1049
  // how much more liabilities can be opened w remaining free collateral
@@ -1133,6 +1133,9 @@ class User {
1133
1133
  isBankrupt() {
1134
1134
  return (this.getUserAccount().status & types_1.UserStatus.BANKRUPT) > 0;
1135
1135
  }
1136
+ isHighLeverageMode() {
1137
+ return (0, types_1.isVariant)(this.getUserAccount().marginMode, 'highLeverage');
1138
+ }
1136
1139
  /**
1137
1140
  * Checks if any user position cumulative funding differs from respective market cumulative funding
1138
1141
  * @returns
@@ -1279,7 +1282,7 @@ class User {
1279
1282
  baseAssetAmount = perpPosition.baseAssetAmount;
1280
1283
  liabilityValue = (0, _1.calculatePerpLiabilityValue)(baseAssetAmount, oraclePrice, (0, types_1.isVariant)(market.contractType, 'prediction'));
1281
1284
  }
1282
- const marginRatio = (0, _1.calculateMarketMarginRatio)(market, baseAssetAmount.abs(), 'Maintenance');
1285
+ const marginRatio = (0, _1.calculateMarketMarginRatio)(market, baseAssetAmount.abs(), 'Maintenance', this.getUserAccount().maxMarginRatio, this.isHighLeverageMode());
1283
1286
  return liabilityValue.mul(new _1.BN(marginRatio)).div(numericConstants_1.MARGIN_PRECISION);
1284
1287
  };
1285
1288
  const freeCollateralConsumptionBefore = calculateMarginRequirement(perpPosition);
@@ -1295,7 +1298,7 @@ class User {
1295
1298
  // zero if include orders == false
1296
1299
  const orderBaseAssetAmount = baseAssetAmount.sub(perpPosition.baseAssetAmount);
1297
1300
  const proposedBaseAssetAmount = baseAssetAmount.add(positionBaseSizeChange);
1298
- const marginRatio = (0, _1.calculateMarketMarginRatio)(market, proposedBaseAssetAmount.abs(), marginCategory, this.getUserAccount().maxMarginRatio);
1301
+ const marginRatio = (0, _1.calculateMarketMarginRatio)(market, proposedBaseAssetAmount.abs(), marginCategory, this.getUserAccount().maxMarginRatio, this.isHighLeverageMode());
1299
1302
  const marginRatioQuotePrecision = new _1.BN(marginRatio)
1300
1303
  .mul(numericConstants_1.QUOTE_PRECISION)
1301
1304
  .div(numericConstants_1.MARGIN_PRECISION);
@@ -1372,7 +1375,8 @@ class User {
1372
1375
  return (0, margin_1.calculateMarginUSDCRequiredForTrade)(this.driftClient, targetMarketIndex, baseSize, this.getUserAccount().maxMarginRatio);
1373
1376
  }
1374
1377
  getCollateralDepositRequiredForTrade(targetMarketIndex, baseSize, collateralIndex) {
1375
- return (0, margin_1.calculateCollateralDepositRequiredForTrade)(this.driftClient, targetMarketIndex, baseSize, collateralIndex, this.getUserAccount().maxMarginRatio);
1378
+ return (0, margin_1.calculateCollateralDepositRequiredForTrade)(this.driftClient, targetMarketIndex, baseSize, collateralIndex, this.getUserAccount().maxMarginRatio, false // assume user cant be high leverage if they havent created user account ?
1379
+ );
1376
1380
  }
1377
1381
  /**
1378
1382
  * Get the maximum trade size for a given market, taking into account the user's current leverage, positions, collateral, etc.
@@ -2002,7 +2006,7 @@ class User {
2002
2006
  this.driftClient.getOracleDataForPerpMarket(perpMarket.marketIndex);
2003
2007
  const oraclePrice = _oraclePriceData.price;
2004
2008
  const { worstCaseBaseAssetAmount: worstCaseBaseAmount, worstCaseLiabilityValue, } = (0, _1.calculateWorstCasePerpLiabilityValue)(settledLpPosition, perpMarket, oraclePrice);
2005
- const marginRatio = new _1.BN((0, _1.calculateMarketMarginRatio)(perpMarket, worstCaseBaseAmount.abs(), marginCategory, this.getUserAccount().maxMarginRatio));
2009
+ const marginRatio = new _1.BN((0, _1.calculateMarketMarginRatio)(perpMarket, worstCaseBaseAmount.abs(), marginCategory, this.getUserAccount().maxMarginRatio, this.isHighLeverageMode()));
2006
2010
  const _quoteOraclePriceData = quoteOraclePriceData ||
2007
2011
  this.driftClient.getOracleDataForSpotMarket(numericConstants_1.QUOTE_SPOT_MARKET_INDEX);
2008
2012
  let marginRequirement = worstCaseLiabilityValue
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@drift-labs/sdk",
3
- "version": "2.97.0-beta.5",
3
+ "version": "2.97.0-beta.7",
4
4
  "main": "lib/index.js",
5
5
  "types": "lib/index.d.ts",
6
6
  "author": "crispheaney",
@@ -300,3 +300,12 @@ export function getTokenProgramForSpotMarket(
300
300
  }
301
301
  return TOKEN_PROGRAM_ID;
302
302
  }
303
+
304
+ export function getHighLeverageModeConfigPublicKey(
305
+ programId: PublicKey
306
+ ): PublicKey {
307
+ return PublicKey.findProgramAddressSync(
308
+ [Buffer.from(anchor.utils.bytes.utf8.encode('high_leverage_mode_config'))],
309
+ programId
310
+ )[0];
311
+ }
@@ -32,6 +32,7 @@ import {
32
32
  getOpenbookV2FulfillmentConfigPublicKey,
33
33
  getPythPullOraclePublicKey,
34
34
  getUserStatsAccountPublicKey,
35
+ getHighLeverageModeConfigPublicKey,
35
36
  } from './addresses/pda';
36
37
  import { squareRootBN } from './math/utils';
37
38
  import { TOKEN_PROGRAM_ID } from '@solana/spl-token';
@@ -1268,6 +1269,50 @@ export class AdminClient extends DriftClient {
1268
1269
  );
1269
1270
  }
1270
1271
 
1272
+ public async updatePerpMarketHighLeverageMarginRatio(
1273
+ perpMarketIndex: number,
1274
+ marginRatioInitial: number,
1275
+ marginRatioMaintenance: number
1276
+ ): Promise<TransactionSignature> {
1277
+ const updatePerpMarketHighLeverageMarginRatioIx =
1278
+ await this.getUpdatePerpMarketHighLeverageMarginRatioIx(
1279
+ perpMarketIndex,
1280
+ marginRatioInitial,
1281
+ marginRatioMaintenance
1282
+ );
1283
+
1284
+ const tx = await this.buildTransaction(
1285
+ updatePerpMarketHighLeverageMarginRatioIx
1286
+ );
1287
+
1288
+ const { txSig } = await this.sendTransaction(tx, [], this.opts);
1289
+
1290
+ return txSig;
1291
+ }
1292
+
1293
+ public async getUpdatePerpMarketHighLeverageMarginRatioIx(
1294
+ perpMarketIndex: number,
1295
+ marginRatioInitial: number,
1296
+ marginRatioMaintenance: number
1297
+ ): Promise<TransactionInstruction> {
1298
+ return await this.program.instruction.updatePerpMarketHighLeverageMarginRatio(
1299
+ marginRatioInitial,
1300
+ marginRatioMaintenance,
1301
+ {
1302
+ accounts: {
1303
+ admin: this.isSubscribed
1304
+ ? this.getStateAccount().admin
1305
+ : this.wallet.publicKey,
1306
+ state: await this.getStatePublicKey(),
1307
+ perpMarket: await getPerpMarketPublicKey(
1308
+ this.program.programId,
1309
+ perpMarketIndex
1310
+ ),
1311
+ },
1312
+ }
1313
+ );
1314
+ }
1315
+
1271
1316
  public async updatePerpMarketImfFactor(
1272
1317
  perpMarketIndex: number,
1273
1318
  imfFactor: number,
@@ -3847,4 +3892,73 @@ export class AdminClient extends DriftClient {
3847
3892
  }
3848
3893
  );
3849
3894
  }
3895
+
3896
+ public async initializeHighLeverageModeConfig(
3897
+ maxUsers: number
3898
+ ): Promise<TransactionSignature> {
3899
+ const initializeHighLeverageModeConfigIx =
3900
+ await this.getInitializeHighLeverageModeConfigIx(maxUsers);
3901
+
3902
+ const tx = await this.buildTransaction(initializeHighLeverageModeConfigIx);
3903
+
3904
+ const { txSig } = await this.sendTransaction(tx, [], this.opts);
3905
+
3906
+ return txSig;
3907
+ }
3908
+
3909
+ public async getInitializeHighLeverageModeConfigIx(
3910
+ maxUsers: number
3911
+ ): Promise<TransactionInstruction> {
3912
+ return await this.program.instruction.initializeHighLeverageModeConfig(
3913
+ maxUsers,
3914
+ {
3915
+ accounts: {
3916
+ admin: this.isSubscribed
3917
+ ? this.getStateAccount().admin
3918
+ : this.wallet.publicKey,
3919
+ state: await this.getStatePublicKey(),
3920
+ rent: SYSVAR_RENT_PUBKEY,
3921
+ systemProgram: anchor.web3.SystemProgram.programId,
3922
+ highLeverageModeConfig: getHighLeverageModeConfigPublicKey(
3923
+ this.program.programId
3924
+ ),
3925
+ },
3926
+ }
3927
+ );
3928
+ }
3929
+
3930
+ public async updateUpdateHighLeverageModeConfig(
3931
+ maxUsers: number,
3932
+ reduceOnly: boolean
3933
+ ): Promise<TransactionSignature> {
3934
+ const updateHighLeverageModeConfigIx =
3935
+ await this.getUpdateHighLeverageModeConfigIx(maxUsers, reduceOnly);
3936
+
3937
+ const tx = await this.buildTransaction(updateHighLeverageModeConfigIx);
3938
+
3939
+ const { txSig } = await this.sendTransaction(tx, [], this.opts);
3940
+
3941
+ return txSig;
3942
+ }
3943
+
3944
+ public async getUpdateHighLeverageModeConfigIx(
3945
+ maxUsers: number,
3946
+ reduceOnly: boolean
3947
+ ): Promise<TransactionInstruction> {
3948
+ return await this.program.instruction.updateHighLeverageModeConfig(
3949
+ maxUsers,
3950
+ reduceOnly,
3951
+ {
3952
+ accounts: {
3953
+ admin: this.isSubscribed
3954
+ ? this.getStateAccount().admin
3955
+ : this.wallet.publicKey,
3956
+ state: await this.getStatePublicKey(),
3957
+ highLeverageModeConfig: getHighLeverageModeConfigPublicKey(
3958
+ this.program.programId
3959
+ ),
3960
+ },
3961
+ }
3962
+ );
3963
+ }
3850
3964
  }
package/src/config.ts CHANGED
@@ -114,16 +114,25 @@ export const initialize = (props: {
114
114
  return currentConfig;
115
115
  };
116
116
 
117
- export function getMarketsAndOraclesForSubscription(env: DriftEnv): {
117
+ export function getMarketsAndOraclesForSubscription(
118
+ env: DriftEnv,
119
+ perpMarkets?: PerpMarketConfig[],
120
+ spotMarkets?: SpotMarketConfig[]
121
+ ): {
118
122
  perpMarketIndexes: number[];
119
123
  spotMarketIndexes: number[];
120
124
  oracleInfos: OracleInfo[];
121
125
  } {
126
+ const perpMarketsToUse =
127
+ perpMarkets?.length > 0 ? perpMarkets : PerpMarkets[env];
128
+ const spotMarketsToUse =
129
+ spotMarkets?.length > 0 ? spotMarkets : SpotMarkets[env];
130
+
122
131
  const perpMarketIndexes = [];
123
132
  const spotMarketIndexes = [];
124
133
  const oracleInfos = new Map<string, OracleInfo>();
125
134
 
126
- for (const market of PerpMarkets[env]) {
135
+ for (const market of perpMarketsToUse) {
127
136
  perpMarketIndexes.push(market.marketIndex);
128
137
  oracleInfos.set(market.oracle.toString(), {
129
138
  publicKey: market.oracle,
@@ -131,7 +140,7 @@ export function getMarketsAndOraclesForSubscription(env: DriftEnv): {
131
140
  });
132
141
  }
133
142
 
134
- for (const spotMarket of SpotMarkets[env]) {
143
+ for (const spotMarket of spotMarketsToUse) {
135
144
  spotMarketIndexes.push(spotMarket.marketIndex);
136
145
  oracleInfos.set(spotMarket.oracle.toString(), {
137
146
  publicKey: spotMarket.oracle,
@@ -82,6 +82,7 @@ import StrictEventEmitter from 'strict-event-emitter-types';
82
82
  import {
83
83
  getDriftSignerPublicKey,
84
84
  getDriftStateAccountPublicKey,
85
+ getHighLeverageModeConfigPublicKey,
85
86
  getInsuranceFundStakeAccountPublicKey,
86
87
  getOpenbookV2FulfillmentConfigPublicKey,
87
88
  getPerpMarketPublicKey,
@@ -8102,6 +8103,73 @@ export class DriftClient {
8102
8103
  return [postIxs, encodedVaaKeypair];
8103
8104
  }
8104
8105
 
8106
+ public async enableUserHighLeverageMode(
8107
+ subAccountId: number,
8108
+ txParams?: TxParams
8109
+ ): Promise<TransactionSignature> {
8110
+ const { txSig } = await this.sendTransaction(
8111
+ await this.buildTransaction(
8112
+ await this.getEnableHighLeverageModeIx(subAccountId),
8113
+ txParams
8114
+ ),
8115
+ [],
8116
+ this.opts
8117
+ );
8118
+ return txSig;
8119
+ }
8120
+
8121
+ public async getEnableHighLeverageModeIx(subAccountId: number) {
8122
+ const ix = await this.program.instruction.enableHighLeverageMode(
8123
+ subAccountId,
8124
+ {
8125
+ accounts: {
8126
+ state: await this.getStatePublicKey(),
8127
+ user: getUserAccountPublicKeySync(
8128
+ this.program.programId,
8129
+ this.wallet.publicKey,
8130
+ subAccountId
8131
+ ),
8132
+ authority: this.wallet.publicKey,
8133
+ highLeverageModeConfig: getHighLeverageModeConfigPublicKey(
8134
+ this.program.programId
8135
+ ),
8136
+ },
8137
+ }
8138
+ );
8139
+
8140
+ return ix;
8141
+ }
8142
+
8143
+ public async disableUserHighLeverageMode(
8144
+ user: PublicKey,
8145
+ txParams?: TxParams
8146
+ ): Promise<TransactionSignature> {
8147
+ const { txSig } = await this.sendTransaction(
8148
+ await this.buildTransaction(
8149
+ await this.getDisableHighLeverageModeIx(user),
8150
+ txParams
8151
+ ),
8152
+ [],
8153
+ this.opts
8154
+ );
8155
+ return txSig;
8156
+ }
8157
+
8158
+ public async getDisableHighLeverageModeIx(user: PublicKey) {
8159
+ const ix = await this.program.instruction.disableHighLeverageMode({
8160
+ accounts: {
8161
+ state: await this.getStatePublicKey(),
8162
+ user,
8163
+ authority: this.wallet.publicKey,
8164
+ highLeverageModeConfig: getHighLeverageModeConfigPublicKey(
8165
+ this.program.programId
8166
+ ),
8167
+ },
8168
+ });
8169
+
8170
+ return ix;
8171
+ }
8172
+
8105
8173
  private handleSignedTransaction(signedTxs: SignedTxData[]) {
8106
8174
  if (this.enableMetricsEvents && this.metricsEventEmitter) {
8107
8175
  this.metricsEventEmitter.emit('txSigned', signedTxs);
@@ -214,7 +214,8 @@ export function calculateMarginUSDCRequiredForTrade(
214
214
  driftClient: DriftClient,
215
215
  targetMarketIndex: number,
216
216
  baseSize: BN,
217
- userMaxMarginRatio?: number
217
+ userMaxMarginRatio?: number,
218
+ userHighLeverageMode?: boolean
218
219
  ): BN {
219
220
  const targetMarket = driftClient.getPerpMarketAccount(targetMarketIndex);
220
221
  const oracleData = driftClient.getOracleDataForPerpMarket(
@@ -232,7 +233,8 @@ export function calculateMarginUSDCRequiredForTrade(
232
233
  targetMarket,
233
234
  baseSize.abs(),
234
235
  'Initial',
235
- userMaxMarginRatio
236
+ userMaxMarginRatio,
237
+ userHighLeverageMode
236
238
  )
237
239
  )
238
240
  .mul(perpLiabilityValue)
@@ -251,13 +253,15 @@ export function calculateCollateralDepositRequiredForTrade(
251
253
  targetMarketIndex: number,
252
254
  baseSize: BN,
253
255
  collateralIndex: number,
254
- userMaxMarginRatio?: number
256
+ userMaxMarginRatio?: number,
257
+ userHighLeverageMode?: boolean
255
258
  ): BN {
256
259
  const marginRequiredUsdc = calculateMarginUSDCRequiredForTrade(
257
260
  driftClient,
258
261
  targetMarketIndex,
259
262
  baseSize,
260
- userMaxMarginRatio
263
+ userMaxMarginRatio,
264
+ userHighLeverageMode
261
265
  );
262
266
 
263
267
  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 = {
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)
@@ -2622,7 +2633,8 @@ export class User {
2622
2633
  targetMarketIndex,
2623
2634
  baseSize,
2624
2635
  collateralIndex,
2625
- this.getUserAccount().maxMarginRatio
2636
+ this.getUserAccount().maxMarginRatio,
2637
+ false // assume user cant be high leverage if they havent created user account ?
2626
2638
  );
2627
2639
  }
2628
2640
 
@@ -3771,7 +3783,8 @@ export class User {
3771
3783
  perpMarket,
3772
3784
  worstCaseBaseAmount.abs(),
3773
3785
  marginCategory,
3774
- this.getUserAccount().maxMarginRatio
3786
+ this.getUserAccount().maxMarginRatio,
3787
+ this.isHighLeverageMode()
3775
3788
  )
3776
3789
  );
3777
3790