@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
@@ -0,0 +1,77 @@
1
+ "use strict";
2
+ exports.__esModule = true;
3
+ exports.calculateWorstCaseBaseAssetAmount = exports.calculateBaseAssetValueWithOracle = exports.calculateOraclePriceForPerpMargin = exports.calculateSizeDiscountAssetWeight = exports.calculateSizePremiumLiabilityWeight = void 0;
4
+ var utils_1 = require("./utils");
5
+ var numericConstants_1 = require("../constants/numericConstants");
6
+ var anchor_1 = require("@project-serum/anchor");
7
+ var assert_1 = require("../assert/assert");
8
+ function calculateSizePremiumLiabilityWeight(size, // AMM_RESERVE_PRECISION
9
+ imfFactor, liabilityWeight, precision) {
10
+ if (imfFactor.eq(numericConstants_1.ZERO)) {
11
+ return liabilityWeight;
12
+ }
13
+ var sizeSqrt = (0, utils_1.squareRootBN)(size.div(new anchor_1.BN(1000)).add(new anchor_1.BN(1))); //1e13 -> 1e10 -> 1e5
14
+ var denom0 = anchor_1.BN.max(new anchor_1.BN(1), numericConstants_1.SPOT_MARKET_IMF_PRECISION.div(imfFactor));
15
+ (0, assert_1.assert)(denom0.gt(numericConstants_1.ZERO));
16
+ var liabilityWeightNumerator = liabilityWeight.sub(liabilityWeight.div(anchor_1.BN.max(new anchor_1.BN(1), numericConstants_1.SPOT_MARKET_IMF_PRECISION.div(imfFactor))));
17
+ var denom = new anchor_1.BN(100000).mul(numericConstants_1.SPOT_MARKET_IMF_PRECISION).div(precision);
18
+ (0, assert_1.assert)(denom.gt(numericConstants_1.ZERO));
19
+ var sizePremiumLiabilityWeight = liabilityWeightNumerator.add(sizeSqrt // 1e5
20
+ .mul(imfFactor)
21
+ .div(denom) // 1e5
22
+ );
23
+ var maxLiabilityWeight = anchor_1.BN.max(liabilityWeight, sizePremiumLiabilityWeight);
24
+ return maxLiabilityWeight;
25
+ }
26
+ exports.calculateSizePremiumLiabilityWeight = calculateSizePremiumLiabilityWeight;
27
+ function calculateSizeDiscountAssetWeight(size, // AMM_RESERVE_PRECISION
28
+ imfFactor, assetWeight) {
29
+ if (imfFactor.eq(numericConstants_1.ZERO)) {
30
+ return assetWeight;
31
+ }
32
+ var sizeSqrt = (0, utils_1.squareRootBN)(size.div(new anchor_1.BN(1000)).add(new anchor_1.BN(1))); //1e13 -> 1e10 -> 1e5
33
+ var imfNumerator = numericConstants_1.SPOT_MARKET_IMF_PRECISION.add(numericConstants_1.SPOT_MARKET_IMF_PRECISION.div(new anchor_1.BN(10)));
34
+ var sizeDiscountAssetWeight = imfNumerator
35
+ .mul(numericConstants_1.SPOT_MARKET_WEIGHT_PRECISION)
36
+ .div(numericConstants_1.SPOT_MARKET_IMF_PRECISION.add(sizeSqrt // 1e5
37
+ .mul(imfFactor)
38
+ .div(new anchor_1.BN(100000)) // 1e5
39
+ ));
40
+ var minAssetWeight = anchor_1.BN.min(assetWeight, sizeDiscountAssetWeight);
41
+ return minAssetWeight;
42
+ }
43
+ exports.calculateSizeDiscountAssetWeight = calculateSizeDiscountAssetWeight;
44
+ function calculateOraclePriceForPerpMargin(perpPosition, market, oraclePriceData) {
45
+ var oraclePriceOffset = anchor_1.BN.min(new anchor_1.BN(market.amm.maxSpread)
46
+ .mul(oraclePriceData.price)
47
+ .div(numericConstants_1.BID_ASK_SPREAD_PRECISION), oraclePriceData.confidence.add(new anchor_1.BN(market.amm.baseSpread)
48
+ .mul(oraclePriceData.price)
49
+ .div(numericConstants_1.BID_ASK_SPREAD_PRECISION)));
50
+ var marginPrice;
51
+ if (perpPosition.baseAssetAmount.gt(numericConstants_1.ZERO)) {
52
+ marginPrice = oraclePriceData.price.sub(oraclePriceOffset);
53
+ }
54
+ else {
55
+ marginPrice = oraclePriceData.price.add(oraclePriceOffset);
56
+ }
57
+ return marginPrice;
58
+ }
59
+ exports.calculateOraclePriceForPerpMargin = calculateOraclePriceForPerpMargin;
60
+ function calculateBaseAssetValueWithOracle(market, perpPosition, oraclePriceData) {
61
+ return perpPosition.baseAssetAmount
62
+ .abs()
63
+ .mul(oraclePriceData.price)
64
+ .div(numericConstants_1.AMM_TO_QUOTE_PRECISION_RATIO.mul(numericConstants_1.MARK_PRICE_PRECISION));
65
+ }
66
+ exports.calculateBaseAssetValueWithOracle = calculateBaseAssetValueWithOracle;
67
+ function calculateWorstCaseBaseAssetAmount(perpPosition) {
68
+ var allBids = perpPosition.baseAssetAmount.add(perpPosition.openBids);
69
+ var allAsks = perpPosition.baseAssetAmount.add(perpPosition.openAsks);
70
+ if (allBids.abs().gt(allAsks.abs())) {
71
+ return allBids;
72
+ }
73
+ else {
74
+ return allAsks;
75
+ }
76
+ }
77
+ exports.calculateWorstCaseBaseAssetAmount = calculateWorstCaseBaseAssetAmount;
@@ -1,7 +1,7 @@
1
1
  import { squareRootBN } from './utils';
