@drift-labs/sdk 0.2.0-master.25 → 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 (184) 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 +7 -6
  7. package/lib/addresses/pda.js +31 -27
  8. package/lib/admin.d.ts +9 -6
  9. package/lib/admin.js +83 -42
  10. package/lib/clearingHouse.d.ts +69 -42
  11. package/lib/clearingHouse.js +753 -277
  12. package/lib/clearingHouseConfig.d.ts +2 -2
  13. package/lib/clearingHouseUser.d.ts +16 -16
  14. package/lib/clearingHouseUser.js +139 -119
  15. package/lib/config.d.ts +7 -7
  16. package/lib/config.js +20 -20
  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/types.d.ts +2 -1
  24. package/lib/events/types.js +1 -0
  25. package/lib/examples/makeTradeExample.js +7 -7
  26. package/lib/idl/clearing_house.json +1008 -279
  27. package/lib/index.d.ts +5 -3
  28. package/lib/index.js +5 -3
  29. package/lib/math/amm.d.ts +2 -2
  30. package/lib/math/amm.js +1 -1
  31. package/lib/math/funding.d.ts +6 -6
  32. package/lib/math/funding.js +2 -1
  33. package/lib/math/margin.d.ts +4 -4
  34. package/lib/math/margin.js +18 -11
  35. package/lib/math/market.d.ts +10 -9
  36. package/lib/math/market.js +29 -6
  37. package/lib/math/oracles.d.ts +2 -1
  38. package/lib/math/oracles.js +11 -1
  39. package/lib/math/orders.d.ts +5 -5
  40. package/lib/math/position.d.ts +13 -13
  41. package/lib/math/position.js +19 -19
  42. package/lib/math/spotBalance.d.ts +19 -0
  43. package/lib/math/spotBalance.js +176 -0
  44. package/lib/math/spotMarket.d.ts +4 -0
  45. package/lib/math/spotMarket.js +8 -0
  46. package/lib/math/spotPosition.d.ts +2 -0
  47. package/lib/math/spotPosition.js +8 -0
  48. package/lib/math/state.js +2 -2
  49. package/lib/math/trade.d.ts +4 -4
  50. package/lib/orderParams.d.ts +4 -4
  51. package/lib/orderParams.js +12 -4
  52. package/lib/serum/serumSubscriber.d.ts +23 -0
  53. package/lib/serum/serumSubscriber.js +41 -0
  54. package/lib/serum/types.d.ts +11 -0
  55. package/lib/serum/types.js +2 -0
  56. package/lib/tx/retryTxSender.d.ts +1 -1
  57. package/lib/tx/retryTxSender.js +4 -2
  58. package/lib/tx/types.d.ts +1 -1
  59. package/lib/types.d.ts +123 -33
  60. package/lib/types.js +31 -9
  61. package/my-script/.env +7 -0
  62. package/my-script/getUserStats.ts +106 -0
  63. package/my-script/multiConnections.ts +119 -0
  64. package/my-script/test-regex.ts +11 -0
  65. package/my-script/utils.ts +52 -0
  66. package/package.json +1 -1
  67. package/src/accounts/bulkAccountLoader.js +249 -0
  68. package/src/accounts/bulkUserStatsSubscription.js +75 -0
  69. package/src/accounts/bulkUserSubscription.js +75 -0
  70. package/src/accounts/fetch.js +92 -0
  71. package/src/accounts/pollingClearingHouseAccountSubscriber.js +465 -0
  72. package/src/accounts/pollingClearingHouseAccountSubscriber.ts +38 -38
  73. package/src/accounts/pollingOracleSubscriber.js +156 -0
  74. package/src/accounts/pollingTokenAccountSubscriber.js +141 -0
  75. package/src/accounts/pollingUserAccountSubscriber.js +208 -0
  76. package/src/accounts/pollingUserStatsAccountSubscriber.js +208 -0
  77. package/src/accounts/types.js +28 -0
  78. package/src/accounts/types.ts +11 -9
  79. package/src/accounts/utils.js +7 -0
  80. package/src/accounts/webSocketAccountSubscriber.js +138 -0
  81. package/src/accounts/webSocketClearingHouseAccountSubscriber.js +433 -0
  82. package/src/accounts/webSocketClearingHouseAccountSubscriber.ts +59 -52
  83. package/src/accounts/webSocketUserAccountSubscriber.js +113 -0
  84. package/src/accounts/webSocketUserStatsAccountSubsriber.js +113 -0
  85. package/src/addresses/pda.js +186 -0
  86. package/src/addresses/pda.ts +49 -44
  87. package/src/admin.js +1284 -0
  88. package/src/admin.ts +140 -47
  89. package/src/assert/assert.js +1 -1
  90. package/src/clearingHouse.js +3433 -0
  91. package/src/clearingHouse.ts +1083 -378
  92. package/src/clearingHouseConfig.js +2 -0
  93. package/src/clearingHouseConfig.ts +2 -2
  94. package/src/clearingHouseUser.js +874 -0
  95. package/src/clearingHouseUser.ts +232 -168
  96. package/src/clearingHouseUserConfig.js +2 -0
  97. package/src/clearingHouseUserStats.js +115 -0
  98. package/src/clearingHouseUserStatsConfig.js +2 -0
  99. package/src/config.js +80 -0
  100. package/src/config.ts +29 -29
  101. package/src/constants/numericConstants.js +18 -11
  102. package/src/constants/numericConstants.ts +17 -15
  103. package/{lib/constants/markets.js → src/constants/perpMarkets.js} +11 -11
  104. package/src/constants/{markets.ts → perpMarkets.ts} +5 -5
  105. package/src/constants/spotMarkets.js +51 -0
  106. package/src/constants/{banks.ts → spotMarkets.ts} +19 -19
  107. package/src/events/eventList.js +66 -23
  108. package/src/events/eventSubscriber.js +202 -0
  109. package/src/events/fetchLogs.js +117 -0
  110. package/src/events/pollingLogProvider.js +113 -0
  111. package/src/events/sort.js +41 -0
  112. package/src/events/txEventCache.js +22 -19
  113. package/src/events/types.js +25 -0
  114. package/src/events/types.ts +3 -0
  115. package/src/events/webSocketLogProvider.js +76 -0
  116. package/src/examples/makeTradeExample.ts +10 -8
  117. package/src/factory/bigNum.js +183 -180
  118. package/src/factory/oracleClient.js +9 -9
  119. package/src/idl/clearing_house.json +1008 -279
  120. package/src/index.js +75 -0
  121. package/src/index.ts +5 -3
  122. package/src/math/amm.js +422 -0
  123. package/src/math/amm.ts +6 -3
  124. package/src/math/auction.js +10 -10
  125. package/src/math/conversion.js +4 -3
  126. package/src/math/funding.js +223 -175
  127. package/src/math/funding.ts +7 -7
  128. package/src/math/insurance.js +27 -0
  129. package/src/math/margin.js +77 -0
  130. package/src/math/margin.ts +34 -23
  131. package/src/math/market.js +105 -0
  132. package/src/math/market.ts +71 -19
  133. package/src/math/oracles.js +40 -10
  134. package/src/math/oracles.ts +18 -1
  135. package/src/math/orders.js +153 -0
  136. package/src/math/orders.ts +5 -5
  137. package/src/math/position.js +172 -0
  138. package/src/math/position.ts +31 -31
  139. package/src/math/repeg.js +40 -40
  140. package/src/math/spotBalance.js +176 -0
  141. package/src/math/spotBalance.ts +290 -0
  142. package/src/math/spotMarket.js +8 -0
  143. package/src/math/spotMarket.ts +9 -0
  144. package/src/math/spotPosition.js +8 -0
  145. package/src/math/spotPosition.ts +6 -0
  146. package/src/math/state.ts +2 -2
  147. package/src/math/trade.js +81 -74
  148. package/src/math/trade.ts +4 -4
  149. package/src/math/utils.js +8 -7
  150. package/src/oracles/oracleClientCache.js +10 -9
  151. package/src/oracles/pythClient.js +52 -17
  152. package/src/oracles/quoteAssetOracleClient.js +44 -13
  153. package/src/oracles/switchboardClient.js +69 -37
  154. package/src/oracles/types.js +1 -1
  155. package/src/orderParams.js +14 -6
  156. package/src/orderParams.ts +16 -8
  157. package/src/serum/serumSubscriber.js +102 -0
  158. package/src/serum/serumSubscriber.ts +80 -0
  159. package/src/serum/types.js +2 -0
  160. package/src/serum/types.ts +13 -0
  161. package/src/slot/SlotSubscriber.js +67 -20
  162. package/src/token/index.js +4 -4
  163. package/src/tokenFaucet.js +288 -154
  164. package/src/tx/retryTxSender.js +280 -0
  165. package/src/tx/retryTxSender.ts +5 -2
  166. package/src/tx/types.js +1 -1
  167. package/src/tx/types.ts +2 -1
  168. package/src/tx/utils.js +7 -6
  169. package/src/types.js +216 -0
  170. package/src/types.ts +110 -33
  171. package/src/userName.js +5 -5
  172. package/src/util/computeUnits.js +46 -11
  173. package/src/util/promiseTimeout.js +5 -5
  174. package/src/util/tps.js +46 -12
  175. package/src/wallet.js +55 -18
  176. package/lib/math/bankBalance.d.ts +0 -15
  177. package/lib/math/bankBalance.js +0 -150
  178. package/src/addresses/marketAddresses.js +0 -26
  179. package/src/constants/banks.js +0 -42
  180. package/src/examples/makeTradeExample.js +0 -80
  181. package/src/math/bankBalance.ts +0 -258
  182. package/src/math/state.js +0 -15
  183. package/src/math/utils.js.map +0 -1
  184. package/src/util/getTokenAddress.js +0 -9
