@drift-labs/sdk 2.42.0-beta.0 → 2.42.0-beta.10

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.
Files changed (64) hide show
  1. package/VERSION +1 -1
  2. package/bun.lockb +0 -0
  3. package/lib/addresses/pda.d.ts +1 -0
  4. package/lib/adminClient.d.ts +1 -0
  5. package/lib/constants/numericConstants.d.ts +62 -59
  6. package/lib/constants/numericConstants.js +2 -1
  7. package/lib/constants/spotMarkets.d.ts +1 -0
  8. package/lib/dlob/DLOB.d.ts +10 -16
  9. package/lib/dlob/DLOB.js +9 -39
  10. package/lib/dlob/DLOBNode.d.ts +1 -0
  11. package/lib/dlob/NodeList.d.ts +1 -0
  12. package/lib/dlob/orderBookLevels.d.ts +2 -1
  13. package/lib/driftClient.d.ts +12 -4
  14. package/lib/driftClient.js +51 -38
  15. package/lib/factory/bigNum.d.ts +8 -7
  16. package/lib/jupiter/jupiterClient.d.ts +1 -0
  17. package/lib/marinade/index.d.ts +1 -0
  18. package/lib/math/amm.d.ts +2 -1
  19. package/lib/math/auction.d.ts +1 -0
  20. package/lib/math/conversion.d.ts +2 -1
  21. package/lib/math/funding.d.ts +1 -0
  22. package/lib/math/funding.js +2 -1
  23. package/lib/math/insurance.d.ts +1 -0
  24. package/lib/math/margin.d.ts +1 -0
  25. package/lib/math/market.d.ts +2 -1
  26. package/lib/math/market.js +3 -2
  27. package/lib/math/oracles.d.ts +1 -0
  28. package/lib/math/orders.d.ts +1 -0
  29. package/lib/math/position.d.ts +1 -0
  30. package/lib/math/repeg.d.ts +1 -0
  31. package/lib/math/spotBalance.d.ts +3 -2
  32. package/lib/math/spotMarket.d.ts +2 -1
  33. package/lib/math/spotMarket.js +9 -3
  34. package/lib/math/spotPosition.d.ts +4 -3
  35. package/lib/math/spotPosition.js +18 -7
  36. package/lib/math/superStake.d.ts +1 -0
  37. package/lib/math/trade.d.ts +1 -0
  38. package/lib/math/utils.d.ts +1 -0
  39. package/lib/oracles/pythClient.d.ts +2 -1
  40. package/lib/oracles/strictOraclePrice.d.ts +1 -0
  41. package/lib/oracles/types.d.ts +1 -0
  42. package/lib/orderParams.d.ts +1 -0
  43. package/lib/phoenix/phoenixSubscriber.d.ts +1 -0
  44. package/lib/serum/serumSubscriber.d.ts +1 -0
  45. package/lib/tokenFaucet.d.ts +1 -0
  46. package/lib/types.d.ts +7 -0
  47. package/lib/types.js +2 -0
  48. package/lib/user.d.ts +15 -3
  49. package/lib/user.js +85 -28
  50. package/package.json +2 -1
  51. package/src/constants/numericConstants.ts +1 -0
  52. package/src/dlob/DLOB.ts +23 -67
  53. package/src/driftClient.ts +79 -53
  54. package/src/math/funding.ts +6 -1
  55. package/src/math/market.ts +12 -7
  56. package/src/math/spotMarket.ts +13 -3
  57. package/src/math/spotPosition.ts +29 -7
  58. package/src/types.ts +2 -0
  59. package/src/user.ts +136 -34
  60. package/tests/amm/test.ts +7 -5
  61. package/tests/auctions/test.ts +22 -11
  62. package/tests/dlob/helpers.ts +15 -13
  63. package/tests/tx/priorityFeeCalculator.ts +1 -1
  64. package/tests/user/test.ts +171 -24
@@ -1,3 +1,4 @@
1
+ /// <reference types="bn.js" />
1
2
  import { BN } from '@coral-xyz/anchor';
2
3
  import { OraclePriceData } from '../oracles/types';
3
4
  import { PerpMarketAccount, PerpPosition } from '..';
@@ -1,3 +1,4 @@
1
+ /// <reference types="bn.js" />
1
2
  import { BN } from '@coral-xyz/anchor';
2
3
  import { PerpMarketAccount, PositionDirection, MarginCategory, SpotMarketAccount } from '../types';
3
4
  import { OraclePriceData } from '../oracles/types';
