@drift-labs/sdk 0.2.0-master.3 → 0.2.0-master.31

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 (208) hide show
  1. package/README.md +13 -13
  2. package/lib/accounts/bulkUserStatsSubscription.d.ts +7 -0
  3. package/lib/accounts/bulkUserStatsSubscription.js +21 -0
  4. package/lib/accounts/bulkUserSubscription.js +0 -1
  5. package/lib/accounts/fetch.d.ts +2 -1
  6. package/lib/accounts/fetch.js +9 -1
  7. package/lib/accounts/pollingClearingHouseAccountSubscriber.d.ts +16 -16
  8. package/lib/accounts/pollingClearingHouseAccountSubscriber.js +31 -28
  9. package/lib/accounts/pollingUserStatsAccountSubscriber.d.ts +27 -0
  10. package/lib/accounts/pollingUserStatsAccountSubscriber.js +113 -0
  11. package/lib/accounts/types.d.ts +22 -11
  12. package/lib/accounts/webSocketClearingHouseAccountSubscriber.d.ts +17 -17
  13. package/lib/accounts/webSocketClearingHouseAccountSubscriber.js +37 -35
  14. package/lib/accounts/webSocketUserStatsAccountSubsriber.d.ts +20 -0
  15. package/lib/accounts/webSocketUserStatsAccountSubsriber.js +47 -0
  16. package/lib/addresses/marketAddresses.d.ts +1 -3
  17. package/lib/addresses/pda.d.ts +10 -4
  18. package/lib/addresses/pda.js +51 -14
  19. package/lib/admin.d.ts +42 -26
  20. package/lib/admin.js +228 -81
  21. package/lib/clearingHouse.d.ts +130 -49
  22. package/lib/clearingHouse.js +1256 -367
  23. package/lib/clearingHouseConfig.d.ts +4 -4
  24. package/lib/clearingHouseUser.d.ts +51 -39
  25. package/lib/clearingHouseUser.js +408 -191
  26. package/lib/clearingHouseUserStats.d.ts +18 -0
  27. package/lib/clearingHouseUserStats.js +49 -0
  28. package/lib/clearingHouseUserStatsConfig.d.ts +14 -0
  29. package/lib/clearingHouseUserStatsConfig.js +2 -0
  30. package/lib/config.d.ts +7 -9
  31. package/lib/config.js +21 -21
  32. package/lib/constants/numericConstants.d.ts +25 -12
  33. package/lib/constants/numericConstants.js +35 -21
  34. package/lib/constants/perpMarkets.d.ts +18 -0
  35. package/lib/constants/{markets.js → perpMarkets.js} +7 -7
  36. package/lib/constants/spotMarkets.d.ts +19 -0
  37. package/lib/constants/spotMarkets.js +53 -0
  38. package/lib/dlob/DLOB.d.ts +74 -0
  39. package/lib/dlob/DLOB.js +595 -0
  40. package/lib/dlob/DLOBNode.d.ts +54 -0
  41. package/lib/dlob/DLOBNode.js +85 -0
  42. package/lib/dlob/NodeList.d.ts +26 -0
  43. package/lib/dlob/NodeList.js +139 -0
  44. package/lib/events/eventList.js +3 -0
  45. package/lib/events/eventSubscriber.d.ts +4 -2
  46. package/lib/events/eventSubscriber.js +16 -9
  47. package/lib/events/fetchLogs.d.ts +10 -1
  48. package/lib/events/fetchLogs.js +27 -7
  49. package/lib/events/pollingLogProvider.d.ts +2 -1
  50. package/lib/events/pollingLogProvider.js +6 -2
  51. package/lib/events/sort.js +8 -11
  52. package/lib/events/types.d.ts +8 -2
  53. package/lib/events/types.js +6 -0
  54. package/lib/examples/makeTradeExample.js +20 -8
  55. package/lib/factory/bigNum.d.ts +2 -0
  56. package/lib/factory/bigNum.js +48 -10
  57. package/lib/idl/clearing_house.json +4889 -1529
  58. package/lib/idl/{mock_usdc_faucet.json → token_faucet.json} +46 -23
  59. package/lib/index.d.ts +21 -6
  60. package/lib/index.js +25 -6
  61. package/lib/math/amm.d.ts +9 -6
  62. package/lib/math/amm.js +91 -66
  63. package/lib/math/auction.js +4 -1
  64. package/lib/math/conversion.js +1 -1
  65. package/lib/math/funding.d.ts +6 -6
  66. package/lib/math/funding.js +11 -10
  67. package/lib/math/insurance.d.ts +4 -0
  68. package/lib/math/insurance.js +27 -0
  69. package/lib/math/margin.d.ts +11 -0
  70. package/lib/math/margin.js +77 -0
  71. package/lib/math/market.d.ts +14 -9
  72. package/lib/math/market.js +72 -10
  73. package/lib/math/oracles.d.ts +4 -0
  74. package/lib/math/oracles.js +36 -8
  75. package/lib/math/orders.d.ts +6 -2
  76. package/lib/math/orders.js +78 -3
  77. package/lib/math/position.d.ts +21 -13
  78. package/lib/math/position.js +76 -36
  79. package/lib/math/repeg.js +14 -5
  80. package/lib/math/spotBalance.d.ts +22 -0
  81. package/lib/math/spotBalance.js +192 -0
  82. package/lib/math/spotMarket.d.ts +4 -0
  83. package/lib/math/spotMarket.js +8 -0
  84. package/lib/math/spotPosition.d.ts +6 -0
  85. package/lib/math/spotPosition.js +23 -0
  86. package/lib/math/trade.d.ts +10 -10
  87. package/lib/math/trade.js +32 -39
  88. package/lib/oracles/pythClient.js +1 -1
  89. package/lib/oracles/quoteAssetOracleClient.js +1 -1
  90. package/lib/oracles/switchboardClient.js +1 -1
  91. package/lib/orderParams.d.ts +14 -5
  92. package/lib/orderParams.js +12 -92
  93. package/lib/serum/serumSubscriber.d.ts +23 -0
  94. package/lib/serum/serumSubscriber.js +41 -0
  95. package/lib/serum/types.d.ts +11 -0
  96. package/lib/serum/types.js +2 -0
  97. package/lib/slot/SlotSubscriber.d.ts +7 -0
  98. package/lib/slot/SlotSubscriber.js +3 -0
  99. package/lib/{mockUSDCFaucet.d.ts → tokenFaucet.d.ts} +8 -5
  100. package/lib/{mockUSDCFaucet.js → tokenFaucet.js} +63 -51
  101. package/lib/tx/retryTxSender.d.ts +1 -1
  102. package/lib/tx/retryTxSender.js +13 -4
  103. package/lib/tx/types.d.ts +1 -1
  104. package/lib/tx/utils.js +1 -1
  105. package/lib/types.d.ts +566 -138
  106. package/lib/types.js +129 -5
  107. package/lib/userMap/userMap.d.ts +25 -0
  108. package/lib/userMap/userMap.js +73 -0
  109. package/lib/userMap/userStatsMap.d.ts +19 -0
  110. package/lib/userMap/userStatsMap.js +68 -0
  111. package/lib/util/computeUnits.js +1 -1
  112. package/lib/util/getTokenAddress.d.ts +2 -0
  113. package/lib/util/getTokenAddress.js +9 -0
  114. package/package.json +12 -6
  115. package/src/accounts/bulkUserStatsSubscription.ts +33 -0
  116. package/src/accounts/bulkUserSubscription.ts +0 -1
  117. package/src/accounts/fetch.ts +27 -2
  118. package/src/accounts/pollingClearingHouseAccountSubscriber.ts +46 -42
  119. package/src/accounts/pollingUserStatsAccountSubscriber.ts +172 -0
  120. package/src/accounts/types.ts +31 -11
  121. package/src/accounts/webSocketClearingHouseAccountSubscriber.ts +64 -59
  122. package/src/accounts/webSocketUserStatsAccountSubsriber.ts +80 -0
  123. package/src/addresses/marketAddresses.ts +1 -2
  124. package/src/addresses/pda.ts +88 -14
  125. package/src/admin.ts +452 -147
  126. package/src/assert/assert.js +9 -0
  127. package/src/clearingHouse.ts +2066 -467
  128. package/src/clearingHouseConfig.ts +4 -3
  129. package/src/clearingHouseUser.ts +747 -294
  130. package/src/clearingHouseUserStats.ts +75 -0
  131. package/src/clearingHouseUserStatsConfig.ts +18 -0
  132. package/src/config.ts +30 -31
  133. package/src/constants/numericConstants.ts +48 -25
  134. package/src/constants/{markets.ts → perpMarkets.ts} +10 -10
  135. package/src/constants/spotMarkets.ts +73 -0
  136. package/src/dlob/DLOB.ts +953 -0
  137. package/src/dlob/DLOBNode.ts +167 -0
  138. package/src/dlob/NodeList.ts +189 -0
  139. package/src/events/eventList.js +77 -0
  140. package/src/events/eventList.ts +3 -0
  141. package/src/events/eventSubscriber.ts +20 -12
  142. package/src/events/fetchLogs.ts +35 -8
  143. package/src/events/pollingLogProvider.ts +10 -2
  144. package/src/events/sort.ts +11 -15
  145. package/src/events/types.ts +19 -1
  146. package/src/examples/makeTradeExample.js +157 -0
  147. package/src/examples/makeTradeExample.ts +32 -14
  148. package/src/factory/bigNum.ts +65 -13
  149. package/src/idl/clearing_house.json +4889 -1529
  150. package/src/idl/{mock_usdc_faucet.json → token_faucet.json} +46 -23
  151. package/src/index.ts +21 -6
  152. package/src/math/amm.ts +171 -88
  153. package/src/math/auction.ts +5 -1
  154. package/src/math/conversion.ts +2 -2
  155. package/src/math/funding.ts +20 -18
  156. package/src/math/insurance.ts +35 -0
  157. package/src/math/margin.ts +127 -0
  158. package/src/math/market.ts +145 -14
  159. package/src/math/oracles.ts +63 -9
  160. package/src/math/orders.ts +138 -4
  161. package/src/math/position.ts +119 -58
  162. package/src/math/repeg.ts +16 -6
  163. package/src/math/spotBalance.ts +319 -0
  164. package/src/math/spotMarket.ts +9 -0
  165. package/src/math/spotPosition.ts +47 -0
  166. package/src/math/trade.ts +53 -59
  167. package/src/oracles/pythClient.ts +2 -2
  168. package/src/oracles/quoteAssetOracleClient.ts +2 -2
  169. package/src/oracles/switchboardClient.ts +2 -2
  170. package/src/orderParams.ts +24 -137
  171. package/src/serum/serumSubscriber.ts +80 -0
  172. package/src/serum/types.ts +13 -0
  173. package/src/slot/SlotSubscriber.ts +11 -1
  174. package/src/token/index.js +38 -0
  175. package/src/{mockUSDCFaucet.ts → tokenFaucet.ts} +82 -70
  176. package/src/tx/retryTxSender.ts +16 -5
  177. package/src/tx/types.js +2 -0
  178. package/src/tx/types.ts +2 -1
  179. package/src/tx/utils.js +17 -0
  180. package/src/tx/utils.ts +1 -1
  181. package/src/types.ts +533 -140
  182. package/src/userMap/userMap.ts +100 -0
  183. package/src/userMap/userStatsMap.ts +110 -0
  184. package/src/util/computeUnits.js +21 -11
  185. package/src/util/computeUnits.ts +1 -1
  186. package/src/util/getTokenAddress.js +9 -0
  187. package/src/util/getTokenAddress.ts +18 -0
  188. package/src/util/promiseTimeout.js +14 -0
  189. package/src/util/tps.js +27 -0
  190. package/tests/bn/test.ts +24 -10
  191. package/tests/dlob/helpers.ts +397 -0
  192. package/tests/dlob/test.ts +3688 -0
  193. package/lib/constants/banks.d.ts +0 -16
  194. package/lib/constants/banks.js +0 -34
  195. package/lib/constants/markets.d.ts +0 -19
  196. package/lib/math/bankBalance.d.ts +0 -9
  197. package/lib/math/bankBalance.js +0 -75
  198. package/lib/math/state.d.ts +0 -8
  199. package/lib/math/state.js +0 -15
  200. package/lib/orders.d.ts +0 -8
  201. package/lib/orders.js +0 -134
  202. package/src/constants/banks.ts +0 -43
  203. package/src/math/bankBalance.ts +0 -112
  204. package/src/math/state.ts +0 -14
  205. package/src/math/utils.js +0 -27
  206. package/src/math/utils.js.map +0 -1
  207. package/src/orders.ts +0 -244
  208. package/src/util/computeUnits.js.map +0 -1