package/src/index.js ADDED
@@ -0,0 +1,75 @@
1
+ "use strict";
2
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
+ if (k2 === undefined) k2 = k;
4
+ Object.defineProperty(o, k2, { enumerable: true, get: function() { return m[k]; } });
5
+ }) : (function(o, m, k, k2) {
6
+ if (k2 === undefined) k2 = k;
7
+ o[k2] = m[k];
8
+ }));
9
+ var __exportStar = (this && this.__exportStar) || function(m, exports) {
10
+ for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
11
+ };
12
+ exports.__esModule = true;
13
+ exports.pyth = exports.PublicKey = exports.BN = void 0;
14
+ var anchor_1 = require("@project-serum/anchor");
15
+ exports.BN = anchor_1.BN;
16
+ var web3_js_1 = require("@solana/web3.js");
17
+ exports.PublicKey = web3_js_1.PublicKey;
18
+ var client_1 = require("@pythnetwork/client");
19
+ exports.pyth = client_1["default"];
20
+ __exportStar(require("./tokenFaucet"), exports);
21
+ __exportStar(require("./oracles/types"), exports);
22
+ __exportStar(require("./oracles/pythClient"), exports);
23
+ __exportStar(require("./oracles/switchboardClient"), exports);
24
+ __exportStar(require("./types"), exports);
25
+ __exportStar(require("./constants/perpMarkets"), exports);
26
+ __exportStar(require("./accounts/fetch"), exports);
27
+ __exportStar(require("./accounts/webSocketClearingHouseAccountSubscriber"), exports);
28
+ __exportStar(require("./accounts/bulkAccountLoader"), exports);
29
+ __exportStar(require("./accounts/bulkUserSubscription"), exports);
30
+ __exportStar(require("./accounts/bulkUserStatsSubscription"), exports);
31
+ __exportStar(require("./accounts/pollingClearingHouseAccountSubscriber"), exports);
32
+ __exportStar(require("./accounts/pollingOracleSubscriber"), exports);
33
+ __exportStar(require("./accounts/pollingTokenAccountSubscriber"), exports);
34
+ __exportStar(require("./accounts/pollingUserAccountSubscriber"), exports);
35
+ __exportStar(require("./accounts/pollingUserStatsAccountSubscriber"), exports);
36
+ __exportStar(require("./accounts/types"), exports);
37
+ __exportStar(require("./addresses/pda"), exports);
38
+ __exportStar(require("./admin"), exports);
39
+ __exportStar(require("./clearingHouseUser"), exports);
40
+ __exportStar(require("./clearingHouseUserConfig"), exports);
41
+ __exportStar(require("./clearingHouseUserStats"), exports);
42
+ __exportStar(require("./clearingHouseUserStatsConfig"), exports);
43
+ __exportStar(require("./clearingHouse"), exports);
44
+ __exportStar(require("./factory/oracleClient"), exports);
45
+ __exportStar(require("./factory/bigNum"), exports);
46
+ __exportStar(require("./events/types"), exports);
47
+ __exportStar(require("./events/eventSubscriber"), exports);
48
+ __exportStar(require("./events/fetchLogs"), exports);
49
+ __exportStar(require("./math/auction"), exports);
50
+ __exportStar(require("./math/spotMarket"), exports);
51
+ __exportStar(require("./math/conversion"), exports);
52
+ __exportStar(require("./math/funding"), exports);
53
+ __exportStar(require("./math/market"), exports);
54
+ __exportStar(require("./math/position"), exports);
55
+ __exportStar(require("./math/oracles"), exports);
56
+ __exportStar(require("./math/amm"), exports);
57
+ __exportStar(require("./math/trade"), exports);
58
+ __exportStar(require("./math/orders"), exports);
59
+ __exportStar(require("./math/repeg"), exports);
60
+ __exportStar(require("./math/margin"), exports);
61
+ __exportStar(require("./math/insurance"), exports);
62
+ __exportStar(require("./orderParams"), exports);
63
+ __exportStar(require("./slot/SlotSubscriber"), exports);
64
+ __exportStar(require("./wallet"), exports);
65
+ __exportStar(require("./types"), exports);
66
+ __exportStar(require("./math/utils"), exports);
67
+ __exportStar(require("./config"), exports);
68
+ __exportStar(require("./constants/numericConstants"), exports);
69
+ __exportStar(require("./serum/serumSubscriber"), exports);
70
+ __exportStar(require("./tx/retryTxSender"), exports);
71
+ __exportStar(require("./util/computeUnits"), exports);
72
+ __exportStar(require("./util/tps"), exports);
73
+ __exportStar(require("./math/spotBalance"), exports);
74
+ __exportStar(require("./constants/spotMarkets"), exports);
75
+ __exportStar(require("./clearingHouseConfig"), exports);
package/src/index.ts CHANGED
@@ -7,7 +7,7 @@ export * from './oracles/types';
7
7
  export * from './oracles/pythClient';
