@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
package/src/math/amm.ts CHANGED
@@ -6,8 +6,10 @@ import {
6
6
  ZERO,
7
7
  BID_ASK_SPREAD_PRECISION,
8
8
  ONE,
9
- // QUOTE_PRECISION,
10
9
  AMM_TO_QUOTE_PRECISION_RATIO,
10
+ QUOTE_PRECISION,
11
+ MARGIN_PRECISION,
12
+ PRICE_DIV_PEG,
11
13
  } from '../constants/numericConstants';
12
14
  import {
13
15
  AMM,
@@ -25,6 +27,71 @@ import {
25
27
  calculateAdjustKCost,
26
28
  calculateBudgetedPeg,
27
29
  } from './repeg';
30
+
31
+ export function calculatePegFromTargetPrice(
32
+ targetPrice: BN,
33
+ baseAssetReserve: BN,
34
+ quoteAssetReserve: BN
35
+ ): BN {
36
+ return targetPrice
37
+ .mul(baseAssetReserve)
38
+ .div(quoteAssetReserve)
39
+ .add(PRICE_DIV_PEG.div(new BN(2)))
40
+ .div(PRICE_DIV_PEG);
41
+ }
42
+
43
+ export function calculateOptimalPegAndBudget(
44
+ amm: AMM,
45
+ oraclePriceData: OraclePriceData
46
+ ): [BN, BN, BN, boolean] {
47
+ const markPriceBefore = calculatePrice(
48
+ amm.baseAssetReserve,
49
+ amm.quoteAssetReserve,
50
+ amm.pegMultiplier
51
+ );
52
+ const targetPrice = oraclePriceData.price;
53
+ const newPeg = calculatePegFromTargetPrice(
54
+ targetPrice,
55
+ amm.baseAssetReserve,
56
+ amm.quoteAssetReserve
57
+ );
58
+ const prePegCost = calculateRepegCost(amm, newPeg);
59
+
60
+ const totalFeeLB = amm.totalExchangeFee.div(new BN(2));
61
+ const budget = BN.max(ZERO, amm.totalFeeMinusDistributions.sub(totalFeeLB));
62
+ if (budget.lt(prePegCost)) {
63
+ const maxPriceSpread = new BN(amm.maxSpread)
64
+ .mul(targetPrice)
65
+ .div(BID_ASK_SPREAD_PRECISION);
66
+
67
+ let newTargetPrice: BN;
68
+ let newOptimalPeg: BN;
69
+ let newBudget: BN;
70
+ const targetPriceGap = markPriceBefore.sub(targetPrice);
71
+
72
+ if (targetPriceGap.abs().gt(maxPriceSpread)) {
73
+ const markAdj = targetPriceGap.abs().sub(maxPriceSpread);
74
+
75
+ if (targetPriceGap.lt(new BN(0))) {
76
+ newTargetPrice = markPriceBefore.add(markAdj);
77
+ } else {
78
+ newTargetPrice = markPriceBefore.sub(markAdj);
79
+ }
80
+
81
+ newOptimalPeg = calculatePegFromTargetPrice(
82
+ newTargetPrice,
83
+ amm.baseAssetReserve,
84
+ amm.quoteAssetReserve
85
+ );
86
+
87
+ newBudget = calculateRepegCost(amm, newOptimalPeg);
88
+ return [newTargetPrice, newOptimalPeg, newBudget, false];
89
+ }
90
+ }
91
+
92
+ return [targetPrice, newPeg, budget, true];
93
+ }
94
+
28
95
  export function calculateNewAmm(
29
96
  amm: AMM,
30
97
  oraclePriceData: OraclePriceData
@@ -32,18 +99,12 @@ export function calculateNewAmm(
32
99
  let pKNumer = new BN(1);
33
100
  let pKDenom = new BN(1);
34
101
 
35
- const targetPrice = oraclePriceData.price;
36
- let newPeg = targetPrice
37
- .mul(amm.baseAssetReserve)
38
- .div(amm.quoteAssetReserve)
39
- .add(MARK_PRICE_PRECISION.div(PEG_PRECISION).div(new BN(2)))
40
- .div(MARK_PRICE_PRECISION.div(PEG_PRECISION));
41
- let prePegCost = calculateRepegCost(amm, newPeg);
42
-
43
- const totalFeeLB = amm.totalExchangeFee.div(new BN(2));
44
- const budget = BN.max(ZERO, amm.totalFeeMinusDistributions.sub(totalFeeLB));
102
+ const [targetPrice, _newPeg, budget, checkLowerBound] =
103
+ calculateOptimalPegAndBudget(amm, oraclePriceData);
104
+ let prePegCost = calculateRepegCost(amm, _newPeg);
105
+ let newPeg = _newPeg;
45
106
 
46
- if (prePegCost.gt(budget)) {
107
+ if (prePegCost.gt(budget) && checkLowerBound) {
47
108
  [pKNumer, pKDenom] = [new BN(999), new BN(1000)];
48
109
  const deficitMadeup = calculateAdjustKCost(amm, pKNumer, pKDenom);
49
110
  assert(deficitMadeup.lte(new BN(0)));
@@ -136,9 +197,16 @@ export function calculateUpdatedAMMSpreadReserves(
136
197
 
137
198
  export function calculateBidAskPrice(
138
199
  amm: AMM,
139
- oraclePriceData: OraclePriceData
200
+ oraclePriceData: OraclePriceData,
201
+ withUpdate = true
140
202
  ): [BN, BN] {
141
- const newAmm = calculateUpdatedAMM(amm, oraclePriceData);
203
+ let newAmm: AMM;
204
+ if (withUpdate) {
205
+ newAmm = calculateUpdatedAMM(amm, oraclePriceData);
206
+ } else {
207
+ newAmm = amm;
208
+ }
209
+
142
210
  const askReserves = calculateSpreadReserves(
143
211
  newAmm,
144
212
  PositionDirection.LONG,
@@ -237,15 +305,115 @@ export function calculateAmmReservesAfterSwap(
237
305
  return [newQuoteAssetReserve, newBaseAssetReserve];
238
306
  }
239
307
 
308
+ export function calculateEffectiveLeverage(
309
+ baseSpread: number,
310
+ quoteAssetReserve: BN,
311
+ terminalQuoteAssetReserve: BN,
312
+ pegMultiplier: BN,
313
+ netBaseAssetAmount: BN,
314
+ markPrice: BN,
315
+ totalFeeMinusDistributions: BN
316
+ ): number {
317
+ // inventory skew
318
+ const netBaseAssetValue = quoteAssetReserve
319
+ .sub(terminalQuoteAssetReserve)
320
+ .mul(pegMultiplier)
321
+ .div(AMM_TIMES_PEG_TO_QUOTE_PRECISION_RATIO);
322
+
323
+ const localBaseAssetValue = netBaseAssetAmount
324
+ .mul(markPrice)
325
+ .div(AMM_TO_QUOTE_PRECISION_RATIO.mul(MARK_PRICE_PRECISION));
326
+
327
+ const effectiveLeverage =
328
+ localBaseAssetValue.sub(netBaseAssetValue).toNumber() /
329
+ (Math.max(0, totalFeeMinusDistributions.toNumber()) + 1) +
330
+ 1 / QUOTE_PRECISION.toNumber();
331
+
332
+ return effectiveLeverage;
333
+ }
334
+
335
+ export function calculateMaxSpread(marginRatioInitial: number): number {
336
+ const maxTargetSpread: number = new BN(marginRatioInitial)
337
+ .mul(BID_ASK_SPREAD_PRECISION.div(MARGIN_PRECISION))
338
+ .toNumber();
339
+
340
+ return maxTargetSpread;
341
+ }
342
+
343
+ export function calculateSpreadBN(
344
+ baseSpread: number,
345
+ lastOracleMarkSpreadPct: BN,
346
+ lastOracleConfPct: BN,
347
+ maxSpread: number,
348
+ quoteAssetReserve: BN,
349
+ terminalQuoteAssetReserve: BN,
350
+ pegMultiplier: BN,
351
+ netBaseAssetAmount: BN,
352
+ markPrice: BN,
353
+ totalFeeMinusDistributions: BN
354
+ ): [number, number] {
355
+ let longSpread = baseSpread / 2;
356
+ let shortSpread = baseSpread / 2;
357
+
358
+ if (lastOracleMarkSpreadPct.gt(ZERO)) {
359
+ shortSpread = Math.max(
360
+ shortSpread,
361
+ lastOracleMarkSpreadPct.abs().toNumber() + lastOracleConfPct.toNumber()
362
+ );
363
+ } else if (lastOracleMarkSpreadPct.lt(ZERO)) {
364
+ longSpread = Math.max(
365
+ longSpread,
366
+ lastOracleMarkSpreadPct.abs().toNumber() + lastOracleConfPct.toNumber()
367
+ );
368
+ }
369
+
370
+ const maxTargetSpread: number = maxSpread;
371
+
372
+ const MAX_INVENTORY_SKEW = 5;
373
+
374
+ const effectiveLeverage = calculateEffectiveLeverage(
375
+ baseSpread,
376
+ quoteAssetReserve,
377
+ terminalQuoteAssetReserve,
378
+ pegMultiplier,
379
+ netBaseAssetAmount,
380
+ markPrice,
381
+ totalFeeMinusDistributions
382
+ );
383
+
384
+ if (totalFeeMinusDistributions.gt(ZERO)) {
385
+ const spreadScale = Math.min(MAX_INVENTORY_SKEW, 1 + effectiveLeverage);
386
+ if (netBaseAssetAmount.gt(ZERO)) {
387
+ longSpread *= spreadScale;
388
+ } else {
389
+ shortSpread *= spreadScale;
390
+ }
391
+ } else {
392
+ longSpread *= MAX_INVENTORY_SKEW;
393
+ shortSpread *= MAX_INVENTORY_SKEW;
394
+ }
395
+
396
+ const totalSpread = longSpread + shortSpread;
397
+ if (totalSpread > maxTargetSpread) {
398
+ if (longSpread > shortSpread) {
399
+ longSpread = Math.min(longSpread, maxTargetSpread);
400
+ shortSpread = maxTargetSpread - longSpread;
401
+ } else {
402
+ shortSpread = Math.min(shortSpread, maxTargetSpread);
403
+ longSpread = maxTargetSpread - shortSpread;
404
+ }
405
+ }
406
+
407
+ return [longSpread, shortSpread];
408
+ }
409
+
240
410
  export function calculateSpread(
241
411
  amm: AMM,
242
412
  direction: PositionDirection,
243
413
  oraclePriceData: OraclePriceData
244
414
  ): number {
245
- let spread = amm.baseSpread / 2;
246
-
247
415
  if (amm.baseSpread == 0 || amm.curveUpdateIntensity == 0) {
248
- return spread;
416
+ return amm.baseSpread / 2;
249
417
  }
250
418
 
251
419
  const markPrice = calculatePrice(
@@ -255,49 +423,36 @@ export function calculateSpread(
255
423
  );
256
424
 
257
425
  const targetPrice = oraclePriceData?.price || markPrice;
426
+ const confInterval = oraclePriceData.confidence || ZERO;
258
427
 
259
428
  const targetMarkSpreadPct = markPrice
260
429
  .sub(targetPrice)
261
430
  .mul(BID_ASK_SPREAD_PRECISION)
262
431
  .div(markPrice);
263
432
 
264
- // oracle retreat
265
- if (
266
- (isVariant(direction, 'long') && targetMarkSpreadPct.lt(ZERO)) ||
267
- (isVariant(direction, 'short') && targetMarkSpreadPct.gt(ZERO))
268
- ) {
269
- spread = Math.max(spread, targetMarkSpreadPct.abs().toNumber());
270
- }
433
+ const confIntervalPct = confInterval
434
+ .mul(BID_ASK_SPREAD_PRECISION)
435
+ .div(markPrice);
271
436
 
272
- // inventory skew
273
- const MAX_INVENTORY_SKEW = 5;
274
- if (
275
- (amm.netBaseAssetAmount.gt(ZERO) && isVariant(direction, 'long')) ||
276
- (amm.netBaseAssetAmount.lt(ZERO) && isVariant(direction, 'short')) ||
277
- amm.totalFeeMinusDistributions.eq(ZERO)
278
- ) {
279
- const netCostBasis = amm.quoteAssetAmountLong.sub(
280
- amm.quoteAssetAmountShort
281
- );
282
- const netBaseAssetValue = amm.quoteAssetReserve
283
- .sub(amm.terminalQuoteAssetReserve)
284
- .mul(amm.pegMultiplier)
285
- .div(AMM_TIMES_PEG_TO_QUOTE_PRECISION_RATIO);
286
-
287
- const localBaseAssetValue = amm.netBaseAssetAmount
288
- .mul(markPrice)
289
- .div(AMM_TO_QUOTE_PRECISION_RATIO.mul(MARK_PRICE_PRECISION));
290
- const netPnl = netBaseAssetValue.sub(netCostBasis);
291
- const localPnl = localBaseAssetValue.sub(netCostBasis);
292
-
293
- let effectiveLeverage = MAX_INVENTORY_SKEW;
294
- if (amm.totalFeeMinusDistributions.gt(ZERO)) {
295
- effectiveLeverage =
296
- localPnl.sub(netPnl).toNumber() /
297
- amm.totalFeeMinusDistributions.toNumber();
298
- }
437
+ const [longSpread, shortSpread] = calculateSpreadBN(
438
+ amm.baseSpread,
439
+ targetMarkSpreadPct,
440
+ confIntervalPct,
441
+ amm.maxSpread,
442
+ amm.quoteAssetReserve,
443
+ amm.terminalQuoteAssetReserve,
444
+ amm.pegMultiplier,
445
+ amm.netBaseAssetAmount,
446
+ markPrice,
447
+ amm.totalFeeMinusDistributions
448
+ );
449
+
450
+ let spread: number;
299
451
 
300
- spread *= Math.min(MAX_INVENTORY_SKEW, 1 + effectiveLeverage);
452
+ if (isVariant(direction, 'long')) {
453
+ spread = longSpread;
454
+ } else {
455
+ spread = shortSpread;
301
456
  }
302
457
 
303
458
  return spread;
@@ -0,0 +1,42 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.getAuctionPrice = exports.isAuctionComplete = void 0;
4
+ const types_1 = require("../types");
5
+ const _1 = require("../.");
6
+ function isAuctionComplete(order, slot) {
7
+ if (order.auctionDuration === 0) {
8
+ return true;
9
+ }
10
+ return new _1.BN(slot).sub(order.slot).gt(new _1.BN(order.auctionDuration));
11
+ }
12
+ exports.isAuctionComplete = isAuctionComplete;
13
+ function getAuctionPrice(order, slot) {
14
+ const slotsElapsed = new _1.BN(slot).sub(order.slot);
15
+ const deltaDenominator = new _1.BN(order.auctionDuration);
16
+ const deltaNumerator = _1.BN.min(slotsElapsed, deltaDenominator);
17
+ if (deltaDenominator.eq(_1.ZERO)) {
18
+ return order.auctionEndPrice;
19
+ }
20
+ let priceDelta;
21
+ if (types_1.isVariant(order.direction, 'long')) {
22
+ priceDelta = order.auctionEndPrice
23
+ .sub(order.auctionStartPrice)
24
+ .mul(deltaNumerator)
25
+ .div(deltaDenominator);
26
+ }
27
+ else {
28
+ priceDelta = order.auctionStartPrice
29
+ .sub(order.auctionEndPrice)
30
+ .mul(deltaNumerator)
31
+ .div(deltaDenominator);
32
+ }
33
+ let price;
34
+ if (types_1.isVariant(order.direction, 'long')) {
35
+ price = order.auctionStartPrice.add(priceDelta);
36
+ }
37
+ else {
38
+ price = order.auctionStartPrice.sub(priceDelta);
39
+ }
40
+ return price;
41
+ }
42
+ exports.getAuctionPrice = getAuctionPrice;
@@ -2,7 +2,11 @@ import { isVariant, Order } from '../types';
2
2
  import { BN, ZERO } from '../.';
3
3
 
4
4
  export function isAuctionComplete(order: Order, slot: number): boolean {
5
- return new BN(slot).sub(order.slot).gte(new BN(order.auctionDuration));
5
+ if (order.auctionDuration === 0) {
6
+ return true;
7
+ }
8
+
9
+ return new BN(slot).sub(order.slot).gt(new BN(order.auctionDuration));
6
10
  }
7
11
 
8
12
  export function getAuctionPrice(order: Order, slot: number): BN {
@@ -1,4 +1,9 @@
1
- import { BankAccount, BankBalanceType, isVariant } from '../types';
1
+ import {
2
+ BankAccount,
3
+ BankBalanceType,
4
+ isVariant,
5
+ MarginCategory,
6
+ } from '../types';
2
7
  import { BN } from '@project-serum/anchor';
3
8
  import {
4
9
  BANK_UTILIZATION_PRECISION,
@@ -6,8 +11,14 @@ import {
6
11
  TEN,
7
12
  ZERO,
8
13
  BANK_INTEREST_PRECISION,
14
+ BANK_WEIGHT_PRECISION,
9
15
  ONE_YEAR,
16
+ AMM_RESERVE_PRECISION,
10
17
  } from '../constants/numericConstants';
18
+ import {
19
+ calculateSizeDiscountAssetWeight,
20
+ calculateSizePremiumLiabilityWeight,
21
+ } from './margin';
11
22
 
12
23
  export function getBalance(
13
24
  tokenAmount: BN,
@@ -43,6 +54,92 @@ export function getTokenAmount(
43
54
  return balanceAmount.mul(cumulativeInterest).div(precisionDecrease);
44
55
  }
45
56
 
57
+ export function calculateAssetWeight(
58
+ balanceAmount: BN,
59
+ bank: BankAccount,
60
+ marginCategory: MarginCategory
61
+ ): BN {
62
+ const sizePrecision = TEN.pow(new BN(bank.decimals));
63
+ let sizeInAmmReservePrecision;
64
+ if (sizePrecision.gt(AMM_RESERVE_PRECISION)) {
65
+ sizeInAmmReservePrecision = balanceAmount.div(
66
+ sizePrecision.div(AMM_RESERVE_PRECISION)
67
+ );
68
+ } else {
69
+ sizeInAmmReservePrecision = balanceAmount
70
+ .mul(AMM_RESERVE_PRECISION)
71
+ .div(sizePrecision);
72
+ }
73
+
74
+ let assetWeight;
75
+
76
+ switch (marginCategory) {
77
+ case 'Initial':
78
+ assetWeight = calculateSizeDiscountAssetWeight(
79
+ sizeInAmmReservePrecision,
80
+ bank.imfFactor,
81
+ bank.initialAssetWeight
82
+ );
83
+ break;
84
+ case 'Maintenance':
85
+ assetWeight = calculateSizeDiscountAssetWeight(
86
+ sizeInAmmReservePrecision,
87
+ bank.imfFactor,
88
+ bank.maintenanceAssetWeight
89
+ );
90
+ break;
91
+ default:
92
+ assetWeight = bank.initialAssetWeight;
93
+ break;
94
+ }
95
+
96
+ return assetWeight;
97
+ }
98
+
99
+ export function calculateLiabilityWeight(
100
+ balanceAmount: BN,
101
+ bank: BankAccount,
102
+ marginCategory: MarginCategory
103
+ ): BN {
104
+ const sizePrecision = TEN.pow(new BN(bank.decimals));
105
+ let sizeInAmmReservePrecision;
106
+ if (sizePrecision.gt(AMM_RESERVE_PRECISION)) {
107
+ sizeInAmmReservePrecision = balanceAmount.div(
108
+ sizePrecision.div(AMM_RESERVE_PRECISION)
109
+ );
110
+ } else {
111
+ sizeInAmmReservePrecision = balanceAmount
112
+ .mul(AMM_RESERVE_PRECISION)
113
+ .div(sizePrecision);
114
+ }
115
+
116
+ let assetWeight;
117
+
118
+ switch (marginCategory) {
119
+ case 'Initial':
120
+ assetWeight = calculateSizePremiumLiabilityWeight(
121
+ sizeInAmmReservePrecision,
122
+ bank.imfFactor,
123
+ bank.initialLiabilityWeight,
124
+ BANK_WEIGHT_PRECISION
125
+ );
126
+ break;
127
+ case 'Maintenance':
128
+ assetWeight = calculateSizePremiumLiabilityWeight(
129
+ sizeInAmmReservePrecision,
130
+ bank.imfFactor,
131
+ bank.maintenanceLiabilityWeight,
132
+ BANK_WEIGHT_PRECISION
133
+ );
134
+ break;
135
+ default:
136
+ assetWeight = bank.initialLiabilityWeight;
137
+ break;
138
+ }
139
+
140
+ return assetWeight;
141
+ }
142
+
46
143
  export function calculateInterestAccumulated(
47
144
  bank: BankAccount,
48
145
  now: BN
@@ -0,0 +1,11 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.convertToNumber = void 0;
4
+ const numericConstants_1 = require("../constants/numericConstants");
5
+ const convertToNumber = (bigNumber, precision = numericConstants_1.MARK_PRICE_PRECISION) => {
6
+ if (!bigNumber)
7
+ return 0;
8
+ return (bigNumber.div(precision).toNumber() +
9
+ bigNumber.mod(precision).toNumber() / precision.toNumber());
10
+ };
11
+ exports.convertToNumber = convertToNumber;