@@ -1,6 +1,6 @@
1
1
  /// <reference types="bn.js" />
2
2
  import { BN } from '@project-serum/anchor';
3
- import { MarketAccount } from '../types';
3
+ import { PerpMarketAccount } from '../types';
4
4
  import { OraclePriceData } from '../oracles/types';
5
5
  /**
6
6
  *
@@ -9,7 +9,7 @@ import { OraclePriceData } from '../oracles/types';
9
9
  * @param periodAdjustment
10
10
  * @returns Estimated funding rate. : Precision //TODO-PRECISION
11
11
  */
12
- export declare function calculateAllEstimatedFundingRate(market: MarketAccount, oraclePriceData?: OraclePriceData, periodAdjustment?: BN): Promise<[BN, BN, BN, BN, BN]>;
12
+ export declare function calculateAllEstimatedFundingRate(market: PerpMarketAccount, oraclePriceData?: OraclePriceData, periodAdjustment?: BN): Promise<[BN, BN, BN, BN, BN]>;
13
13
  /**
14
14
  *
15
15
  * @param market
@@ -18,7 +18,7 @@ export declare function calculateAllEstimatedFundingRate(market: MarketAccount,
18
18
  * @param estimationMethod
19
19
  * @returns Estimated funding rate. : Precision //TODO-PRECISION
20
20
  */
