@drift-labs/sdk 0.2.0-master.11 → 0.2.0-master.14

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 (114) hide show
  1. package/lib/accounts/fetch.d.ts +2 -1
  2. package/lib/accounts/fetch.js +9 -1
  3. package/lib/accounts/pollingUserStatsAccountSubscriber.d.ts +27 -0
  4. package/lib/accounts/pollingUserStatsAccountSubscriber.js +113 -0
  5. package/lib/accounts/types.d.ts +14 -1
  6. package/lib/accounts/webSocketUserStatsAccountSubsriber.d.ts +20 -0
  7. package/lib/accounts/webSocketUserStatsAccountSubsriber.js +47 -0
  8. package/lib/addresses/pda.d.ts +1 -0
  9. package/lib/addresses/pda.js +8 -1
  10. package/lib/admin.d.ts +2 -0
  11. package/lib/admin.js +18 -0
  12. package/lib/clearingHouse.d.ts +24 -3
  13. package/lib/clearingHouse.js +352 -51
  14. package/lib/clearingHouseConfig.d.ts +1 -0
  15. package/lib/clearingHouseUser.d.ts +15 -15
  16. package/lib/clearingHouseUser.js +185 -73
  17. package/lib/clearingHouseUserStats.d.ts +17 -0
  18. package/lib/clearingHouseUserStats.js +36 -0
  19. package/lib/clearingHouseUserStatsConfig.d.ts +14 -0
  20. package/lib/clearingHouseUserStatsConfig.js +2 -0
  21. package/lib/config.js +1 -1
  22. package/lib/constants/banks.d.ts +2 -2
  23. package/lib/constants/banks.js +4 -3
  24. package/lib/constants/numericConstants.d.ts +2 -0
  25. package/lib/constants/numericConstants.js +3 -1
  26. package/lib/events/eventList.js +3 -0
  27. package/lib/events/types.d.ts +2 -1
  28. package/lib/factory/bigNum.d.ts +1 -0
  29. package/lib/factory/bigNum.js +37 -11
  30. package/lib/idl/clearing_house.json +692 -58
  31. package/lib/index.d.ts +1 -0
  32. package/lib/index.js +1 -0
  33. package/lib/math/amm.js +2 -2
  34. package/lib/math/bankBalance.d.ts +7 -1
  35. package/lib/math/bankBalance.js +76 -1
  36. package/lib/math/margin.d.ts +11 -0
  37. package/lib/math/margin.js +72 -0
  38. package/lib/math/market.d.ts +4 -1
  39. package/lib/math/market.js +35 -1
  40. package/lib/math/oracles.d.ts +3 -0
  41. package/lib/math/oracles.js +25 -5
  42. package/lib/math/position.d.ts +8 -0
  43. package/lib/math/position.js +43 -12
  44. package/lib/math/trade.js +2 -2
  45. package/lib/orders.d.ts +1 -2
  46. package/lib/orders.js +2 -77
  47. package/lib/tokenFaucet.d.ts +1 -0
  48. package/lib/tokenFaucet.js +23 -12
  49. package/lib/tx/retryTxSender.js +9 -2
  50. package/lib/types.d.ts +78 -10
  51. package/lib/types.js +12 -0
  52. package/lib/util/getTokenAddress.d.ts +2 -0
  53. package/lib/util/getTokenAddress.js +9 -0
  54. package/package.json +1 -1
  55. package/src/accounts/fetch.ts +27 -2
  56. package/src/accounts/pollingUserStatsAccountSubscriber.ts +172 -0
  57. package/src/accounts/types.ts +18 -0
  58. package/src/accounts/webSocketUserStatsAccountSubsriber.ts +80 -0
  59. package/src/addresses/pda.ts +13 -0
  60. package/src/admin.ts +29 -1
  61. package/src/clearingHouse.ts +619 -62
  62. package/src/clearingHouseConfig.ts +1 -0
  63. package/src/clearingHouseUser.ts +317 -105
  64. package/src/clearingHouseUserStats.ts +53 -0
  65. package/src/clearingHouseUserStatsConfig.ts +18 -0
  66. package/src/config.ts +1 -1
  67. package/src/constants/banks.js +42 -0
  68. package/src/constants/banks.ts +6 -3
  69. package/src/constants/markets.js +42 -0
  70. package/src/constants/numericConstants.js +41 -0
  71. package/src/constants/numericConstants.ts +3 -0
  72. package/src/events/eventList.ts +3 -0
  73. package/src/events/types.ts +2 -0
  74. package/src/factory/bigNum.js +37 -11
  75. package/src/factory/bigNum.ts +43 -13
  76. package/src/idl/clearing_house.json +692 -58
  77. package/src/index.ts +1 -0
  78. package/src/math/amm.ts +8 -5
  79. package/src/math/bankBalance.ts +147 -1
  80. package/src/math/margin.ts +124 -0
  81. package/src/math/market.ts +66 -1
  82. package/src/math/oracles.ts +42 -5
  83. package/src/math/position.ts +60 -9
  84. package/src/math/trade.ts +2 -2
  85. package/src/orders.ts +4 -157
  86. package/src/tokenFaucet.js +189 -0
  87. package/src/tokenFaucet.ts +38 -15
  88. package/src/tx/retryTxSender.ts +11 -3
  89. package/src/types.js +12 -1
  90. package/src/types.ts +83 -10
  91. package/src/{accounts/fetch.js → util/computeUnits.js} +11 -13
  92. package/src/util/getTokenAddress.js +9 -0
  93. package/src/util/getTokenAddress.ts +18 -0
  94. package/tests/bn/test.ts +2 -0
  95. package/src/accounts/bulkAccountLoader.js +0 -197
  96. package/src/accounts/bulkUserSubscription.js +0 -33
  97. package/src/accounts/pollingClearingHouseAccountSubscriber.js +0 -311
  98. package/src/accounts/pollingOracleSubscriber.js +0 -93
  99. package/src/accounts/pollingTokenAccountSubscriber.js +0 -90
  100. package/src/accounts/pollingUserAccountSubscriber.js +0 -132
  101. package/src/accounts/types.js +0 -10
  102. package/src/accounts/utils.js +0 -7
  103. package/src/accounts/webSocketAccountSubscriber.js +0 -93
  104. package/src/accounts/webSocketClearingHouseAccountSubscriber.js +0 -233
  105. package/src/accounts/webSocketUserAccountSubscriber.js +0 -62
  106. package/src/addresses/pda.js +0 -104
  107. package/src/index.js +0 -100
  108. package/src/math/bankBalance.js +0 -75
  109. package/src/math/market.js +0 -57
  110. package/src/math/orders.js +0 -110
  111. package/src/math/position.js +0 -140
  112. package/src/mockUSDCFaucet.js +0 -280
  113. package/src/orders.js +0 -134
  114. package/src/tx/retryTxSender.js +0 -188