@@ -26,7 +27,7 @@ export declare function calculateAskPrice(market: PerpMarketAccount, oraclePrice
26
27
  export declare function calculateNewMarketAfterTrade(baseAssetAmount: BN, direction: PositionDirection, market: PerpMarketAccount): PerpMarketAccount;
27
28
  export declare function calculateOracleReserveSpread(market: PerpMarketAccount, oraclePriceData: OraclePriceData): BN;
28
29
  export declare function calculateOracleSpread(price: BN, oraclePriceData: OraclePriceData): BN;
29
- export declare function calculateMarketMarginRatio(market: PerpMarketAccount, size: BN, marginCategory: MarginCategory): number;
30
+ export declare function calculateMarketMarginRatio(market: PerpMarketAccount, size: BN, marginCategory: MarginCategory, customMarginRatio?: number): number;
30
31
  export declare function calculateUnrealizedAssetWeight(market: PerpMarketAccount, quoteSpotMarket: SpotMarketAccount, unrealizedPnl: BN, marginCategory: MarginCategory, oraclePriceData: OraclePriceData): BN;
31
32
  export declare function calculateMarketAvailablePNL(perpMarket: PerpMarketAccount, spotMarket: SpotMarketAccount): BN;
32
33
  export declare function calculateMarketMaxAvailableInsurance(perpMarket: PerpMarketAccount, spotMarket: SpotMarketAccount): BN;
@@ -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
- marginRatio = (0, margin_1.calculateSizePremiumLiabilityWeight)(size, new anchor_1.BN(market.imfFactor), new anchor_1.BN(market.marginRatioInitial), numericConstants_1.MARGIN_PRECISION).toNumber();
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': {
@@ -1,3 +1,4 @@
1
+ /// <reference types="bn.js" />
1
2
  import { AMM, OracleGuardRails } from '../types';
2
3
  import { OraclePriceData } from '../oracles/types';
3
4
  import { BN, HistoricalOracleData, PerpMarketAccount } from '../index';
@@ -1,3 +1,4 @@
1
+ /// <reference types="bn.js" />
1
2
  import { User } from '../user';
2
3
  import { PerpMarketAccount, AMM, Order, PositionDirection } from '../types';
3
4
  import { BN } from '@coral-xyz/anchor';
@@ -1,3 +1,4 @@
1
+ /// <reference types="bn.js" />
1
2
  import { BN, SpotMarketAccount } from '../';
2
3
  import { OraclePriceData } from '../oracles/types';
3
4
  import { PerpMarketAccount, PositionDirection, PerpPosition } from '../types';
@@ -1,3 +1,4 @@
1
+ /// <reference types="bn.js" />
1
2
  import { BN } from '@coral-xyz/anchor';
2
3
  import { AMM } from '../types';
3
4
  /**
@@ -1,3 +1,4 @@
1
+ /// <reference types="bn.js" />
1
2
  import { SpotMarketAccount, SpotBalanceType, MarginCategory } from '../types';
2
3
  import { BN } from '@coral-xyz/anchor';
3
4
  import { OraclePriceData } from '../oracles/types';
@@ -50,7 +51,7 @@ export declare function getTokenValue(tokenAmount: BN, spotDecimals: number, ora
50
51
  export declare function calculateAssetWeight(balanceAmount: BN, oraclePrice: BN, spotMarket: SpotMarketAccount, marginCategory: MarginCategory): BN;
51
52
  export declare function calculateScaledInitialAssetWeight(spotMarket: SpotMarketAccount, oraclePrice: BN): BN;
52
53
  export declare function calculateLiabilityWeight(size: BN, spotMarket: SpotMarketAccount, marginCategory: MarginCategory): BN;
53
- export declare function calculateUtilization(bank: SpotMarketAccount, delta?: any): BN;
54
+ export declare function calculateUtilization(bank: SpotMarketAccount, delta?: BN): BN;
54
55
  /**
55
56
  * calculates max borrow amount where rate would stay below targetBorrowRate
56
57
  * @param spotMarketAccount
@@ -61,7 +62,7 @@ export declare function calculateSpotMarketBorrowCapacity(spotMarketAccount: Spo
61
62
  totalCapacity: BN;
62
63
  remainingCapacity: BN;
63
64
  };
64
- export declare function calculateInterestRate(bank: SpotMarketAccount, delta?: any): BN;
65
+ export declare function calculateInterestRate(bank: SpotMarketAccount, delta?: BN): BN;
65
66
  export declare function calculateDepositRate(bank: SpotMarketAccount): BN;
66
67
  export declare function calculateBorrowRate(bank: SpotMarketAccount): BN;
67
68
  export declare function calculateInterestAccumulated(bank: SpotMarketAccount, now: BN): {
@@ -1,4 +1,5 @@
1
+ /// <reference types="bn.js" />
1
2
  import { BN } from '@coral-xyz/anchor';
2
3
  import { MarginCategory, SpotBalanceType, SpotMarketAccount } from '../types';
3
4
  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;
5
+ export declare function calculateSpotMarketMarginRatio(market: SpotMarketAccount, oraclePrice: BN, marginCategory: MarginCategory, size: BN, balanceType: SpotBalanceType, customMarginRatio?: number): number;
@@ -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
- return numericConstants_1.MARGIN_PRECISION.sub(assetWeight).toNumber();
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
- return liabilityWeight.sub(numericConstants_1.MARGIN_PRECISION).toNumber();
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;
@@ -1,3 +1,4 @@
1
+ /// <reference types="bn.js" />
1
2
  import { MarginCategory, SpotMarketAccount, SpotPosition } from '../types';
2
3
  import { BN } from '@coral-xyz/anchor';
3
4
  import { StrictOraclePrice } from '../oracles/strictOraclePrice';
@@ -10,9 +11,9 @@ export type OrderFillSimulation = {
10
11
  weightedTokenValue: BN;
11
12
  freeCollateralContribution: any;
12
13
  };
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): {
14
+ export declare function getWorstCaseTokenAmounts(spotPosition: SpotPosition, spotMarketAccount: SpotMarketAccount, strictOraclePrice: StrictOraclePrice, marginCategory: MarginCategory, customMarginRatio?: number): OrderFillSimulation;
15
+ export declare function calculateWeightedTokenValue(tokenAmount: BN, tokenValue: BN, oraclePrice: BN, spotMarket: SpotMarketAccount, marginCategory: MarginCategory, customMarginRatio?: number): {
15
16
  weight: BN;
16
17
  weightedTokenValue: BN;
17
18
  };
18
- export declare function simulateOrderFill(tokenAmount: BN, tokenValue: BN, openOrders: BN, strictOraclePrice: StrictOraclePrice, spotMarket: SpotMarketAccount, marginCategory: MarginCategory): OrderFillSimulation;
19
+ export declare function simulateOrderFill(tokenAmount: BN, tokenValue: BN, openOrders: BN, strictOraclePrice: StrictOraclePrice, spotMarket: SpotMarketAccount, marginCategory: MarginCategory, customMarginRatio?: number): OrderFillSimulation;
@@ -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,
@@ -1,3 +1,4 @@
1
+ /// <reference types="bn.js" />
1
2
  import { AddressLookupTableAccount, PublicKey, TransactionInstruction } from '@solana/web3.js';
2
3
  import { JupiterClient } from '../jupiter/jupiterClient';
3
4
  import { DriftClient } from '../driftClient';
@@ -1,3 +1,4 @@
1
+ /// <reference types="bn.js" />
1
2
  import { PerpMarketAccount, PositionDirection, SpotMarketAccount } from '../types';
2
3
  import { BN } from '@coral-xyz/anchor';
3
4
  import { AssetType } from './amm';
@@ -1,3 +1,4 @@
1
+ /// <reference types="bn.js" />
1
2
  import { BN } from '../';
2
3
  export declare function clampBN(x: BN, min: BN, max: BN): BN;
3
4
  export declare const squareRootBN: (n: BN) => BN;
@@ -1,3 +1,4 @@
1
+ /// <reference types="bn.js" />
1
2
  /// <reference types="node" />
2
3
  import { Connection, PublicKey } from '@solana/web3.js';
3
4
  import { OracleClient, OraclePriceData } from './types';
@@ -6,7 +7,7 @@ export declare class PythClient implements OracleClient {
6
7
  private connection;
7
8
  private multiple;
8
9
  private stableCoin;
9
- constructor(connection: Connection, multiple?: any, stableCoin?: boolean);
10
+ constructor(connection: Connection, multiple?: BN, stableCoin?: boolean);
10
11
  getOraclePriceData(pricePublicKey: PublicKey): Promise<OraclePriceData>;
11
12
  getOraclePriceDataFromBuffer(buffer: Buffer): OraclePriceData;
12
13
  }
@@ -1,3 +1,4 @@
1
+ /// <reference types="bn.js" />
1
2
  import { BN } from '@coral-xyz/anchor';
2
3
  export declare class StrictOraclePrice {
3
4
  current: BN;
@@ -1,3 +1,4 @@
1
+ /// <reference types="bn.js" />
1
2
  /// <reference types="node" />
2
3
  import { BN } from '@coral-xyz/anchor';
3
4
  import { PublicKey } from '@solana/web3.js';
@@ -1,3 +1,4 @@
1
+ /// <reference types="bn.js" />
1
2
  import { OptionalOrderParams, OrderParams, OrderTriggerCondition } from './types';
2
3
  import { BN } from '@coral-xyz/anchor';
3
4
  export declare function getLimitOrderParams(params: Omit<OptionalOrderParams, 'orderType'> & {
@@ -1,3 +1,4 @@
1
+ /// <reference types="bn.js" />
1
2
  import { Connection, PublicKey } from '@solana/web3.js';
2
3
  import { BulkAccountLoader } from '../accounts/bulkAccountLoader';
3
4
  import { Client, Market } from '@ellipsis-labs/phoenix-sdk';
@@ -1,3 +1,4 @@
1
+ /// <reference types="bn.js" />
1
2
  import { Connection, PublicKey } from '@solana/web3.js';
2
3
  import { BulkAccountLoader } from '../accounts/bulkAccountLoader';
3
4
  import { Market, Orderbook } from '@project-serum/serum';
@@ -1,3 +1,4 @@
1
+ /// <reference types="bn.js" />
1
2
  import * as anchor from '@coral-xyz/anchor';
2
3
  import { AnchorProvider, Program } from '@coral-xyz/anchor';
3
4
  import { Account } from '@solana/spl-token';
package/lib/types.d.ts CHANGED
@@ -1,3 +1,4 @@
1
+ /// <reference types="bn.js" />
1
2
  import { PublicKey, Transaction, VersionedTransaction } from '@solana/web3.js';
2
3
  import { BN } from '.';
3
4
  export declare enum ExchangeStatus {
@@ -316,6 +317,12 @@ export declare class StakeAction {
316
317
  static readonly UNSTAKE: {
317
318
  unstake: {};
318
319
  };
320
+ static readonly UNSTAKE_TRANSFER: {
321
+ unstakeTransfer: {};
322
+ };
323
+ static readonly STAKE_TRANSFER: {
324
+ stakeTransfer: {};
325
+ };
319
326
  }
320
327
  export declare function isVariant(object: unknown, type: string): boolean;
321
328
  export declare function isOneOfVariant(object: unknown, types: string[]): boolean;
package/lib/types.js CHANGED
@@ -201,6 +201,8 @@ StakeAction.STAKE = { stake: {} };
201
201
  StakeAction.UNSTAKE_REQUEST = { unstakeRequest: {} };
202
202
  StakeAction.UNSTAKE_CANCEL_REQUEST = { unstakeCancelRequest: {} };
203
203
  StakeAction.UNSTAKE = { unstake: {} };
204
+ StakeAction.UNSTAKE_TRANSFER = { unstakeTransfer: {} };
205
+ StakeAction.STAKE_TRANSFER = { stakeTransfer: {} };
204
206
  function isVariant(object, type) {
205
207
  return object.hasOwnProperty(type);
206
208
  }
package/lib/user.d.ts CHANGED
@@ -1,4 +1,5 @@
1
1
  /// <reference types="node" />
2
+ /// <reference types="bn.js" />
2
3
  import { PublicKey } from '@solana/web3.js';
3
4
  import { EventEmitter } from 'events';
4
5
  import StrictEventEmitter from 'strict-event-emitter-types';
@@ -99,7 +100,7 @@ export declare class User {
99
100
  * calculates Buying Power = free collateral / initial margin ratio
100
101
  * @returns : Precision QUOTE_PRECISION
101
102
  */
102
- getPerpBuyingPower(marketIndex: number, collateralBuffer?: any): BN;
103
+ getPerpBuyingPower(marketIndex: number, collateralBuffer?: BN): BN;
103
104
  getPerpBuyingPowerFromFreeCollateralAndBaseAssetAmount(marketIndex: number, freeCollateral: BN, baseAssetAmount: BN): BN;
104
105
  /**
105
106
  * calculates Free Collateral = Total collateral - margin requirement
@@ -187,7 +188,7 @@ export declare class User {
187
188
  spotAssetValue: BN;
188
189
  spotLiabilityValue: BN;
189
190
  }): BN;
190
- getLeverageComponents(includeOpenOrders?: boolean): {
191
+ getLeverageComponents(includeOpenOrders?: boolean, marginCategory?: MarginCategory): {
191
192
  perpLiabilityValue: BN;
192
193
  perpPnl: BN;
193
194
  spotAssetValue: BN;
@@ -335,8 +336,19 @@ export declare class User {
335
336
  * @returns leverageRatio : Precision TEN_THOUSAND
336
337
  */
337
338
  accountLeverageRatioAfterTrade(targetMarketIndex: number, targetMarketType: MarketType, tradeQuoteAmount: BN, tradeSide: PositionDirection, includeOpenOrders?: boolean): BN;
339
+ getUserFeeTier(marketType: MarketType): import("./types").FeeTier;
338
340
  /**
339
- * Calculates how much fee will be taken for a given sized trade
341
+ * Calculates taker / maker fee (as a percentage, e.g. .001 = 10 basis points) for particular marketType
342
+ * @param marketType
343
+ * @param positionMarketIndex
344
+ * @returns : {takerFee: number, makerFee: number} Precision None
345
+ */
346
+ getMarketFees(marketType: MarketType, marketIndex?: number): {
347
+ takerFee: number;
348
+ makerFee: number;
349
+ };
350
+ /**
351
+ * Calculates how much perp fee will be taken for a given sized trade
340
352
  * @param quoteAmount
341
353
  * @returns feeForQuote : Precision QUOTE_PRECISION
342
354
  */
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 !== null && marginCategory !== void 0 ? marginCategory : 'Initial');
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
- weight = _1.BN.max(weight, new _1.BN(this.getUserAccount().maxMarginRatio));
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
- const weight = (0, spotBalance_1.calculateAssetWeight)(tokenAmount, strictOraclePrice.current, spotMarketAccount, marginCategory);
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(undefined, undefined, includeOpenOrders);
839
- const perpPnl = this.getUnrealizedPNL(true);
840
- const { totalAssetValue: spotAssetValue, totalLiabilityValue: spotLiabilityValue, } = this.getSpotMarketAssetAndLiabilityValue(undefined, undefined, undefined, includeOpenOrders);
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);
@@ -1590,13 +1593,67 @@ class User {
1590
1593
  .div(netAssetValue);
1591
1594
  return newLeverage;
1592
1595
  }