21
- export declare function calculateEstimatedFundingRate(market: MarketAccount, oraclePriceData?: OraclePriceData, periodAdjustment?: BN, estimationMethod?: 'interpolated' | 'lowerbound' | 'capped'): Promise<BN>;
21
+ export declare function calculateEstimatedFundingRate(market: PerpMarketAccount, oraclePriceData?: OraclePriceData, periodAdjustment?: BN, estimationMethod?: 'interpolated' | 'lowerbound' | 'capped'): Promise<BN>;
22
22
  /**
23
23
  *
24
24
  * @param market
@@ -26,7 +26,7 @@ export declare function calculateEstimatedFundingRate(market: MarketAccount, ora
26
26
  * @param periodAdjustment
27
27
  * @returns Estimated funding rate. : Precision //TODO-PRECISION
28
28
  */
29
- export declare function calculateLongShortFundingRate(market: MarketAccount, oraclePriceData?: OraclePriceData, periodAdjustment?: BN): Promise<[BN, BN]>;
29
+ export declare function calculateLongShortFundingRate(market: PerpMarketAccount, oraclePriceData?: OraclePriceData, periodAdjustment?: BN): Promise<[BN, BN]>;
30
30
  /**
31
31
  *
32
32
  * @param market
@@ -34,10 +34,10 @@ export declare function calculateLongShortFundingRate(market: MarketAccount, ora
34
34
  * @param periodAdjustment
35
35
  * @returns Estimated funding rate. : Precision //TODO-PRECISION
36
36
  */
37
- export declare function calculateLongShortFundingRateAndLiveTwaps(market: MarketAccount, oraclePriceData?: OraclePriceData, periodAdjustment?: BN): Promise<[BN, BN, BN, BN]>;
37
+ export declare function calculateLongShortFundingRateAndLiveTwaps(market: PerpMarketAccount, oraclePriceData?: OraclePriceData, periodAdjustment?: BN): Promise<[BN, BN, BN, BN]>;
38
38
  /**
39
39
  *
40
40
  * @param market
41
41
  * @returns Estimated fee pool size
42
42
  */
43
- export declare function calculateFundingPool(market: MarketAccount): BN;
43
+ export declare function calculateFundingPool(market: PerpMarketAccount): BN;
@@ -3,6 +3,7 @@ Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.calculateFundingPool = exports.calculateLongShortFundingRateAndLiveTwaps = exports.calculateLongShortFundingRate = exports.calculateEstimatedFundingRate = exports.calculateAllEstimatedFundingRate = void 0;
4
4
  const anchor_1 = require("@project-serum/anchor");
5
5
  const numericConstants_1 = require("../constants/numericConstants");
6
+ const types_1 = require("../types");
6
7
  const market_1 = require("./market");