@@ -49,6 +49,11 @@ export declare class ClearingHouseUser {
49
49
  getOrderByUserOrderId(userOrderId: number): Order | undefined;
50
50
  getUserAccountPublicKey(): PublicKey;
51
51
  exists(): Promise<boolean>;
52
+ /**
53
+ * calculates the market position if the lp position was settled
54
+ * @returns : userPosition
55
+ */
56
+ getSettledLPPosition(marketIndex: BN): [UserPosition, BN];
52
57
  /**
53
58
  * calculates Buying Power = FC * MAX_LEVERAGE
54
59
  * @returns : Precision QUOTE_PRECISION
@@ -61,48 +66,43 @@ export declare class ClearingHouseUser {
61
66
  getFreeCollateral(): BN;
62
67
  getInitialMarginRequirement(): BN;
63
68
  /**
64
- * @returns The partial margin requirement in USDC. : QUOTE_PRECISION
69
+ * @returns The maintenance margin requirement in USDC. : QUOTE_PRECISION
65
70
  */
66
71
  getMaintenanceMarginRequirement(): BN;
67
72
  /**
68
73
  * calculates unrealized position price pnl
69
74
  * @returns : Precision QUOTE_PRECISION
70
75
  */
71
- getUnrealizedPNL(withFunding?: boolean, marketIndex?: BN): BN;
72
- /**
73
- * calculates unrealized position price pnl
74
- * @returns : Precision QUOTE_PRECISION
75
- */
76
- getUnsettledPNL(marketIndex?: BN): BN;
76
+ getUnrealizedPNL(withFunding?: boolean, marketIndex?: BN, withWeightMarginCategory?: MarginCategory): BN;
77
77
  /**
78
78
  * calculates unrealized funding payment pnl
79
79
  * @returns : Precision QUOTE_PRECISION
80
80
  */
81
81
  getUnrealizedFundingPNL(marketIndex?: BN): BN;
82
- getTotalLiability(): BN;
83
- getCollateralValue(bankIndex?: BN): BN;
82
+ getBankLiabilityValue(bankIndex?: BN, withWeightMarginCategory?: MarginCategory): BN;
83
+ getBankAssetValue(bankIndex?: BN, withWeightMarginCategory?: MarginCategory): BN;
84
+ getNetBankValue(withWeightMarginCategory?: MarginCategory): BN;
84
85
  /**
85
86
  * calculates TotalCollateral: collateral + unrealized pnl
86
- * TODO: rename to total equity (for perpetuals swaps)
87
87
  * @returns : Precision QUOTE_PRECISION
88
88
  */
89
- getTotalCollateral(): BN;
89
+ getTotalCollateral(marginCategory?: MarginCategory): BN;
90
90
  /**
91
- * calculates sum of position value across all positions
91
+ * calculates sum of position value across all positions in margin system
92
92
  * @returns : Precision QUOTE_PRECISION
93
93
  */
94
94
  getTotalPositionValue(): BN;
95
95
  /**
96
- * calculates position value from closing 100%
96
+ * calculates position value in margin system
97
97
  * @returns : Precision QUOTE_PRECISION
98
98
  */
99
99
  getPositionValue(marketIndex: BN, oraclePriceData: OraclePriceData): BN;
100
100
  getPositionSide(currentPosition: Pick<UserPosition, 'baseAssetAmount'>): PositionDirection | undefined;
101
101
  /**
102
- * calculates average exit price for closing 100% of position
102
+ * calculates average exit price (optionally for closing up to 100% of position)
103
103
  * @returns : Precision MARK_PRICE_PRECISION
104
104
  */
105
- getPositionEstimatedExitPriceAndPnl(position: UserPosition, amountToClose?: BN): [BN, BN];
105
+ getPositionEstimatedExitPriceAndPnl(position: UserPosition, amountToClose?: BN, useAMMClose?: boolean): [BN, BN];
106
106
  /**
107
107
  * calculates current user leverage across all positions
108
108
  * @returns : Precision TEN_THOUSAND
@@ -6,6 +6,7 @@ const position_1 = require("./math/position");
6
6
  const numericConstants_1 = require("./constants/numericConstants");
7
7
  const _1 = require(".");
8
8
  const bankBalance_1 = require("./math/bankBalance");
9
+ const margin_1 = require("./math/margin");
9
10
  const pollingUserAccountSubscriber_1 = require("./accounts/pollingUserAccountSubscriber");
10
11
  const webSocketUserAccountSubscriber_1 = require("./accounts/webSocketUserAccountSubscriber");
11
12
  class ClearingHouseUser {
@@ -68,9 +69,13 @@ class ClearingHouseUser {
68
69
  quoteAssetAmount: numericConstants_1.ZERO,
69
70
  quoteEntryAmount: numericConstants_1.ZERO,
70
71
  openOrders: numericConstants_1.ZERO,
71
- unsettledPnl: numericConstants_1.ZERO,
72
72
  openBids: numericConstants_1.ZERO,
73
73
  openAsks: numericConstants_1.ZERO,
74
+ realizedPnl: numericConstants_1.ZERO,
75
+ lpShares: numericConstants_1.ZERO,
76
+ lastFeePerLp: numericConstants_1.ZERO,
77
+ lastNetBaseAssetAmountPerLp: numericConstants_1.ZERO,
78
+ lastNetQuoteAssetAmountPerLp: numericConstants_1.ZERO,
74
79
  };
75
80
  }
76
81
  /**
@@ -94,6 +99,89 @@ class ClearingHouseUser {
94
99
  const userAccountRPCResponse = await this.clearingHouse.connection.getParsedAccountInfo(this.userAccountPublicKey);
95
100
  return userAccountRPCResponse.value !== null;
96
101
  }
102
+ /**
103
+ * calculates the market position if the lp position was settled
104
+ * @returns : userPosition
105
+ */
106
+ getSettledLPPosition(marketIndex) {
107
+ const position = this.getUserPosition(marketIndex);
108
+ const market = this.clearingHouse.getMarketAccount(position.marketIndex);
109
+ const nShares = position.lpShares;
110
+ const deltaBaa = market.amm.marketPositionPerLp.baseAssetAmount
111
+ .sub(position.lastNetBaseAssetAmountPerLp)
112
+ .mul(nShares)
113
+ .div(numericConstants_1.AMM_RESERVE_PRECISION);
114
+ const deltaQaa = market.amm.marketPositionPerLp.quoteAssetAmount
115
+ .sub(position.lastNetQuoteAssetAmountPerLp)
116
+ .mul(nShares)
117
+ .div(numericConstants_1.AMM_RESERVE_PRECISION);
118
+ function sign(v) {
119
+ const sign = { true: new _1.BN(1), false: new _1.BN(-1) }[v.gte(numericConstants_1.ZERO).toString()];
120
+ return sign;
121
+ }
122
+ const remainder = deltaBaa
123
+ .abs()
124
+ .mod(market.amm.baseAssetAmountStepSize)
125
+ .mul(sign(deltaBaa));
126
+ const _standardizedBaa = deltaBaa.sub(remainder);
127
+ let remainderBaa;
128
+ if (_standardizedBaa.abs().gte(market.amm.baseAssetAmountStepSize)) {
129
+ remainderBaa = remainder;
130
+ }
131
+ else {
132
+ remainderBaa = deltaBaa;
133
+ }
134
+ const standardizedBaa = deltaBaa.sub(remainderBaa);
135
+ const reaminderPerLP = remainderBaa.mul(numericConstants_1.AMM_RESERVE_PRECISION).div(nShares);
136
+ position.baseAssetAmount = position.baseAssetAmount.add(standardizedBaa);
137
+ position.quoteAssetAmount = position.quoteAssetAmount.add(deltaQaa);
138
+ position.lastNetBaseAssetAmountPerLp =
139
+ market.amm.marketPositionPerLp.baseAssetAmount.sub(reaminderPerLP);
140
+ let updateType;
141
+ if (position.baseAssetAmount.eq(numericConstants_1.ZERO)) {
142
+ updateType = 'open';
143
+ }
144
+ else if (sign(position.baseAssetAmount).eq(sign(deltaBaa))) {
145
+ updateType = 'increase';
146
+ }
147
+ else if (position.baseAssetAmount.abs().gt(deltaBaa.abs())) {
148
+ updateType = 'reduce';
149
+ }
150
+ else if (position.baseAssetAmount.abs().eq(deltaBaa.abs())) {
151
+ updateType = 'close';
152
+ }
153
+ else {
154
+ updateType = 'flip';
155
+ }
156
+ let newQuoteEntry;
157
+ let pnl;
158
+ if (updateType == 'open' || updateType == 'increase') {
159
+ newQuoteEntry = position.quoteEntryAmount.add(deltaQaa);
160
+ pnl = 0;
161
+ }
162
+ else if (updateType == 'reduce' || updateType == 'close') {
163
+ newQuoteEntry = position.quoteEntryAmount.sub(position.quoteEntryAmount
164
+ .mul(deltaBaa.abs())
165
+ .div(position.baseAssetAmount.abs()));
166
+ pnl = position.quoteEntryAmount.sub(newQuoteEntry);
167
+ }
168
+ else {
169
+ newQuoteEntry = deltaQaa.sub(deltaQaa.mul(position.baseAssetAmount.abs()).div(deltaBaa.abs()));
170
+ pnl = position.quoteEntryAmount.add(deltaQaa.sub(newQuoteEntry));
171
+ }
172
+ position.quoteEntryAmount = newQuoteEntry;
173
+ if (position.baseAssetAmount.gt(numericConstants_1.ZERO)) {
174
+ position.lastCumulativeFundingRate = market.amm.cumulativeFundingRateLong;
175
+ }
176
+ else if (position.baseAssetAmount.lt(numericConstants_1.ZERO)) {
177
+ position.lastCumulativeFundingRate =
178
+ market.amm.cumulativeFundingRateShort;
179
+ }
180
+ else {
181
+ position.lastCumulativeFundingRate = numericConstants_1.ZERO;
182
+ }
183
+ return [position, pnl];
184
+ }
97
185
  /**
98
186
  * calculates Buying Power = FC * MAX_LEVERAGE
99
187
  * @returns : Precision QUOTE_PRECISION
@@ -114,49 +202,55 @@ class ClearingHouseUser {
114
202
  return freeCollateral.gte(numericConstants_1.ZERO) ? freeCollateral : numericConstants_1.ZERO;
115
203
  }
116
204
  getInitialMarginRequirement() {
117
- return this.getUserAccount()
118
- .positions.reduce((marginRequirement, marketPosition) => {
205
+ const postionMarginRequirement = this.getUserAccount().positions.reduce((marginRequirement, marketPosition) => {
119
206
  const market = this.clearingHouse.getMarketAccount(marketPosition.marketIndex);
120
- return marginRequirement.add((0, _1.calculateBaseAssetValue)(market, marketPosition, this.getOracleDataForMarket(market.marketIndex))
121
- .mul(new _1.BN(market.marginRatioInitial))
122
- .div(numericConstants_1.MARGIN_PRECISION));
123
- }, numericConstants_1.ZERO)
124
- .add(this.getTotalLiability());
207
+ const worstCaseBaseAssetAmount = (0, margin_1.calculateWorstCaseBaseAssetAmount)(marketPosition);
208
+ const worstCaseAssetValue = worstCaseBaseAssetAmount
209
+ .abs()
210
+ .mul(this.getOracleDataForMarket(market.marketIndex).price)
211
+ .div(numericConstants_1.AMM_TO_QUOTE_PRECISION_RATIO.mul(numericConstants_1.MARK_PRICE_PRECISION));
212
+ const marketMarginRatio = new _1.BN((0, _1.calculateMarketMarginRatio)(market, worstCaseBaseAssetAmount.abs(), 'Initial'));
213
+ return marginRequirement.add(worstCaseAssetValue.mul(marketMarginRatio).div(numericConstants_1.MARGIN_PRECISION));
214
+ }, numericConstants_1.ZERO);
215
+ const bankMarginRequirement = this.getBankLiabilityValue(undefined, 'Initial');
216
+ return bankMarginRequirement.add(postionMarginRequirement);
125
217
  }
126
218
  /**
127
- * @returns The partial margin requirement in USDC. : QUOTE_PRECISION
219
+ * @returns The maintenance margin requirement in USDC. : QUOTE_PRECISION
128
220
  */
129
221
  getMaintenanceMarginRequirement() {
130
222
  return this.getUserAccount()
131
223
  .positions.reduce((marginRequirement, marketPosition) => {
132
224
  const market = this.clearingHouse.getMarketAccount(marketPosition.marketIndex);
133
- return marginRequirement.add((0, _1.calculateBaseAssetValue)(market, marketPosition, this.getOracleDataForMarket(market.marketIndex))
134
- .mul(new _1.BN(market.marginRatioMaintenance))
225
+ const worstCaseBaseAssetAmount = (0, margin_1.calculateWorstCaseBaseAssetAmount)(marketPosition);
226
+ const worstCaseAssetValue = worstCaseBaseAssetAmount
227
+ .abs()
228
+ .mul(this.getOracleDataForMarket(market.marketIndex).price)
229
+ .div(numericConstants_1.AMM_TO_QUOTE_PRECISION_RATIO.mul(numericConstants_1.MARK_PRICE_PRECISION));
230
+ return marginRequirement.add(worstCaseAssetValue
231
+ .mul(new _1.BN((0, _1.calculateMarketMarginRatio)(market, worstCaseBaseAssetAmount.abs(), 'Maintenance')))
135
232
  .div(numericConstants_1.MARGIN_PRECISION));
136
233
  }, numericConstants_1.ZERO)
137
- .add(this.getTotalLiability());
234
+ .add(this.getBankLiabilityValue(undefined, 'Maintenance'));
138
235
  }
139
236
  /**
140
237
  * calculates unrealized position price pnl
141
238
  * @returns : Precision QUOTE_PRECISION
142
239
  */
143
- getUnrealizedPNL(withFunding, marketIndex) {
240
+ getUnrealizedPNL(withFunding, marketIndex, withWeightMarginCategory) {
144
241
  return this.getUserAccount()
145
242
  .positions.filter((pos) => marketIndex ? pos.marketIndex === marketIndex : true)
146
243
  .reduce((pnl, marketPosition) => {
147
244
  const market = this.clearingHouse.getMarketAccount(marketPosition.marketIndex);
148
- return pnl.add((0, _1.calculatePositionPNL)(market, marketPosition, withFunding, this.getOracleDataForMarket(market.marketIndex)));
149
- }, numericConstants_1.ZERO);
150
- }
151
- /**
152
- * calculates unrealized position price pnl
153
- * @returns : Precision QUOTE_PRECISION
154
- */
155
- getUnsettledPNL(marketIndex) {
156
- return this.getUserAccount()
157
- .positions.filter((pos) => marketIndex ? pos.marketIndex === marketIndex : true)
158
- .reduce((pnl, marketPosition) => {
159
- return pnl.add(marketPosition.unsettledPnl);
245
+ let pnl0 = (0, _1.calculatePositionPNL)(market, marketPosition, withFunding, this.getOracleDataForMarket(market.marketIndex));
246
+ if (withWeightMarginCategory !== undefined) {
247
+ if (pnl0.gt(numericConstants_1.ZERO)) {
248
+ pnl0 = pnl0
249
+ .mul((0, _1.calculateUnsettledAssetWeight)(market, pnl0, withWeightMarginCategory))
250
+ .div(new _1.BN(numericConstants_1.BANK_WEIGHT_PRECISION));
251
+ }
252
+ }
253
+ return pnl.add(pnl0);
160
254
  }, numericConstants_1.ZERO);
161
255
  }
162
256
  /**
@@ -171,45 +265,58 @@ class ClearingHouseUser {
171
265
  return pnl.add((0, _1.calculatePositionFundingPNL)(market, marketPosition));
172
266
  }, numericConstants_1.ZERO);
173
267
  }
174
- getTotalLiability() {
175
- return this.getUserAccount().bankBalances.reduce((totalAssetValue, bankBalance) => {
268
+ getBankLiabilityValue(bankIndex, withWeightMarginCategory) {
269
+ return this.getUserAccount().bankBalances.reduce((totalLiabilityValue, bankBalance) => {
176
270
  if (bankBalance.balance.eq(numericConstants_1.ZERO) ||
177
- (0, types_1.isVariant)(bankBalance.balanceType, 'deposit')) {
178
- return totalAssetValue;
271
+ (0, types_1.isVariant)(bankBalance.balanceType, 'deposit') ||
272
+ (bankIndex !== undefined && !bankBalance.bankIndex.eq(bankIndex))) {
273
+ return totalLiabilityValue;
179
274
  }
180
275
  // Todo this needs to account for whether it's based on initial or maintenance requirements
181
276
  const bankAccount = this.clearingHouse.getBankAccount(bankBalance.bankIndex);
182
277
  const tokenAmount = (0, bankBalance_1.getTokenAmount)(bankBalance.balance, bankAccount, bankBalance.balanceType);
183
- return totalAssetValue.add(tokenAmount
278
+ let liabilityValue = tokenAmount
184
279
  .mul(this.getOracleDataForBank(bankAccount.bankIndex).price)
185
- .mul(bankAccount.initialLiabilityWeight)
186
- .div(numericConstants_1.BANK_WEIGHT_PRECISION)
187
- .div(numericConstants_1.MARK_PRICE_PRECISION));
280
+ .div(numericConstants_1.MARK_PRICE_PRECISION)
281
+ .div(new _1.BN(10).pow(new _1.BN(bankAccount.decimals).sub(numericConstants_1.BANK_BALANCE_PRECISION_EXP)));
282
+ if (withWeightMarginCategory !== undefined) {
283
+ const weight = (0, bankBalance_1.calculateLiabilityWeight)(tokenAmount, bankAccount, withWeightMarginCategory);
284
+ liabilityValue = liabilityValue
285
+ .mul(weight)
286
+ .div(numericConstants_1.BANK_WEIGHT_PRECISION);
287
+ }
288
+ return totalLiabilityValue.add(liabilityValue);
188
289
  }, numericConstants_1.ZERO);
189
290
  }
190
- getCollateralValue(bankIndex) {
291
+ getBankAssetValue(bankIndex, withWeightMarginCategory) {
191
292
  return this.getUserAccount().bankBalances.reduce((totalAssetValue, bankBalance) => {
192
293
  if (bankBalance.balance.eq(numericConstants_1.ZERO) ||
294
+ (0, types_1.isVariant)(bankBalance.balanceType, 'borrow') ||
193
295
  (bankIndex !== undefined && !bankBalance.bankIndex.eq(bankIndex))) {
194
296
  return totalAssetValue;
195
297
  }
196
298
  // Todo this needs to account for whether it's based on initial or maintenance requirements
197
299
  const bankAccount = this.clearingHouse.getBankAccount(bankBalance.bankIndex);
198
- let tokenAmount = (0, bankBalance_1.getTokenAmount)(bankBalance.balance, bankAccount, bankBalance.balanceType);
199
- if ((0, types_1.isVariant)(bankBalance.balanceType, 'borrow')) {
200
- tokenAmount = tokenAmount.mul(new _1.BN(-1));
201
- }
202
- return totalAssetValue.add(tokenAmount
300
+ const tokenAmount = (0, bankBalance_1.getTokenAmount)(bankBalance.balance, bankAccount, bankBalance.balanceType);
301
+ let assetValue = tokenAmount
203
302
  .mul(this.getOracleDataForBank(bankAccount.bankIndex).price)
204
- .div(numericConstants_1.MARK_PRICE_PRECISION));
303
+ .div(numericConstants_1.MARK_PRICE_PRECISION)
304
+ .div(new _1.BN(10).pow(new _1.BN(bankAccount.decimals).sub(numericConstants_1.BANK_BALANCE_PRECISION_EXP)));
305
+ if (withWeightMarginCategory !== undefined) {
306
+ const weight = (0, bankBalance_1.calculateAssetWeight)(tokenAmount, bankAccount, withWeightMarginCategory);
307
+ assetValue = assetValue.mul(weight).div(numericConstants_1.BANK_WEIGHT_PRECISION);
308
+ }
309
+ return totalAssetValue.add(assetValue);
205
310
  }, numericConstants_1.ZERO);
206
311
  }
312
+ getNetBankValue(withWeightMarginCategory) {
313
+ return this.getBankAssetValue(undefined, withWeightMarginCategory).sub(this.getBankLiabilityValue(undefined, withWeightMarginCategory));
314
+ }
207
315
  /**
208
316
  * calculates TotalCollateral: collateral + unrealized pnl
209
- * TODO: rename to total equity (for perpetuals swaps)
210
317
  * @returns : Precision QUOTE_PRECISION
211
318
  */
212
- getTotalCollateral() {
319
+ getTotalCollateral(marginCategory = 'Initial') {
213
320
  return this.getUserAccount()
214
321
  .bankBalances.reduce((totalAssetValue, bankBalance) => {
215
322
  if (bankBalance.balance.eq(numericConstants_1.ZERO) ||
@@ -219,33 +326,36 @@ class ClearingHouseUser {
219
326
  // Todo this needs to account for whether it's based on initial or maintenance requirements
220
327
  const bankAccount = this.clearingHouse.getBankAccount(bankBalance.bankIndex);
221
328
  const tokenAmount = (0, bankBalance_1.getTokenAmount)(bankBalance.balance, bankAccount, bankBalance.balanceType);
329
+ const weight = (0, bankBalance_1.calculateAssetWeight)(tokenAmount, bankAccount, marginCategory);
222
330
  return totalAssetValue.add(tokenAmount
223
331
  .mul(this.getOracleDataForBank(bankAccount.bankIndex).price)
224
- .mul(bankAccount.initialAssetWeight)
332
+ .mul(weight)
225
333
  .div(numericConstants_1.BANK_WEIGHT_PRECISION)
226
- .div(numericConstants_1.MARK_PRICE_PRECISION));
334
+ .div(numericConstants_1.MARK_PRICE_PRECISION)
335
+ // Adjust for decimals of bank account
336
+ .div(new _1.BN(10).pow(new _1.BN(bankAccount.decimals).sub(numericConstants_1.BANK_BALANCE_PRECISION_EXP))));
227
337
  }, numericConstants_1.ZERO)
228
- .add(this.getUnrealizedPNL(true))
229
- .add(this.getUnsettledPNL());
338
+ .add(this.getUnrealizedPNL(true, undefined, marginCategory));
230
339
  }
231
340
  /**
232
- * calculates sum of position value across all positions
341
+ * calculates sum of position value across all positions in margin system
233
342
  * @returns : Precision QUOTE_PRECISION
234
343
  */
235
344
  getTotalPositionValue() {
236
345
  return this.getUserAccount().positions.reduce((positionValue, marketPosition) => {
237
346
  const market = this.clearingHouse.getMarketAccount(marketPosition.marketIndex);
238
- return positionValue.add((0, _1.calculateBaseAssetValue)(market, marketPosition, this.getOracleDataForMarket(market.marketIndex)));
347
+ const posVal = (0, margin_1.calculateMarginBaseAssetValue)(market, marketPosition, this.getOracleDataForMarket(market.marketIndex));
348
+ return positionValue.add(posVal);
239
349
  }, numericConstants_1.ZERO);
240
350
  }
241
351
  /**
242
- * calculates position value from closing 100%
352
+ * calculates position value in margin system
243
353
  * @returns : Precision QUOTE_PRECISION
244
354
  */
245
355
  getPositionValue(marketIndex, oraclePriceData) {
246
356
  const userPosition = this.getUserPosition(marketIndex) || this.getEmptyPosition(marketIndex);
247
357
  const market = this.clearingHouse.getMarketAccount(userPosition.marketIndex);
248
- return (0, _1.calculateBaseAssetValue)(market, userPosition, oraclePriceData);
358
+ return (0, margin_1.calculateMarginBaseAssetValue)(market, userPosition, oraclePriceData);
249
359
  }
250
360
  getPositionSide(currentPosition) {
251
361
  if (currentPosition.baseAssetAmount.gt(numericConstants_1.ZERO)) {
@@ -259,10 +369,10 @@ class ClearingHouseUser {
259
369
  }
260
370
  }
261
371
  /**
262
- * calculates average exit price for closing 100% of position
372
+ * calculates average exit price (optionally for closing up to 100% of position)
263
373
  * @returns : Precision MARK_PRICE_PRECISION
264
374
  */
265
- getPositionEstimatedExitPriceAndPnl(position, amountToClose) {
375
+ getPositionEstimatedExitPriceAndPnl(position, amountToClose, useAMMClose = false) {
266
376
  const market = this.clearingHouse.getMarketAccount(position.marketIndex);
267
377
  const entryPrice = (0, position_1.calculateEntryPrice)(position);
268
378
  const oraclePriceData = this.getOracleDataForMarket(position.marketIndex);
@@ -277,7 +387,13 @@ class ClearingHouseUser {
277
387
  quoteAssetAmount: position.quoteAssetAmount,
278
388
  };
279
389
  }
280
- const baseAssetValue = (0, _1.calculateBaseAssetValue)(market, position, oraclePriceData);
390
+ let baseAssetValue;
391
+ if (useAMMClose) {
392
+ baseAssetValue = (0, _1.calculateBaseAssetValue)(market, position, oraclePriceData);
393
+ }
394
+ else {
395
+ baseAssetValue = (0, margin_1.calculateMarginBaseAssetValue)(market, position, oraclePriceData);
396
+ }
281
397
  if (position.baseAssetAmount.eq(numericConstants_1.ZERO)) {
282
398
  return [numericConstants_1.ZERO, numericConstants_1.ZERO];
283
399
  }
@@ -311,18 +427,10 @@ class ClearingHouseUser {
311
427
  */
312
428
  getMaxLeverage(marketIndex, category = 'Initial') {
313
429
  const market = this.clearingHouse.getMarketAccount(marketIndex);
314
- let marginRatioCategory;
315
- switch (category) {
316
- case 'Initial':
317
- marginRatioCategory = market.marginRatioInitial;
318
- break;
319
- case 'Maintenance':
320
- marginRatioCategory = market.marginRatioMaintenance;
321
- break;
322
- default:
323
- marginRatioCategory = market.marginRatioInitial;
324
- break;
325
- }
430
+ const marginRatioCategory = (0, _1.calculateMarketMarginRatio)(market,
431
+ // worstCaseBaseAssetAmount.abs(),
432
+ numericConstants_1.ZERO, // todo
433
+ category);
326
434
  const maxLeverage = numericConstants_1.TEN_THOUSAND.mul(numericConstants_1.TEN_THOUSAND).div(new _1.BN(marginRatioCategory));
327
435
  return maxLeverage;
328
436
  }
@@ -391,26 +499,30 @@ class ClearingHouseUser {
391
499
  const proposedMarketPosition = {
392
500
  marketIndex: marketPosition.marketIndex,
393
501
  baseAssetAmount: proposedBaseAssetAmount,
394
- lastCumulativeFundingRate: currentMarketPosition.lastCumulativeFundingRate,
395
502
  quoteAssetAmount: new _1.BN(0),
503
+ lastCumulativeFundingRate: numericConstants_1.ZERO,
396
504
  quoteEntryAmount: new _1.BN(0),
397
505
  openOrders: new _1.BN(0),
398
- unsettledPnl: new _1.BN(0),
399
506
  openBids: new _1.BN(0),
400
507
  openAsks: new _1.BN(0),
508
+ realizedPnl: numericConstants_1.ZERO,
509
+ lpShares: numericConstants_1.ZERO,
510
+ lastFeePerLp: numericConstants_1.ZERO,
511
+ lastNetBaseAssetAmountPerLp: numericConstants_1.ZERO,
512
+ lastNetQuoteAssetAmountPerLp: numericConstants_1.ZERO,
401
513
  };
402
514
  if (proposedBaseAssetAmount.eq(numericConstants_1.ZERO))
403
515
  return new _1.BN(-1);
404
516
  const market = this.clearingHouse.getMarketAccount(proposedMarketPosition.marketIndex);
405
- const proposedMarketPositionValue = (0, _1.calculateBaseAssetValue)(market, proposedMarketPosition, this.getOracleDataForMarket(market.marketIndex));
517
+ const proposedMarketPositionValue = (0, margin_1.calculateMarginBaseAssetValue)(market, proposedMarketPosition, this.getOracleDataForMarket(market.marketIndex));
406
518
  // total position value after trade
407
519
  const totalPositionValueAfterTrade = totalPositionValueExcludingTargetMarket.add(proposedMarketPositionValue);
408
520
  const marginRequirementExcludingTargetMarket = this.getUserAccount().positions.reduce((totalMarginRequirement, position) => {
409
521
  if (!position.marketIndex.eq(marketPosition.marketIndex)) {
410
522
  const market = this.clearingHouse.getMarketAccount(position.marketIndex);
411
- const positionValue = (0, _1.calculateBaseAssetValue)(market, position, this.getOracleDataForMarket(market.marketIndex));
523
+ const positionValue = (0, margin_1.calculateMarginBaseAssetValue)(market, position, this.getOracleDataForMarket(market.marketIndex));
412
524
  const marketMarginRequirement = positionValue
413
- .mul(new _1.BN(market.marginRatioMaintenance))
525
+ .mul(new _1.BN((0, _1.calculateMarketMarginRatio)(market, position.baseAssetAmount.abs(), 'Maintenance')))
414
526
  .div(numericConstants_1.MARGIN_PRECISION);
415
527
  totalMarginRequirement = totalMarginRequirement.add(marketMarginRequirement);
416
528
  }
@@ -423,7 +535,7 @@ class ClearingHouseUser {
423
535
  return new _1.BN(-1);
424
536
  }
425
537
  const marginRequirementAfterTrade = marginRequirementExcludingTargetMarket.add(proposedMarketPositionValue
426
- .mul(new _1.BN(market.marginRatioMaintenance))
538
+ .mul(new _1.BN((0, _1.calculateMarketMarginRatio)(market, proposedMarketPosition.baseAssetAmount.abs(), 'Maintenance')))
427
539
  .div(numericConstants_1.MARGIN_PRECISION));
428
540
  const freeCollateralAfterTrade = totalCollateral.sub(marginRequirementAfterTrade);
429
541
  const marketMaxLeverage = this.getMaxLeverage(proposedMarketPosition.marketIndex, 'Maintenance');
@@ -470,10 +582,10 @@ class ClearingHouseUser {
470
582
  this.getEmptyPosition(positionMarketIndex);
471
583
  const closeBaseAmount = currentPosition.baseAssetAmount
472
584
  .mul(closeQuoteAmount)
473
- .div(currentPosition.quoteAssetAmount)
585
+ .div(currentPosition.quoteAssetAmount.abs())
474
586
  .add(currentPosition.baseAssetAmount
475
587
  .mul(closeQuoteAmount)
476
- .mod(currentPosition.quoteAssetAmount))
588
+ .mod(currentPosition.quoteAssetAmount.abs()))
477
589
  .neg();
478
590
  return this.liquidationPrice({
479
591
  marketIndex: positionMarketIndex,
@@ -0,0 +1,17 @@
1
+ import { ClearingHouse } from './clearingHouse';
2
+ import { PublicKey } from '@solana/web3.js';
3
+ import { DataAndSlot, UserStatsAccountSubscriber } from './accounts/types';
4
+ import { ClearingHouseUserStatsConfig } from './clearingHouseUserStatsConfig';
5
+ import { UserStatsAccount } from './types';
6
+ export declare class ClearingHouseUserStats {
7
+ clearingHouse: ClearingHouse;
8
+ userStatsAccountPublicKey: PublicKey;
9
+ accountSubscriber: UserStatsAccountSubscriber;
10
+ isSubscribed: boolean;
11
+ constructor(config: ClearingHouseUserStatsConfig);
12
+ subscribe(): Promise<boolean>;
13
+ fetchAccounts(): Promise<void>;
14
+ unsubscribe(): Promise<void>;
15
+ getAccountAndSlot(): DataAndSlot<UserStatsAccount>;
16
+ getAccount(): UserStatsAccount;
17
+ }
@@ -0,0 +1,36 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.ClearingHouseUserStats = void 0;
4
+ const pollingUserStatsAccountSubscriber_1 = require("./accounts/pollingUserStatsAccountSubscriber");
5
+ const webSocketUserStatsAccountSubsriber_1 = require("./accounts/webSocketUserStatsAccountSubsriber");
6
+ class ClearingHouseUserStats {
7
+ constructor(config) {
8
+ var _a;
9
+ this.clearingHouse = config.clearingHouse;
10
+ this.userStatsAccountPublicKey = config.userStatsAccountPublicKey;
11
+ if (((_a = config.accountSubscription) === null || _a === void 0 ? void 0 : _a.type) === 'polling') {
12
+ this.accountSubscriber = new pollingUserStatsAccountSubscriber_1.PollingUserStatsAccountSubscriber(config.clearingHouse.program, config.userStatsAccountPublicKey, config.accountSubscription.accountLoader);
13
+ }
14
+ else {
15
+ this.accountSubscriber = new webSocketUserStatsAccountSubsriber_1.WebSocketUserStatsAccountSubscriber(config.clearingHouse.program, config.userStatsAccountPublicKey);
16
+ }
17
+ }
18
+ async subscribe() {
19
+ this.isSubscribed = await this.accountSubscriber.subscribe();
20
+ return this.isSubscribed;
21
+ }
22
+ async fetchAccounts() {
23
+ await this.accountSubscriber.fetch();
24
+ }
25
+ async unsubscribe() {
26
+ await this.accountSubscriber.unsubscribe();
27
+ this.isSubscribed = false;
28
+ }
29
+ getAccountAndSlot() {
30
+ return this.accountSubscriber.getUserStatsAccountAndSlot();
31
+ }
32
+ getAccount() {
33
+ return this.accountSubscriber.getUserStatsAccountAndSlot().data;
34
+ }
35
+ }
36
+ exports.ClearingHouseUserStats = ClearingHouseUserStats;
@@ -0,0 +1,14 @@
1
+ import { ClearingHouse } from './clearingHouse';
2
+ import { PublicKey } from '@solana/web3.js';
3
+ import { BulkAccountLoader } from './accounts/bulkAccountLoader';
4
+ export declare type ClearingHouseUserStatsConfig = {
5
+ accountSubscription?: ClearingHouseUserStatsAccountSubscriptionConfig;
6
+ clearingHouse: ClearingHouse;
7
+ userStatsAccountPublicKey: PublicKey;
8
+ };
9
+ export declare type ClearingHouseUserStatsAccountSubscriptionConfig = {
10
+ type: 'websocket';
11
+ } | {
12
+ type: 'polling';
13
+ accountLoader: BulkAccountLoader;
14
+ };
@@ -0,0 +1,2 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
package/lib/config.js CHANGED
@@ -7,7 +7,7 @@ exports.configs = {
7
7
  devnet: {
8
8
  ENV: 'devnet',
9
9
  PYTH_ORACLE_MAPPING_ADDRESS: 'BmA9Z6FjioHJPpjT39QazZyhDRUdZy2ezwx4GiDdE2u2',
10
- CLEARING_HOUSE_PROGRAM_ID: '4oyTJnAQ9FqJj1y9mPytbWsLeeHmBzGYfuFqypwyQvuh',
10
+ CLEARING_HOUSE_PROGRAM_ID: 'D9bW92Maa1yDigJqvabRgr5S5VybPNDB5xxSpQD6mkkV',
11
11
  USDC_MINT_ADDRESS: '8zGuJQqwhZafTah7Uc7Z4tXRnguqkn5KLFAP8oV6PHe2',
12
12
  MARKETS: markets_1.DevnetMarkets,
13
13
  BANKS: banks_1.DevnetBanks,
@@ -1,7 +1,6 @@
1
1
  /// <reference types="bn.js" />
2
- import { BN, OracleSource } from '../';
3
- import { DriftEnv } from '../';
4
2
  import { PublicKey } from '@solana/web3.js';
3
+ import { BN, DriftEnv, OracleSource } from '../';
5
4
  export declare type BankConfig = {
6
5
  symbol: string;
7
6
  bankIndex: BN;
@@ -9,6 +8,7 @@ export declare type BankConfig = {
9
8
  mint: PublicKey;
10
9
  oracleSource: OracleSource;
11
10
  };
11
+ export declare const WRAPPED_SOL_MINT: PublicKey;
12
12
  export declare const DevnetBanks: BankConfig[];
13
13
  export declare const MainnetBanks: BankConfig[];
14
14
  export declare const Banks: {
@@ -1,8 +1,9 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.Banks = exports.MainnetBanks = exports.DevnetBanks = void 0;
4
- const __1 = require("../");
3
+ exports.Banks = exports.MainnetBanks = exports.DevnetBanks = exports.WRAPPED_SOL_MINT = void 0;
5
4
  const web3_js_1 = require("@solana/web3.js");
5
+ const __1 = require("../");
6
+ exports.WRAPPED_SOL_MINT = new web3_js_1.PublicKey('So11111111111111111111111111111111111111112');
6
7
  exports.DevnetBanks = [
7
8
  {
8
9
  symbol: 'USDC',
@@ -16,7 +17,7 @@ exports.DevnetBanks = [
16
17
  bankIndex: new __1.BN(1),
17
18
  oracle: new web3_js_1.PublicKey('J83w4HKfqxwcq3BEMMkPFSppX3gqekLyLJBexebFVkix'),
18
19
  oracleSource: __1.OracleSource.PYTH,
19
- mint: new web3_js_1.PublicKey('So11111111111111111111111111111111111111112'),
20
+ mint: new web3_js_1.PublicKey(exports.WRAPPED_SOL_MINT),
20
21
  },
21
22
  {
22
23
  symbol: 'BTC',
@@ -21,6 +21,8 @@ export declare const BANK_RATE_PRECISION: BN;
21
21
  export declare const BANK_WEIGHT_PRECISION: BN;
22
22
  export declare const BANK_BALANCE_PRECISION_EXP: BN;
23
23
  export declare const BANK_BALANCE_PRECISION: BN;
24
+ export declare const BANK_IMF_PRECISION_EXP: BN;
25
+ export declare const BANK_IMF_PRECISION: BN;
24
26
  export declare const LIQUIDATION_FEE_PRECISION: BN;
25
27
  export declare const QUOTE_PRECISION: BN;
26
28
  export declare const MARK_PRICE_PRECISION: BN;
@@ -1,6 +1,6 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.QUOTE_ASSET_BANK_INDEX = exports.ONE_YEAR = exports.BID_ASK_SPREAD_PRECISION = exports.MARGIN_PRECISION = exports.AMM_TIMES_PEG_TO_QUOTE_PRECISION_RATIO = exports.PRICE_TO_QUOTE_PRECISION = exports.PRICE_DIV_PEG = exports.AMM_TO_QUOTE_PRECISION_RATIO = exports.BASE_PRECISION_EXP = exports.BASE_PRECISION = exports.AMM_RESERVE_PRECISION = exports.PEG_PRECISION = exports.FUNDING_PAYMENT_PRECISION = exports.MARK_PRICE_PRECISION = exports.QUOTE_PRECISION = exports.LIQUIDATION_FEE_PRECISION = exports.BANK_BALANCE_PRECISION = exports.BANK_BALANCE_PRECISION_EXP = exports.BANK_WEIGHT_PRECISION = exports.BANK_RATE_PRECISION = exports.BANK_UTILIZATION_PRECISION = exports.BANK_CUMULATIVE_INTEREST_PRECISION = exports.BANK_INTEREST_PRECISION = exports.AMM_RESERVE_PRECISION_EXP = exports.PEG_PRECISION_EXP = exports.FUNDING_RATE_PRECISION_EXP = exports.MARK_PRICE_PRECISION_EXP = exports.FUNDING_PAYMENT_PRECISION_EXP = exports.QUOTE_PRECISION_EXP = exports.MAX_LEVERAGE = exports.TEN_MILLION = exports.BN_MAX = exports.TEN_THOUSAND = exports.TEN = exports.TWO = exports.ONE = exports.ZERO = void 0;
3
+ exports.QUOTE_ASSET_BANK_INDEX = exports.ONE_YEAR = exports.BID_ASK_SPREAD_PRECISION = exports.MARGIN_PRECISION = exports.AMM_TIMES_PEG_TO_QUOTE_PRECISION_RATIO = exports.PRICE_TO_QUOTE_PRECISION = exports.PRICE_DIV_PEG = exports.AMM_TO_QUOTE_PRECISION_RATIO = exports.BASE_PRECISION_EXP = exports.BASE_PRECISION = exports.AMM_RESERVE_PRECISION = exports.PEG_PRECISION = exports.FUNDING_PAYMENT_PRECISION = exports.MARK_PRICE_PRECISION = exports.QUOTE_PRECISION = exports.LIQUIDATION_FEE_PRECISION = exports.BANK_IMF_PRECISION = exports.BANK_IMF_PRECISION_EXP = exports.BANK_BALANCE_PRECISION = exports.BANK_BALANCE_PRECISION_EXP = exports.BANK_WEIGHT_PRECISION = exports.BANK_RATE_PRECISION = exports.BANK_UTILIZATION_PRECISION = exports.BANK_CUMULATIVE_INTEREST_PRECISION = exports.BANK_INTEREST_PRECISION = exports.AMM_RESERVE_PRECISION_EXP = exports.PEG_PRECISION_EXP = exports.FUNDING_RATE_PRECISION_EXP = exports.MARK_PRICE_PRECISION_EXP = exports.FUNDING_PAYMENT_PRECISION_EXP = exports.QUOTE_PRECISION_EXP = exports.MAX_LEVERAGE = exports.TEN_MILLION = exports.BN_MAX = exports.TEN_THOUSAND = exports.TEN = exports.TWO = exports.ONE = exports.ZERO = void 0;
4
4
  const __1 = require("../");
5
5
  exports.ZERO = new __1.BN(0);
6
6
  exports.ONE = new __1.BN(1);
@@ -23,6 +23,8 @@ exports.BANK_RATE_PRECISION = new __1.BN(1000000);
23
23
  exports.BANK_WEIGHT_PRECISION = new __1.BN(100);
24
24
  exports.BANK_BALANCE_PRECISION_EXP = new __1.BN(6);
25
25
  exports.BANK_BALANCE_PRECISION = new __1.BN(10).pow(exports.BANK_BALANCE_PRECISION_EXP);
26
+ exports.BANK_IMF_PRECISION_EXP = new __1.BN(6);
27
+ exports.BANK_IMF_PRECISION = new __1.BN(10).pow(exports.BANK_IMF_PRECISION_EXP);
26
28
  exports.LIQUIDATION_FEE_PRECISION = new __1.BN(1000000);
27
29
  exports.QUOTE_PRECISION = new __1.BN(10).pow(exports.QUOTE_PRECISION_EXP);
28
30
  exports.MARK_PRICE_PRECISION = new __1.BN(10).pow(exports.MARK_PRICE_PRECISION_EXP);