@drift-labs/sdk 0.2.0-master.1 → 0.2.0-master.12

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 (142) hide show
  1. package/lib/accounts/types.d.ts +1 -0
  2. package/lib/admin.d.ts +8 -5
  3. package/lib/admin.js +43 -11
  4. package/lib/clearingHouse.d.ts +35 -20
  5. package/lib/clearingHouse.js +497 -154
  6. package/lib/clearingHouseUser.d.ts +12 -17
  7. package/lib/clearingHouseUser.js +97 -88
  8. package/lib/config.js +1 -1
  9. package/lib/constants/banks.d.ts +2 -2
  10. package/lib/constants/banks.js +12 -4
  11. package/lib/constants/numericConstants.d.ts +4 -0
  12. package/lib/constants/numericConstants.js +5 -1
  13. package/lib/events/eventList.js +3 -0
  14. package/lib/events/types.d.ts +2 -1
  15. package/lib/factory/bigNum.d.ts +9 -2
  16. package/lib/factory/bigNum.js +50 -16
  17. package/lib/idl/clearing_house.json +858 -177
  18. package/lib/idl/{mock_usdc_faucet.json → token_faucet.json} +46 -23
  19. package/lib/index.d.ts +4 -2
  20. package/lib/index.js +8 -2
  21. package/lib/math/amm.d.ts +6 -1
  22. package/lib/math/amm.js +124 -41
  23. package/lib/math/auction.js +4 -1
  24. package/lib/math/bankBalance.d.ts +3 -1
  25. package/lib/math/bankBalance.js +54 -1
  26. package/lib/math/margin.d.ts +11 -0
  27. package/lib/math/margin.js +72 -0
  28. package/lib/math/market.d.ts +4 -1
  29. package/lib/math/market.js +35 -1
  30. package/lib/math/orders.d.ts +2 -2
  31. package/lib/math/orders.js +18 -11
  32. package/lib/math/position.d.ts +8 -0
  33. package/lib/math/position.js +44 -12
  34. package/lib/math/repeg.js +1 -1
  35. package/lib/math/trade.d.ts +1 -1
  36. package/lib/math/trade.js +7 -10
  37. package/lib/orderParams.d.ts +14 -5
  38. package/lib/orderParams.js +8 -96
  39. package/lib/orders.d.ts +2 -4
  40. package/lib/orders.js +7 -161
  41. package/lib/slot/SlotSubscriber.d.ts +7 -0
  42. package/lib/slot/SlotSubscriber.js +3 -0
  43. package/lib/{mockUSDCFaucet.d.ts → tokenFaucet.d.ts} +8 -5
  44. package/lib/{mockUSDCFaucet.js → tokenFaucet.js} +63 -51
  45. package/lib/tx/retryTxSender.js +9 -2
  46. package/lib/tx/utils.js +1 -1
  47. package/lib/types.d.ts +159 -15
  48. package/lib/types.js +59 -1
  49. package/lib/util/computeUnits.js +1 -1
  50. package/lib/util/getTokenAddress.d.ts +2 -0
  51. package/lib/util/getTokenAddress.js +9 -0
  52. package/package.json +3 -3
  53. package/src/accounts/bulkAccountLoader.js +197 -0
  54. package/src/accounts/bulkUserSubscription.js +33 -0
  55. package/src/accounts/pollingClearingHouseAccountSubscriber.js +311 -0
  56. package/src/accounts/pollingOracleSubscriber.js +93 -0
  57. package/src/accounts/pollingTokenAccountSubscriber.js +90 -0
  58. package/src/accounts/pollingUserAccountSubscriber.js +132 -0
  59. package/src/accounts/types.js +10 -0
  60. package/src/accounts/utils.js +7 -0
  61. package/src/accounts/webSocketAccountSubscriber.js +93 -0
  62. package/src/accounts/webSocketClearingHouseAccountSubscriber.js +233 -0
  63. package/src/accounts/webSocketUserAccountSubscriber.js +62 -0
  64. package/src/addresses/marketAddresses.js +26 -0
  65. package/src/admin.ts +66 -14
  66. package/src/assert/assert.js +9 -0
  67. package/src/clearingHouse.ts +836 -254
  68. package/src/clearingHouseConfig.js +2 -0
  69. package/src/clearingHouseUser.ts +219 -121
  70. package/src/clearingHouseUserConfig.js +2 -0
  71. package/src/config.ts +1 -1
  72. package/src/constants/banks.js +42 -0
  73. package/src/constants/banks.ts +14 -4
  74. package/src/constants/markets.js +42 -0
  75. package/src/constants/numericConstants.js +41 -0
  76. package/src/constants/numericConstants.ts +5 -0
  77. package/src/events/eventList.js +77 -0
  78. package/src/events/eventList.ts +3 -0
  79. package/src/events/eventSubscriber.js +139 -0
  80. package/src/events/fetchLogs.js +50 -0
  81. package/src/events/pollingLogProvider.js +64 -0
  82. package/src/events/sort.js +44 -0
  83. package/src/events/txEventCache.js +71 -0
  84. package/src/events/types.js +20 -0
  85. package/src/events/types.ts +2 -0
  86. package/src/events/webSocketLogProvider.js +41 -0
  87. package/src/examples/makeTradeExample.js +80 -0
  88. package/src/factory/bigNum.js +390 -0
  89. package/src/factory/bigNum.ts +65 -18
  90. package/src/factory/oracleClient.js +20 -0
  91. package/src/idl/clearing_house.json +858 -177
  92. package/src/idl/{mock_usdc_faucet.json → token_faucet.json} +46 -23
  93. package/src/index.js +69 -0
  94. package/src/index.ts +4 -2
  95. package/src/math/amm.js +369 -0
  96. package/src/math/amm.ts +207 -52
  97. package/src/math/auction.js +42 -0
  98. package/src/math/auction.ts +5 -1
  99. package/src/math/bankBalance.ts +98 -1
  100. package/src/math/conversion.js +11 -0
  101. package/src/math/funding.js +248 -0
  102. package/src/math/margin.ts +124 -0
  103. package/src/math/market.ts +66 -1
  104. package/src/math/oracles.js +26 -0
  105. package/src/math/orders.ts +17 -13
  106. package/src/math/position.ts +63 -9
  107. package/src/math/repeg.js +128 -0
  108. package/src/math/repeg.ts +2 -1
  109. package/src/math/state.js +15 -0
  110. package/src/math/trade.js +253 -0
  111. package/src/math/trade.ts +23 -25
  112. package/src/math/utils.js +0 -1
  113. package/src/mockUSDCFaucet.js +280 -0
  114. package/src/oracles/oracleClientCache.js +19 -0
  115. package/src/oracles/pythClient.js +46 -0
  116. package/src/oracles/quoteAssetOracleClient.js +32 -0
  117. package/src/oracles/switchboardClient.js +69 -0
  118. package/src/oracles/types.js +2 -0
  119. package/src/orderParams.js +20 -0
  120. package/src/orderParams.ts +20 -141
  121. package/src/orders.ts +10 -287
  122. package/src/slot/SlotSubscriber.js +39 -0
  123. package/src/slot/SlotSubscriber.ts +11 -1
  124. package/src/token/index.js +38 -0
  125. package/src/tokenFaucet.js +189 -0
  126. package/src/{mockUSDCFaucet.ts → tokenFaucet.ts} +82 -70
  127. package/src/tx/retryTxSender.ts +11 -3
  128. package/src/tx/types.js +2 -0
  129. package/src/tx/utils.js +17 -0
  130. package/src/tx/utils.ts +1 -1
  131. package/src/types.js +125 -0
  132. package/src/types.ts +155 -17
  133. package/src/userName.js +20 -0
  134. package/src/util/computeUnits.js +21 -11
  135. package/src/util/computeUnits.ts +1 -1
  136. package/src/util/getTokenAddress.js +9 -0
  137. package/src/util/getTokenAddress.ts +18 -0
  138. package/src/util/promiseTimeout.js +14 -0
  139. package/src/util/tps.js +27 -0
  140. package/src/wallet.js +35 -0
  141. package/tests/bn/test.ts +2 -0
  142. package/src/util/computeUnits.js.map +0 -1