1596
+ getUserFeeTier(marketType) {
1597
+ const state = this.driftClient.getStateAccount();
1598
+ let feeTierIndex = 0;
1599
+ if ((0, types_1.isVariant)(marketType, 'perp')) {
1600
+ const userStatsAccount = this.driftClient
1601
+ .getUserStats()
1602
+ .getAccount();
1603
+ const total30dVolume = userStatsAccount.takerVolume30D.add(userStatsAccount.makerVolume30D); // todo: update using now and lastTs?
1604
+ const stakedQuoteAssetAmount = userStatsAccount.ifStakedQuoteAssetAmount;
1605
+ const volumeTiers = [
1606
+ new _1.BN(100000000).mul(numericConstants_1.QUOTE_PRECISION),
1607
+ new _1.BN(50000000).mul(numericConstants_1.QUOTE_PRECISION),
1608
+ new _1.BN(10000000).mul(numericConstants_1.QUOTE_PRECISION),
1609
+ new _1.BN(5000000).mul(numericConstants_1.QUOTE_PRECISION),
1610
+ new _1.BN(1000000).mul(numericConstants_1.QUOTE_PRECISION),
1611
+ ];
1612
+ const stakedTiers = [
1613
+ new _1.BN(10000).mul(numericConstants_1.QUOTE_PRECISION),
1614
+ new _1.BN(5000).mul(numericConstants_1.QUOTE_PRECISION),
1615
+ new _1.BN(2000).mul(numericConstants_1.QUOTE_PRECISION),
1616
+ new _1.BN(1000).mul(numericConstants_1.QUOTE_PRECISION),
1617
+ new _1.BN(500).mul(numericConstants_1.QUOTE_PRECISION),
1618
+ ];
1619
+ for (let i = 0; i < volumeTiers.length; i++) {
1620
+ if (total30dVolume.gte(volumeTiers[i]) ||
1621
+ stakedQuoteAssetAmount.gte(stakedTiers[i])) {
1622
+ feeTierIndex = 5 - i;
1623
+ break;
1624
+ }
1625
+ }
1626
+ return state.perpFeeStructure.feeTiers[feeTierIndex];
1627
+ }
1628
+ return state.spotFeeStructure.feeTiers[feeTierIndex];
1629
+ }
1630
+ /**
1631
+ * Calculates taker / maker fee (as a percentage, e.g. .001 = 10 basis points) for particular marketType
1632
+ * @param marketType
1633
+ * @param positionMarketIndex
1634
+ * @returns : {takerFee: number, makerFee: number} Precision None
1635
+ */
1636
+ getMarketFees(marketType, marketIndex) {
1637
+ const feeTier = this.getUserFeeTier(marketType);
1638
+ let takerFee = feeTier.feeNumerator / feeTier.feeDenominator;
1639
+ let makerFee = feeTier.makerRebateNumerator / feeTier.makerRebateDenominator;
1640
+ if (marketIndex && (0, types_1.isVariant)(marketType, 'perp')) {
1641
+ const marketAccount = this.driftClient.getPerpMarketAccount(marketIndex);
1642
+ takerFee += (takerFee * marketAccount.feeAdjustment) / 100;
1643
+ makerFee += (makerFee * marketAccount.feeAdjustment) / 100;
1644
+ }
1645
+ return {
1646
+ takerFee,
1647
+ makerFee,
1648
+ };
1649
+ }
1593
1650
  /**
1594
- * Calculates how much fee will be taken for a given sized trade
1651
+ * Calculates how much perp fee will be taken for a given sized trade
1595
1652
  * @param quoteAmount
1596
1653
  * @returns feeForQuote : Precision QUOTE_PRECISION
1597
1654
  */
