@drift-labs/sdk 0.2.0-master.24 → 0.2.0-master.26

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 (193) hide show
  1. package/lib/accounts/pollingClearingHouseAccountSubscriber.d.ts +13 -13
  2. package/lib/accounts/pollingClearingHouseAccountSubscriber.js +27 -27
  3. package/lib/accounts/types.d.ts +8 -9
  4. package/lib/accounts/webSocketClearingHouseAccountSubscriber.d.ts +14 -14
  5. package/lib/accounts/webSocketClearingHouseAccountSubscriber.js +35 -34
  6. package/lib/addresses/pda.d.ts +8 -6
  7. package/lib/addresses/pda.js +35 -27
  8. package/lib/admin.d.ts +9 -6
  9. package/lib/admin.js +90 -54
  10. package/lib/clearingHouse.d.ts +71 -42
  11. package/lib/clearingHouse.js +765 -282
  12. package/lib/clearingHouseConfig.d.ts +2 -2
  13. package/lib/clearingHouseUser.d.ts +19 -17
  14. package/lib/clearingHouseUser.js +145 -123
  15. package/lib/config.d.ts +7 -7
  16. package/lib/config.js +21 -21
  17. package/lib/constants/numericConstants.d.ts +12 -12
  18. package/lib/constants/numericConstants.js +13 -13
  19. package/lib/constants/{markets.d.ts → perpMarkets.d.ts} +5 -5
  20. package/{src/constants/markets.js → lib/constants/perpMarkets.js} +4 -4
  21. package/lib/constants/{banks.d.ts → spotMarkets.d.ts} +6 -6
  22. package/lib/constants/{banks.js → spotMarkets.js} +16 -16
  23. package/lib/events/eventSubscriber.d.ts +4 -2
  24. package/lib/events/eventSubscriber.js +16 -9
  25. package/lib/events/fetchLogs.d.ts +10 -1
  26. package/lib/events/fetchLogs.js +27 -7
  27. package/lib/events/pollingLogProvider.d.ts +2 -1
  28. package/lib/events/pollingLogProvider.js +6 -2
  29. package/lib/events/types.d.ts +4 -2
  30. package/lib/events/types.js +2 -0
  31. package/lib/examples/makeTradeExample.js +18 -6
  32. package/lib/idl/clearing_house.json +1128 -347
  33. package/lib/index.d.ts +6 -3
  34. package/lib/index.js +6 -3
  35. package/lib/math/amm.d.ts +5 -3
  36. package/lib/math/amm.js +42 -4
  37. package/lib/math/funding.d.ts +6 -6
  38. package/lib/math/funding.js +2 -1
  39. package/lib/math/margin.d.ts +4 -4
  40. package/lib/math/margin.js +18 -11
  41. package/lib/math/market.d.ts +10 -9
  42. package/lib/math/market.js +29 -6
  43. package/lib/math/oracles.d.ts +2 -1
  44. package/lib/math/oracles.js +11 -1
  45. package/lib/math/orders.d.ts +5 -5
  46. package/lib/math/position.d.ts +13 -13
  47. package/lib/math/position.js +19 -19
  48. package/lib/math/spotBalance.d.ts +19 -0
  49. package/lib/math/spotBalance.js +176 -0
  50. package/lib/math/spotMarket.d.ts +4 -0
  51. package/lib/math/spotMarket.js +8 -0
  52. package/lib/math/spotPosition.d.ts +2 -0
  53. package/lib/math/spotPosition.js +8 -0
  54. package/lib/math/state.js +2 -2
  55. package/lib/math/trade.d.ts +4 -4
  56. package/lib/orderParams.d.ts +4 -4
  57. package/lib/orderParams.js +12 -4
  58. package/lib/serum/serumSubscriber.d.ts +23 -0
  59. package/lib/serum/serumSubscriber.js +41 -0
  60. package/lib/serum/types.d.ts +11 -0
  61. package/lib/serum/types.js +2 -0
  62. package/lib/tx/retryTxSender.d.ts +1 -1
  63. package/lib/tx/retryTxSender.js +4 -2
  64. package/lib/tx/types.d.ts +1 -1
  65. package/lib/types.d.ts +148 -39
  66. package/lib/types.js +37 -9
  67. package/my-script/.env +7 -0
  68. package/my-script/getUserStats.ts +106 -0
  69. package/my-script/multiConnections.ts +119 -0
  70. package/my-script/test-regex.ts +11 -0
  71. package/my-script/utils.ts +52 -0
  72. package/package.json +1 -1
  73. package/src/accounts/bulkAccountLoader.js +249 -0
  74. package/src/accounts/bulkUserStatsSubscription.js +75 -0
  75. package/src/accounts/bulkUserSubscription.js +75 -0
  76. package/src/accounts/fetch.js +92 -0
  77. package/src/accounts/pollingClearingHouseAccountSubscriber.js +465 -0
  78. package/src/accounts/pollingClearingHouseAccountSubscriber.ts +38 -38
  79. package/src/accounts/pollingOracleSubscriber.js +156 -0
  80. package/src/accounts/pollingTokenAccountSubscriber.js +141 -0
  81. package/src/accounts/pollingUserAccountSubscriber.js +208 -0
  82. package/src/accounts/pollingUserStatsAccountSubscriber.js +208 -0
  83. package/src/accounts/types.js +28 -0
  84. package/src/accounts/types.ts +11 -9
  85. package/src/accounts/utils.js +7 -0
  86. package/src/accounts/webSocketAccountSubscriber.js +138 -0
  87. package/src/accounts/webSocketClearingHouseAccountSubscriber.js +433 -0
  88. package/src/accounts/webSocketClearingHouseAccountSubscriber.ts +59 -52
  89. package/src/accounts/webSocketUserAccountSubscriber.js +113 -0
  90. package/src/accounts/webSocketUserStatsAccountSubsriber.js +113 -0
  91. package/src/addresses/pda.js +186 -0
  92. package/src/addresses/pda.ts +56 -42
  93. package/src/admin.js +1284 -0
  94. package/src/admin.ts +149 -75
  95. package/src/assert/assert.js +1 -1
  96. package/src/clearingHouse.js +3433 -0
  97. package/src/clearingHouse.ts +1097 -380
  98. package/src/clearingHouseConfig.js +2 -0
  99. package/src/clearingHouseConfig.ts +2 -2
  100. package/src/clearingHouseUser.js +874 -0
  101. package/src/clearingHouseUser.ts +237 -172
  102. package/src/clearingHouseUserConfig.js +2 -0
  103. package/src/clearingHouseUserStats.js +115 -0
  104. package/src/clearingHouseUserStatsConfig.js +2 -0
  105. package/src/config.js +80 -0
  106. package/src/config.ts +30 -30
  107. package/src/constants/numericConstants.js +18 -11
  108. package/src/constants/numericConstants.ts +17 -15
  109. package/{lib/constants/markets.js → src/constants/perpMarkets.js} +11 -11
  110. package/src/constants/{markets.ts → perpMarkets.ts} +5 -5
  111. package/src/constants/spotMarkets.js +51 -0
  112. package/src/constants/{banks.ts → spotMarkets.ts} +19 -19
  113. package/src/events/eventList.js +66 -23
  114. package/src/events/eventSubscriber.js +202 -0
  115. package/src/events/eventSubscriber.ts +20 -12
  116. package/src/events/fetchLogs.js +117 -0
  117. package/src/events/fetchLogs.ts +35 -8
  118. package/src/events/pollingLogProvider.js +113 -0
  119. package/src/events/pollingLogProvider.ts +10 -2
  120. package/src/events/sort.js +41 -0
  121. package/src/events/txEventCache.js +22 -19
  122. package/src/events/types.js +25 -0
  123. package/src/events/types.ts +7 -1
  124. package/src/events/webSocketLogProvider.js +76 -0
  125. package/src/examples/makeTradeExample.ts +27 -6
  126. package/src/factory/bigNum.js +183 -180
  127. package/src/factory/oracleClient.js +9 -9
  128. package/src/idl/clearing_house.json +1128 -347
  129. package/src/index.js +75 -0
  130. package/src/index.ts +6 -3
  131. package/src/math/amm.js +422 -0
  132. package/src/math/amm.ts +73 -5
  133. package/src/math/auction.js +10 -10
  134. package/src/math/conversion.js +4 -3
  135. package/src/math/funding.js +223 -175
  136. package/src/math/funding.ts +7 -7
  137. package/src/math/insurance.js +27 -0
  138. package/src/math/margin.js +77 -0
  139. package/src/math/margin.ts +34 -23
  140. package/src/math/market.js +105 -0
  141. package/src/math/market.ts +71 -19
  142. package/src/math/oracles.js +40 -10
  143. package/src/math/oracles.ts +18 -1
  144. package/src/math/orders.js +153 -0
  145. package/src/math/orders.ts +5 -5
  146. package/src/math/position.js +172 -0
  147. package/src/math/position.ts +31 -31
  148. package/src/math/repeg.js +40 -40
  149. package/src/math/spotBalance.js +176 -0
  150. package/src/math/spotBalance.ts +290 -0
  151. package/src/math/spotMarket.js +8 -0
  152. package/src/math/spotMarket.ts +9 -0
  153. package/src/math/spotPosition.js +8 -0
  154. package/src/math/spotPosition.ts +6 -0
  155. package/src/math/state.ts +2 -2
  156. package/src/math/trade.js +81 -74
  157. package/src/math/trade.ts +4 -4
  158. package/src/math/utils.js +8 -7
  159. package/src/oracles/oracleClientCache.js +10 -9
  160. package/src/oracles/pythClient.js +52 -17
  161. package/src/oracles/quoteAssetOracleClient.js +44 -13
  162. package/src/oracles/switchboardClient.js +69 -37
  163. package/src/oracles/types.js +1 -1
  164. package/src/orderParams.js +14 -6
  165. package/src/orderParams.ts +16 -8
  166. package/src/serum/serumSubscriber.js +102 -0
  167. package/src/serum/serumSubscriber.ts +80 -0
  168. package/src/serum/types.js +2 -0
  169. package/src/serum/types.ts +13 -0
  170. package/src/slot/SlotSubscriber.js +67 -20
  171. package/src/token/index.js +4 -4
  172. package/src/tokenFaucet.js +288 -154
  173. package/src/tx/retryTxSender.js +280 -0
  174. package/src/tx/retryTxSender.ts +5 -2
  175. package/src/tx/types.js +1 -1
  176. package/src/tx/types.ts +2 -1
  177. package/src/tx/utils.js +7 -6
  178. package/src/types.js +216 -0
  179. package/src/types.ts +131 -39
  180. package/src/userName.js +5 -5
  181. package/src/util/computeUnits.js +46 -11
  182. package/src/util/promiseTimeout.js +5 -5
  183. package/src/util/tps.js +46 -12
  184. package/src/wallet.js +55 -18
  185. package/lib/math/bankBalance.d.ts +0 -15
  186. package/lib/math/bankBalance.js +0 -150
  187. package/src/addresses/marketAddresses.js +0 -26
  188. package/src/constants/banks.js +0 -42
  189. package/src/examples/makeTradeExample.js +0 -80
  190. package/src/math/bankBalance.ts +0 -258
  191. package/src/math/state.js +0 -15
  192. package/src/math/utils.js.map +0 -1
  193. package/src/util/getTokenAddress.js +0 -9