8
8
  export * from './oracles/switchboardClient';
9
9
  export * from './types';
10
- export * from './constants/markets';
10
+ export * from './constants/perpMarkets';
11
11
  export * from './accounts/fetch';
12
12
  export * from './accounts/webSocketClearingHouseAccountSubscriber';
13
13
  export * from './accounts/bulkAccountLoader';
@@ -32,6 +32,7 @@ export * from './events/types';
32
32
  export * from './events/eventSubscriber';
33
33
  export * from './events/fetchLogs';
34
34
  export * from './math/auction';
35
+ export * from './math/spotMarket';
35
36
  export * from './math/conversion';
36
37
  export * from './math/funding';
37
38
  export * from './math/market';
@@ -50,11 +51,12 @@ export * from './types';
50
51
  export * from './math/utils';
51
52
  export * from './config';
52
53
  export * from './constants/numericConstants';
54
+ export * from './serum/serumSubscriber';
53
55
  export * from './tx/retryTxSender';
54
56
  export * from './util/computeUnits';
55
57
  export * from './util/tps';
56
- export * from './math/bankBalance';
57
- export * from './constants/banks';
58
+ export * from './math/spotBalance';
59
+ export * from './constants/spotMarkets';
58
60
  export * from './clearingHouseConfig';
59
61
 
60
62
  export { BN, PublicKey, pyth };