@@ -0,0 +1,2 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
@@ -21,6 +21,7 @@ import {
21
21
  PRICE_TO_QUOTE_PRECISION,
22
22
  MARGIN_PRECISION,
23
23
  BANK_WEIGHT_PRECISION,
24
+ BANK_BALANCE_PRECISION_EXP,
24
25
  } from './constants/numericConstants';
25
26
  import {
26
27
  UserAccountSubscriber,
@@ -32,12 +33,22 @@ import {
32
33
  calculateBaseAssetValue,
33
34
  calculatePositionFundingPNL,
34
35
  calculatePositionPNL,
36
+ calculateUnsettledAssetWeight,
37
+ calculateMarketMarginRatio,
35
38
  PositionDirection,
36
39
  calculateTradeSlippage,
37
40
  BN,
38
41
  BankAccount,
39
42
  } from '.';
40
- import { getTokenAmount } from './math/bankBalance';
43
+ import {
44
+ getTokenAmount,
45
+ calculateAssetWeight,
46
+ calculateLiabilityWeight,
47
+ } from './math/bankBalance';
48
+ import {
49
+ calculateMarginBaseAssetValue,
50
+ calculateWorstCaseBaseAssetAmount,
51
+ } from './math/margin';
41
52
  import { OraclePriceData } from './oracles/types';
42
53
  import { ClearingHouseUserConfig } from './clearingHouseUserConfig';
43
54
  import { PollingUserAccountSubscriber } from './accounts/pollingUserAccountSubscriber';
@@ -124,7 +135,6 @@ export class ClearingHouseUser {
124
135
  quoteAssetAmount: ZERO,
125
136
  quoteEntryAmount: ZERO,
126
137
  openOrders: ZERO,
127
- unsettledPnl: ZERO,
128
138
  openBids: ZERO,
129
139
  openAsks: ZERO,
130
140
  };
@@ -184,51 +194,84 @@ export class ClearingHouseUser {
184
194
  }
185
195
 
186
196
  public getInitialMarginRequirement(): BN {
187
- return this.getUserAccount()
188
- .positions.reduce((marginRequirement, marketPosition) => {
197
+ const postionMarginRequirement = this.getUserAccount().positions.reduce(
198
+ (marginRequirement, marketPosition) => {
189
199
  const market = this.clearingHouse.getMarketAccount(
190
200
  marketPosition.marketIndex
191
201
  );
192
- return marginRequirement.add(
193
- calculateBaseAssetValue(
202
+ const worstCaseBaseAssetAmount =
203
+ calculateWorstCaseBaseAssetAmount(marketPosition);
204
+
205
+ const worstCaseAssetValue = worstCaseBaseAssetAmount
206
+ .abs()
207
+ .mul(this.getOracleDataForMarket(market.marketIndex).price)
208
+ .div(AMM_TO_QUOTE_PRECISION_RATIO.mul(MARK_PRICE_PRECISION));
209
+
210
+ const marketMarginRatio = new BN(
211
+ calculateMarketMarginRatio(
194
212
  market,
195
- marketPosition,
196
- this.getOracleDataForMarket(market.marketIndex)
213
+ worstCaseBaseAssetAmount.abs(),
214
+ 'Initial'
197
215
  )
198
- .mul(new BN(market.marginRatioInitial))
199
- .div(MARGIN_PRECISION)
200
216
  );
201
- }, ZERO)
202
- .add(this.getTotalLiability());
217
+ return marginRequirement.add(
218
+ worstCaseAssetValue.mul(marketMarginRatio).div(MARGIN_PRECISION)
219
+ );
220
+ },
221
+ ZERO
222
+ );
223
+
224
+ const bankMarginRequirement = this.getBankLiabilityValue(
225
+ undefined,
226
+ 'Initial'
227
+ );
228
+
229
+ return bankMarginRequirement.add(postionMarginRequirement);
203
230
  }
204
231
 
205
232
  /**
206
- * @returns The partial margin requirement in USDC. : QUOTE_PRECISION
233
+ * @returns The maintenance margin requirement in USDC. : QUOTE_PRECISION
207
234
  */
208
- public getPartialMarginRequirement(): BN {
235
+ public getMaintenanceMarginRequirement(): BN {
209
236
  return this.getUserAccount()
210
237
  .positions.reduce((marginRequirement, marketPosition) => {
211
238
  const market = this.clearingHouse.getMarketAccount(
212
239
  marketPosition.marketIndex
213
240
  );
241
+ const worstCaseBaseAssetAmount =
242
+ calculateWorstCaseBaseAssetAmount(marketPosition);
243
+
244
+ const worstCaseAssetValue = worstCaseBaseAssetAmount
245
+ .abs()
246
+ .mul(this.getOracleDataForMarket(market.marketIndex).price)
247
+ .div(AMM_TO_QUOTE_PRECISION_RATIO.mul(MARK_PRICE_PRECISION));
248
+
214
249
  return marginRequirement.add(
215
- calculateBaseAssetValue(
216
- market,
217
- marketPosition,
218
- this.getOracleDataForMarket(market.marketIndex)
219
- )
220
- .mul(new BN(market.marginRatioPartial))
250
+ worstCaseAssetValue
251
+ .mul(
252
+ new BN(
253
+ calculateMarketMarginRatio(
254
+ market,
255
+ worstCaseBaseAssetAmount.abs(),
256
+ 'Maintenance'
257
+ )
258
+ )
259
+ )
221
260
  .div(MARGIN_PRECISION)
222
261
  );
223
262
  }, ZERO)
224
- .add(this.getTotalLiability());
263
+ .add(this.getBankLiabilityValue(undefined, 'Maintenance'));
225
264
  }
226
265
 
227
266
  /**
228
267
  * calculates unrealized position price pnl
229
268
  * @returns : Precision QUOTE_PRECISION
230
269
  */
231
- public getUnrealizedPNL(withFunding?: boolean, marketIndex?: BN): BN {
270
+ public getUnrealizedPNL(
271
+ withFunding?: boolean,
272
+ marketIndex?: BN,
273
+ withWeightMarginCategory?: MarginCategory
274
+ ): BN {
232
275
  return this.getUserAccount()
233
276
  .positions.filter((pos) =>
234
277
  marketIndex ? pos.marketIndex === marketIndex : true
@@ -237,28 +280,28 @@ export class ClearingHouseUser {
237
280
  const market = this.clearingHouse.getMarketAccount(
238
281
  marketPosition.marketIndex
239
282
  );
240
- return pnl.add(
241
- calculatePositionPNL(
242
- market,
243
- marketPosition,
244
- withFunding,
245
- this.getOracleDataForMarket(market.marketIndex)
246
- )
283
+ let pnl0 = calculatePositionPNL(
284
+ market,
285
+ marketPosition,
286
+ withFunding,
287
+ this.getOracleDataForMarket(market.marketIndex)
247
288
  );
248
- }, ZERO);
249
- }
250
289
 
251
- /**
252
- * calculates unrealized position price pnl
253
- * @returns : Precision QUOTE_PRECISION
254
- */
255
- public getUnsettledPNL(marketIndex?: BN): BN {
256
- return this.getUserAccount()
257
- .positions.filter((pos) =>
258
- marketIndex ? pos.marketIndex === marketIndex : true
259
- )
260
- .reduce((pnl, marketPosition) => {
261
- return pnl.add(marketPosition.unsettledPnl);
290
+ if (withWeightMarginCategory !== undefined) {
291
+ if (pnl0.gt(ZERO)) {
292
+ pnl0 = pnl0
293
+ .mul(
294
+ calculateUnsettledAssetWeight(
295
+ market,
296
+ pnl0,
297
+ withWeightMarginCategory
298
+ )
299
+ )
300
+ .div(new BN(BANK_WEIGHT_PRECISION));
301
+ }
302
+ }
303
+
304
+ return pnl.add(pnl0);
262
305
  }, ZERO);
263
306
  }
264
307
 
@@ -279,14 +322,18 @@ export class ClearingHouseUser {
279
322
  }, ZERO);
280
323
  }
281
324
 
282
- public getTotalLiability(): BN {
325
+ public getBankLiabilityValue(
326
+ bankIndex?: BN,
327
+ withWeightMarginCategory?: MarginCategory
328
+ ): BN {
283
329
  return this.getUserAccount().bankBalances.reduce(
284
- (totalAssetValue, bankBalance) => {
330
+ (totalLiabilityValue, bankBalance) => {
285
331
  if (
286
332
  bankBalance.balance.eq(ZERO) ||
287
- isVariant(bankBalance.balanceType, 'deposit')
333
+ isVariant(bankBalance.balanceType, 'deposit') ||
334
+ (bankIndex !== undefined && !bankBalance.bankIndex.eq(bankIndex))
288
335
  ) {
289
- return totalAssetValue;
336
+ return totalLiabilityValue;
290
337
  }
291
338
 
292
339
  // Todo this needs to account for whether it's based on initial or maintenance requirements
@@ -299,23 +346,42 @@ export class ClearingHouseUser {
299
346
  bankAccount,
300
347
  bankBalance.balanceType
301
348
  );
302
- return totalAssetValue.add(
303
- tokenAmount
304
- .mul(this.getOracleDataForBank(bankAccount.bankIndex).price)
305
- .mul(bankAccount.initialLiabilityWeight)
306
- .div(BANK_WEIGHT_PRECISION)
307
- .div(MARK_PRICE_PRECISION)
308
- );
349
+
350
+ let liabilityValue = tokenAmount
351
+ .mul(this.getOracleDataForBank(bankAccount.bankIndex).price)
352
+ .div(MARK_PRICE_PRECISION)
353
+ .div(
354
+ new BN(10).pow(
355
+ new BN(bankAccount.decimals).sub(BANK_BALANCE_PRECISION_EXP)
356
+ )
357
+ );
358
+
359
+ if (withWeightMarginCategory !== undefined) {
360
+ const weight = calculateLiabilityWeight(
361
+ tokenAmount,
362
+ bankAccount,
363
+ withWeightMarginCategory
364
+ );
365
+ liabilityValue = liabilityValue
366
+ .mul(weight)
367
+ .div(BANK_WEIGHT_PRECISION);
368
+ }
369
+
370
+ return totalLiabilityValue.add(liabilityValue);
309
371
  },
310
372
  ZERO
311
373
  );
312
374
  }
313
375
 
314
- public getCollateralValue(bankIndex?: BN): BN {
376
+ public getBankAssetValue(
377
+ bankIndex?: BN,
378
+ withWeightMarginCategory?: MarginCategory
379
+ ): BN {
315
380
  return this.getUserAccount().bankBalances.reduce(
316
381
  (totalAssetValue, bankBalance) => {
317
382
  if (
318
383
  bankBalance.balance.eq(ZERO) ||
384
+ isVariant(bankBalance.balanceType, 'borrow') ||
319
385
  (bankIndex !== undefined && !bankBalance.bankIndex.eq(bankIndex))
320
386
  ) {
321
387
  return totalAssetValue;
@@ -326,32 +392,46 @@ export class ClearingHouseUser {
326
392
  bankBalance.bankIndex
327
393
  );
328
394
 
329
- let tokenAmount = getTokenAmount(
395
+ const tokenAmount = getTokenAmount(
330
396
  bankBalance.balance,
331
397
  bankAccount,
332
398
  bankBalance.balanceType
333
399
  );
334
400
 
335
- if (isVariant(bankBalance.balanceType, 'borrow')) {
336
- tokenAmount = tokenAmount.mul(new BN(-1));
401
+ let assetValue = tokenAmount
402
+ .mul(this.getOracleDataForBank(bankAccount.bankIndex).price)
403
+ .div(MARK_PRICE_PRECISION)
404
+ .div(
405
+ new BN(10).pow(
406
+ new BN(bankAccount.decimals).sub(BANK_BALANCE_PRECISION_EXP)
407
+ )
408
+ );
409
+ if (withWeightMarginCategory !== undefined) {
410
+ const weight = calculateAssetWeight(
411
+ tokenAmount,
412
+ bankAccount,
413
+ withWeightMarginCategory
414
+ );
415
+ assetValue = assetValue.mul(weight).div(BANK_WEIGHT_PRECISION);
337
416
  }
338
417
 
339
- return totalAssetValue.add(
340
- tokenAmount
341
- .mul(this.getOracleDataForBank(bankAccount.bankIndex).price)
342
- .div(MARK_PRICE_PRECISION)
343
- );
418
+ return totalAssetValue.add(assetValue);
344
419
  },
345
420
  ZERO
346
421
  );
347
422
  }
348
423
 
424
+ public getNetBankValue(withWeightMarginCategory?: MarginCategory): BN {
425
+ return this.getBankAssetValue(undefined, withWeightMarginCategory).sub(
426
+ this.getBankLiabilityValue(undefined, withWeightMarginCategory)
427
+ );
428
+ }
429
+
349
430
  /**
350
431
  * calculates TotalCollateral: collateral + unrealized pnl
351
- * TODO: rename to total equity (for perpetuals swaps)
352
432
  * @returns : Precision QUOTE_PRECISION
353
433
  */
354
- public getTotalCollateral(): BN {
434
+ public getTotalCollateral(marginCategory: MarginCategory = 'Initial'): BN {
355
435
  return this.getUserAccount()
356
436
  .bankBalances.reduce((totalAssetValue, bankBalance) => {
357
437
  if (
@@ -371,20 +451,32 @@ export class ClearingHouseUser {
371
451
  bankAccount,
372
452
  bankBalance.balanceType
373
453
  );
454
+
455
+ const weight = calculateAssetWeight(
456
+ tokenAmount,
457
+ bankAccount,
458
+ marginCategory
459
+ );
460
+
374
461
  return totalAssetValue.add(
375
462
  tokenAmount
376
463
  .mul(this.getOracleDataForBank(bankAccount.bankIndex).price)
377
- .mul(bankAccount.initialAssetWeight)
464
+ .mul(weight)
378
465
  .div(BANK_WEIGHT_PRECISION)
379
466
  .div(MARK_PRICE_PRECISION)
467
+ // Adjust for decimals of bank account
468
+ .div(
469
+ new BN(10).pow(
470
+ new BN(bankAccount.decimals).sub(BANK_BALANCE_PRECISION_EXP)
471
+ )
472
+ )
380
473
  );
381
474
  }, ZERO)
382
- .add(this.getUnrealizedPNL(true))
383
- .add(this.getUnsettledPNL());
475
+ .add(this.getUnrealizedPNL(true, undefined, marginCategory));
384
476
  }
385
477
 
386
478
  /**
387
- * calculates sum of position value across all positions
479
+ * calculates sum of position value across all positions in margin system
388
480
  * @returns : Precision QUOTE_PRECISION
389
481
  */
390
482
  getTotalPositionValue(): BN {
@@ -393,20 +485,20 @@ export class ClearingHouseUser {
393
485
  const market = this.clearingHouse.getMarketAccount(
394
486
  marketPosition.marketIndex
395
487
  );
396
- return positionValue.add(
397
- calculateBaseAssetValue(
398
- market,
399
- marketPosition,
400
- this.getOracleDataForMarket(market.marketIndex)
401
- )
488
+ const posVal = calculateMarginBaseAssetValue(
489
+ market,
490
+ marketPosition,
491
+ this.getOracleDataForMarket(market.marketIndex)
402
492
  );
493
+
494
+ return positionValue.add(posVal);
403
495
  },
404
496
  ZERO
405
497
  );
406
498
  }
407
499
 
408
500
  /**
409
- * calculates position value from closing 100%
501
+ * calculates position value in margin system
410
502
  * @returns : Precision QUOTE_PRECISION
411
503
  */
412
504
  public getPositionValue(
@@ -418,7 +510,7 @@ export class ClearingHouseUser {
418
510
  const market = this.clearingHouse.getMarketAccount(
419
511
  userPosition.marketIndex
420
512
  );
421
- return calculateBaseAssetValue(market, userPosition, oraclePriceData);
513
+ return calculateMarginBaseAssetValue(market, userPosition, oraclePriceData);
422
514
  }
423
515
 
424
516
  public getPositionSide(
@@ -434,12 +526,13 @@ export class ClearingHouseUser {
434
526
  }
435
527
 
436
528
  /**
437
- * calculates average exit price for closing 100% of position
529
+ * calculates average exit price (optionally for closing up to 100% of position)
438
530
  * @returns : Precision MARK_PRICE_PRECISION
439
531
  */
440
532
  public getPositionEstimatedExitPriceAndPnl(
441
533
  position: UserPosition,
442
- amountToClose?: BN
534
+ amountToClose?: BN,
535
+ useAMMClose = false
443
536
  ): [BN, BN] {
444
537
  const market = this.clearingHouse.getMarketAccount(position.marketIndex);
445
538
 
@@ -459,11 +552,21 @@ export class ClearingHouseUser {
459
552
  } as UserPosition;
460
553
  }
461
554
 
462
- const baseAssetValue = calculateBaseAssetValue(
463
- market,
464
- position,
465
- oraclePriceData
466
- );
555
+ let baseAssetValue: BN;
556
+
557
+ if (useAMMClose) {
558
+ baseAssetValue = calculateBaseAssetValue(
559
+ market,
560
+ position,
561
+ oraclePriceData
562
+ );
563
+ } else {
564
+ baseAssetValue = calculateMarginBaseAssetValue(
565
+ market,
566
+ position,
567
+ oraclePriceData
568
+ );
569
+ }
467
570
  if (position.baseAssetAmount.eq(ZERO)) {
468
571
  return [ZERO, ZERO];
469
572
  }
@@ -505,22 +608,13 @@ export class ClearingHouseUser {
505
608
  category: MarginCategory = 'Initial'
506
609
  ): BN {
507
610
  const market = this.clearingHouse.getMarketAccount(marketIndex);
508
- let marginRatioCategory: number;
509
-
510
- switch (category) {
511
- case 'Initial':
512
- marginRatioCategory = market.marginRatioInitial;
513
- break;
514
- case 'Maintenance':
515
- marginRatioCategory = market.marginRatioMaintenance;
516
- break;
517
- case 'Partial':
518
- marginRatioCategory = market.marginRatioPartial;
519
- break;
520
- default:
521
- marginRatioCategory = market.marginRatioInitial;
522
- break;
523
- }
611
+
612
+ const marginRatioCategory = calculateMarketMarginRatio(
613
+ market,
614
+ // worstCaseBaseAssetAmount.abs(),
615
+ ZERO, // todo
616
+ category
617
+ );
524
618
  const maxLeverage = TEN_THOUSAND.mul(TEN_THOUSAND).div(
525
619
  new BN(marginRatioCategory)
526
620
  );
@@ -543,7 +637,8 @@ export class ClearingHouseUser {
543
637
 
544
638
  public canBeLiquidated(): [boolean, BN] {
545
639
  const totalCollateral = this.getTotalCollateral();
546
- const partialMaintenanceRequirement = this.getPartialMarginRequirement();
640
+ const partialMaintenanceRequirement =
641
+ this.getMaintenanceMarginRequirement();
547
642
  const marginRatio = this.getMarginRatio();
548
643
  const canLiquidate = totalCollateral.lt(partialMaintenanceRequirement);
549
644
  return [canLiquidate, marginRatio];
@@ -587,8 +682,7 @@ export class ClearingHouseUser {
587
682
  */
588
683
  public liquidationPrice(
589
684
  marketPosition: Pick<UserPosition, 'marketIndex'>,
590
- positionBaseSizeChange: BN = ZERO,
591
- partial = false
685
+ positionBaseSizeChange: BN = ZERO
592
686
  ): BN {
593
687
  // solves formula for example canBeLiquidated below
594
688
 
@@ -627,7 +721,6 @@ export class ClearingHouseUser {
627
721
  quoteAssetAmount: new BN(0),
628
722
  quoteEntryAmount: new BN(0),
629
723
  openOrders: new BN(0),
630
- unsettledPnl: new BN(0),
631
724
  openBids: new BN(0),
632
725
  openAsks: new BN(0),
633
726
  };
@@ -638,7 +731,7 @@ export class ClearingHouseUser {
638
731
  proposedMarketPosition.marketIndex
639
732
  );
640
733
 
641
- const proposedMarketPositionValue = calculateBaseAssetValue(
734
+ const proposedMarketPositionValue = calculateMarginBaseAssetValue(
642
735
  market,
643
736
  proposedMarketPosition,
644
737
  this.getOracleDataForMarket(market.marketIndex)
@@ -655,18 +748,19 @@ export class ClearingHouseUser {
655
748
  const market = this.clearingHouse.getMarketAccount(
656
749
  position.marketIndex
657
750
  );
658
- const positionValue = calculateBaseAssetValue(
751
+ const positionValue = calculateMarginBaseAssetValue(
659
752
  market,
660
753
  position,
661
754
  this.getOracleDataForMarket(market.marketIndex)
662
755
  );
663
- const marketMarginRequirement = positionValue
664
- .mul(
665
- partial
666
- ? new BN(market.marginRatioPartial)
667
- : new BN(market.marginRatioMaintenance)
756
+ const marketMarginRequirement = positionValue;
757
+ new BN(
758
+ calculateMarketMarginRatio(
759
+ market,
760
+ position.baseAssetAmount.abs(),
761
+ 'Maintenance'
668
762
  )
669
- .div(MARGIN_PRECISION);
763
+ ).div(MARGIN_PRECISION);
670
764
  totalMarginRequirement = totalMarginRequirement.add(
671
765
  marketMarginRequirement
672
766
  );
@@ -692,9 +786,13 @@ export class ClearingHouseUser {
692
786
  marginRequirementExcludingTargetMarket.add(
693
787
  proposedMarketPositionValue
694
788
  .mul(
695
- partial
696
- ? new BN(market.marginRatioPartial)
697
- : new BN(market.marginRatioMaintenance)
789
+ new BN(
790
+ calculateMarketMarginRatio(
791
+ market,
792
+ proposedMarketPosition.baseAssetAmount.abs(),
793
+ 'Maintenance'
794
+ )
795
+ )
698
796
  )
699
797
  .div(MARGIN_PRECISION)
700
798
  );
@@ -702,9 +800,10 @@ export class ClearingHouseUser {
702
800
  marginRequirementAfterTrade
703
801
  );
704
802
 
705
- const marketMaxLeverage = partial
706
- ? this.getMaxLeverage(proposedMarketPosition.marketIndex, 'Partial')
707
- : this.getMaxLeverage(proposedMarketPosition.marketIndex, 'Maintenance');
803
+ const marketMaxLeverage = this.getMaxLeverage(
804
+ proposedMarketPosition.marketIndex,
805
+ 'Maintenance'
806
+ );
708
807
 
709
808
  let priceDelta;
710
809
  if (proposedBaseAssetAmount.lt(ZERO)) {
@@ -765,11 +864,11 @@ export class ClearingHouseUser {
765
864
 
766
865
  const closeBaseAmount = currentPosition.baseAssetAmount
767
866
  .mul(closeQuoteAmount)
768
- .div(currentPosition.quoteAssetAmount)
867
+ .div(currentPosition.quoteAssetAmount.abs())
769
868
  .add(
770
869
  currentPosition.baseAssetAmount
771
870
  .mul(closeQuoteAmount)
772
- .mod(currentPosition.quoteAssetAmount)
871
+ .mod(currentPosition.quoteAssetAmount.abs())
773
872
  )
774
873
  .neg();
775
874
 
@@ -777,8 +876,7 @@ export class ClearingHouseUser {
777
876
  {
778
877
  marketIndex: positionMarketIndex,
779
878
  },
780
- closeBaseAmount,
781
- true
879
+ closeBaseAmount
782
880
  );
783
881
  }
784
882
 
@@ -0,0 +1,2 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
package/src/config.ts CHANGED
@@ -28,7 +28,7 @@ export const configs: { [key in DriftEnv]: DriftConfig } = {
28
28
  devnet: {
29
29
  ENV: 'devnet',
30
30
  PYTH_ORACLE_MAPPING_ADDRESS: 'BmA9Z6FjioHJPpjT39QazZyhDRUdZy2ezwx4GiDdE2u2',
31
- CLEARING_HOUSE_PROGRAM_ID: 'GCuH76fb1rXc7bjFXNcnNvWSekLgzpsnMbc1Ng4FsGSs',
31
+ CLEARING_HOUSE_PROGRAM_ID: '7HDuhZ94TVTWpH3vba3dJhGWyHvQuy2zBjniRxE7PU88',
32
32
  USDC_MINT_ADDRESS: '8zGuJQqwhZafTah7Uc7Z4tXRnguqkn5KLFAP8oV6PHe2',
33
33
  MARKETS: DevnetMarkets,
34
34
  BANKS: DevnetBanks,
@@ -0,0 +1,42 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.Banks = exports.MainnetBanks = exports.DevnetBanks = exports.WRAPPED_SOL_MINT = void 0;
4
+ const web3_js_1 = require("@solana/web3.js");
5
+ const __1 = require("../");
6
+ exports.WRAPPED_SOL_MINT = new web3_js_1.PublicKey('So11111111111111111111111111111111111111112');
7
+ exports.DevnetBanks = [
8
+ {
9
+ symbol: 'USDC',
10
+ bankIndex: new __1.BN(0),
11
+ oracle: web3_js_1.PublicKey.default,
12
+ oracleSource: __1.OracleSource.QUOTE_ASSET,
13
+ mint: new web3_js_1.PublicKey('8zGuJQqwhZafTah7Uc7Z4tXRnguqkn5KLFAP8oV6PHe2'),
14
+ },
15
+ {
16
+ symbol: 'SOL',
17
+ bankIndex: new __1.BN(1),
18
+ oracle: new web3_js_1.PublicKey('J83w4HKfqxwcq3BEMMkPFSppX3gqekLyLJBexebFVkix'),
19
+ oracleSource: __1.OracleSource.PYTH,
20
+ mint: new web3_js_1.PublicKey(exports.WRAPPED_SOL_MINT),
21
+ },
22
+ {
23
+ symbol: 'BTC',
24
+ bankIndex: new __1.BN(2),
25
+ oracle: new web3_js_1.PublicKey('HovQMDrbAgAYPCmHVSrezcSmkMtXSSUsLDFANExrZh2J'),
26
+ oracleSource: __1.OracleSource.PYTH,
27
+ mint: new web3_js_1.PublicKey('3BZPwbcqB5kKScF3TEXxwNfx5ipV13kbRVDvfVp5c6fv'),
28
+ },
29
+ ];
30
+ exports.MainnetBanks = [
31
+ {
32
+ symbol: 'USDC',
33
+ bankIndex: new __1.BN(0),
34
+ oracle: web3_js_1.PublicKey.default,
35
+ oracleSource: __1.OracleSource.QUOTE_ASSET,
36
+ mint: new web3_js_1.PublicKey('EPjFWdd5AufqSSqeM2qN1xzybapC8G4wEGGkZwyTDt1v'),
37
+ },
38
+ ];
39
+ exports.Banks = {
40
+ devnet: exports.DevnetBanks,
41
+ 'mainnet-beta': exports.MainnetBanks,
42
+ };
@@ -1,6 +1,5 @@
1
- import { BN, OracleSource } from '../';
2
- import { DriftEnv } from '../';
3
1
  import { PublicKey } from '@solana/web3.js';
2
+ import { BN, DriftEnv, OracleSource } from '../';
4
3
 
5
4
  export type BankConfig = {
6
5
  symbol: string;
@@ -10,6 +9,10 @@ export type BankConfig = {
10
9
  oracleSource: OracleSource;
11
10
  };
12
11
 
12
+ export const WRAPPED_SOL_MINT = new PublicKey(
13
+ 'So11111111111111111111111111111111111111112'
14
+ );
15
+
13
16
  export const DevnetBanks: BankConfig[] = [
14
17
  {
15
18
  symbol: 'USDC',
@@ -19,11 +22,18 @@ export const DevnetBanks: BankConfig[] = [
19
22
  mint: new PublicKey('8zGuJQqwhZafTah7Uc7Z4tXRnguqkn5KLFAP8oV6PHe2'),
20
23
  },
21
24
  {
22
- symbol: 'BTC',
25
+ symbol: 'SOL',
23
26
  bankIndex: new BN(1),
27
+ oracle: new PublicKey('J83w4HKfqxwcq3BEMMkPFSppX3gqekLyLJBexebFVkix'),
28
+ oracleSource: OracleSource.PYTH,
29
+ mint: new PublicKey(WRAPPED_SOL_MINT),
30
+ },
31
+ {
32
+ symbol: 'BTC',
33
+ bankIndex: new BN(2),
24
34
  oracle: new PublicKey('HovQMDrbAgAYPCmHVSrezcSmkMtXSSUsLDFANExrZh2J'),
25
35
  oracleSource: OracleSource.PYTH,
26
- mint: new PublicKey('Gh9ZwEmdLJ8DscKNTkTqPbNwLNNBjuSzaG9Vp2KGtKJr'),
36
+ mint: new PublicKey('3BZPwbcqB5kKScF3TEXxwNfx5ipV13kbRVDvfVp5c6fv'),
27
37
  },
28
38
  ];
29
39