7
8
  /**
8
9
  *
@@ -19,7 +20,7 @@ async function calculateAllEstimatedFundingRate(market, oraclePriceData, periodA
19
20
  const secondsInHour = new anchor_1.BN(3600);
20
21
  const hoursInDay = new anchor_1.BN(24);
21
22
  const ONE = new anchor_1.BN(1);
22
- if (!market.initialized) {
23
+ if ((0, types_1.isVariant)(market.status, 'uninitialized')) {
23
24
  return [numericConstants_1.ZERO, numericConstants_1.ZERO, numericConstants_1.ZERO, numericConstants_1.ZERO, numericConstants_1.ZERO];
24
25
  }
25
26
  const payFreq = new anchor_1.BN(market.amm.fundingPeriod);
@@ -31,15 +32,15 @@ async function calculateAllEstimatedFundingRate(market, oraclePriceData, periodA
31
32
  const lastMarkPriceTwapTs = market.amm.lastMarkPriceTwapTs;
32
33
  const timeSinceLastMarkChange = now.sub(lastMarkPriceTwapTs);
33
34
  const markTwapTimeSinceLastUpdate = anchor_1.BN.max(secondsInHour, anchor_1.BN.max(numericConstants_1.ZERO, secondsInHour.sub(timeSinceLastMarkChange)));
34
- const baseAssetPriceWithMantissa = (0, market_1.calculateMarkPrice)(market, oraclePriceData);
35
+ const baseAssetPriceWithMantissa = (0, market_1.calculateReservePrice)(market, oraclePriceData);
35
36
  const markTwapWithMantissa = markTwapTimeSinceLastUpdate
36
37
  .mul(lastMarkTwapWithMantissa)
37
38
  .add(timeSinceLastMarkChange.mul(baseAssetPriceWithMantissa))
38
39
  .div(timeSinceLastMarkChange.add(markTwapTimeSinceLastUpdate));
39
40
  // calculate real-time (predicted) oracle twap
40
41
  // note: oracle twap depends on `when the chord is struck` (market is trade)
41
- const lastOracleTwapWithMantissa = market.amm.lastOraclePriceTwap;
42
- const lastOraclePriceTwapTs = market.amm.lastOraclePriceTwapTs;
42
+ const lastOracleTwapWithMantissa = market.amm.historicalOracleData.lastOraclePriceTwap;
43
+ const lastOraclePriceTwapTs = market.amm.historicalOracleData.lastOraclePriceTwapTs;
43
44
  const oracleInvalidDuration = anchor_1.BN.max(numericConstants_1.ZERO, lastMarkPriceTwapTs.sub(lastOraclePriceTwapTs));
44
45
  const timeSinceLastOracleTwapUpdate = now.sub(lastOraclePriceTwapTs);
45
46
  const oracleTwapTimeSinceLastUpdate = anchor_1.BN.max(ONE, anchor_1.BN.min(secondsInHour, anchor_1.BN.max(ONE, secondsInHour.sub(timeSinceLastOracleTwapUpdate))));
@@ -50,11 +51,11 @@ async function calculateAllEstimatedFundingRate(market, oraclePriceData, periodA
50
51
  const oracleLiveVsTwap = oraclePrice
51
52
  .sub(lastOracleTwapWithMantissa)
52
53
  .abs()
53
- .mul(numericConstants_1.MARK_PRICE_PRECISION)
54
+ .mul(numericConstants_1.PRICE_PRECISION)
54
55
  .mul(new anchor_1.BN(100))
55
56
  .div(lastOracleTwapWithMantissa);
56
57
  // verify pyth live input is within 10% of last twap for live update
57
- if (oracleLiveVsTwap.lte(numericConstants_1.MARK_PRICE_PRECISION.mul(new anchor_1.BN(10)))) {
58
+ if (oracleLiveVsTwap.lte(numericConstants_1.PRICE_PRECISION.mul(new anchor_1.BN(10)))) {
58
59
  oracleTwapWithMantissa = oracleTwapTimeSinceLastUpdate
59
60
  .mul(lastOracleTwapWithMantissa)
60
61
  .add(timeSinceLastMarkChange.mul(oraclePrice))
@@ -67,7 +68,7 @@ async function calculateAllEstimatedFundingRate(market, oraclePriceData, periodA
67
68
  .div(oracleTwapTimeSinceLastUpdate.add(oracleInvalidDuration));
68
69
  const twapSpread = lastMarkTwapWithMantissa.sub(shrunkLastOracleTwapwithMantissa);
69
70
  const twapSpreadPct = twapSpread
70
- .mul(numericConstants_1.MARK_PRICE_PRECISION)
71
+ .mul(numericConstants_1.PRICE_PRECISION)
71
72
  .mul(new anchor_1.BN(100))
72
73
  .div(shrunkLastOracleTwapwithMantissa);
73
74
  const lowerboundEst = twapSpreadPct
@@ -81,7 +82,7 @@ async function calculateAllEstimatedFundingRate(market, oraclePriceData, periodA
81
82
  const interpRateQuote = twapSpreadPct
82
83
  .mul(periodAdjustment)
83
84
  .div(hoursInDay)
84
- .div(numericConstants_1.MARK_PRICE_PRECISION.div(numericConstants_1.QUOTE_PRECISION));
85
+ .div(numericConstants_1.PRICE_PRECISION.div(numericConstants_1.QUOTE_PRECISION));
85
86
  let feePoolSize = calculateFundingPool(market);
86
87
  if (interpRateQuote.lt(new anchor_1.BN(0))) {
87
88
  feePoolSize = feePoolSize.mul(new anchor_1.BN(-1));
@@ -128,11 +129,11 @@ async function calculateAllEstimatedFundingRate(market, oraclePriceData, periodA
128
129
  // funding smaller flow
129
130
  cappedAltEst = smallerSide.mul(twapSpread).div(hoursInDay);
130
131
  const feePoolTopOff = feePoolSize
131
- .mul(numericConstants_1.MARK_PRICE_PRECISION.div(numericConstants_1.QUOTE_PRECISION))
132
+ .mul(numericConstants_1.PRICE_PRECISION.div(numericConstants_1.QUOTE_PRECISION))
132
133
  .mul(numericConstants_1.AMM_RESERVE_PRECISION);
133
134
  cappedAltEst = cappedAltEst.add(feePoolTopOff).div(largerSide);
134
135
  cappedAltEst = cappedAltEst
135
- .mul(numericConstants_1.MARK_PRICE_PRECISION)
136
+ .mul(numericConstants_1.PRICE_PRECISION)
136
137
  .mul(new anchor_1.BN(100))
137
138
  .div(oracleTwapWithMantissa)
138
139
  .mul(periodAdjustment);
@@ -0,0 +1,4 @@
1
+ /// <reference types="bn.js" />
2
+ import { BN } from '../index';
3
+ export declare function stakeAmountToShares(amount: BN, totalIfShares: BN, insuranceFundVaultBalance: BN): BN;
4
+ export declare function unstakeSharesToAmount(nShares: BN, totalIfShares: BN, insuranceFundVaultBalance: BN): BN;
@@ -0,0 +1,27 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.unstakeSharesToAmount = exports.stakeAmountToShares = void 0;
4
+ const numericConstants_1 = require("../constants/numericConstants");
5
+ const index_1 = require("../index");
6
+ function stakeAmountToShares(amount, totalIfShares, insuranceFundVaultBalance) {
7
+ let nShares;
8
+ if (insuranceFundVaultBalance.gt(numericConstants_1.ZERO)) {
9
+ nShares = amount.mul(totalIfShares).div(insuranceFundVaultBalance);
10
+ }
11
+ else {
12
+ nShares = amount;
13
+ }
14
+ return nShares;
15
+ }
16
+ exports.stakeAmountToShares = stakeAmountToShares;
17
+ function unstakeSharesToAmount(nShares, totalIfShares, insuranceFundVaultBalance) {
18
+ let amount;
19
+ if (totalIfShares.gt(numericConstants_1.ZERO)) {
20
+ amount = index_1.BN.max(numericConstants_1.ZERO, nShares.mul(insuranceFundVaultBalance).div(totalIfShares));
21
+ }
22
+ else {
23
+ amount = numericConstants_1.ZERO;
24
+ }
25
+ return amount;
26
+ }
27
+ exports.unstakeSharesToAmount = unstakeSharesToAmount;
@@ -0,0 +1,11 @@
1
+ /// <reference types="bn.js" />
2
+ import { BN } from '@project-serum/anchor';
3
+ import { OraclePriceData } from '../oracles/types';
4
+ import { PerpMarketAccount, PerpPosition } from '..';
5
+ export declare function calculateSizePremiumLiabilityWeight(size: BN, // AMM_RESERVE_PRECISION
6
+ imfFactor: BN, liabilityWeight: BN, precision: BN): BN;
7
+ export declare function calculateSizeDiscountAssetWeight(size: BN, // AMM_RESERVE_PRECISION
8
+ imfFactor: BN, assetWeight: BN): BN;
9
+ export declare function calculateOraclePriceForPerpMargin(perpPosition: PerpPosition, market: PerpMarketAccount, oraclePriceData: OraclePriceData): BN;
10
+ export declare function calculateBaseAssetValueWithOracle(market: PerpMarketAccount, perpPosition: PerpPosition, oraclePriceData: OraclePriceData): BN;
11
+ export declare function calculateWorstCaseBaseAssetAmount(perpPosition: PerpPosition): BN;
@@ -0,0 +1,77 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.calculateWorstCaseBaseAssetAmount = exports.calculateBaseAssetValueWithOracle = exports.calculateOraclePriceForPerpMargin = exports.calculateSizeDiscountAssetWeight = exports.calculateSizePremiumLiabilityWeight = void 0;
4
+ const utils_1 = require("./utils");
5
+ const numericConstants_1 = require("../constants/numericConstants");
6
+ const anchor_1 = require("@project-serum/anchor");
7
+ const 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
+ const sizeSqrt = (0, utils_1.squareRootBN)(size.mul(new anchor_1.BN(10)).add(new anchor_1.BN(1))); //1e9 -> 1e10 -> 1e5
14
+ const 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
+ const liabilityWeightNumerator = liabilityWeight.sub(liabilityWeight.div(anchor_1.BN.max(new anchor_1.BN(1), numericConstants_1.SPOT_MARKET_IMF_PRECISION.div(imfFactor))));
17
+ const 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
+ const sizePremiumLiabilityWeight = liabilityWeightNumerator.add(sizeSqrt // 1e5
20
+ .mul(imfFactor)
21
+ .div(denom) // 1e5
22
+ );
23
+ const 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
+ const sizeSqrt = (0, utils_1.squareRootBN)(size.mul(new anchor_1.BN(10)).add(new anchor_1.BN(1))); //1e9 -> 1e10 -> 1e5
33
+ const imfNumerator = numericConstants_1.SPOT_MARKET_IMF_PRECISION.add(numericConstants_1.SPOT_MARKET_IMF_PRECISION.div(new anchor_1.BN(10)));
34
+ const 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
+ const minAssetWeight = anchor_1.BN.min(assetWeight, sizeDiscountAssetWeight);
41
+ return minAssetWeight;
42
+ }
43
+ exports.calculateSizeDiscountAssetWeight = calculateSizeDiscountAssetWeight;
44
+ function calculateOraclePriceForPerpMargin(perpPosition, market, oraclePriceData) {
45
+ const 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
+ let 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_RESERVE_PRECISION);
65
+ }
66
+ exports.calculateBaseAssetValueWithOracle = calculateBaseAssetValueWithOracle;
67
+ function calculateWorstCaseBaseAssetAmount(perpPosition) {
68
+ const allBids = perpPosition.baseAssetAmount.add(perpPosition.openBids);
69
+ const 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,28 +1,33 @@
1
1
  /// <reference types="bn.js" />
2
2
  import { BN } from '@project-serum/anchor';
3
- import { MarketAccount, PositionDirection } from '../types';
3
+ import { PerpMarketAccount, PositionDirection, MarginCategory, SpotMarketAccount } from '../types';
4
4
  import { OraclePriceData } from '../oracles/types';
5
5
  /**
6
6
  * Calculates market mark price
7
7
  *
8
8
  * @param market
9
- * @return markPrice : Precision MARK_PRICE_PRECISION
9
+ * @return markPrice : Precision PRICE_PRECISION
10
10
  */