@@ -0,0 +1,422 @@
1
+ "use strict";
2
+ exports.__esModule = true;
3
+ exports.calculateMaxBaseAssetAmountFillable = exports.calculateQuoteAssetAmountSwapped = exports.calculateMaxBaseAssetAmountToTrade = exports.calculateTerminalPrice = exports.getSwapDirection = exports.calculateSwapOutput = exports.calculateSpreadReserves = exports.calculateSpread = exports.calculateSpreadBN = exports.calculateMaxSpread = exports.calculateEffectiveLeverage = exports.calculateInventoryScale = exports.calculateMarketOpenBidAsk = exports.calculateAmmReservesAfterSwap = exports.calculatePrice = exports.calculateBidAskPrice = exports.calculateUpdatedAMMSpreadReserves = exports.calculateUpdatedAMM = exports.calculateNewAmm = exports.calculateOptimalPegAndBudget = exports.calculatePegFromTargetPrice = void 0;
4
+ var anchor_1 = require("@project-serum/anchor");
5
+ var numericConstants_1 = require("../constants/numericConstants");
6
+ var types_1 = require("../types");
7
+ var assert_1 = require("../assert/assert");
8
+ var __1 = require("..");
9
+ var repeg_1 = require("./repeg");
10
+ function calculatePegFromTargetPrice(targetPrice, baseAssetReserve, quoteAssetReserve) {
11
+ return anchor_1.BN.max(targetPrice
12
+ .mul(baseAssetReserve)
13
+ .div(quoteAssetReserve)
14
+ .add(numericConstants_1.PRICE_DIV_PEG.div(new anchor_1.BN(2)))
15
+ .div(numericConstants_1.PRICE_DIV_PEG), numericConstants_1.ONE);
16
+ }
17
+ exports.calculatePegFromTargetPrice = calculatePegFromTargetPrice;
18
+ function calculateOptimalPegAndBudget(amm, oraclePriceData) {
19
+ var markPriceBefore = calculatePrice(amm.baseAssetReserve, amm.quoteAssetReserve, amm.pegMultiplier);
20
+ var targetPrice = oraclePriceData.price;
21
+ var newPeg = calculatePegFromTargetPrice(targetPrice, amm.baseAssetReserve, amm.quoteAssetReserve);
22
+ var prePegCost = (0, repeg_1.calculateRepegCost)(amm, newPeg);
23
+ var totalFeeLB = amm.totalExchangeFee.div(new anchor_1.BN(2));
24
+ var budget = anchor_1.BN.max(numericConstants_1.ZERO, amm.totalFeeMinusDistributions.sub(totalFeeLB));
25
+ if (budget.lt(prePegCost)) {
26
+ var maxPriceSpread = new anchor_1.BN(amm.maxSpread)
27
+ .mul(targetPrice)
28
+ .div(numericConstants_1.BID_ASK_SPREAD_PRECISION);
29
+ var newTargetPrice = void 0;
30
+ var newOptimalPeg = void 0;
31
+ var newBudget = void 0;
32
+ var targetPriceGap = markPriceBefore.sub(targetPrice);
33
+ if (targetPriceGap.abs().gt(maxPriceSpread)) {
34
+ var markAdj = targetPriceGap.abs().sub(maxPriceSpread);
35
+ if (targetPriceGap.lt(new anchor_1.BN(0))) {
36
+ newTargetPrice = markPriceBefore.add(markAdj);
37
+ }
38
+ else {
39
+ newTargetPrice = markPriceBefore.sub(markAdj);
40
+ }
41
+ newOptimalPeg = calculatePegFromTargetPrice(newTargetPrice, amm.baseAssetReserve, amm.quoteAssetReserve);
42
+ newBudget = (0, repeg_1.calculateRepegCost)(amm, newOptimalPeg);
43
+ return [newTargetPrice, newOptimalPeg, newBudget, false];
44
+ }
45
+ }
46
+ return [targetPrice, newPeg, budget, true];
47
+ }
48
+ exports.calculateOptimalPegAndBudget = calculateOptimalPegAndBudget;
49
+ function calculateNewAmm(amm, oraclePriceData) {
50
+ var _a;
51
+ var pKNumer = new anchor_1.BN(1);
52
+ var pKDenom = new anchor_1.BN(1);
53
+ var _b = calculateOptimalPegAndBudget(amm, oraclePriceData), targetPrice = _b[0], _newPeg = _b[1], budget = _b[2], checkLowerBound = _b[3];
54
+ var prePegCost = (0, repeg_1.calculateRepegCost)(amm, _newPeg);
55
+ var newPeg = _newPeg;
56
+ if (prePegCost.gt(budget) && checkLowerBound) {
57
+ _a = [new anchor_1.BN(999), new anchor_1.BN(1000)], pKNumer = _a[0], pKDenom = _a[1];
58
+ var deficitMadeup = (0, repeg_1.calculateAdjustKCost)(amm, pKNumer, pKDenom);
59
+ (0, assert_1.assert)(deficitMadeup.lte(new anchor_1.BN(0)));
60
+ prePegCost = budget.add(deficitMadeup.abs());
61
+ var newAmm = Object.assign({}, amm);
62
+ newAmm.baseAssetReserve = newAmm.baseAssetReserve.mul(pKNumer).div(pKDenom);
63
+ newAmm.sqrtK = newAmm.sqrtK.mul(pKNumer).div(pKDenom);
64
+ var invariant = newAmm.sqrtK.mul(newAmm.sqrtK);
65
+ newAmm.quoteAssetReserve = invariant.div(newAmm.baseAssetReserve);
66
+ var directionToClose = amm.netBaseAssetAmount.gt(numericConstants_1.ZERO)
67
+ ? types_1.PositionDirection.SHORT
68
+ : types_1.PositionDirection.LONG;
69
+ var _c = calculateAmmReservesAfterSwap(newAmm, 'base', amm.netBaseAssetAmount.abs(), getSwapDirection('base', directionToClose)), newQuoteAssetReserve = _c[0], _newBaseAssetReserve = _c[1];
70
+ newAmm.terminalQuoteAssetReserve = newQuoteAssetReserve;
71
+ newPeg = (0, repeg_1.calculateBudgetedPeg)(newAmm, prePegCost, targetPrice);
72
+ prePegCost = (0, repeg_1.calculateRepegCost)(newAmm, newPeg);
73
+ }
74
+ return [prePegCost, pKNumer, pKDenom, newPeg];
75
+ }
76
+ exports.calculateNewAmm = calculateNewAmm;
77
+ function calculateUpdatedAMM(amm, oraclePriceData) {
78
+ if (amm.curveUpdateIntensity == 0) {
79
+ return amm;
80
+ }
81
+ var newAmm = Object.assign({}, amm);
82
+ var _a = calculateNewAmm(amm, oraclePriceData), prepegCost = _a[0], pKNumer = _a[1], pKDenom = _a[2], newPeg = _a[3];
83
+ newAmm.baseAssetReserve = newAmm.baseAssetReserve.mul(pKNumer).div(pKDenom);
84
+ newAmm.sqrtK = newAmm.sqrtK.mul(pKNumer).div(pKDenom);
85
+ var invariant = newAmm.sqrtK.mul(newAmm.sqrtK);
86
+ newAmm.quoteAssetReserve = invariant.div(newAmm.baseAssetReserve);
87
+ newAmm.pegMultiplier = newPeg;
88
+ var directionToClose = amm.netBaseAssetAmount.gt(numericConstants_1.ZERO)
89
+ ? types_1.PositionDirection.SHORT
90
+ : types_1.PositionDirection.LONG;
91
+ var _b = calculateAmmReservesAfterSwap(newAmm, 'base', amm.netBaseAssetAmount.abs(), getSwapDirection('base', directionToClose)), newQuoteAssetReserve = _b[0], _newBaseAssetReserve = _b[1];
92
+ newAmm.terminalQuoteAssetReserve = newQuoteAssetReserve;
93
+ newAmm.totalFeeMinusDistributions =
94
+ newAmm.totalFeeMinusDistributions.sub(prepegCost);
95
+ return newAmm;
96
+ }
97
+ exports.calculateUpdatedAMM = calculateUpdatedAMM;
98
+ function calculateUpdatedAMMSpreadReserves(amm, direction, oraclePriceData) {
99
+ var newAmm = calculateUpdatedAMM(amm, oraclePriceData);
100
+ var dirReserves = calculateSpreadReserves(newAmm, direction, oraclePriceData);
101
+ var result = {
102
+ baseAssetReserve: dirReserves.baseAssetReserve,
103
+ quoteAssetReserve: dirReserves.quoteAssetReserve,
104
+ sqrtK: newAmm.sqrtK,
105
+ newPeg: newAmm.pegMultiplier
106
+ };
107
+ return result;
108
+ }
109
+ exports.calculateUpdatedAMMSpreadReserves = calculateUpdatedAMMSpreadReserves;
110
+ function calculateBidAskPrice(amm, oraclePriceData, withUpdate) {
111
+ if (withUpdate === void 0) { withUpdate = true; }
112
+ var newAmm;
113
+ if (withUpdate) {
114
+ newAmm = calculateUpdatedAMM(amm, oraclePriceData);
115
+ }
116
+ else {
117
+ newAmm = amm;
118
+ }
119
+ var askReserves = calculateSpreadReserves(newAmm, types_1.PositionDirection.LONG, oraclePriceData);
120
+ var bidReserves = calculateSpreadReserves(newAmm, types_1.PositionDirection.SHORT, oraclePriceData);
121
+ var askPrice = calculatePrice(askReserves.baseAssetReserve, askReserves.quoteAssetReserve, newAmm.pegMultiplier);
122
+ var bidPrice = calculatePrice(bidReserves.baseAssetReserve, bidReserves.quoteAssetReserve, newAmm.pegMultiplier);
123
+ return [bidPrice, askPrice];
124
+ }
125
+ exports.calculateBidAskPrice = calculateBidAskPrice;
126
+ /**
127
+ * Calculates a price given an arbitrary base and quote amount (they must have the same precision)
128
+ *
129
+ * @param baseAssetReserves
130
+ * @param quoteAssetReserves
131
+ * @param pegMultiplier
132
+ * @returns price : Precision MARK_PRICE_PRECISION
133
+ */
134
+ function calculatePrice(baseAssetReserves, quoteAssetReserves, pegMultiplier) {
135
+ if (baseAssetReserves.abs().lte(numericConstants_1.ZERO)) {
136
+ return new anchor_1.BN(0);
137
+ }
138
+ return quoteAssetReserves
139
+ .mul(numericConstants_1.MARK_PRICE_PRECISION)
140
+ .mul(pegMultiplier)
141
+ .div(numericConstants_1.PEG_PRECISION)
142
+ .div(baseAssetReserves);
143
+ }
144
+ exports.calculatePrice = calculatePrice;
145
+ /**
146
+ * Calculates what the amm reserves would be after swapping a quote or base asset amount.
147
+ *
148
+ * @param amm
149
+ * @param inputAssetType
150
+ * @param swapAmount
151
+ * @param swapDirection
152
+ * @returns quoteAssetReserve and baseAssetReserve after swap. : Precision AMM_RESERVE_PRECISION
153
+ */
154
+ function calculateAmmReservesAfterSwap(amm, inputAssetType, swapAmount, swapDirection) {
155
+ var _a, _b;
156
+ (0, assert_1.assert)(swapAmount.gte(numericConstants_1.ZERO), 'swapAmount must be greater than 0');
157
+ var newQuoteAssetReserve;
158
+ var newBaseAssetReserve;
159
+ if (inputAssetType === 'quote') {
160
+ swapAmount = swapAmount
161
+ .mul(numericConstants_1.AMM_TIMES_PEG_TO_QUOTE_PRECISION_RATIO)
162
+ .div(amm.pegMultiplier);
163
+ _a = calculateSwapOutput(amm.quoteAssetReserve, swapAmount, swapDirection, amm.sqrtK.mul(amm.sqrtK)), newQuoteAssetReserve = _a[0], newBaseAssetReserve = _a[1];
164
+ }
165
+ else {
166
+ _b = calculateSwapOutput(amm.baseAssetReserve, swapAmount, swapDirection, amm.sqrtK.mul(amm.sqrtK)), newBaseAssetReserve = _b[0], newQuoteAssetReserve = _b[1];
167
+ }
168
+ return [newQuoteAssetReserve, newBaseAssetReserve];
169
+ }
170
+ exports.calculateAmmReservesAfterSwap = calculateAmmReservesAfterSwap;
171
+ function calculateMarketOpenBidAsk(baseAssetReserve, minBaseAssetReserve, maxBaseAssetReserve) {
172
+ // open orders
173
+ var openAsks;
174
+ if (maxBaseAssetReserve > baseAssetReserve) {
175
+ openAsks = maxBaseAssetReserve.sub(baseAssetReserve).mul(new anchor_1.BN(-1));
176
+ }
177
+ else {
178
+ openAsks = numericConstants_1.ZERO;
179
+ }
180
+ var openBids;
181
+ if (minBaseAssetReserve < baseAssetReserve) {
182
+ openBids = baseAssetReserve.sub(minBaseAssetReserve);
183
+ }
184
+ else {
185
+ openBids = numericConstants_1.ZERO;
186
+ }
187
+ return [openBids, openAsks];
188
+ }
189
+ exports.calculateMarketOpenBidAsk = calculateMarketOpenBidAsk;
190
+ function calculateInventoryScale(netBaseAssetAmount, baseAssetReserve, minBaseAssetReserve, maxBaseAssetReserve) {
191
+ // inventory skew
192
+ var _a = calculateMarketOpenBidAsk(baseAssetReserve, minBaseAssetReserve, maxBaseAssetReserve), openBids = _a[0], openAsks = _a[1];
193
+ var totalLiquidity = anchor_1.BN.max(openBids.abs().add(openAsks.abs()), new anchor_1.BN(1));
194
+ var inventoryScale = anchor_1.BN.min(netBaseAssetAmount.abs(), totalLiquidity)
195
+ .mul(numericConstants_1.BID_ASK_SPREAD_PRECISION.mul(new anchor_1.BN(5)))
196
+ .div(totalLiquidity)
197
+ .toNumber() / numericConstants_1.BID_ASK_SPREAD_PRECISION.toNumber();
198
+ return inventoryScale;
199
+ }
200
+ exports.calculateInventoryScale = calculateInventoryScale;
201
+ function calculateEffectiveLeverage(baseSpread, quoteAssetReserve, terminalQuoteAssetReserve, pegMultiplier, netBaseAssetAmount, markPrice, totalFeeMinusDistributions) {
202
+ // inventory skew
203
+ var netBaseAssetValue = quoteAssetReserve
204
+ .sub(terminalQuoteAssetReserve)
205
+ .mul(pegMultiplier)
206
+ .div(numericConstants_1.AMM_TIMES_PEG_TO_QUOTE_PRECISION_RATIO);
207
+ var localBaseAssetValue = netBaseAssetAmount
208
+ .mul(markPrice)
209
+ .div(numericConstants_1.AMM_TO_QUOTE_PRECISION_RATIO.mul(numericConstants_1.MARK_PRICE_PRECISION));
210
+ var effectiveLeverage = localBaseAssetValue.sub(netBaseAssetValue).toNumber() /
211
+ (Math.max(0, totalFeeMinusDistributions.toNumber()) + 1) +
212
+ 1 / numericConstants_1.QUOTE_PRECISION.toNumber();
213
+ return effectiveLeverage;
214
+ }
215
+ exports.calculateEffectiveLeverage = calculateEffectiveLeverage;
216
+ function calculateMaxSpread(marginRatioInitial) {
217
+ var maxTargetSpread = new anchor_1.BN(marginRatioInitial)
218
+ .mul(numericConstants_1.BID_ASK_SPREAD_PRECISION.div(numericConstants_1.MARGIN_PRECISION))
219
+ .toNumber();
220
+ return maxTargetSpread;
221
+ }
222
+ exports.calculateMaxSpread = calculateMaxSpread;
223
+ function calculateSpreadBN(baseSpread, lastOracleMarkSpreadPct, lastOracleConfPct, maxSpread, quoteAssetReserve, terminalQuoteAssetReserve, pegMultiplier, netBaseAssetAmount, markPrice, totalFeeMinusDistributions, baseAssetReserve, minBaseAssetReserve, maxBaseAssetReserve) {
224
+ var longSpread = baseSpread / 2;
225
+ var shortSpread = baseSpread / 2;
226
+ if (lastOracleMarkSpreadPct.gt(numericConstants_1.ZERO)) {
227
+ shortSpread = Math.max(shortSpread, lastOracleMarkSpreadPct.abs().toNumber() + lastOracleConfPct.toNumber());
228
+ }
229
+ else if (lastOracleMarkSpreadPct.lt(numericConstants_1.ZERO)) {
230
+ longSpread = Math.max(longSpread, lastOracleMarkSpreadPct.abs().toNumber() + lastOracleConfPct.toNumber());
231
+ }
232
+ var maxTargetSpread = Math.max(maxSpread, lastOracleMarkSpreadPct.abs().toNumber());
233
+ var MAX_INVENTORY_SKEW = 5;
234
+ var inventoryScale = calculateInventoryScale(netBaseAssetAmount, baseAssetReserve, minBaseAssetReserve, maxBaseAssetReserve);
235
+ var inventorySpreadScale = Math.min(MAX_INVENTORY_SKEW, 1 + inventoryScale);
236
+ if (netBaseAssetAmount.gt(numericConstants_1.ZERO)) {
237
+ longSpread *= inventorySpreadScale;
238
+ }
239
+ else if (netBaseAssetAmount.lt(numericConstants_1.ZERO)) {
240
+ shortSpread *= inventorySpreadScale;
241
+ }
242
+ var effectiveLeverage = calculateEffectiveLeverage(baseSpread, quoteAssetReserve, terminalQuoteAssetReserve, pegMultiplier, netBaseAssetAmount, markPrice, totalFeeMinusDistributions);
243
+ if (totalFeeMinusDistributions.gt(numericConstants_1.ZERO)) {
244
+ var spreadScale = Math.min(MAX_INVENTORY_SKEW, 1 + effectiveLeverage);
245
+ if (netBaseAssetAmount.gt(numericConstants_1.ZERO)) {
246
+ longSpread *= spreadScale;
247
+ }
248
+ else {
249
+ shortSpread *= spreadScale;
250
+ }
251
+ }
252
+ else {
253
+ longSpread *= MAX_INVENTORY_SKEW;
254
+ shortSpread *= MAX_INVENTORY_SKEW;
255
+ }
256
+ var totalSpread = longSpread + shortSpread;
257
+ if (totalSpread > maxTargetSpread) {
258
+ if (longSpread > shortSpread) {
259
+ longSpread = Math.min(longSpread, maxTargetSpread);
260
+ shortSpread = maxTargetSpread - longSpread;
261
+ }
262
+ else {
263
+ shortSpread = Math.min(shortSpread, maxTargetSpread);
264
+ longSpread = maxTargetSpread - shortSpread;
265
+ }
266
+ }
267
+ return [longSpread, shortSpread];
268
+ }
269
+ exports.calculateSpreadBN = calculateSpreadBN;
270
+ function calculateSpread(amm, direction, oraclePriceData) {
271
+ if (amm.baseSpread == 0 || amm.curveUpdateIntensity == 0) {
272
+ return amm.baseSpread / 2;
273
+ }
274
+ var markPrice = calculatePrice(amm.baseAssetReserve, amm.quoteAssetReserve, amm.pegMultiplier);
275
+ var targetPrice = (oraclePriceData === null || oraclePriceData === void 0 ? void 0 : oraclePriceData.price) || markPrice;
276
+ var confInterval = oraclePriceData.confidence || numericConstants_1.ZERO;
277
+ var targetMarkSpreadPct = markPrice
278
+ .sub(targetPrice)
279
+ .mul(numericConstants_1.BID_ASK_SPREAD_PRECISION)
280
+ .div(markPrice);
281
+ var confIntervalPct = confInterval
282
+ .mul(numericConstants_1.BID_ASK_SPREAD_PRECISION)
283
+ .div(markPrice);
284
+ var _a = calculateSpreadBN(amm.baseSpread, targetMarkSpreadPct, confIntervalPct, amm.maxSpread, amm.quoteAssetReserve, amm.terminalQuoteAssetReserve, amm.pegMultiplier, amm.netBaseAssetAmount, markPrice, amm.totalFeeMinusDistributions, amm.baseAssetReserve, amm.minBaseAssetReserve, amm.maxBaseAssetReserve), longSpread = _a[0], shortSpread = _a[1];
285
+ var spread;
286
+ if ((0, types_1.isVariant)(direction, 'long')) {
287
+ spread = longSpread;
288
+ }
289
+ else {
290
+ spread = shortSpread;
291
+ }
292
+ return spread;
293
+ }
294
+ exports.calculateSpread = calculateSpread;
295
+ function calculateSpreadReserves(amm, direction, oraclePriceData) {
296
+ var spread = calculateSpread(amm, direction, oraclePriceData);
297
+ if (spread === 0) {
298
+ return {
299
+ baseAssetReserve: amm.baseAssetReserve,
300
+ quoteAssetReserve: amm.quoteAssetReserve
301
+ };
302
+ }
303
+ var quoteAsserReserveDelta = amm.quoteAssetReserve.div(numericConstants_1.BID_ASK_SPREAD_PRECISION.div(new anchor_1.BN(spread / 2)));
304
+ var quoteAssetReserve;
305
+ if ((0, types_1.isVariant)(direction, 'long')) {
306
+ quoteAssetReserve = amm.quoteAssetReserve.add(quoteAsserReserveDelta);
307
+ }
308
+ else {
309
+ quoteAssetReserve = amm.quoteAssetReserve.sub(quoteAsserReserveDelta);
310
+ }
311
+ var baseAssetReserve = amm.sqrtK.mul(amm.sqrtK).div(quoteAssetReserve);
312
+ return {
313
+ baseAssetReserve: baseAssetReserve,
314
+ quoteAssetReserve: quoteAssetReserve
315
+ };
316
+ }
317
+ exports.calculateSpreadReserves = calculateSpreadReserves;
318
+ /**
319
+ * Helper function calculating constant product curve output. Agnostic to whether input asset is quote or base
320
+ *
321
+ * @param inputAssetReserve
322
+ * @param swapAmount
323
+ * @param swapDirection
324
+ * @param invariant
325
+ * @returns newInputAssetReserve and newOutputAssetReserve after swap. : Precision AMM_RESERVE_PRECISION
326
+ */
327
+ function calculateSwapOutput(inputAssetReserve, swapAmount, swapDirection, invariant) {
328
+ var newInputAssetReserve;
329
+ if (swapDirection === types_1.SwapDirection.ADD) {
330
+ newInputAssetReserve = inputAssetReserve.add(swapAmount);
331
+ }
332
+ else {
333
+ newInputAssetReserve = inputAssetReserve.sub(swapAmount);
334
+ }
335
+ var newOutputAssetReserve = invariant.div(newInputAssetReserve);
336
+ return [newInputAssetReserve, newOutputAssetReserve];
337
+ }
338
+ exports.calculateSwapOutput = calculateSwapOutput;
339
+ /**
340
+ * Translate long/shorting quote/base asset into amm operation
341
+ *
342
+ * @param inputAssetType
343
+ * @param positionDirection
344
+ */
345
+ function getSwapDirection(inputAssetType, positionDirection) {
346
+ if ((0, types_1.isVariant)(positionDirection, 'long') && inputAssetType === 'base') {
347
+ return types_1.SwapDirection.REMOVE;
348
+ }
349
+ if ((0, types_1.isVariant)(positionDirection, 'short') && inputAssetType === 'quote') {
350
+ return types_1.SwapDirection.REMOVE;
351
+ }
352
+ return types_1.SwapDirection.ADD;
353
+ }
354
+ exports.getSwapDirection = getSwapDirection;
355
+ /**
356
+ * Helper function calculating terminal price of amm
357
+ *
358
+ * @param market
359
+ * @returns cost : Precision MARK_PRICE_PRECISION
360
+ */
361
+ function calculateTerminalPrice(market) {
362
+ var directionToClose = market.amm.netBaseAssetAmount.gt(numericConstants_1.ZERO)
363
+ ? types_1.PositionDirection.SHORT
364
+ : types_1.PositionDirection.LONG;
365
+ var _a = calculateAmmReservesAfterSwap(market.amm, 'base', market.amm.netBaseAssetAmount.abs(), getSwapDirection('base', directionToClose)), newQuoteAssetReserve = _a[0], newBaseAssetReserve = _a[1];
366
+ var terminalPrice = newQuoteAssetReserve
367
+ .mul(numericConstants_1.MARK_PRICE_PRECISION)
368
+ .mul(market.amm.pegMultiplier)
369
+ .div(numericConstants_1.PEG_PRECISION)
370
+ .div(newBaseAssetReserve);
371
+ return terminalPrice;
372
+ }
373
+ exports.calculateTerminalPrice = calculateTerminalPrice;
374
+ function calculateMaxBaseAssetAmountToTrade(amm, limit_price, direction, oraclePriceData) {
375
+ var invariant = amm.sqrtK.mul(amm.sqrtK);
376
+ var newBaseAssetReserveSquared = invariant
377
+ .mul(numericConstants_1.MARK_PRICE_PRECISION)
378
+ .mul(amm.pegMultiplier)
379
+ .div(limit_price)
380
+ .div(numericConstants_1.PEG_PRECISION);
381
+ var newBaseAssetReserve = (0, __1.squareRootBN)(newBaseAssetReserveSquared);
382
+ var baseAssetReserveBefore = calculateSpreadReserves(amm, direction, oraclePriceData).baseAssetReserve;
383
+ if (newBaseAssetReserve.gt(baseAssetReserveBefore)) {
384
+ return [
385
+ newBaseAssetReserve.sub(baseAssetReserveBefore),
386
+ types_1.PositionDirection.SHORT,
387
+ ];
388
+ }
389
+ else if (newBaseAssetReserve.lt(baseAssetReserveBefore)) {
390
+ return [
391
+ baseAssetReserveBefore.sub(newBaseAssetReserve),
392
+ types_1.PositionDirection.LONG,
393
+ ];
394
+ }
395
+ else {
396
+ console.log('tradeSize Too Small');
397
+ return [new anchor_1.BN(0), types_1.PositionDirection.LONG];
398
+ }
399
+ }
400
+ exports.calculateMaxBaseAssetAmountToTrade = calculateMaxBaseAssetAmountToTrade;
401
+ function calculateQuoteAssetAmountSwapped(quoteAssetReserves, pegMultiplier, swapDirection) {
402
+ var quoteAssetAmount = quoteAssetReserves
403
+ .mul(pegMultiplier)
404
+ .div(numericConstants_1.AMM_TIMES_PEG_TO_QUOTE_PRECISION_RATIO);
405
+ if ((0, types_1.isVariant)(swapDirection, 'remove')) {
406
+ quoteAssetAmount = quoteAssetAmount.add(numericConstants_1.ONE);
407
+ }
408
+ return quoteAssetAmount;
409
+ }
410
+ exports.calculateQuoteAssetAmountSwapped = calculateQuoteAssetAmountSwapped;
411
+ function calculateMaxBaseAssetAmountFillable(amm, orderDirection) {
412
+ var maxFillSize = amm.baseAssetReserve.div(new anchor_1.BN(amm.maxBaseAssetAmountRatio));
413
+ var maxBaseAssetAmountOnSide;
414
+ if ((0, types_1.isVariant)(orderDirection, 'long')) {
415
+ maxBaseAssetAmountOnSide = anchor_1.BN.max(numericConstants_1.ZERO, amm.baseAssetReserve.sub(amm.minBaseAssetReserve));
416
+ }
417
+ else {
418
+ maxBaseAssetAmountOnSide = anchor_1.BN.max(numericConstants_1.ZERO, amm.maxBaseAssetReserve.sub(amm.baseAssetReserve));
419
+ }
420
+ return (0, __1.standardizeBaseAssetAmount)(anchor_1.BN.min(maxFillSize, maxBaseAssetAmountOnSide), amm.baseAssetAmountStepSize);
421
+ }
422
+ exports.calculateMaxBaseAssetAmountFillable = calculateMaxBaseAssetAmountFillable;
package/src/math/amm.ts CHANGED
@@ -15,7 +15,7 @@ import {
15
15
  AMM,
16
16
  PositionDirection,
17
17
  SwapDirection,
18
- MarketAccount,
18
+ PerpMarketAccount,
19
19
  isVariant,
20
20
  } from '../types';