2
2
  import {
3
- BANK_WEIGHT_PRECISION,
4
- BANK_IMF_PRECISION,
3
+ SPOT_MARKET_WEIGHT_PRECISION,
4
+ SPOT_MARKET_IMF_PRECISION,
5
5
  ZERO,
6
6
  BID_ASK_SPREAD_PRECISION,
7
7
  AMM_TO_QUOTE_PRECISION_RATIO,
@@ -9,7 +9,8 @@ import {
9
9
  } from '../constants/numericConstants';
10
10
  import { BN } from '@project-serum/anchor';
11
11
  import { OraclePriceData } from '../oracles/types';
12
- import { MarketAccount, UserPosition } from '..';
12
+ import { PerpMarketAccount, PerpPosition } from '..';
13
+ import { assert } from '../assert/assert';
13
14
 
14
15
  export function calculateSizePremiumLiabilityWeight(
15
16
  size: BN, // AMM_RESERVE_PRECISION
@@ -22,14 +23,22 @@ export function calculateSizePremiumLiabilityWeight(
22
23
  }
23
24
 
24
25
  const sizeSqrt = squareRootBN(size.div(new BN(1000)).add(new BN(1))); //1e13 -> 1e10 -> 1e5
26
+
27
+ const denom0 = BN.max(new BN(1), SPOT_MARKET_IMF_PRECISION.div(imfFactor));
28
+ assert(denom0.gt(ZERO));
25
29
  const liabilityWeightNumerator = liabilityWeight.sub(
26
- liabilityWeight.div(BN.max(new BN(1), BANK_IMF_PRECISION.div(imfFactor)))
30
+ liabilityWeight.div(
31
+ BN.max(new BN(1), SPOT_MARKET_IMF_PRECISION.div(imfFactor))
32
+ )
27
33
  );
28
34
 
35
+ const denom = new BN(100_000).mul(SPOT_MARKET_IMF_PRECISION).div(precision);
36
+ assert(denom.gt(ZERO));
37
+
29
38
  const sizePremiumLiabilityWeight = liabilityWeightNumerator.add(
30
39
  sizeSqrt // 1e5
31
40
  .mul(imfFactor)
32
- .div(new BN(100_000).mul(BANK_IMF_PRECISION).div(precision)) // 1e5
41
+ .div(denom) // 1e5
33
42
  );
34
43
 
35
44
  const maxLiabilityWeight = BN.max(
@@ -49,17 +58,19 @@ export function calculateSizeDiscountAssetWeight(
49
58
  }
50
59
 
51
60
  const sizeSqrt = squareRootBN(size.div(new BN(1000)).add(new BN(1))); //1e13 -> 1e10 -> 1e5
52
- const imfNumerator = BANK_IMF_PRECISION.add(
53
- BANK_IMF_PRECISION.div(new BN(10))
61
+ const imfNumerator = SPOT_MARKET_IMF_PRECISION.add(
62
+ SPOT_MARKET_IMF_PRECISION.div(new BN(10))
54
63
  );
55
64
 
56
- const sizeDiscountAssetWeight = imfNumerator.mul(BANK_WEIGHT_PRECISION).div(
57
- BANK_IMF_PRECISION.add(
58
- sizeSqrt // 1e5
59
- .mul(imfFactor)
60
- .div(new BN(100_000)) // 1e5
61
- )
62
- );
65
+ const sizeDiscountAssetWeight = imfNumerator
66
+ .mul(SPOT_MARKET_WEIGHT_PRECISION)
67
+ .div(
68
+ SPOT_MARKET_IMF_PRECISION.add(
69
+ sizeSqrt // 1e5
70
+ .mul(imfFactor)
71
+ .div(new BN(100_000)) // 1e5
72
+ )
73
+ );
63
74
 
64
75
  const minAssetWeight = BN.min(assetWeight, sizeDiscountAssetWeight);
65
76
 
@@ -67,8 +78,8 @@ export function calculateSizeDiscountAssetWeight(
67
78
  }
68
79
 
69
80
  export function calculateOraclePriceForPerpMargin(
70
- marketPosition: UserPosition,
71
- market: MarketAccount,
81
+ perpPosition: PerpPosition,
82
+ market: PerpMarketAccount,
72
83
  oraclePriceData: OraclePriceData
73
84
  ): BN {
74
85
  const oraclePriceOffset = BN.min(
@@ -83,7 +94,7 @@ export function calculateOraclePriceForPerpMargin(
83
94
  );
84
95
 
85
96
  let marginPrice: BN;
86
- if (marketPosition.baseAssetAmount.gt(ZERO)) {
97
+ if (perpPosition.baseAssetAmount.gt(ZERO)) {
87
98
  marginPrice = oraclePriceData.price.sub(oraclePriceOffset);
88
99
  } else {
89
100
  marginPrice = oraclePriceData.price.add(oraclePriceOffset);
@@ -93,21 +104,21 @@ export function calculateOraclePriceForPerpMargin(
93
104
  }
94
105
 
95
106
  export function calculateBaseAssetValueWithOracle(
96
- market: MarketAccount,
97
- marketPosition: UserPosition,
107
+ market: PerpMarketAccount,
108
+ perpPosition: PerpPosition,
98
109
  oraclePriceData: OraclePriceData
99
110
  ): BN {
100
- return marketPosition.baseAssetAmount
111
+ return perpPosition.baseAssetAmount
101
112
  .abs()
102
113
  .mul(oraclePriceData.price)
103
114
  .div(AMM_TO_QUOTE_PRECISION_RATIO.mul(MARK_PRICE_PRECISION));
104
115
  }
105
116
 
106
117
  export function calculateWorstCaseBaseAssetAmount(
107
- marketPosition: UserPosition
118
+ perpPosition: PerpPosition
108
119
  ): BN {
109
- const allBids = marketPosition.baseAssetAmount.add(marketPosition.openBids);
110
- const allAsks = marketPosition.baseAssetAmount.add(marketPosition.openAsks);
120
+ const allBids = perpPosition.baseAssetAmount.add(perpPosition.openBids);
121
+ const allAsks = perpPosition.baseAssetAmount.add(perpPosition.openAsks);
111
122
 
112
123
  if (allBids.abs().gt(allAsks.abs())) {
113
124
  return allBids;
@@ -0,0 +1,105 @@
1
+ "use strict";
2
+ exports.__esModule = true;
3
+ exports.calculateNetUserImbalance = exports.calculateMarketAvailablePNL = exports.calculateUnrealizedAssetWeight = exports.calculateMarketMarginRatio = exports.calculateOracleSpread = exports.calculateMarkOracleSpread = exports.calculateNewMarketAfterTrade = exports.calculateAskPrice = exports.calculateBidPrice = exports.calculateMarkPrice = void 0;
4
+ var anchor_1 = require("@project-serum/anchor");
5
+ var types_1 = require("../types");
6
+ var amm_1 = require("./amm");
7
+ var margin_1 = require("./margin");
8
+ var numericConstants_1 = require("../constants/numericConstants");
9
+ var spotBalance_1 = require("./spotBalance");
10
+ /**
11
+ * Calculates market mark price
12
+ *
13
+ * @param market
14
+ * @return markPrice : Precision MARK_PRICE_PRECISION
15
+ */
16
+ function calculateMarkPrice(market, oraclePriceData) {
17
+ var newAmm = (0, amm_1.calculateUpdatedAMM)(market.amm, oraclePriceData);
18
+ return (0, amm_1.calculatePrice)(newAmm.baseAssetReserve, newAmm.quoteAssetReserve, newAmm.pegMultiplier);
19
+ }
20
+ exports.calculateMarkPrice = calculateMarkPrice;
21
+ /**
22
+ * Calculates market bid price
23
+ *
24
+ * @param market
25
+ * @return bidPrice : Precision MARK_PRICE_PRECISION
26
+ */
27
+ function calculateBidPrice(market, oraclePriceData) {
28
+ var _a = (0, amm_1.calculateUpdatedAMMSpreadReserves)(market.amm, types_1.PositionDirection.SHORT, oraclePriceData), baseAssetReserve = _a.baseAssetReserve, quoteAssetReserve = _a.quoteAssetReserve, newPeg = _a.newPeg;
29
+ return (0, amm_1.calculatePrice)(baseAssetReserve, quoteAssetReserve, newPeg);
30
+ }
31
+ exports.calculateBidPrice = calculateBidPrice;
32
+ /**
33
+ * Calculates market ask price
34
+ *
35
+ * @param market
36
+ * @return bidPrice : Precision MARK_PRICE_PRECISION
37
+ */
38
+ function calculateAskPrice(market, oraclePriceData) {
39
+ var _a = (0, amm_1.calculateUpdatedAMMSpreadReserves)(market.amm, types_1.PositionDirection.LONG, oraclePriceData), baseAssetReserve = _a.baseAssetReserve, quoteAssetReserve = _a.quoteAssetReserve, newPeg = _a.newPeg;
40
+ return (0, amm_1.calculatePrice)(baseAssetReserve, quoteAssetReserve, newPeg);
41
+ }
42
+ exports.calculateAskPrice = calculateAskPrice;
43
+ function calculateNewMarketAfterTrade(baseAssetAmount, direction, market) {
44
+ var _a = (0, amm_1.calculateAmmReservesAfterSwap)(market.amm, 'base', baseAssetAmount.abs(), (0, amm_1.getSwapDirection)('base', direction)), newQuoteAssetReserve = _a[0], newBaseAssetReserve = _a[1];
45
+ var newAmm = Object.assign({}, market.amm);
46
+ var newMarket = Object.assign({}, market);
47
+ newMarket.amm = newAmm;
48
+ newMarket.amm.quoteAssetReserve = newQuoteAssetReserve;
49
+ newMarket.amm.baseAssetReserve = newBaseAssetReserve;
50
+ return newMarket;
51
+ }
52
+ exports.calculateNewMarketAfterTrade = calculateNewMarketAfterTrade;
53
+ function calculateMarkOracleSpread(market, oraclePriceData) {
54
+ var markPrice = calculateMarkPrice(market, oraclePriceData);
55
+ return calculateOracleSpread(markPrice, oraclePriceData);
56
+ }
57
+ exports.calculateMarkOracleSpread = calculateMarkOracleSpread;
58
+ function calculateOracleSpread(price, oraclePriceData) {
59
+ return price.sub(oraclePriceData.price);
60
+ }
61
+ exports.calculateOracleSpread = calculateOracleSpread;
62
+ function calculateMarketMarginRatio(market, size, marginCategory) {
63
+ var marginRatio;
64
+ switch (marginCategory) {
65
+ case 'Initial':
66
+ marginRatio = (0, margin_1.calculateSizePremiumLiabilityWeight)(size, market.imfFactor, new anchor_1.BN(market.marginRatioInitial), numericConstants_1.MARGIN_PRECISION).toNumber();
67
+ break;
68
+ case 'Maintenance':
69
+ marginRatio = market.marginRatioMaintenance;
70
+ break;
71
+ }
72
+ return marginRatio;
73
+ }
74
+ exports.calculateMarketMarginRatio = calculateMarketMarginRatio;
75
+ function calculateUnrealizedAssetWeight(market, unrealizedPnl, marginCategory) {
76
+ var assetWeight;
77
+ switch (marginCategory) {
78
+ case 'Initial':
79
+ assetWeight = (0, margin_1.calculateSizeDiscountAssetWeight)(unrealizedPnl, market.unrealizedImfFactor, new anchor_1.BN(market.unrealizedInitialAssetWeight));
80
+ break;
81
+ case 'Maintenance':
82
+ assetWeight = new anchor_1.BN(market.unrealizedMaintenanceAssetWeight);
83
+ break;
84
+ }
85
+ return assetWeight;
86
+ }
87
+ exports.calculateUnrealizedAssetWeight = calculateUnrealizedAssetWeight;
88
+ function calculateMarketAvailablePNL(perpMarket, spotMarket) {
89
+ return (0, spotBalance_1.getTokenAmount)(perpMarket.pnlPool.balance, spotMarket, types_1.SpotBalanceType.DEPOSIT);
90
+ }
91
+ exports.calculateMarketAvailablePNL = calculateMarketAvailablePNL;
92
+ function calculateNetUserImbalance(market, bank, oraclePriceData) {
93
+ var netUserPositionValue = market.amm.netBaseAssetAmount
94
+ .mul(oraclePriceData.price)
95
+ .div(numericConstants_1.BASE_PRECISION)
96
+ .div(numericConstants_1.PRICE_TO_QUOTE_PRECISION);
97
+ var netUserCostBasis = market.amm.quoteAssetAmountLong
98
+ .add(market.amm.quoteAssetAmountShort)
99
+ .sub(market.amm.cumulativeSocialLoss);
100
+ var userEntitledPnl = netUserPositionValue.add(netUserCostBasis);
101
+ var pnlPool = (0, spotBalance_1.getTokenAmount)(market.pnlPool.balance, bank, types_1.SpotBalanceType.DEPOSIT);
102
+ var imbalance = userEntitledPnl.sub(pnlPool);
103
+ return imbalance;
104
+ }
105
+ exports.calculateNetUserImbalance = calculateNetUserImbalance;
@@ -1,10 +1,10 @@
1
1
  import { BN } from '@project-serum/anchor';
2
2
  import {
3
- MarketAccount,
3
+ PerpMarketAccount,
4
4
  PositionDirection,
5
5
  MarginCategory,
6
- BankAccount,
7
- BankBalanceType,
6
+ SpotMarketAccount,
7
+ SpotBalanceType,
8
8
  } from '../types';
9
9
  import {
10
10
  calculateAmmReservesAfterSwap,
@@ -18,8 +18,13 @@ import {
18
18
  calculateSizePremiumLiabilityWeight,
19
19
  } from './margin';
20
20
  import { OraclePriceData } from '../oracles/types';
21
- import { MARGIN_PRECISION } from '../constants/numericConstants';
22
- import { getTokenAmount } from './bankBalance';
21
+ import {
22
+ BASE_PRECISION,
23
+ MARGIN_PRECISION,
24
+ PRICE_TO_QUOTE_PRECISION,
25
+ ZERO,
26
+ } from '../constants/numericConstants';
27
+ import { getTokenAmount } from './spotBalance';
23
28
 
24
29
  /**
25
30
  * Calculates market mark price
@@ -28,7 +33,7 @@ import { getTokenAmount } from './bankBalance';
28
33
  * @return markPrice : Precision MARK_PRICE_PRECISION
29
34
  */
30
35
  export function calculateMarkPrice(
31
- market: MarketAccount,
36
+ market: PerpMarketAccount,
32
37
  oraclePriceData: OraclePriceData
33
38
  ): BN {
34
39
  const newAmm = calculateUpdatedAMM(market.amm, oraclePriceData);
@@ -46,7 +51,7 @@ export function calculateMarkPrice(
46
51
  * @return bidPrice : Precision MARK_PRICE_PRECISION
47
52
  */
48
53
  export function calculateBidPrice(
49
- market: MarketAccount,
54
+ market: PerpMarketAccount,
50
55
  oraclePriceData: OraclePriceData
51
56
  ): BN {
52
57
  const { baseAssetReserve, quoteAssetReserve, newPeg } =
@@ -66,7 +71,7 @@ export function calculateBidPrice(
66
71
  * @return bidPrice : Precision MARK_PRICE_PRECISION
67
72
  */
68
73
  export function calculateAskPrice(
69
- market: MarketAccount,
74
+ market: PerpMarketAccount,
70
75
  oraclePriceData: OraclePriceData
71
76
  ): BN {
72
77
  const { baseAssetReserve, quoteAssetReserve, newPeg } =
@@ -82,8 +87,8 @@ export function calculateAskPrice(
82
87
  export function calculateNewMarketAfterTrade(
83
88
  baseAssetAmount: BN,
84
89
  direction: PositionDirection,
85
- market: MarketAccount
86
- ): MarketAccount {
90
+ market: PerpMarketAccount
91
+ ): PerpMarketAccount {
87
92
  const [newQuoteAssetReserve, newBaseAssetReserve] =
88
93
  calculateAmmReservesAfterSwap(
89
94
  market.amm,
@@ -102,7 +107,7 @@ export function calculateNewMarketAfterTrade(
102
107
  }
103
108
 
104
109
  export function calculateMarkOracleSpread(
105
- market: MarketAccount,
110
+ market: PerpMarketAccount,
106
111
  oraclePriceData: OraclePriceData
107
112
  ): BN {
108
113
  const markPrice = calculateMarkPrice(market, oraclePriceData);
@@ -117,7 +122,7 @@ export function calculateOracleSpread(
117
122
  }
118
123
 
119
124
  export function calculateMarketMarginRatio(
120
- market: MarketAccount,
125
+ market: PerpMarketAccount,
121
126
  size: BN,
122
127
  marginCategory: MarginCategory
123
128
  ): number {
@@ -140,18 +145,34 @@ export function calculateMarketMarginRatio(
140
145
  }
141
146
 
142
147
  export function calculateUnrealizedAssetWeight(
143
- market: MarketAccount,
148
+ market: PerpMarketAccount,
149
+ quoteSpotMarket: SpotMarketAccount,
144
150
  unrealizedPnl: BN,
145
- marginCategory: MarginCategory
151
+ marginCategory: MarginCategory,
152
+ oraclePriceData: OraclePriceData
146
153
  ): BN {
147
154
  let assetWeight: BN;
148
-
149
155
  switch (marginCategory) {
150
156
  case 'Initial':
157
+ assetWeight = new BN(market.unrealizedInitialAssetWeight);
158
+
159
+ if (market.unrealizedMaxImbalance.gt(ZERO)) {
160
+ const netUnsettledPnl = calculateNetUserImbalance(
161
+ market,
162
+ quoteSpotMarket,
163
+ oraclePriceData
164
+ );
165
+ if (netUnsettledPnl.gt(market.unrealizedMaxImbalance)) {
166
+ assetWeight = assetWeight
167
+ .mul(market.unrealizedMaxImbalance)
168
+ .div(netUnsettledPnl);
169
+ }
170
+ }
171
+
151
172
  assetWeight = calculateSizeDiscountAssetWeight(
152
173
  unrealizedPnl,
153
174
  market.unrealizedImfFactor,
154
- new BN(market.unrealizedInitialAssetWeight)
175
+ assetWeight
155
176
  );
156
177
  break;
157
178
  case 'Maintenance':
@@ -163,8 +184,39 @@ export function calculateUnrealizedAssetWeight(
163
184
  }
164
185
 
165
186
  export function calculateMarketAvailablePNL(
166
- market: MarketAccount,
167
- bank: BankAccount
187
+ perpMarket: PerpMarketAccount,
188
+ spotMarket: SpotMarketAccount
189
+ ): BN {
190
+ return getTokenAmount(
191
+ perpMarket.pnlPool.balance,
192
+ spotMarket,
193
+ SpotBalanceType.DEPOSIT
194
+ );
195
+ }
196
+
197
+ export function calculateNetUserImbalance(
198
+ market: PerpMarketAccount,
199
+ bank: SpotMarketAccount,
200
+ oraclePriceData: OraclePriceData
168
201
  ): BN {
169
- return getTokenAmount(market.pnlPool.balance, bank, BankBalanceType.DEPOSIT);
202
+ const netUserPositionValue = market.amm.netBaseAssetAmount
203
+ .mul(oraclePriceData.price)
204
+ .div(BASE_PRECISION)
205
+ .div(PRICE_TO_QUOTE_PRECISION);
206
+
207
+ const netUserCostBasis = market.amm.quoteAssetAmountLong
208
+ .add(market.amm.quoteAssetAmountShort)
209
+ .sub(market.amm.cumulativeSocialLoss);
210
+
211
+ const userEntitledPnl = netUserPositionValue.add(netUserCostBasis);
212
+
213
+ const pnlPool = getTokenAmount(
214
+ market.pnlPool.balance,
215
+ bank,
216
+ SpotBalanceType.DEPOSIT
217
+ );
218
+
219
+ const imbalance = userEntitledPnl.sub(pnlPool);
220
+
221
+ return imbalance;
170
222
  }
@@ -1,20 +1,32 @@
1
1
  "use strict";
2
- Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.isOracleValid = void 0;
4
- const numericConstants_1 = require("../constants/numericConstants");
5
- const index_1 = require("../index");
2
+ exports.__esModule = true;
3
+ exports.isOracleTooDivergent = exports.isOracleValid = exports.oraclePriceBands = void 0;
4
+ var numericConstants_1 = require("../constants/numericConstants");
5
+ var index_1 = require("../index");
6
+ var assert_1 = require("../assert/assert");
7
+ function oraclePriceBands(market, oraclePriceData) {
8
+ var maxPercentDiff = market.marginRatioInitial - market.marginRatioMaintenance;
9
+ var offset = oraclePriceData.price
10
+ .mul(new index_1.BN(maxPercentDiff))
11
+ .div(numericConstants_1.MARGIN_PRECISION);
12
+ (0, assert_1.assert)(offset.gt(numericConstants_1.ZERO));
13
+ return [oraclePriceData.price.sub(offset), oraclePriceData.price.add(offset)];
14
+ }
15
+ exports.oraclePriceBands = oraclePriceBands;
6
16
  function isOracleValid(amm, oraclePriceData, oracleGuardRails, slot) {
7
- const isOraclePriceNonPositive = oraclePriceData.price.lt(numericConstants_1.ZERO);
8
- const isOraclePriceTooVolatile = oraclePriceData.price
17
+ var isOraclePriceNonPositive = oraclePriceData.price.lte(numericConstants_1.ZERO);
18
+ var isOraclePriceTooVolatile = oraclePriceData.price
9
19
  .div(index_1.BN.max(numericConstants_1.ONE, amm.lastOraclePriceTwap))
10
20
  .gt(oracleGuardRails.validity.tooVolatileRatio) ||
11
21
  amm.lastOraclePriceTwap
12
22
  .div(index_1.BN.max(numericConstants_1.ONE, oraclePriceData.price))
13
23
  .gt(oracleGuardRails.validity.tooVolatileRatio);
14
- const isConfidenceTooLarge = oraclePriceData.price
15
- .div(index_1.BN.max(numericConstants_1.ONE, oraclePriceData.confidence))
16
- .lt(oracleGuardRails.validity.confidenceIntervalMaxSize);
17
- const oracleIsStale = oraclePriceData.slot
24
+ var isConfidenceTooLarge = new index_1.BN(amm.baseSpread)
25
+ .add(index_1.BN.max(numericConstants_1.ONE, oraclePriceData.confidence))
26
+ .mul(numericConstants_1.BID_ASK_SPREAD_PRECISION)
27
+ .div(oraclePriceData.price)
28
+ .gt(new index_1.BN(amm.maxSpread));
29
+ var oracleIsStale = oraclePriceData.slot
18
30
  .sub(new index_1.BN(slot))
19
31
  .gt(oracleGuardRails.validity.slotsBeforeStale);
20
32
  return !(!oraclePriceData.hasSufficientNumberOfDataPoints ||
@@ -24,3 +36,21 @@ function isOracleValid(amm, oraclePriceData, oracleGuardRails, slot) {
24
36
  isConfidenceTooLarge);
25
37
  }
26
38
  exports.isOracleValid = isOracleValid;
39
+ function isOracleTooDivergent(amm, oraclePriceData, oracleGuardRails, now) {
40
+ var sinceLastUpdate = now.sub(amm.lastOraclePriceTwapTs);
41
+ var sinceStart = index_1.BN.max(numericConstants_1.ZERO, new index_1.BN(60 * 5).sub(sinceLastUpdate));
42
+ var oracleTwap5min = amm.lastOraclePriceTwap5min
43
+ .mul(sinceStart)
44
+ .add(oraclePriceData.price)
45
+ .mul(sinceLastUpdate)
46
+ .div(sinceStart.add(sinceLastUpdate));
47
+ var oracleSpread = oracleTwap5min.sub(oraclePriceData.price);
48
+ var oracleSpreadPct = oracleSpread
49
+ .mul(numericConstants_1.MARK_PRICE_PRECISION)
50
+ .div(oracleTwap5min);
51
+ var tooDivergent = oracleSpreadPct
52
+ .abs()
53
+ .gte(numericConstants_1.BID_ASK_SPREAD_PRECISION.mul(oracleGuardRails.priceDivergence.markOracleDivergenceNumerator).div(oracleGuardRails.priceDivergence.markOracleDivergenceDenominator));
54
+ return tooDivergent;
55
+ }
56
+ exports.isOracleTooDivergent = isOracleTooDivergent;
@@ -2,11 +2,28 @@ import { AMM, OracleGuardRails } from '../types';
2
2
  import { OraclePriceData } from '../oracles/types';
3
3
  import {
4
4
  BID_ASK_SPREAD_PRECISION,
5
+ MARGIN_PRECISION,
5
6
  MARK_PRICE_PRECISION,
6
7
  ONE,
7
8
  ZERO,
8
9
  } from '../constants/numericConstants';
9
- import { BN } from '../index';
10
+ import { BN, PerpMarketAccount } from '../index';
11
+ import { assert } from '../assert/assert';
12
+
13
+ export function oraclePriceBands(
14
+ market: PerpMarketAccount,
15
+ oraclePriceData: OraclePriceData
16
+ ): [BN, BN] {
17
+ const maxPercentDiff =
18
+ market.marginRatioInitial - market.marginRatioMaintenance;
19
+ const offset = oraclePriceData.price
20
+ .mul(new BN(maxPercentDiff))
21
+ .div(MARGIN_PRECISION);
22
+
23
+ assert(offset.gt(ZERO));
24
+
25
+ return [oraclePriceData.price.sub(offset), oraclePriceData.price.add(offset)];
26
+ }
10
27
 
11
28
  export function isOracleValid(
12
29
  amm: AMM,