11
- export declare function calculateMarkPrice(market: MarketAccount, oraclePriceData: OraclePriceData): BN;
11
+ export declare function calculateReservePrice(market: PerpMarketAccount, oraclePriceData: OraclePriceData): BN;
12
12
  /**
13
13
  * Calculates market bid price
14
14
  *
15
15
  * @param market
16
- * @return bidPrice : Precision MARK_PRICE_PRECISION
16
+ * @return bidPrice : Precision PRICE_PRECISION
17
17
  */
18
- export declare function calculateBidPrice(market: MarketAccount, oraclePriceData: OraclePriceData): BN;
18
+ export declare function calculateBidPrice(market: PerpMarketAccount, oraclePriceData: OraclePriceData): BN;
19
19
  /**
20
20
  * Calculates market ask price
21
21
  *
22
22
  * @param market
23
- * @return bidPrice : Precision MARK_PRICE_PRECISION
23
+ * @return askPrice : Precision PRICE_PRECISION
24
24
  */
25
- export declare function calculateAskPrice(market: MarketAccount, oraclePriceData: OraclePriceData): BN;
26
- export declare function calculateNewMarketAfterTrade(baseAssetAmount: BN, direction: PositionDirection, market: MarketAccount): MarketAccount;
27
- export declare function calculateMarkOracleSpread(market: MarketAccount, oraclePriceData: OraclePriceData): BN;
25
+ export declare function calculateAskPrice(market: PerpMarketAccount, oraclePriceData: OraclePriceData): BN;
26
+ export declare function calculateNewMarketAfterTrade(baseAssetAmount: BN, direction: PositionDirection, market: PerpMarketAccount): PerpMarketAccount;
27
+ export declare function calculateOracleReserveSpread(market: PerpMarketAccount, oraclePriceData: OraclePriceData): BN;
28
28
  export declare function calculateOracleSpread(price: BN, oraclePriceData: OraclePriceData): BN;
29
+ export declare function calculateMarketMarginRatio(market: PerpMarketAccount, size: BN, marginCategory: MarginCategory): number;
30
+ export declare function calculateUnrealizedAssetWeight(market: PerpMarketAccount, quoteSpotMarket: SpotMarketAccount, unrealizedPnl: BN, marginCategory: MarginCategory, oraclePriceData: OraclePriceData): BN;
31
+ export declare function calculateMarketAvailablePNL(perpMarket: PerpMarketAccount, spotMarket: SpotMarketAccount): BN;
32
+ export declare function calculateNetUserPnl(perpMarket: PerpMarketAccount, oraclePriceData: OraclePriceData): BN;
33
+ export declare function calculateNetUserPnlImbalance(perpMarket: PerpMarketAccount, spotMarket: SpotMarketAccount, oraclePriceData: OraclePriceData): BN;
@@ -1,24 +1,28 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.calculateOracleSpread = exports.calculateMarkOracleSpread = exports.calculateNewMarketAfterTrade = exports.calculateAskPrice = exports.calculateBidPrice = exports.calculateMarkPrice = void 0;
3
+ exports.calculateNetUserPnlImbalance = exports.calculateNetUserPnl = exports.calculateMarketAvailablePNL = exports.calculateUnrealizedAssetWeight = exports.calculateMarketMarginRatio = exports.calculateOracleSpread = exports.calculateOracleReserveSpread = exports.calculateNewMarketAfterTrade = exports.calculateAskPrice = exports.calculateBidPrice = exports.calculateReservePrice = void 0;
4
+ const anchor_1 = require("@project-serum/anchor");
4
5
  const types_1 = require("../types");