1598
1655
  calculateFeeForQuoteAmount(quoteAmount) {
1599
- const feeTier = this.driftClient.getStateAccount().perpFeeStructure.feeTiers[0];
1656
+ const feeTier = this.getUserFeeTier(_1.MarketType.PERP);
1600
1657
  return quoteAmount
1601
1658
  .mul(new _1.BN(feeTier.feeNumerator))
1602
1659
  .div(new _1.BN(feeTier.feeDenominator));
@@ -1747,7 +1804,7 @@ class User {
1747
1804
  const oraclePriceData = this.driftClient.getOraclePriceDataAndSlot(perpMarket.amm.oracle).data;
1748
1805
  const oraclePrice = oraclePriceData.price;
1749
1806
  const worstCaseBaseAmount = (0, margin_1.calculateWorstCaseBaseAssetAmount)(perpPosition);
1750
- 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));
1751
1808
  const quoteSpotMarket = this.driftClient.getSpotMarketAccount(perpMarket.quoteSpotMarketIndex);
1752
1809
  const quoteOraclePriceData = this.driftClient.getOraclePriceDataAndSlot(quoteSpotMarket.oracle).data;
1753
1810
  const baseAssetValue = worstCaseBaseAmount
@@ -1807,7 +1864,7 @@ class User {
1807
1864
  netQuoteValue = netQuoteValue.add(tokenAmount);
1808
1865
  continue;
1809
1866
  }
