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

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 (143) hide show
  1. package/lib/accounts/pollingClearingHouseAccountSubscriber.d.ts +1 -0
  2. package/lib/accounts/pollingClearingHouseAccountSubscriber.js +3 -0
  3. package/lib/accounts/types.d.ts +1 -0
  4. package/lib/accounts/webSocketClearingHouseAccountSubscriber.d.ts +1 -0
  5. package/lib/accounts/webSocketClearingHouseAccountSubscriber.js +3 -0
  6. package/lib/admin.d.ts +5 -2
  7. package/lib/admin.js +30 -4
  8. package/lib/clearingHouse.d.ts +2 -0
  9. package/lib/clearingHouse.js +14 -1
  10. package/lib/clearingHouseUser.d.ts +11 -9
  11. package/lib/clearingHouseUser.js +182 -106
  12. package/lib/config.js +1 -1
  13. package/lib/dlob/DLOB.d.ts +73 -0
  14. package/lib/dlob/DLOB.js +557 -0
  15. package/lib/dlob/DLOBNode.d.ts +52 -0
  16. package/lib/dlob/DLOBNode.js +82 -0
  17. package/lib/dlob/NodeList.d.ts +26 -0
  18. package/lib/dlob/NodeList.js +138 -0
  19. package/lib/idl/clearing_house.json +122 -202
  20. package/lib/index.d.ts +5 -0
  21. package/lib/index.js +5 -0
  22. package/lib/math/market.d.ts +1 -1
  23. package/lib/math/market.js +1 -1
  24. package/lib/math/orders.d.ts +3 -3
  25. package/lib/math/orders.js +31 -16
  26. package/lib/math/spotBalance.d.ts +3 -0
  27. package/lib/math/spotBalance.js +18 -1
  28. package/lib/math/spotPosition.d.ts +5 -1
  29. package/lib/math/spotPosition.js +16 -1
  30. package/lib/types.d.ts +24 -23
  31. package/lib/types.js +9 -3
  32. package/lib/userMap/userMap.d.ts +25 -0
  33. package/lib/userMap/userMap.js +73 -0
  34. package/lib/userMap/userStatsMap.d.ts +19 -0
  35. package/lib/userMap/userStatsMap.js +68 -0
  36. package/package.json +6 -3
  37. package/src/accounts/pollingClearingHouseAccountSubscriber.ts +4 -0
  38. package/src/accounts/types.ts +1 -0
  39. package/src/accounts/webSocketClearingHouseAccountSubscriber.ts +6 -0
  40. package/src/addresses/marketAddresses.js +26 -0
  41. package/src/admin.ts +50 -8
  42. package/src/assert/assert.js +1 -1
  43. package/src/clearingHouse.ts +23 -1
  44. package/src/clearingHouseUser.ts +364 -165
  45. package/src/config.ts +1 -1
  46. package/src/constants/banks.js +42 -0
  47. package/src/constants/{perpMarkets.js → markets.js} +11 -11
  48. package/src/dlob/DLOB.ts +884 -0
  49. package/src/dlob/DLOBNode.ts +163 -0
  50. package/src/dlob/NodeList.ts +185 -0
  51. package/src/events/eventList.js +23 -66
  52. package/src/events/txEventCache.js +19 -22
  53. package/src/examples/makeTradeExample.js +157 -0
  54. package/src/factory/bigNum.js +180 -183
  55. package/src/factory/oracleClient.js +9 -9
  56. package/src/idl/clearing_house.json +122 -202
  57. package/src/index.ts +5 -0
  58. package/src/math/auction.js +10 -10
  59. package/src/math/conversion.js +3 -4
  60. package/src/math/funding.js +175 -223
  61. package/src/math/market.ts +1 -1
  62. package/src/math/orders.ts +29 -21
  63. package/src/math/repeg.js +40 -40
  64. package/src/math/spotBalance.ts +26 -0
  65. package/src/math/spotPosition.ts +42 -1
  66. package/src/math/trade.js +74 -81
  67. package/src/math/utils.js +7 -8
  68. package/src/math/utils.js.map +1 -0
  69. package/src/oracles/oracleClientCache.js +9 -10
  70. package/src/oracles/pythClient.js +17 -52
  71. package/src/oracles/quoteAssetOracleClient.js +13 -44
  72. package/src/oracles/switchboardClient.js +37 -69
  73. package/src/oracles/types.js +1 -1
  74. package/src/token/index.js +4 -4
  75. package/src/tx/types.js +1 -1
  76. package/src/tx/utils.js +6 -7
  77. package/src/types.ts +25 -23
  78. package/src/userMap/userMap.ts +100 -0
  79. package/src/userMap/userStatsMap.ts +110 -0
  80. package/src/userName.js +5 -5
  81. package/src/util/computeUnits.js +11 -46
  82. package/src/util/getTokenAddress.js +9 -0
  83. package/src/util/promiseTimeout.js +5 -5
  84. package/src/util/tps.js +12 -46
  85. package/src/wallet.js +18 -55
  86. package/tests/bn/test.ts +2 -3
  87. package/tests/dlob/helpers.ts +322 -0
  88. package/tests/dlob/test.ts +2865 -0
  89. package/my-script/.env +0 -7
  90. package/my-script/getUserStats.ts +0 -106
  91. package/my-script/multiConnections.ts +0 -119
  92. package/my-script/test-regex.ts +0 -11
  93. package/my-script/utils.ts +0 -52
  94. package/src/accounts/bulkAccountLoader.js +0 -249
  95. package/src/accounts/bulkUserStatsSubscription.js +0 -75
  96. package/src/accounts/bulkUserSubscription.js +0 -75
  97. package/src/accounts/fetch.js +0 -92
  98. package/src/accounts/pollingClearingHouseAccountSubscriber.js +0 -465
  99. package/src/accounts/pollingOracleSubscriber.js +0 -156
  100. package/src/accounts/pollingTokenAccountSubscriber.js +0 -141
  101. package/src/accounts/pollingUserAccountSubscriber.js +0 -208
  102. package/src/accounts/pollingUserStatsAccountSubscriber.js +0 -208
  103. package/src/accounts/types.js +0 -28
  104. package/src/accounts/utils.js +0 -7
  105. package/src/accounts/webSocketAccountSubscriber.js +0 -138
  106. package/src/accounts/webSocketClearingHouseAccountSubscriber.js +0 -433
  107. package/src/accounts/webSocketUserAccountSubscriber.js +0 -113
  108. package/src/accounts/webSocketUserStatsAccountSubsriber.js +0 -113
  109. package/src/addresses/pda.js +0 -186
  110. package/src/admin.js +0 -1284
  111. package/src/clearingHouse.js +0 -3433
  112. package/src/clearingHouseConfig.js +0 -2
  113. package/src/clearingHouseUser.js +0 -874
  114. package/src/clearingHouseUserConfig.js +0 -2
  115. package/src/clearingHouseUserStats.js +0 -115
  116. package/src/clearingHouseUserStatsConfig.js +0 -2
  117. package/src/config.js +0 -80
  118. package/src/constants/numericConstants.js +0 -48
  119. package/src/constants/spotMarkets.js +0 -51
  120. package/src/events/eventSubscriber.js +0 -202
  121. package/src/events/fetchLogs.js +0 -117
  122. package/src/events/pollingLogProvider.js +0 -113
  123. package/src/events/sort.js +0 -41
  124. package/src/events/types.js +0 -25
  125. package/src/events/webSocketLogProvider.js +0 -76
  126. package/src/index.js +0 -75
  127. package/src/math/amm.js +0 -422
  128. package/src/math/insurance.js +0 -27
  129. package/src/math/margin.js +0 -77
  130. package/src/math/market.js +0 -105
  131. package/src/math/oracles.js +0 -56
  132. package/src/math/orders.js +0 -153
  133. package/src/math/position.js +0 -172
  134. package/src/math/spotBalance.js +0 -176
  135. package/src/math/spotMarket.js +0 -8
  136. package/src/math/spotPosition.js +0 -8
  137. package/src/orderParams.js +0 -28
  138. package/src/serum/serumSubscriber.js +0 -102
  139. package/src/serum/types.js +0 -2
  140. package/src/slot/SlotSubscriber.js +0 -86
  141. package/src/tokenFaucet.js +0 -323
  142. package/src/tx/retryTxSender.js +0 -280
  143. package/src/types.js +0 -216