5
6
  const amm_1 = require("./amm");
7
+ const margin_1 = require("./margin");
8
+ const numericConstants_1 = require("../constants/numericConstants");
9
+ const spotBalance_1 = require("./spotBalance");
6
10
  /**
7
11
  * Calculates market mark price
8
12
  *
9
13
  * @param market
10
- * @return markPrice : Precision MARK_PRICE_PRECISION
14
+ * @return markPrice : Precision PRICE_PRECISION
11
15
  */
12
- function calculateMarkPrice(market, oraclePriceData) {
16
+ function calculateReservePrice(market, oraclePriceData) {
13
17
  const newAmm = (0, amm_1.calculateUpdatedAMM)(market.amm, oraclePriceData);
14
18
  return (0, amm_1.calculatePrice)(newAmm.baseAssetReserve, newAmm.quoteAssetReserve, newAmm.pegMultiplier);
15
19
  }
16
- exports.calculateMarkPrice = calculateMarkPrice;
20
+ exports.calculateReservePrice = calculateReservePrice;
17
21
  /**
18
22
  * Calculates market bid price
19
23
  *
20
24
  * @param market
21
- * @return bidPrice : Precision MARK_PRICE_PRECISION
25
+ * @return bidPrice : Precision PRICE_PRECISION
22
26
  */
23
27
  function calculateBidPrice(market, oraclePriceData) {
24
28
  const { baseAssetReserve, quoteAssetReserve, newPeg } = (0, amm_1.calculateUpdatedAMMSpreadReserves)(market.amm, types_1.PositionDirection.SHORT, oraclePriceData);
@@ -29,7 +33,7 @@ exports.calculateBidPrice = calculateBidPrice;
29
33
  * Calculates market ask price
30
34
  *
31
35
  * @param market
32
- * @return bidPrice : Precision MARK_PRICE_PRECISION
36
+ * @return askPrice : Precision PRICE_PRECISION
33
37
  */
34
38
  function calculateAskPrice(market, oraclePriceData) {
35
39
  const { baseAssetReserve, quoteAssetReserve, newPeg } = (0, amm_1.calculateUpdatedAMMSpreadReserves)(market.amm, types_1.PositionDirection.LONG, oraclePriceData);
@@ -46,12 +50,70 @@ function calculateNewMarketAfterTrade(baseAssetAmount, direction, market) {
46
50
  return newMarket;
47
51
  }
48
52
  exports.calculateNewMarketAfterTrade = calculateNewMarketAfterTrade;
49
- function calculateMarkOracleSpread(market, oraclePriceData) {
50
- const markPrice = calculateMarkPrice(market, oraclePriceData);
51
- return calculateOracleSpread(markPrice, oraclePriceData);
53
+ function calculateOracleReserveSpread(market, oraclePriceData) {
54
+ const reservePrice = calculateReservePrice(market, oraclePriceData);
55
+ return calculateOracleSpread(reservePrice, oraclePriceData);
52
56
  }
53
- exports.calculateMarkOracleSpread = calculateMarkOracleSpread;
57
+ exports.calculateOracleReserveSpread = calculateOracleReserveSpread;
54
58
  function calculateOracleSpread(price, oraclePriceData) {
55
59
  return price.sub(oraclePriceData.price);
56
60
  }
57
61
  exports.calculateOracleSpread = calculateOracleSpread;
62
+ function calculateMarketMarginRatio(market, size, marginCategory) {
63
+ let 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 = (0, margin_1.calculateSizePremiumLiabilityWeight)(size, market.imfFactor, new anchor_1.BN(market.marginRatioMaintenance), numericConstants_1.MARGIN_PRECISION).toNumber();
70
+ break;
71
+ }
72
+ return marginRatio;
73
+ }
74
+ exports.calculateMarketMarginRatio = calculateMarketMarginRatio;
75
+ function calculateUnrealizedAssetWeight(market, quoteSpotMarket, unrealizedPnl, marginCategory, oraclePriceData) {
76
+ let assetWeight;
77
+ switch (marginCategory) {
78
+ case 'Initial':
79
+ assetWeight = new anchor_1.BN(market.unrealizedInitialAssetWeight);
80
+ if (market.unrealizedMaxImbalance.gt(numericConstants_1.ZERO)) {
81
+ const netUnsettledPnl = calculateNetUserPnlImbalance(market, quoteSpotMarket, oraclePriceData);
82
+ if (netUnsettledPnl.gt(market.unrealizedMaxImbalance)) {
83
+ assetWeight = assetWeight
84
+ .mul(market.unrealizedMaxImbalance)
85
+ .div(netUnsettledPnl);
86
+ }
87
+ }
88
+ assetWeight = (0, margin_1.calculateSizeDiscountAssetWeight)(unrealizedPnl, market.unrealizedImfFactor, assetWeight);
89
+ break;
90
+ case 'Maintenance':
91
+ assetWeight = new anchor_1.BN(market.unrealizedMaintenanceAssetWeight);
92
+ break;
93
+ }
94
+ return assetWeight;
95
+ }
96
+ exports.calculateUnrealizedAssetWeight = calculateUnrealizedAssetWeight;
97
+ function calculateMarketAvailablePNL(perpMarket, spotMarket) {
98
+ return (0, spotBalance_1.getTokenAmount)(perpMarket.pnlPool.balance, spotMarket, types_1.SpotBalanceType.DEPOSIT);
99
+ }
100
+ exports.calculateMarketAvailablePNL = calculateMarketAvailablePNL;
101
+ function calculateNetUserPnl(perpMarket, oraclePriceData) {
102
+ const netUserPositionValue = perpMarket.amm.netBaseAssetAmount
103
+ .mul(oraclePriceData.price)
104
+ .div(numericConstants_1.BASE_PRECISION)
105
+ .div(numericConstants_1.PRICE_TO_QUOTE_PRECISION);
106
+ const netUserCostBasis = perpMarket.amm.quoteAssetAmountLong
107
+ .add(perpMarket.amm.quoteAssetAmountShort)
108
+ .sub(perpMarket.amm.cumulativeSocialLoss);
109
+ const netUserPnl = netUserPositionValue.add(netUserCostBasis);
110
+ return netUserPnl;
111
+ }
112
+ exports.calculateNetUserPnl = calculateNetUserPnl;
113
+ function calculateNetUserPnlImbalance(perpMarket, spotMarket, oraclePriceData) {
114
+ const netUserPnl = calculateNetUserPnl(perpMarket, oraclePriceData);
115
+ const pnlPool = (0, spotBalance_1.getTokenAmount)(perpMarket.pnlPool.balance, spotMarket, types_1.SpotBalanceType.DEPOSIT);
116
+ const imbalance = netUserPnl.sub(pnlPool);
117
+ return imbalance;
118
+ }
119
+ exports.calculateNetUserPnlImbalance = calculateNetUserPnlImbalance;
@@ -1,3 +1,7 @@
1
+ /// <reference types="bn.js" />
1
2
  import { AMM, OracleGuardRails } from '../types';
2
3
  import { OraclePriceData } from '../oracles/types';
4
+ import { BN, PerpMarketAccount } from '../index';
5
+ export declare function oraclePriceBands(market: PerpMarketAccount, oraclePriceData: OraclePriceData): [BN, BN];
3
6
  export declare function isOracleValid(amm: AMM, oraclePriceData: OraclePriceData, oracleGuardRails: OracleGuardRails, slot: number): boolean;
7
+ export declare function isOracleTooDivergent(amm: AMM, oraclePriceData: OraclePriceData, oracleGuardRails: OracleGuardRails, now: BN): boolean;
@@ -1,22 +1,34 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.isOracleValid = void 0;
3
+ exports.isOracleTooDivergent = exports.isOracleValid = exports.oraclePriceBands = void 0;
4
4
  const numericConstants_1 = require("../constants/numericConstants");
5
5
  const index_1 = require("../index");
6
+ const assert_1 = require("../assert/assert");
7
+ function oraclePriceBands(market, oraclePriceData) {
8
+ const maxPercentDiff = market.marginRatioInitial - market.marginRatioMaintenance;
9
+ const 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);
17
+ const isOraclePriceNonPositive = oraclePriceData.price.lte(numericConstants_1.ZERO);
8
18
  const isOraclePriceTooVolatile = oraclePriceData.price
9
- .div(index_1.BN.max(numericConstants_1.ONE, amm.lastOraclePriceTwap))
19
+ .div(index_1.BN.max(numericConstants_1.ONE, amm.historicalOracleData.lastOraclePriceTwap))
10
20
  .gt(oracleGuardRails.validity.tooVolatileRatio) ||
11
- amm.lastOraclePriceTwap
21
+ amm.historicalOracleData.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);
24
+ const 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));
17
29
  const oracleIsStale = oraclePriceData.slot