1810
- 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);
1811
1868
  netQuoteValue = netQuoteValue.add(ordersValue);
1812
1869
  const baseAssetValue = tokenValue.abs();
1813
1870
  const weightedValue = weightedTokenValue.abs();
@@ -1834,7 +1891,7 @@ class User {
1834
1891
  const spotMarketAccount = this.driftClient.getQuoteSpotMarketAccount();
1835
1892
  const oraclePriceData = this.getOracleDataForSpotMarket(numericConstants_1.QUOTE_SPOT_MARKET_INDEX);
1836
1893
  const baseAssetValue = (0, _1.getTokenValue)(netQuoteValue, spotMarketAccount.decimals, oraclePriceData);
1837
- 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);
1838
1895
  if (netQuoteValue.lt(numericConstants_1.ZERO)) {
1839
1896
  healthComponents.borrows.push({
1840
1897
  marketIndex: spotMarketAccount.marketIndex,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@drift-labs/sdk",
3
- "version": "2.42.0-beta.0",
3
+ "version": "2.42.0-beta.10",
4
4
  "main": "lib/index.js",
5
5
  "types": "lib/index.d.ts",
6
6
  "author": "crispheaney",
@@ -45,6 +45,7 @@
45
45
  },
46
46
  "devDependencies": {
47
47
  "@types/big.js": "^6.2.0",
48
+ "@types/bn.js": "^5.1.3",
48
49
  "@types/chai": "^4.3.1",
49
50
  "@types/jest": "^28.1.3",
50
51
  "@types/mocha": "^9.1.1",