@@ -8,39 +8,11 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, ge
8
8
  step((generator = generator.apply(thisArg, _arguments || [])).next());
9
9
  });
10
10
  };
11
- var __generator = (this && this.__generator) || function (thisArg, body) {
12
- var _ = { label: 0, sent: function() { if (t[0] & 1) throw t[1]; return t[1]; }, trys: [], ops: [] }, f, y, t, g;
13
- return g = { next: verb(0), "throw": verb(1), "return": verb(2) }, typeof Symbol === "function" && (g[Symbol.iterator] = function() { return this; }), g;
14
- function verb(n) { return function (v) { return step([n, v]); }; }
15
- function step(op) {
16
- if (f) throw new TypeError("Generator is already executing.");
17
- while (_) try {
18
- if (f = 1, y && (t = op[0] & 2 ? y["return"] : op[0] ? y["throw"] || ((t = y["return"]) && t.call(y), 0) : y.next) && !(t = t.call(y, op[1])).done) return t;
19
- if (y = 0, t) op = [op[0] & 2, t.value];
20
- switch (op[0]) {
21
- case 0: case 1: t = op; break;
22
- case 4: _.label++; return { value: op[1], done: false };
23
- case 5: _.label++; y = op[1]; op = [0]; continue;
24
- case 7: op = _.ops.pop(); _.trys.pop(); continue;
25
- default:
26
- if (!(t = _.trys, t = t.length > 0 && t[t.length - 1]) && (op[0] === 6 || op[0] === 2)) { _ = 0; continue; }
27
- if (op[0] === 3 && (!t || (op[1] > t[0] && op[1] < t[3]))) { _.label = op[1]; break; }
28
- if (op[0] === 6 && _.label < t[1]) { _.label = t[1]; t = op; break; }
29
- if (t && _.label < t[2]) { _.label = t[2]; _.ops.push(op); break; }
30
- if (t[2]) _.ops.pop();
31
- _.trys.pop(); continue;
32
- }
33
- op = body.call(thisArg, _);
34
- } catch (e) { op = [6, e]; y = 0; } finally { f = t = 0; }
35
- if (op[0] & 5) throw op[1]; return { value: op[0] ? op[1] : void 0, done: true };
36
- }
37
- };
38
- exports.__esModule = true;
11
+ Object.defineProperty(exports, "__esModule", { value: true });
39
12
  exports.calculateFundingPool = exports.calculateLongShortFundingRateAndLiveTwaps = exports.calculateLongShortFundingRate = exports.calculateEstimatedFundingRate = exports.calculateAllEstimatedFundingRate = void 0;