18
30
  .sub(new index_1.BN(slot))
19
- .gt(oracleGuardRails.validity.slotsBeforeStale);
31
+ .gt(oracleGuardRails.validity.slotsBeforeStaleForAmm);
20
32
  return !(!oraclePriceData.hasSufficientNumberOfDataPoints ||
21
33
  oracleIsStale ||
22
34
  isOraclePriceNonPositive ||
@@ -24,3 +36,19 @@ function isOracleValid(amm, oraclePriceData, oracleGuardRails, slot) {
24
36
  isConfidenceTooLarge);
25
37
  }
26
38
  exports.isOracleValid = isOracleValid;
39
+ function isOracleTooDivergent(amm, oraclePriceData, oracleGuardRails, now) {
40
+ const sinceLastUpdate = now.sub(amm.historicalOracleData.lastOraclePriceTwapTs);
41
+ const sinceStart = index_1.BN.max(numericConstants_1.ZERO, new index_1.BN(60 * 5).sub(sinceLastUpdate));
42
+ const oracleTwap5min = amm.historicalOracleData.lastOraclePriceTwap5min
43
+ .mul(sinceStart)
44
+ .add(oraclePriceData.price)
45
+ .mul(sinceLastUpdate)
46
+ .div(sinceStart.add(sinceLastUpdate));
47
+ const oracleSpread = oracleTwap5min.sub(oraclePriceData.price);
48
+ const oracleSpreadPct = oracleSpread.mul(numericConstants_1.PRICE_PRECISION).div(oracleTwap5min);
49
+ const tooDivergent = oracleSpreadPct
50
+ .abs()
51
+ .gte(numericConstants_1.BID_ASK_SPREAD_PRECISION.mul(oracleGuardRails.priceDivergence.markOracleDivergenceNumerator).div(oracleGuardRails.priceDivergence.markOracleDivergenceDenominator));
52
+ return tooDivergent;
53
+ }
54
+ exports.isOracleTooDivergent = isOracleTooDivergent;
@@ -1,10 +1,14 @@
1
1
  /// <reference types="bn.js" />
2
2
  import { ClearingHouseUser } from '../clearingHouseUser';
3
- import { Order } from '../types';
3
+ import { PerpMarketAccount, Order } from '../types';
4
4
  import { BN } from '@project-serum/anchor';
5
5
  import { OraclePriceData } from '../oracles/types';
6
6
  export declare function isOrderRiskIncreasing(user: ClearingHouseUser, order: Order): boolean;
7
7
  export declare function isOrderRiskIncreasingInSameDirection(user: ClearingHouseUser, order: Order): boolean;
8
8
  export declare function isOrderReduceOnly(user: ClearingHouseUser, order: Order): boolean;
9
9
  export declare function standardizeBaseAssetAmount(baseAssetAmount: BN, stepSize: BN): BN;
10
- export declare function getLimitPrice(order: Order, oraclePriceData: OraclePriceData, slot: number): BN;
10
+ export declare function getLimitPrice(order: Order, oraclePriceData: OraclePriceData, slot: number, perpMarket?: PerpMarketAccount): BN;
11
+ export declare function isFillableByVAMM(order: Order, market: PerpMarketAccount, oraclePriceData: OraclePriceData, slot: number): boolean;
12
+ export declare function calculateBaseAssetAmountForAmmToFulfill(order: Order, market: PerpMarketAccount, oraclePriceData: OraclePriceData, slot: number): BN;
13
+ export declare function calculateBaseAssetAmountToFillUpToLimitPrice(order: Order, market: PerpMarketAccount, limitPrice: BN, oraclePriceData: OraclePriceData): BN;
14
+ export declare function isOrderExpired(order: Order, slot: number): boolean;
@@ -1,9 +1,12 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.getLimitPrice = exports.standardizeBaseAssetAmount = exports.isOrderReduceOnly = exports.isOrderRiskIncreasingInSameDirection = exports.isOrderRiskIncreasing = void 0;
3
+ exports.isOrderExpired = exports.calculateBaseAssetAmountToFillUpToLimitPrice = exports.calculateBaseAssetAmountForAmmToFulfill = exports.isFillableByVAMM = exports.getLimitPrice = exports.standardizeBaseAssetAmount = exports.isOrderReduceOnly = exports.isOrderRiskIncreasingInSameDirection = exports.isOrderRiskIncreasing = void 0;
4
4
  const types_1 = require("../types");