21
21
  import { assert } from '../assert/assert';
@@ -418,7 +418,10 @@ export function calculateSpreadBN(
418
418
  );
419
419
  }
420
420
 
421
- const maxTargetSpread: number = maxSpread;
421
+ const maxTargetSpread: number = Math.max(
422
+ maxSpread,
423
+ lastOracleMarkSpreadPct.abs().toNumber()
424
+ );
422
425
 
423
426
  const MAX_INVENTORY_SKEW = 5;
424
427
 
@@ -613,7 +616,7 @@ export function getSwapDirection(
613
616
  * @param market
614
617
  * @returns cost : Precision MARK_PRICE_PRECISION
615
618
  */
616
- export function calculateTerminalPrice(market: MarketAccount) {
619
+ export function calculateTerminalPrice(market: PerpMarketAccount) {
617
620
  const directionToClose = market.amm.netBaseAssetAmount.gt(ZERO)
618
621
  ? PositionDirection.SHORT
619
622
  : PositionDirection.LONG;
@@ -1,8 +1,8 @@
1
1
  "use strict";
2
- Object.defineProperty(exports, "__esModule", { value: true });
2
+ exports.__esModule = true;
3
3
  exports.getAuctionPrice = exports.isAuctionComplete = void 0;
4
- const types_1 = require("../types");
5
- const _1 = require("../.");
4
+ var types_1 = require("../types");
5
+ var _1 = require("../.");
6
6
  function isAuctionComplete(order, slot) {
7
7
  if (order.auctionDuration === 0) {
8
8
  return true;
@@ -11,14 +11,14 @@ function isAuctionComplete(order, slot) {
11
11
  }
12
12
  exports.isAuctionComplete = isAuctionComplete;
13
13
  function getAuctionPrice(order, slot) {
14
- const slotsElapsed = new _1.BN(slot).sub(order.slot);
15
- const deltaDenominator = new _1.BN(order.auctionDuration);
16
- const deltaNumerator = _1.BN.min(slotsElapsed, deltaDenominator);
14
+ var slotsElapsed = new _1.BN(slot).sub(order.slot);
15
+ var deltaDenominator = new _1.BN(order.auctionDuration);
16
+ var deltaNumerator = _1.BN.min(slotsElapsed, deltaDenominator);
17
17
  if (deltaDenominator.eq(_1.ZERO)) {
18
18
  return order.auctionEndPrice;
19
19
  }
20
- let priceDelta;
21
- if (types_1.isVariant(order.direction, 'long')) {
20
+ var priceDelta;
21
+ if ((0, types_1.isVariant)(order.direction, 'long')) {
22
22
  priceDelta = order.auctionEndPrice
23
23
  .sub(order.auctionStartPrice)
24
24
  .mul(deltaNumerator)
@@ -30,8 +30,8 @@ function getAuctionPrice(order, slot) {
30
30
  .mul(deltaNumerator)
31
31
  .div(deltaDenominator);
32
32
  }
33
- let price;
34
- if (types_1.isVariant(order.direction, 'long')) {
33
+ var price;
34
+ if ((0, types_1.isVariant)(order.direction, 'long')) {
35
35
  price = order.auctionStartPrice.add(priceDelta);
36
36
  }
37
37
  else {
@@ -1,8 +1,9 @@
1
1
  "use strict";
2
- Object.defineProperty(exports, "__esModule", { value: true });
2
+ exports.__esModule = true;
3
3
  exports.convertToNumber = void 0;
4
- const numericConstants_1 = require("../constants/numericConstants");
5
- const convertToNumber = (bigNumber, precision = numericConstants_1.MARK_PRICE_PRECISION) => {
4
+ var numericConstants_1 = require("../constants/numericConstants");
5
+ var convertToNumber = function (bigNumber, precision) {
6
+ if (precision === void 0) { precision = numericConstants_1.MARK_PRICE_PRECISION; }
6
7
  if (!bigNumber)
7
8
  return 0;
8
9
  return (bigNumber.div(precision).toNumber() +