40
- var anchor_1 = require("@project-serum/anchor");
41
- var numericConstants_1 = require("../constants/numericConstants");
42
- var types_1 = require("../types");
43
- var market_1 = require("./market");
13
+ const anchor_1 = require("@project-serum/anchor");
14
+ const numericConstants_1 = require("../constants/numericConstants");
15
+ const market_1 = require("./market");
44
16
  /**
45
17
  *
46
18
  * @param market
@@ -48,139 +20,146 @@ var market_1 = require("./market");
48
20
  * @param periodAdjustment
49
21
  * @returns Estimated funding rate. : Precision //TODO-PRECISION
50
22
  */
51
- function calculateAllEstimatedFundingRate(market, oraclePriceData, periodAdjustment) {
52
- if (periodAdjustment === void 0) { periodAdjustment = new anchor_1.BN(1); }
53
- return __awaiter(this, void 0, void 0, function () {
54
- var secondsInHour, hoursInDay, ONE, payFreq, now, timeSinceLastUpdate, lastMarkTwapWithMantissa, lastMarkPriceTwapTs, timeSinceLastMarkChange, markTwapTimeSinceLastUpdate, baseAssetPriceWithMantissa, markTwapWithMantissa, lastOracleTwapWithMantissa, lastOraclePriceTwapTs, oracleInvalidDuration, timeSinceLastOracleTwapUpdate, oracleTwapTimeSinceLastUpdate, oracleTwapWithMantissa, oraclePrice, oracleLiveVsTwap, shrunkLastOracleTwapwithMantissa, twapSpread, twapSpreadPct, lowerboundEst, interpEst, interpRateQuote, feePoolSize, cappedAltEst, largerSide, smallerSide, feePoolTopOff;
55
- return __generator(this, function (_a) {
56
- secondsInHour = new anchor_1.BN(3600);
57
- hoursInDay = new anchor_1.BN(24);
58
- ONE = new anchor_1.BN(1);
59
- if ((0, types_1.isVariant)(market.status, 'uninitialized')) {
60
- return [2 /*return*/, [numericConstants_1.ZERO, numericConstants_1.ZERO, numericConstants_1.ZERO, numericConstants_1.ZERO, numericConstants_1.ZERO]];
61
- }
62
- payFreq = new anchor_1.BN(market.amm.fundingPeriod);
63
- now = new anchor_1.BN((Date.now() / 1000).toFixed(0));
64
- timeSinceLastUpdate = now.sub(market.amm.lastFundingRateTs);
65
- lastMarkTwapWithMantissa = market.amm.lastMarkPriceTwap;
66
- lastMarkPriceTwapTs = market.amm.lastMarkPriceTwapTs;
67
- timeSinceLastMarkChange = now.sub(lastMarkPriceTwapTs);
68
- markTwapTimeSinceLastUpdate = anchor_1.BN.max(secondsInHour, anchor_1.BN.max(numericConstants_1.ZERO, secondsInHour.sub(timeSinceLastMarkChange)));
69
- baseAssetPriceWithMantissa = (0, market_1.calculateMarkPrice)(market, oraclePriceData);
70
- markTwapWithMantissa = markTwapTimeSinceLastUpdate
71
- .mul(lastMarkTwapWithMantissa)
72
- .add(timeSinceLastMarkChange.mul(baseAssetPriceWithMantissa))
73
- .div(timeSinceLastMarkChange.add(markTwapTimeSinceLastUpdate));
74
- lastOracleTwapWithMantissa = market.amm.lastOraclePriceTwap;
75
- lastOraclePriceTwapTs = market.amm.lastOraclePriceTwapTs;
76
- oracleInvalidDuration = anchor_1.BN.max(numericConstants_1.ZERO, lastMarkPriceTwapTs.sub(lastOraclePriceTwapTs));
77
- timeSinceLastOracleTwapUpdate = now.sub(lastOraclePriceTwapTs);
78
- oracleTwapTimeSinceLastUpdate = anchor_1.BN.max(ONE, anchor_1.BN.min(secondsInHour, anchor_1.BN.max(ONE, secondsInHour.sub(timeSinceLastOracleTwapUpdate))));
79
- oracleTwapWithMantissa = lastOracleTwapWithMantissa;
80
- // if passing live oracle data, improve predicted calc estimate
81
- if (oraclePriceData) {
82
- oraclePrice = oraclePriceData.price;
83
- oracleLiveVsTwap = oraclePrice
84
- .sub(lastOracleTwapWithMantissa)
85
- .abs()
86
- .mul(numericConstants_1.MARK_PRICE_PRECISION)
87
- .mul(new anchor_1.BN(100))
88
- .div(lastOracleTwapWithMantissa);
89
- // verify pyth live input is within 10% of last twap for live update
90
- if (oracleLiveVsTwap.lte(numericConstants_1.MARK_PRICE_PRECISION.mul(new anchor_1.BN(10)))) {
91
- oracleTwapWithMantissa = oracleTwapTimeSinceLastUpdate
92
- .mul(lastOracleTwapWithMantissa)
93
- .add(timeSinceLastMarkChange.mul(oraclePrice))
94
- .div(timeSinceLastMarkChange.add(oracleTwapTimeSinceLastUpdate));
95
- }
96
- }
97
- shrunkLastOracleTwapwithMantissa = oracleTwapTimeSinceLastUpdate
98
- .mul(lastOracleTwapWithMantissa)
99
- .add(oracleInvalidDuration.mul(lastMarkTwapWithMantissa))
100
- .div(oracleTwapTimeSinceLastUpdate.add(oracleInvalidDuration));
101
- twapSpread = lastMarkTwapWithMantissa.sub(shrunkLastOracleTwapwithMantissa);
102
- twapSpreadPct = twapSpread
23
+ function calculateAllEstimatedFundingRate(market, oraclePriceData, periodAdjustment = new anchor_1.BN(1)) {
24
+ return __awaiter(this, void 0, void 0, function* () {
25
+ // periodAdjustment
26
+ // 1: hourly
27
+ // 24: daily
28
+ // 24 * 365.25: annualized
29
+ const secondsInHour = new anchor_1.BN(3600);
30
+ const hoursInDay = new anchor_1.BN(24);
31
+ const ONE = new anchor_1.BN(1);
32
+ if (!market.initialized) {
33
+ return [numericConstants_1.ZERO, numericConstants_1.ZERO, numericConstants_1.ZERO, numericConstants_1.ZERO, numericConstants_1.ZERO];
34
+ }
35
+ const payFreq = new anchor_1.BN(market.amm.fundingPeriod);
36
+ // todo: sufficiently differs from blockchain timestamp?
37
+ const now = new anchor_1.BN((Date.now() / 1000).toFixed(0));
38
+ const timeSinceLastUpdate = now.sub(market.amm.lastFundingRateTs);
39
+ // calculate real-time mark twap
40
+ const lastMarkTwapWithMantissa = market.amm.lastMarkPriceTwap;
41
+ const lastMarkPriceTwapTs = market.amm.lastMarkPriceTwapTs;
42
+ const timeSinceLastMarkChange = now.sub(lastMarkPriceTwapTs);
43
+ const markTwapTimeSinceLastUpdate = anchor_1.BN.max(secondsInHour, anchor_1.BN.max(numericConstants_1.ZERO, secondsInHour.sub(timeSinceLastMarkChange)));
44
+ const baseAssetPriceWithMantissa = market_1.calculateMarkPrice(market, oraclePriceData);
45
+ const markTwapWithMantissa = markTwapTimeSinceLastUpdate
46
+ .mul(lastMarkTwapWithMantissa)
47
+ .add(timeSinceLastMarkChange.mul(baseAssetPriceWithMantissa))
48
+ .div(timeSinceLastMarkChange.add(markTwapTimeSinceLastUpdate));
49
+ // calculate real-time (predicted) oracle twap
50
+ // note: oracle twap depends on `when the chord is struck` (market is trade)
51
+ const lastOracleTwapWithMantissa = market.amm.lastOraclePriceTwap;
52
+ const lastOraclePriceTwapTs = market.amm.lastOraclePriceTwapTs;
53
+ const oracleInvalidDuration = anchor_1.BN.max(numericConstants_1.ZERO, lastMarkPriceTwapTs.sub(lastOraclePriceTwapTs));
54
+ const timeSinceLastOracleTwapUpdate = now.sub(lastOraclePriceTwapTs);
55
+ const oracleTwapTimeSinceLastUpdate = anchor_1.BN.max(ONE, anchor_1.BN.min(secondsInHour, anchor_1.BN.max(ONE, secondsInHour.sub(timeSinceLastOracleTwapUpdate))));
56
+ let oracleTwapWithMantissa = lastOracleTwapWithMantissa;
57
+ // if passing live oracle data, improve predicted calc estimate
58
+ if (oraclePriceData) {
59
+ const oraclePrice = oraclePriceData.price;
60
+ const oracleLiveVsTwap = oraclePrice
61
+ .sub(lastOracleTwapWithMantissa)
62
+ .abs()
103
63
  .mul(numericConstants_1.MARK_PRICE_PRECISION)
104
64
  .mul(new anchor_1.BN(100))
105
- .div(shrunkLastOracleTwapwithMantissa);
106
- lowerboundEst = twapSpreadPct
107
- .mul(payFreq)
108
- .mul(anchor_1.BN.min(secondsInHour, timeSinceLastUpdate))
109
- .mul(periodAdjustment)
110
- .div(secondsInHour)
111
- .div(secondsInHour)
112
- .div(hoursInDay);
113
- interpEst = twapSpreadPct.mul(periodAdjustment).div(hoursInDay);
114
- interpRateQuote = twapSpreadPct
115
- .mul(periodAdjustment)
116
- .div(hoursInDay)
117
- .div(numericConstants_1.MARK_PRICE_PRECISION.div(numericConstants_1.QUOTE_PRECISION));
118
- feePoolSize = calculateFundingPool(market);
119
- if (interpRateQuote.lt(new anchor_1.BN(0))) {
120
- feePoolSize = feePoolSize.mul(new anchor_1.BN(-1));
121
- }
122
- if (market.baseAssetAmountLong.gt(market.baseAssetAmountShort.abs())) {
123
- largerSide = market.baseAssetAmountLong.abs();
124
- smallerSide = market.baseAssetAmountShort.abs();
125
- if (twapSpread.gt(new anchor_1.BN(0))) {
126
- return [2 /*return*/, [
127
- markTwapWithMantissa,
128
- oracleTwapWithMantissa,
129
- lowerboundEst,
130
- interpEst,
131
- interpEst,
132
- ]];
133
- }
134
- }
135
- else if (market.baseAssetAmountLong.lt(market.baseAssetAmountShort.abs())) {
136
- largerSide = market.baseAssetAmountShort.abs();
137
- smallerSide = market.baseAssetAmountLong.abs();
138
- if (twapSpread.lt(new anchor_1.BN(0))) {
139
- return [2 /*return*/, [
140
- markTwapWithMantissa,
141
- oracleTwapWithMantissa,
142
- lowerboundEst,
143
- interpEst,
144
- interpEst,
145
- ]];
146
- }
65
+ .div(lastOracleTwapWithMantissa);
66
+ // verify pyth live input is within 10% of last twap for live update
67
+ if (oracleLiveVsTwap.lte(numericConstants_1.MARK_PRICE_PRECISION.mul(new anchor_1.BN(10)))) {
68
+ oracleTwapWithMantissa = oracleTwapTimeSinceLastUpdate
69
+ .mul(lastOracleTwapWithMantissa)
70
+ .add(timeSinceLastMarkChange.mul(oraclePrice))
71
+ .div(timeSinceLastMarkChange.add(oracleTwapTimeSinceLastUpdate));
147
72
  }
148
- else {
149
- return [2 /*return*/, [
150
- markTwapWithMantissa,
151
- oracleTwapWithMantissa,
152
- lowerboundEst,
153
- interpEst,
154
- interpEst,
155
- ]];
156
- }
157
- if (largerSide.gt(numericConstants_1.ZERO)) {
158
- // funding smaller flow
159
- cappedAltEst = smallerSide.mul(twapSpread).div(hoursInDay);
160
- feePoolTopOff = feePoolSize
161
- .mul(numericConstants_1.MARK_PRICE_PRECISION.div(numericConstants_1.QUOTE_PRECISION))
162
- .mul(numericConstants_1.AMM_RESERVE_PRECISION);
163
- cappedAltEst = cappedAltEst.add(feePoolTopOff).div(largerSide);
164
- cappedAltEst = cappedAltEst
165
- .mul(numericConstants_1.MARK_PRICE_PRECISION)
166
- .mul(new anchor_1.BN(100))
167
- .div(oracleTwapWithMantissa)
168
- .mul(periodAdjustment);
169
- if (cappedAltEst.abs().gte(interpEst.abs())) {
170
- cappedAltEst = interpEst;
171
- }
172
- }
173
- else {
174
- cappedAltEst = interpEst;
73
+ }
74
+ const shrunkLastOracleTwapwithMantissa = oracleTwapTimeSinceLastUpdate
75
+ .mul(lastOracleTwapWithMantissa)
76
+ .add(oracleInvalidDuration.mul(lastMarkTwapWithMantissa))
77
+ .div(oracleTwapTimeSinceLastUpdate.add(oracleInvalidDuration));
78
+ const twapSpread = lastMarkTwapWithMantissa.sub(shrunkLastOracleTwapwithMantissa);
79
+ const twapSpreadPct = twapSpread
80
+ .mul(numericConstants_1.MARK_PRICE_PRECISION)
81
+ .mul(new anchor_1.BN(100))
82
+ .div(shrunkLastOracleTwapwithMantissa);
83
+ const lowerboundEst = twapSpreadPct
84
+ .mul(payFreq)
85
+ .mul(anchor_1.BN.min(secondsInHour, timeSinceLastUpdate))
86
+ .mul(periodAdjustment)
87
+ .div(secondsInHour)
88
+ .div(secondsInHour)
89
+ .div(hoursInDay);
90
+ const interpEst = twapSpreadPct.mul(periodAdjustment).div(hoursInDay);
91
+ const interpRateQuote = twapSpreadPct
92
+ .mul(periodAdjustment)
93
+ .div(hoursInDay)
94
+ .div(numericConstants_1.MARK_PRICE_PRECISION.div(numericConstants_1.QUOTE_PRECISION));
95
+ let feePoolSize = calculateFundingPool(market);
96
+ if (interpRateQuote.lt(new anchor_1.BN(0))) {
97
+ feePoolSize = feePoolSize.mul(new anchor_1.BN(-1));
98
+ }
99
+ let cappedAltEst;
100
+ let largerSide;
101
+ let smallerSide;
102
+ if (market.baseAssetAmountLong.gt(market.baseAssetAmountShort.abs())) {
103
+ largerSide = market.baseAssetAmountLong.abs();
104
+ smallerSide = market.baseAssetAmountShort.abs();
105
+ if (twapSpread.gt(new anchor_1.BN(0))) {
106
+ return [
107
+ markTwapWithMantissa,
108
+ oracleTwapWithMantissa,
109
+ lowerboundEst,
110
+ interpEst,
111
+ interpEst,
112
+ ];
175
113
  }
176
- return [2 /*return*/, [
114
+ }
115
+ else if (market.baseAssetAmountLong.lt(market.baseAssetAmountShort.abs())) {
116
+ largerSide = market.baseAssetAmountShort.abs();
117
+ smallerSide = market.baseAssetAmountLong.abs();
118
+ if (twapSpread.lt(new anchor_1.BN(0))) {
119
+ return [
177
120
  markTwapWithMantissa,
178
121
  oracleTwapWithMantissa,
179
122
  lowerboundEst,
180
- cappedAltEst,
181
123
  interpEst,
182
- ]];
183
- });
124
+ interpEst,
125
+ ];
126
+ }
127
+ }
128
+ else {
129
+ return [
130
+ markTwapWithMantissa,
131
+ oracleTwapWithMantissa,
132
+ lowerboundEst,
133
+ interpEst,
134
+ interpEst,
135
+ ];
136
+ }
137
+ if (largerSide.gt(numericConstants_1.ZERO)) {
138
+ // funding smaller flow
139
+ cappedAltEst = smallerSide.mul(twapSpread).div(hoursInDay);
140
+ const feePoolTopOff = feePoolSize
141
+ .mul(numericConstants_1.MARK_PRICE_PRECISION.div(numericConstants_1.QUOTE_PRECISION))
142
+ .mul(numericConstants_1.AMM_RESERVE_PRECISION);
143
+ cappedAltEst = cappedAltEst.add(feePoolTopOff).div(largerSide);
144
+ cappedAltEst = cappedAltEst
145
+ .mul(numericConstants_1.MARK_PRICE_PRECISION)
146
+ .mul(new anchor_1.BN(100))
147
+ .div(oracleTwapWithMantissa)
148
+ .mul(periodAdjustment);
149
+ if (cappedAltEst.abs().gte(interpEst.abs())) {
150
+ cappedAltEst = interpEst;
151
+ }
152
+ }
153
+ else {
154
+ cappedAltEst = interpEst;
155
+ }
156
+ return [
157
+ markTwapWithMantissa,
158
+ oracleTwapWithMantissa,
159
+ lowerboundEst,
160
+ cappedAltEst,
161
+ interpEst,
162
+ ];
184
163
  });
185
164
  }
186
165
  exports.calculateAllEstimatedFundingRate = calculateAllEstimatedFundingRate;
@@ -192,28 +171,19 @@ exports.calculateAllEstimatedFundingRate = calculateAllEstimatedFundingRate;
192
171
  * @param estimationMethod
193
172
  * @returns Estimated funding rate. : Precision //TODO-PRECISION
194
173
  */
195
- function calculateEstimatedFundingRate(market, oraclePriceData, periodAdjustment, estimationMethod) {
196
- if (periodAdjustment === void 0) { periodAdjustment = new anchor_1.BN(1); }
197
- return __awaiter(this, void 0, void 0, function () {
198
- var _a, _1, _2, lowerboundEst, cappedAltEst, interpEst;
199
- return __generator(this, function (_b) {
200
- switch (_b.label) {
201
- case 0: return [4 /*yield*/, calculateAllEstimatedFundingRate(market, oraclePriceData, periodAdjustment)];
202
- case 1:
203
- _a = _b.sent(), _1 = _a[0], _2 = _a[1], lowerboundEst = _a[2], cappedAltEst = _a[3], interpEst = _a[4];
204
- if (estimationMethod == 'lowerbound') {
205
- //assuming remaining funding period has no gap
206
- return [2 /*return*/, lowerboundEst];
207
- }
208
- else if (estimationMethod == 'capped') {
209
- return [2 /*return*/, cappedAltEst];
210
- }
211
- else {
212
- return [2 /*return*/, interpEst];
213
- }
214
- return [2 /*return*/];
215
- }
216
- });
174
+ function calculateEstimatedFundingRate(market, oraclePriceData, periodAdjustment = new anchor_1.BN(1), estimationMethod) {
175
+ return __awaiter(this, void 0, void 0, function* () {
176
+ const [_1, _2, lowerboundEst, cappedAltEst, interpEst] = yield calculateAllEstimatedFundingRate(market, oraclePriceData, periodAdjustment);
177
+ if (estimationMethod == 'lowerbound') {
178
+ //assuming remaining funding period has no gap
179
+ return lowerboundEst;
180
+ }
181
+ else if (estimationMethod == 'capped') {
182
+ return cappedAltEst;
183
+ }
184
+ else {
185
+ return interpEst;
186
+ }
217
187
  });
218
188
  }
219
189
  exports.calculateEstimatedFundingRate = calculateEstimatedFundingRate;
@@ -224,27 +194,18 @@ exports.calculateEstimatedFundingRate = calculateEstimatedFundingRate;
224
194
  * @param periodAdjustment
225
195
  * @returns Estimated funding rate. : Precision //TODO-PRECISION
226
196
  */
227
- function calculateLongShortFundingRate(market, oraclePriceData, periodAdjustment) {
228
- if (periodAdjustment === void 0) { periodAdjustment = new anchor_1.BN(1); }
229
- return __awaiter(this, void 0, void 0, function () {
230
- var _a, _1, _2, _, cappedAltEst, interpEst;
231
- return __generator(this, function (_b) {
232
- switch (_b.label) {
233
- case 0: return [4 /*yield*/, calculateAllEstimatedFundingRate(market, oraclePriceData, periodAdjustment)];
234
- case 1:
235
- _a = _b.sent(), _1 = _a[0], _2 = _a[1], _ = _a[2], cappedAltEst = _a[3], interpEst = _a[4];
236
- if (market.baseAssetAmountLong.gt(market.baseAssetAmountShort)) {
237
- return [2 /*return*/, [cappedAltEst, interpEst]];
238
- }
239
- else if (market.baseAssetAmountLong.lt(market.baseAssetAmountShort)) {
240
- return [2 /*return*/, [interpEst, cappedAltEst]];
241
- }
242
- else {
243
- return [2 /*return*/, [interpEst, interpEst]];
244
- }
245
- return [2 /*return*/];
246
- }
247
- });
197
+ function calculateLongShortFundingRate(market, oraclePriceData, periodAdjustment = new anchor_1.BN(1)) {
198
+ return __awaiter(this, void 0, void 0, function* () {
199
+ const [_1, _2, _, cappedAltEst, interpEst] = yield calculateAllEstimatedFundingRate(market, oraclePriceData, periodAdjustment);
200
+ if (market.baseAssetAmountLong.gt(market.baseAssetAmountShort)) {
201
+ return [cappedAltEst, interpEst];
202
+ }
203
+ else if (market.baseAssetAmountLong.lt(market.baseAssetAmountShort)) {
204
+ return [interpEst, cappedAltEst];
205
+ }
206
+ else {
207
+ return [interpEst, interpEst];
208
+ }
248
209
  });
249
210
  }
250
211
  exports.calculateLongShortFundingRate = calculateLongShortFundingRate;
@@ -255,27 +216,18 @@ exports.calculateLongShortFundingRate = calculateLongShortFundingRate;
255
216
  * @param periodAdjustment
256
217
  * @returns Estimated funding rate. : Precision //TODO-PRECISION
257
218
  */
258
- function calculateLongShortFundingRateAndLiveTwaps(market, oraclePriceData, periodAdjustment) {
259
- if (periodAdjustment === void 0) { periodAdjustment = new anchor_1.BN(1); }
260
- return __awaiter(this, void 0, void 0, function () {
261
- var _a, markTwapLive, oracleTwapLive, _2, cappedAltEst, interpEst;
262
- return __generator(this, function (_b) {
263
- switch (_b.label) {
264
- case 0: return [4 /*yield*/, calculateAllEstimatedFundingRate(market, oraclePriceData, periodAdjustment)];
265
- case 1:
266
- _a = _b.sent(), markTwapLive = _a[0], oracleTwapLive = _a[1], _2 = _a[2], cappedAltEst = _a[3], interpEst = _a[4];
267
- if (market.baseAssetAmountLong.gt(market.baseAssetAmountShort.abs())) {
268
- return [2 /*return*/, [markTwapLive, oracleTwapLive, cappedAltEst, interpEst]];
269
- }
270
- else if (market.baseAssetAmountLong.lt(market.baseAssetAmountShort.abs())) {
271
- return [2 /*return*/, [markTwapLive, oracleTwapLive, interpEst, cappedAltEst]];
272
- }
273
- else {
274
- return [2 /*return*/, [markTwapLive, oracleTwapLive, interpEst, interpEst]];
275
- }
276
- return [2 /*return*/];
277
- }
278
- });
219
+ function calculateLongShortFundingRateAndLiveTwaps(market, oraclePriceData, periodAdjustment = new anchor_1.BN(1)) {
220
+ return __awaiter(this, void 0, void 0, function* () {
221
+ const [markTwapLive, oracleTwapLive, _2, cappedAltEst, interpEst] = yield calculateAllEstimatedFundingRate(market, oraclePriceData, periodAdjustment);
222
+ if (market.baseAssetAmountLong.gt(market.baseAssetAmountShort.abs())) {
223
+ return [markTwapLive, oracleTwapLive, cappedAltEst, interpEst];
224
+ }
225
+ else if (market.baseAssetAmountLong.lt(market.baseAssetAmountShort.abs())) {
226
+ return [markTwapLive, oracleTwapLive, interpEst, cappedAltEst];
227
+ }
228
+ else {
229
+ return [markTwapLive, oracleTwapLive, interpEst, interpEst];
230
+ }
279
231
  });
280
232
  }
281
233
  exports.calculateLongShortFundingRateAndLiveTwaps = calculateLongShortFundingRateAndLiveTwaps;
@@ -286,8 +238,8 @@ exports.calculateLongShortFundingRateAndLiveTwaps = calculateLongShortFundingRat
286
238
  */
287
239
  function calculateFundingPool(market) {
288
240
  // todo
289
- var totalFeeLB = market.amm.totalExchangeFee.div(new anchor_1.BN(2));
290
- var feePool = anchor_1.BN.max(numericConstants_1.ZERO, market.amm.totalFeeMinusDistributions
241
+ const totalFeeLB = market.amm.totalExchangeFee.div(new anchor_1.BN(2));
242
+ const feePool = anchor_1.BN.max(numericConstants_1.ZERO, market.amm.totalFeeMinusDistributions
291
243
  .sub(totalFeeLB)
292
244
  .mul(new anchor_1.BN(1))
293
245
  .div(new anchor_1.BN(3)));
@@ -68,7 +68,7 @@ export function calculateBidPrice(
68
68
  * Calculates market ask price
69
69
  *
70
70
  * @param market
71
- * @return bidPrice : Precision MARK_PRICE_PRECISION
71
+ * @return askPrice : Precision MARK_PRICE_PRECISION
72
72
  */
73
73
  export function calculateAskPrice(
74
74
  market: PerpMarketAccount,
@@ -131,9 +131,9 @@ export function standardizeBaseAssetAmount(
131
131
 
132
132
  export function getLimitPrice(
133
133
  order: Order,
134
- market: PerpMarketAccount,
135
134
  oraclePriceData: OraclePriceData,
136
- slot: number
135
+ slot: number,
136
+ perpMarket?: PerpMarketAccount
137
137
  ): BN {
138
138
  let limitPrice;
139
139
  if (!order.oraclePriceOffset.eq(ZERO)) {
@@ -143,14 +143,26 @@ export function getLimitPrice(
143
143
  limitPrice = getAuctionPrice(order, slot);
144
144
  } else if (!order.price.eq(ZERO)) {
145
145
  limitPrice = order.price;
146
- } else if (isVariant(order.direction, 'long')) {
147
- const askPrice = calculateAskPrice(market, oraclePriceData);
148
- const delta = askPrice.div(new BN(market.amm.maxSlippageRatio));
149
- limitPrice = askPrice.add(delta);
150
146
  } else {
151
- const bidPrice = calculateBidPrice(market, oraclePriceData);
152
- const delta = bidPrice.div(new BN(market.amm.maxSlippageRatio));
153
- limitPrice = bidPrice.sub(delta);
147
+ if (perpMarket) {
148
+ if (isVariant(order.direction, 'long')) {
149
+ const askPrice = calculateAskPrice(perpMarket, oraclePriceData);
150
+ const delta = askPrice.div(new BN(perpMarket.amm.maxSlippageRatio));
151
+ limitPrice = askPrice.add(delta);
152
+ } else {
153
+ const bidPrice = calculateBidPrice(perpMarket, oraclePriceData);
154
+ const delta = bidPrice.div(new BN(perpMarket.amm.maxSlippageRatio));
155
+ limitPrice = bidPrice.sub(delta);
156
+ }
157
+ } else {
158
+ // check oracle validity?
159
+ const oraclePrice1Pct = oraclePriceData.price.div(new BN(100));
160
+ if (isVariant(order.direction, 'long')) {
161
+ limitPrice = oraclePriceData.price.add(oraclePrice1Pct);
162
+ } else {
163
+ limitPrice = oraclePriceData.price.sub(oraclePrice1Pct);
164
+ }
165
+ }
154
166
  }
155
167
  } else {
156
168
  limitPrice = order.price;
@@ -163,8 +175,7 @@ export function isFillableByVAMM(
163
175
  order: Order,
164
176
  market: PerpMarketAccount,
165
177
  oraclePriceData: OraclePriceData,
166
- slot: number,
167
- maxAuctionDuration: number
178
+ slot: number
168
179
  ): boolean {
169
180
  return (
170
181
  (isAuctionComplete(order, slot) &&
@@ -174,7 +185,7 @@ export function isFillableByVAMM(
174
185
  oraclePriceData,
175
186
  slot
176
187
  ).eq(ZERO)) ||
177
- isOrderExpired(order, slot, maxAuctionDuration)
188
+ isOrderExpired(order, slot)
178
189
  );
179
190
  }
180
191
 
@@ -191,7 +202,7 @@ export function calculateBaseAssetAmountForAmmToFulfill(
191
202
  return ZERO;
192
203
  }
193
204
 
194
- const limitPrice = getLimitPrice(order, market, oraclePriceData, slot);
205
+ const limitPrice = getLimitPrice(order, oraclePriceData, slot, market);
195
206
  const baseAssetAmount = calculateBaseAssetAmountToFillUpToLimitPrice(
196
207
  order,
197
208
  market,
@@ -246,17 +257,14 @@ function isSameDirection(
246
257
  );
247
258
  }
248
259
 
249
- export function isOrderExpired(
250
- order: Order,
251
- slot: number,
252
- maxAuctionDuration: number
253
- ): boolean {
260
+ export function isOrderExpired(order: Order, slot: number): boolean {
254
261
  if (
255
- !isVariant(order.orderType, 'market') ||
256
- !isVariant(order.status, 'open')
262
+ isOneOfVariant(order.orderType, ['triggerMarket', 'triggerLimit']) ||
263
+ !isVariant(order.status, 'open') ||
264
+ order.timeInForce === 0
257
265
  ) {
258
266
  return false;
259
267
  }
260
268
 
261
- return new BN(slot).sub(order.slot).gt(new BN(maxAuctionDuration));
269
+ return new BN(slot).sub(order.slot).gt(new BN(order.timeInForce));
262
270
  }