5
5
  const numericConstants_1 = require("../constants/numericConstants");
6
+ const anchor_1 = require("@project-serum/anchor");
6
7
  const auction_1 = require("./auction");
8
+ const market_1 = require("./market");
9
+ const amm_1 = require("./amm");
7
10
  function isOrderRiskIncreasing(user, order) {
8
11
  if ((0, types_1.isVariant)(order.status, 'init')) {
9
12
  return false;
@@ -77,13 +80,42 @@ function standardizeBaseAssetAmount(baseAssetAmount, stepSize) {
77
80
  return baseAssetAmount.sub(remainder);
78
81
  }
79
82
  exports.standardizeBaseAssetAmount = standardizeBaseAssetAmount;
80
- function getLimitPrice(order, oraclePriceData, slot) {
83
+ function getLimitPrice(order, oraclePriceData, slot, perpMarket) {
81
84
  let limitPrice;
82
85
  if (!order.oraclePriceOffset.eq(numericConstants_1.ZERO)) {
83
86
  limitPrice = oraclePriceData.price.add(order.oraclePriceOffset);
84
87
  }
85
88
  else if ((0, types_1.isOneOfVariant)(order.orderType, ['market', 'triggerMarket'])) {
86
- limitPrice = (0, auction_1.getAuctionPrice)(order, slot);
89
+ if (!(0, auction_1.isAuctionComplete)(order, slot)) {
90
+ limitPrice = (0, auction_1.getAuctionPrice)(order, slot);
91
+ }
92
+ else if (!order.price.eq(numericConstants_1.ZERO)) {
93
+ limitPrice = order.price;
94
+ }
95
+ else {
96
+ if (perpMarket) {
97
+ if ((0, types_1.isVariant)(order.direction, 'long')) {
98
+ const askPrice = (0, market_1.calculateAskPrice)(perpMarket, oraclePriceData);
99
+ const delta = askPrice.div(new anchor_1.BN(perpMarket.amm.maxSlippageRatio));
100
+ limitPrice = askPrice.add(delta);
101
+ }
102
+ else {
103
+ const bidPrice = (0, market_1.calculateBidPrice)(perpMarket, oraclePriceData);
104
+ const delta = bidPrice.div(new anchor_1.BN(perpMarket.amm.maxSlippageRatio));
105
+ limitPrice = bidPrice.sub(delta);
106
+ }
107
+ }
108
+ else {
109
+ // check oracle validity?
110
+ const oraclePrice1Pct = oraclePriceData.price.div(new anchor_1.BN(100));
111
+ if ((0, types_1.isVariant)(order.direction, 'long')) {
112
+ limitPrice = oraclePriceData.price.add(oraclePrice1Pct);
113
+ }
114
+ else {
115
+ limitPrice = oraclePriceData.price.sub(oraclePrice1Pct);
116
+ }
117
+ }
118
+ }
87
119
  }
88
120
  else {
89
121
  limitPrice = order.price;
@@ -91,3 +123,46 @@ function getLimitPrice(order, oraclePriceData, slot) {
91
123
  return limitPrice;
92
124
  }
93
125
  exports.getLimitPrice = getLimitPrice;
126
+ function isFillableByVAMM(order, market, oraclePriceData, slot) {
127
+ return (((0, auction_1.isAuctionComplete)(order, slot) &&
128
+ !calculateBaseAssetAmountForAmmToFulfill(order, market, oraclePriceData, slot).eq(numericConstants_1.ZERO)) ||
129
+ isOrderExpired(order, slot));
130
+ }
131
+ exports.isFillableByVAMM = isFillableByVAMM;
132
+ function calculateBaseAssetAmountForAmmToFulfill(order, market, oraclePriceData, slot) {
133
+ if ((0, types_1.isOneOfVariant)(order.orderType, ['triggerMarket', 'triggerLimit']) &&
134
+ order.triggered === false) {
135
+ return numericConstants_1.ZERO;
136
+ }
137
+ const limitPrice = getLimitPrice(order, oraclePriceData, slot, market);
138
+ const baseAssetAmount = calculateBaseAssetAmountToFillUpToLimitPrice(order, market, limitPrice, oraclePriceData);
139
+ const maxBaseAssetAmount = (0, amm_1.calculateMaxBaseAssetAmountFillable)(market.amm, order.direction);
140
+ return anchor_1.BN.min(maxBaseAssetAmount, baseAssetAmount);
141
+ }
142
+ exports.calculateBaseAssetAmountForAmmToFulfill = calculateBaseAssetAmountForAmmToFulfill;
143
+ function calculateBaseAssetAmountToFillUpToLimitPrice(order, market, limitPrice, oraclePriceData) {
144
+ const [maxAmountToTrade, direction] = (0, amm_1.calculateMaxBaseAssetAmountToTrade)(market.amm, limitPrice, order.direction, oraclePriceData);
145
+ const baseAssetAmount = standardizeBaseAssetAmount(maxAmountToTrade, market.amm.baseAssetAmountStepSize);
146
+ // Check that directions are the same
147
+ const sameDirection = isSameDirection(direction, order.direction);
148
+ if (!sameDirection) {
149
+ return numericConstants_1.ZERO;
150
+ }
151
+ return baseAssetAmount.gt(order.baseAssetAmount)
152
+ ? order.baseAssetAmount
153
+ : baseAssetAmount;
154
+ }
155
+ exports.calculateBaseAssetAmountToFillUpToLimitPrice = calculateBaseAssetAmountToFillUpToLimitPrice;
156
+ function isSameDirection(firstDirection, secondDirection) {
157
+ return (((0, types_1.isVariant)(firstDirection, 'long') && (0, types_1.isVariant)(secondDirection, 'long')) ||
158
+ ((0, types_1.isVariant)(firstDirection, 'short') && (0, types_1.isVariant)(secondDirection, 'short')));
159
+ }
160
+ function isOrderExpired(order, slot) {
161
+ if ((0, types_1.isOneOfVariant)(order.orderType, ['triggerMarket', 'triggerLimit']) ||
162
+ !(0, types_1.isVariant)(order.status, 'open') ||
163
+ order.timeInForce === 0) {
164
+ return false;
165
+ }
166
+ return new anchor_1.BN(slot).sub(order.slot).gt(new anchor_1.BN(order.timeInForce));
167
+ }
168
+ exports.isOrderExpired = isOrderExpired;