package/src/math/repeg.js CHANGED
@@ -1,9 +1,9 @@
1
1
  "use strict";
2
- Object.defineProperty(exports, "__esModule", { value: true });
2
+ exports.__esModule = true;
3
3
  exports.calculateBudgetedPeg = exports.calculateBudgetedK = exports.calculateBudgetedKBN = exports.calculateRepegCost = exports.calculateAdjustKCost = void 0;
4
- const anchor_1 = require("@project-serum/anchor");
5
- const assert_1 = require("../assert/assert");
6
- const numericConstants_1 = require("../constants/numericConstants");
4
+ var anchor_1 = require("@project-serum/anchor");
5
+ var assert_1 = require("../assert/assert");
6
+ var numericConstants_1 = require("../constants/numericConstants");
7
7
  /**
8
8
  * Helper function calculating adjust k cost
9
9
  * @param amm
@@ -13,13 +13,13 @@ const numericConstants_1 = require("../constants/numericConstants");
13
13
  */
14
14
  function calculateAdjustKCost(amm, numerator, denomenator) {
15
15
  // const k = market.amm.sqrtK.mul(market.amm.sqrtK);
16
- const x = amm.baseAssetReserve;
17
- const y = amm.quoteAssetReserve;
18
- const d = amm.netBaseAssetAmount;
19
- const Q = amm.pegMultiplier;
20
- const quoteScale = y.mul(d).mul(Q); //.div(AMM_RESERVE_PRECISION);
21
- const p = numerator.mul(numericConstants_1.MARK_PRICE_PRECISION).div(denomenator);
22
- const cost = quoteScale
16
+ var x = amm.baseAssetReserve;
17
+ var y = amm.quoteAssetReserve;
18
+ var d = amm.netBaseAssetAmount;
19
+ var Q = amm.pegMultiplier;
20
+ var quoteScale = y.mul(d).mul(Q); //.div(AMM_RESERVE_PRECISION);
21
+ var p = numerator.mul(numericConstants_1.MARK_PRICE_PRECISION).div(denomenator);
22
+ var cost = quoteScale
23
23
  .div(x.add(d))
24
24
  .sub(quoteScale
25
25
  .mul(p)
@@ -38,8 +38,8 @@ exports.calculateAdjustKCost = calculateAdjustKCost;
38
38
  * @returns cost : Precision QUOTE_ASSET_PRECISION
39
39
  */
40
40
  function calculateRepegCost(amm, newPeg) {
41
- const dqar = amm.quoteAssetReserve.sub(amm.terminalQuoteAssetReserve);
42
- const cost = dqar
41
+ var dqar = amm.quoteAssetReserve.sub(amm.terminalQuoteAssetReserve);
42
+ var cost = dqar
43
43
  .mul(newPeg.sub(amm.pegMultiplier))
44
44
  .div(numericConstants_1.AMM_TO_QUOTE_PRECISION_RATIO)
45
45
  .div(numericConstants_1.PEG_PRECISION);
@@ -47,32 +47,32 @@ function calculateRepegCost(amm, newPeg) {
47
47
  }
48
48
  exports.calculateRepegCost = calculateRepegCost;
49
49
  function calculateBudgetedKBN(x, y, budget, Q, d) {
50
- assert_1.assert(Q.gt(new anchor_1.BN(0)));
51
- const C = budget.mul(new anchor_1.BN(-1));
52
- let dSign = new anchor_1.BN(1);
50
+ (0, assert_1.assert)(Q.gt(new anchor_1.BN(0)));
51
+ var C = budget.mul(new anchor_1.BN(-1));
52
+ var dSign = new anchor_1.BN(1);
53
53
  if (d.lt(new anchor_1.BN(0))) {
54
54
  dSign = new anchor_1.BN(-1);
55
55
  }
56
- const pegged_y_d_d = y
56
+ var pegged_y_d_d = y
57
57
  .mul(d)
58
58
  .mul(d)
59
59
  .mul(Q)
60
60
  .div(numericConstants_1.AMM_RESERVE_PRECISION)
61
61
  .div(numericConstants_1.AMM_RESERVE_PRECISION)
62
62
  .div(numericConstants_1.PEG_PRECISION);
63
- const numer1 = pegged_y_d_d;
64
- const numer2 = C.mul(d)
63
+ var numer1 = pegged_y_d_d;
64
+ var numer2 = C.mul(d)
65
65
  .div(numericConstants_1.QUOTE_PRECISION)
66
66
  .mul(x.add(d))
67
67
  .div(numericConstants_1.AMM_RESERVE_PRECISION)
68
68
  .mul(dSign);
69
- const denom1 = C.mul(x)
69
+ var denom1 = C.mul(x)
70
70
  .mul(x.add(d))
71
71
  .div(numericConstants_1.AMM_RESERVE_PRECISION)
72
72
  .div(numericConstants_1.QUOTE_PRECISION);
73
- const denom2 = pegged_y_d_d;
74
- const numerator = numer1.sub(numer2).div(numericConstants_1.AMM_TO_QUOTE_PRECISION_RATIO);
75
- const denominator = denom1.add(denom2).div(numericConstants_1.AMM_TO_QUOTE_PRECISION_RATIO);
73
+ var denom2 = pegged_y_d_d;
74
+ var numerator = numer1.sub(numer2).div(numericConstants_1.AMM_TO_QUOTE_PRECISION_RATIO);
75
+ var denominator = denom1.add(denom2).div(numericConstants_1.AMM_TO_QUOTE_PRECISION_RATIO);
76
76
  return [numerator, denominator];
77
77
  }
78
78
  exports.calculateBudgetedKBN = calculateBudgetedKBN;
@@ -90,11 +90,11 @@ function calculateBudgetedK(amm, cost) {
90
90
  // = x/d**2 + 1 / d + mark/C
91
91
  // todo: assumes k = x * y
92
92
  // otherwise use: (y(1-p) + (kp^2/(x*p+d)) - k/(x+d)) * Q = C solve for p
93
- const x = amm.baseAssetReserve;
94
- const y = amm.quoteAssetReserve;
95
- const d = amm.netBaseAssetAmount;
96
- const Q = amm.pegMultiplier;
97
- const [numerator, denominator] = calculateBudgetedKBN(x, y, cost, Q, d);
93
+ var x = amm.baseAssetReserve;
94
+ var y = amm.quoteAssetReserve;
95
+ var d = amm.netBaseAssetAmount;
96
+ var Q = amm.pegMultiplier;
97
+ var _a = calculateBudgetedKBN(x, y, cost, Q, d), numerator = _a[0], denominator = _a[1];
98
98
  return [numerator, denominator];
99
99
  }
100
100
  exports.calculateBudgetedK = calculateBudgetedK;
@@ -104,25 +104,25 @@ function calculateBudgetedPeg(amm, cost, targetPrice) {
104
104
  // p = (d(y*d*Q - C(x+d))) / (C*x(x+d) + y*y*d*Q)
105
105
  // todo: assumes k = x * y
106
106
  // otherwise use: (y(1-p) + (kp^2/(x*p+d)) - k/(x+d)) * Q = C solve for p
107
- const targetPeg = targetPrice
107
+ var targetPeg = targetPrice
108
108
  .mul(amm.baseAssetReserve)
109
109
  .div(amm.quoteAssetReserve)
110
110
  .div(numericConstants_1.PRICE_DIV_PEG);
111
- const k = amm.sqrtK.mul(amm.sqrtK);
112
- const x = amm.baseAssetReserve;
113
- const y = amm.quoteAssetReserve;
114
- const d = amm.netBaseAssetAmount;
115
- const Q = amm.pegMultiplier;
116
- const C = cost.mul(new anchor_1.BN(-1));
117
- const deltaQuoteAssetReserves = y.sub(k.div(x.add(d)));
118
- const pegChangeDirection = targetPeg.sub(Q);
119
- const useTargetPeg = (deltaQuoteAssetReserves.lt(numericConstants_1.ZERO) && pegChangeDirection.gt(numericConstants_1.ZERO)) ||
111
+ var k = amm.sqrtK.mul(amm.sqrtK);
112
+ var x = amm.baseAssetReserve;
113
+ var y = amm.quoteAssetReserve;
114
+ var d = amm.netBaseAssetAmount;
115
+ var Q = amm.pegMultiplier;
116
+ var C = cost.mul(new anchor_1.BN(-1));
117
+ var deltaQuoteAssetReserves = y.sub(k.div(x.add(d)));
118
+ var pegChangeDirection = targetPeg.sub(Q);
119
+ var useTargetPeg = (deltaQuoteAssetReserves.lt(numericConstants_1.ZERO) && pegChangeDirection.gt(numericConstants_1.ZERO)) ||
120
120
  (deltaQuoteAssetReserves.gt(numericConstants_1.ZERO) && pegChangeDirection.lt(numericConstants_1.ZERO));
121
121
  if (deltaQuoteAssetReserves.eq(numericConstants_1.ZERO) || useTargetPeg) {
122
122
  return targetPeg;
123
123
  }
124
- const deltaPegMultiplier = C.mul(numericConstants_1.MARK_PRICE_PRECISION).div(deltaQuoteAssetReserves.div(numericConstants_1.AMM_TO_QUOTE_PRECISION_RATIO));
125
- const newPeg = Q.sub(deltaPegMultiplier.mul(numericConstants_1.PEG_PRECISION).div(numericConstants_1.MARK_PRICE_PRECISION));
124
+ var deltaPegMultiplier = C.mul(numericConstants_1.MARK_PRICE_PRECISION).div(deltaQuoteAssetReserves.div(numericConstants_1.AMM_TO_QUOTE_PRECISION_RATIO));
125
+ var newPeg = Q.sub(deltaPegMultiplier.mul(numericConstants_1.PEG_PRECISION).div(numericConstants_1.MARK_PRICE_PRECISION));
126
126
  return newPeg;
127
127
  }
128
128
  exports.calculateBudgetedPeg = calculateBudgetedPeg;
@@ -0,0 +1,176 @@
1
+ "use strict";
2
+ exports.__esModule = true;
3
+ exports.calculateWithdrawLimit = exports.calculateInterestAccumulated = exports.calculateBorrowRate = exports.calculateDepositRate = exports.calculateInterestRate = exports.calculateUtilization = exports.calculateLiabilityWeight = exports.calculateAssetWeight = exports.getTokenAmount = exports.getBalance = void 0;
4
+ var types_1 = require("../types");
5
+ var anchor_1 = require("@project-serum/anchor");
6
+ var numericConstants_1 = require("../constants/numericConstants");
7
+ var margin_1 = require("./margin");
8
+ function getBalance(tokenAmount, spotMarket, balanceType) {
9
+ var precisionIncrease = numericConstants_1.TEN.pow(new anchor_1.BN(16 - spotMarket.decimals));
10
+ var cumulativeInterest = (0, types_1.isVariant)(balanceType, 'deposit')
11
+ ? spotMarket.cumulativeDepositInterest
12
+ : spotMarket.cumulativeBorrowInterest;
13
+ var balance = tokenAmount.mul(precisionIncrease).div(cumulativeInterest);
14
+ if (!balance.eq(numericConstants_1.ZERO) && (0, types_1.isVariant)(balanceType, 'borrow')) {
15
+ balance = balance.add(numericConstants_1.ONE);
16
+ }
17
+ return balance;
18
+ }
19
+ exports.getBalance = getBalance;
20
+ function getTokenAmount(balanceAmount, spotMarket, balanceType) {
21
+ var precisionDecrease = numericConstants_1.TEN.pow(new anchor_1.BN(16 - spotMarket.decimals));
22
+ var cumulativeInterest = (0, types_1.isVariant)(balanceType, 'deposit')
23
+ ? spotMarket.cumulativeDepositInterest
24
+ : spotMarket.cumulativeBorrowInterest;
25
+ return balanceAmount.mul(cumulativeInterest).div(precisionDecrease);
26
+ }
27
+ exports.getTokenAmount = getTokenAmount;
28
+ function calculateAssetWeight(balanceAmount, spotMarket, marginCategory) {
29
+ var sizePrecision = numericConstants_1.TEN.pow(new anchor_1.BN(spotMarket.decimals));
30
+ var sizeInAmmReservePrecision;
31
+ if (sizePrecision.gt(numericConstants_1.AMM_RESERVE_PRECISION)) {
32
+ sizeInAmmReservePrecision = balanceAmount.div(sizePrecision.div(numericConstants_1.AMM_RESERVE_PRECISION));
33
+ }
34
+ else {
35
+ sizeInAmmReservePrecision = balanceAmount
36
+ .mul(numericConstants_1.AMM_RESERVE_PRECISION)
37
+ .div(sizePrecision);
38
+ }
39
+ var assetWeight;
40
+ switch (marginCategory) {
41
+ case 'Initial':
42
+ assetWeight = (0, margin_1.calculateSizeDiscountAssetWeight)(sizeInAmmReservePrecision, spotMarket.imfFactor, spotMarket.initialAssetWeight);
43
+ break;
44
+ case 'Maintenance':
45
+ assetWeight = (0, margin_1.calculateSizeDiscountAssetWeight)(sizeInAmmReservePrecision, spotMarket.imfFactor, spotMarket.maintenanceAssetWeight);
46
+ break;
47
+ default:
48
+ assetWeight = spotMarket.initialAssetWeight;
49
+ break;
50
+ }
51
+ return assetWeight;
52
+ }
53
+ exports.calculateAssetWeight = calculateAssetWeight;
54
+ function calculateLiabilityWeight(balanceAmount, spotMarket, marginCategory) {
55
+ var sizePrecision = numericConstants_1.TEN.pow(new anchor_1.BN(spotMarket.decimals));
56
+ var sizeInAmmReservePrecision;
57
+ if (sizePrecision.gt(numericConstants_1.AMM_RESERVE_PRECISION)) {
58
+ sizeInAmmReservePrecision = balanceAmount.div(sizePrecision.div(numericConstants_1.AMM_RESERVE_PRECISION));
59
+ }
60
+ else {
61
+ sizeInAmmReservePrecision = balanceAmount
62
+ .mul(numericConstants_1.AMM_RESERVE_PRECISION)
63
+ .div(sizePrecision);
64
+ }
65
+ var assetWeight;
66
+ switch (marginCategory) {
67
+ case 'Initial':
68
+ assetWeight = (0, margin_1.calculateSizePremiumLiabilityWeight)(sizeInAmmReservePrecision, spotMarket.imfFactor, spotMarket.initialLiabilityWeight, numericConstants_1.SPOT_MARKET_WEIGHT_PRECISION);
69
+ break;
70
+ case 'Maintenance':
71
+ assetWeight = (0, margin_1.calculateSizePremiumLiabilityWeight)(sizeInAmmReservePrecision, spotMarket.imfFactor, spotMarket.maintenanceLiabilityWeight, numericConstants_1.SPOT_MARKET_WEIGHT_PRECISION);
72
+ break;
73
+ default:
74
+ assetWeight = spotMarket.initialLiabilityWeight;
75
+ break;
76
+ }
77
+ return assetWeight;
78
+ }
79
+ exports.calculateLiabilityWeight = calculateLiabilityWeight;
80
+ function calculateUtilization(bank) {
81
+ var tokenDepositAmount = getTokenAmount(bank.depositBalance, bank, types_1.SpotBalanceType.DEPOSIT);
82
+ var tokenBorrowAmount = getTokenAmount(bank.borrowBalance, bank, types_1.SpotBalanceType.BORROW);
83
+ var utilization;
84
+ if (tokenBorrowAmount.eq(numericConstants_1.ZERO) && tokenDepositAmount.eq(numericConstants_1.ZERO)) {
85
+ utilization = numericConstants_1.ZERO;
86
+ }
87
+ else if (tokenDepositAmount.eq(numericConstants_1.ZERO)) {
88
+ utilization = numericConstants_1.SPOT_MARKET_UTILIZATION_PRECISION;
89
+ }
90
+ else {
91
+ utilization = tokenBorrowAmount
92
+ .mul(numericConstants_1.SPOT_MARKET_UTILIZATION_PRECISION)
93
+ .div(tokenDepositAmount);
94
+ }
95
+ return utilization;
96
+ }
97
+ exports.calculateUtilization = calculateUtilization;
98
+ function calculateInterestRate(bank) {
99
+ var utilization = calculateUtilization(bank);
100
+ var interestRate;
101
+ if (utilization.gt(bank.optimalUtilization)) {
102
+ var surplusUtilization = utilization.sub(bank.optimalUtilization);
103
+ var borrowRateSlope = bank.maxBorrowRate
104
+ .sub(bank.optimalBorrowRate)
105
+ .mul(numericConstants_1.SPOT_MARKET_UTILIZATION_PRECISION)
106
+ .div(numericConstants_1.SPOT_MARKET_UTILIZATION_PRECISION.sub(bank.optimalUtilization));
107
+ interestRate = bank.optimalBorrowRate.add(surplusUtilization
108
+ .mul(borrowRateSlope)
109
+ .div(numericConstants_1.SPOT_MARKET_UTILIZATION_PRECISION));
110
+ }
111
+ else {
112
+ var borrowRateSlope = bank.optimalBorrowRate
113
+ .mul(numericConstants_1.SPOT_MARKET_UTILIZATION_PRECISION)
114
+ .div(numericConstants_1.SPOT_MARKET_UTILIZATION_PRECISION.sub(bank.optimalUtilization));
115
+ interestRate = utilization
116
+ .mul(borrowRateSlope)
117
+ .div(numericConstants_1.SPOT_MARKET_UTILIZATION_PRECISION);
118
+ }
119
+ return interestRate;
120
+ }
121
+ exports.calculateInterestRate = calculateInterestRate;
122
+ function calculateDepositRate(bank) {
123
+ var utilization = calculateUtilization(bank);
124
+ var borrowRate = calculateBorrowRate(bank);
125
+ var depositRate = borrowRate
126
+ .mul(utilization)
127
+ .div(numericConstants_1.SPOT_MARKET_UTILIZATION_PRECISION);
128
+ return depositRate;
129
+ }
130
+ exports.calculateDepositRate = calculateDepositRate;
131
+ function calculateBorrowRate(bank) {
132
+ return calculateInterestRate(bank);
133
+ }
134
+ exports.calculateBorrowRate = calculateBorrowRate;
135
+ function calculateInterestAccumulated(bank, now) {
136
+ var interestRate = calculateInterestRate(bank);
137
+ var timeSinceLastUpdate = now.sub(bank.lastInterestTs);
138
+ var modifiedBorrowRate = interestRate.mul(timeSinceLastUpdate);
139
+ var utilization = calculateUtilization(bank);
140
+ var modifiedDepositRate = modifiedBorrowRate
141
+ .mul(utilization)
142
+ .div(numericConstants_1.SPOT_MARKET_UTILIZATION_PRECISION);
143
+ var borrowInterest = bank.cumulativeBorrowInterest
144
+ .mul(modifiedBorrowRate)
145
+ .div(numericConstants_1.ONE_YEAR)
146
+ .div(numericConstants_1.SPOT_MARKET_INTEREST_PRECISION)
147
+ .add(numericConstants_1.ONE);
148
+ var depositInterest = bank.cumulativeDepositInterest
149
+ .mul(modifiedDepositRate)
150
+ .div(numericConstants_1.ONE_YEAR)
151
+ .div(numericConstants_1.SPOT_MARKET_INTEREST_PRECISION);
152
+ return { borrowInterest: borrowInterest, depositInterest: depositInterest };
153
+ }
154
+ exports.calculateInterestAccumulated = calculateInterestAccumulated;
155
+ function calculateWithdrawLimit(spotMarket, now) {
156
+ var marketDepositTokenAmount = getTokenAmount(spotMarket.depositBalance, spotMarket, types_1.SpotBalanceType.DEPOSIT);
157
+ var marketBorrowTokenAmount = getTokenAmount(spotMarket.borrowBalance, spotMarket, types_1.SpotBalanceType.BORROW);
158
+ var twentyFourHours = new anchor_1.BN(60 * 60 * 24);
159
+ var sinceLast = now.sub(spotMarket.lastTwapTs);
160
+ var sinceStart = anchor_1.BN.max(numericConstants_1.ZERO, twentyFourHours.sub(sinceLast));
161
+ var borrowTokenTwapLive = spotMarket.borrowTokenTwap
162
+ .mul(sinceStart)
163
+ .add(marketBorrowTokenAmount.mul(sinceLast))
164
+ .div(sinceLast.add(sinceLast));
165
+ var depositTokenTwapLive = spotMarket.depositTokenTwap
166
+ .mul(sinceStart)
167
+ .add(marketDepositTokenAmount.mul(sinceLast))
168
+ .div(sinceLast.add(sinceLast));
169
+ var maxBorrowTokens = anchor_1.BN.min(anchor_1.BN.max(marketDepositTokenAmount.div(new anchor_1.BN(6)), borrowTokenTwapLive.add(borrowTokenTwapLive.div(new anchor_1.BN(5)))), marketDepositTokenAmount.sub(marketDepositTokenAmount.div(new anchor_1.BN(10)))); // between ~15-90% utilization with friction on twap
170
+ var minDepositTokens = depositTokenTwapLive.sub(anchor_1.BN.min(anchor_1.BN.max(depositTokenTwapLive.div(new anchor_1.BN(5)), spotMarket.withdrawGuardThreshold), depositTokenTwapLive));
171
+ return {
172
+ borrowLimit: maxBorrowTokens.sub(marketBorrowTokenAmount),
173
+ withdrawLimit: marketDepositTokenAmount.sub(minDepositTokens)
174
+ };
175
+ }
176
+ exports.calculateWithdrawLimit = calculateWithdrawLimit;
@@ -0,0 +1,290 @@
1
+ import {
2
+ SpotMarketAccount,
3
+ SpotBalanceType,
4
+ isVariant,
5
+ MarginCategory,
6
+ } from '../types';
7
+ import { BN } from '@project-serum/anchor';
8
+ import {
9
+ SPOT_MARKET_UTILIZATION_PRECISION,
10
+ ONE,
11
+ TEN,
12
+ ZERO,
13
+ SPOT_MARKET_INTEREST_PRECISION,
14
+ SPOT_MARKET_WEIGHT_PRECISION,
15
+ ONE_YEAR,
16
+ AMM_RESERVE_PRECISION,
17
+ } from '../constants/numericConstants';
18
+ import {
19
+ calculateSizeDiscountAssetWeight,
20
+ calculateSizePremiumLiabilityWeight,
21
+ } from './margin';
22
+
23
+ export function getBalance(
24
+ tokenAmount: BN,
25
+ spotMarket: SpotMarketAccount,
26
+ balanceType: SpotBalanceType
27
+ ): BN {
28
+ const precisionIncrease = TEN.pow(new BN(16 - spotMarket.decimals));
29
+
30
+ const cumulativeInterest = isVariant(balanceType, 'deposit')
31
+ ? spotMarket.cumulativeDepositInterest
32
+ : spotMarket.cumulativeBorrowInterest;
33
+
34
+ let balance = tokenAmount.mul(precisionIncrease).div(cumulativeInterest);
35
+
36
+ if (!balance.eq(ZERO) && isVariant(balanceType, 'borrow')) {
37
+ balance = balance.add(ONE);
38
+ }
39
+
40
+ return balance;
41
+ }
42
+
43
+ export function getTokenAmount(
44
+ balanceAmount: BN,
45
+ spotMarket: SpotMarketAccount,
46
+ balanceType: SpotBalanceType
47
+ ): BN {
48
+ const precisionDecrease = TEN.pow(new BN(16 - spotMarket.decimals));
49
+
50
+ const cumulativeInterest = isVariant(balanceType, 'deposit')
51
+ ? spotMarket.cumulativeDepositInterest
52
+ : spotMarket.cumulativeBorrowInterest;
53
+
54
+ return balanceAmount.mul(cumulativeInterest).div(precisionDecrease);
55
+ }
56
+
57
+ export function calculateAssetWeight(
58
+ balanceAmount: BN,
59
+ spotMarket: SpotMarketAccount,
60
+ marginCategory: MarginCategory
61
+ ): BN {
62
+ const sizePrecision = TEN.pow(new BN(spotMarket.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
+ spotMarket.imfFactor,
81
+ spotMarket.initialAssetWeight
82
+ );
83
+ break;
84
+ case 'Maintenance':
85
+ assetWeight = calculateSizeDiscountAssetWeight(
86
+ sizeInAmmReservePrecision,
87
+ spotMarket.imfFactor,
88
+ spotMarket.maintenanceAssetWeight
89
+ );
90
+ break;
91
+ default:
92
+ assetWeight = spotMarket.initialAssetWeight;
93
+ break;
94
+ }
95
+
96
+ return assetWeight;
97
+ }
98
+
99
+ export function calculateLiabilityWeight(
100
+ balanceAmount: BN,
101
+ spotMarket: SpotMarketAccount,
102
+ marginCategory: MarginCategory
103
+ ): BN {
104
+ const sizePrecision = TEN.pow(new BN(spotMarket.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
+ spotMarket.imfFactor,
123
+ spotMarket.initialLiabilityWeight,
124
+ SPOT_MARKET_WEIGHT_PRECISION
125
+ );
126
+ break;
127
+ case 'Maintenance':
128
+ assetWeight = calculateSizePremiumLiabilityWeight(
129
+ sizeInAmmReservePrecision,
130
+ spotMarket.imfFactor,
131
+ spotMarket.maintenanceLiabilityWeight,
132
+ SPOT_MARKET_WEIGHT_PRECISION
133
+ );
134
+ break;
135
+ default:
136
+ assetWeight = spotMarket.initialLiabilityWeight;
137
+ break;
138
+ }
139
+
140
+ return assetWeight;
141
+ }
142
+
143
+ export function calculateUtilization(bank: SpotMarketAccount): BN {
144
+ const tokenDepositAmount = getTokenAmount(
145
+ bank.depositBalance,
146
+ bank,
147
+ SpotBalanceType.DEPOSIT
148
+ );
149
+ const tokenBorrowAmount = getTokenAmount(
150
+ bank.borrowBalance,
151
+ bank,
152
+ SpotBalanceType.BORROW
153
+ );
154
+
155
+ let utilization: BN;
156
+ if (tokenBorrowAmount.eq(ZERO) && tokenDepositAmount.eq(ZERO)) {
157
+ utilization = ZERO;
158
+ } else if (tokenDepositAmount.eq(ZERO)) {
159
+ utilization = SPOT_MARKET_UTILIZATION_PRECISION;
160
+ } else {
161
+ utilization = tokenBorrowAmount
162
+ .mul(SPOT_MARKET_UTILIZATION_PRECISION)
163
+ .div(tokenDepositAmount);
164
+ }
165
+
166
+ return utilization;
167
+ }
168
+
169
+ export function calculateInterestRate(bank: SpotMarketAccount): BN {
170
+ const utilization = calculateUtilization(bank);
171
+
172
+ let interestRate: BN;
173
+ if (utilization.gt(bank.optimalUtilization)) {
174
+ const surplusUtilization = utilization.sub(bank.optimalUtilization);
175
+ const borrowRateSlope = bank.maxBorrowRate
176
+ .sub(bank.optimalBorrowRate)
177
+ .mul(SPOT_MARKET_UTILIZATION_PRECISION)
178
+ .div(SPOT_MARKET_UTILIZATION_PRECISION.sub(bank.optimalUtilization));
179
+
180
+ interestRate = bank.optimalBorrowRate.add(
181
+ surplusUtilization
182
+ .mul(borrowRateSlope)
183
+ .div(SPOT_MARKET_UTILIZATION_PRECISION)
184
+ );
185
+ } else {
186
+ const borrowRateSlope = bank.optimalBorrowRate
187
+ .mul(SPOT_MARKET_UTILIZATION_PRECISION)
188
+ .div(SPOT_MARKET_UTILIZATION_PRECISION.sub(bank.optimalUtilization));
189
+
190
+ interestRate = utilization
191
+ .mul(borrowRateSlope)
192
+ .div(SPOT_MARKET_UTILIZATION_PRECISION);
193
+ }
194
+
195
+ return interestRate;
196
+ }
197
+
198
+ export function calculateDepositRate(bank: SpotMarketAccount): BN {
199
+ const utilization = calculateUtilization(bank);
200
+ const borrowRate = calculateBorrowRate(bank);
201
+ const depositRate = borrowRate
202
+ .mul(utilization)
203
+ .div(SPOT_MARKET_UTILIZATION_PRECISION);
204
+ return depositRate;
205
+ }
206
+
207
+ export function calculateBorrowRate(bank: SpotMarketAccount): BN {
208
+ return calculateInterestRate(bank);
209
+ }
210
+
211
+ export function calculateInterestAccumulated(
212
+ bank: SpotMarketAccount,
213
+ now: BN
214
+ ): { borrowInterest: BN; depositInterest: BN } {
215
+ const interestRate = calculateInterestRate(bank);
216
+
217
+ const timeSinceLastUpdate = now.sub(bank.lastInterestTs);
218
+
219
+ const modifiedBorrowRate = interestRate.mul(timeSinceLastUpdate);
220
+
221
+ const utilization = calculateUtilization(bank);
222
+
223
+ const modifiedDepositRate = modifiedBorrowRate
224
+ .mul(utilization)
225
+ .div(SPOT_MARKET_UTILIZATION_PRECISION);
226
+
227
+ const borrowInterest = bank.cumulativeBorrowInterest
228
+ .mul(modifiedBorrowRate)
229
+ .div(ONE_YEAR)
230
+ .div(SPOT_MARKET_INTEREST_PRECISION)
231
+ .add(ONE);
232
+ const depositInterest = bank.cumulativeDepositInterest
233
+ .mul(modifiedDepositRate)
234
+ .div(ONE_YEAR)
235
+ .div(SPOT_MARKET_INTEREST_PRECISION);
236
+
237
+ return { borrowInterest, depositInterest };
238
+ }
239
+
240
+ export function calculateWithdrawLimit(
241
+ spotMarket: SpotMarketAccount,
242
+ now: BN
243
+ ): { borrowLimit: BN; withdrawLimit: BN } {
244
+ const marketDepositTokenAmount = getTokenAmount(
245
+ spotMarket.depositBalance,
246
+ spotMarket,
247
+ SpotBalanceType.DEPOSIT
248
+ );
249
+ const marketBorrowTokenAmount = getTokenAmount(
250
+ spotMarket.borrowBalance,
251
+ spotMarket,
252
+ SpotBalanceType.BORROW
253
+ );
254
+
255
+ const twentyFourHours = new BN(60 * 60 * 24);
256
+ const sinceLast = now.sub(spotMarket.lastTwapTs);
257
+ const sinceStart = BN.max(ZERO, twentyFourHours.sub(sinceLast));
258
+ const borrowTokenTwapLive = spotMarket.borrowTokenTwap
259
+ .mul(sinceStart)
260
+ .add(marketBorrowTokenAmount.mul(sinceLast))
261
+ .div(sinceLast.add(sinceLast));
262
+
263
+ const depositTokenTwapLive = spotMarket.depositTokenTwap
264
+ .mul(sinceStart)
265
+ .add(marketDepositTokenAmount.mul(sinceLast))
266
+ .div(sinceLast.add(sinceLast));
267
+
268
+ const maxBorrowTokens = BN.min(
269
+ BN.max(
270
+ marketDepositTokenAmount.div(new BN(6)),
271
+ borrowTokenTwapLive.add(borrowTokenTwapLive.div(new BN(5)))
272
+ ),
273
+ marketDepositTokenAmount.sub(marketDepositTokenAmount.div(new BN(10)))
274
+ ); // between ~15-90% utilization with friction on twap
275
+
276
+ const minDepositTokens = depositTokenTwapLive.sub(
277
+ BN.min(
278
+ BN.max(
279
+ depositTokenTwapLive.div(new BN(5)),
280
+ spotMarket.withdrawGuardThreshold
281
+ ),
282
+ depositTokenTwapLive
283
+ )
284
+ );
285
+
286
+ return {
287
+ borrowLimit: maxBorrowTokens.sub(marketBorrowTokenAmount),
288
+ withdrawLimit: marketDepositTokenAmount.sub(minDepositTokens),
289
+ };
290
+ }
@@ -0,0 +1,8 @@
1
+ "use strict";
2
+ exports.__esModule = true;
3
+ exports.castNumberToSpotPrecision = void 0;
4
+ var anchor_1 = require("@project-serum/anchor");
5
+ function castNumberToSpotPrecision(value, spotMarket) {
6
+ return new anchor_1.BN(value * Math.pow(10, spotMarket.decimals));
7
+ }
8
+ exports.castNumberToSpotPrecision = castNumberToSpotPrecision;
@@ -0,0 +1,9 @@
1
+ import { BN } from '@project-serum/anchor';
2
+ import { SpotMarketAccount } from '../types';
3
+
4
+ export function castNumberToSpotPrecision(
5
+ value: number,
6
+ spotMarket: SpotMarketAccount
7
+ ): BN {
8
+ return new BN(value * Math.pow(10, spotMarket.decimals));
9
+ }
@@ -0,0 +1,8 @@
1
+ "use strict";
2
+ exports.__esModule = true;
3
+ exports.isSpotPositionAvailable = void 0;
4
+ var numericConstants_1 = require("../constants/numericConstants");
5
+ function isSpotPositionAvailable(position) {
6
+ return position.balance.eq(numericConstants_1.ZERO) && position.openOrders === 0;
7
+ }
8
+ exports.isSpotPositionAvailable = isSpotPositionAvailable;
@@ -0,0 +1,6 @@
1
+ import { SpotPosition } from '../types';
2
+ import { ZERO } from '../constants/numericConstants';
3
+
4
+ export function isSpotPositionAvailable(position: SpotPosition): boolean {
5
+ return position.balance.eq(ZERO) && position.openOrders === 0;
6
+ }
package/src/math/state.ts CHANGED
@@ -8,7 +8,7 @@ import { StateAccount } from '../types';
8
8
  */
9
9
  export function getExchangeFee(state: StateAccount): number {
10
10
  const exchangeFee =
11
- state.feeStructure.feeNumerator.toNumber() /
12
- state.feeStructure.feeDenominator.toNumber();
11
+ state.perpFeeStructure.feeNumerator.toNumber() /
12
+ state.perpFeeStructure.feeDenominator.toNumber();
13
13
  return exchangeFee;
14
14
  }