@drift-labs/sdk 0.2.0-master.4 → 0.2.0-master.40

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 (234) hide show
  1. package/README.md +27 -27
  2. package/lib/accounts/bulkAccountLoader.d.ts +2 -0
  3. package/lib/accounts/bulkAccountLoader.js +36 -29
  4. package/lib/accounts/bulkUserStatsSubscription.d.ts +7 -0
  5. package/lib/accounts/bulkUserStatsSubscription.js +21 -0
  6. package/lib/accounts/bulkUserSubscription.d.ts +2 -2
  7. package/lib/accounts/bulkUserSubscription.js +0 -1
  8. package/lib/accounts/fetch.d.ts +2 -1
  9. package/lib/accounts/fetch.js +9 -1
  10. package/lib/accounts/{pollingClearingHouseAccountSubscriber.d.ts → pollingDriftClientAccountSubscriber.d.ts} +20 -25
  11. package/lib/accounts/{pollingClearingHouseAccountSubscriber.js → pollingDriftClientAccountSubscriber.js} +45 -49
  12. package/lib/accounts/{pollingOracleSubscriber.d.ts → pollingOracleAccountSubscriber.d.ts} +2 -2
  13. package/lib/accounts/{pollingOracleSubscriber.js → pollingOracleAccountSubscriber.js} +3 -3
  14. package/lib/accounts/pollingUserStatsAccountSubscriber.d.ts +27 -0
  15. package/lib/accounts/pollingUserStatsAccountSubscriber.js +113 -0
  16. package/lib/accounts/types.d.ts +26 -15
  17. package/lib/accounts/webSocketDriftClientAccountSubscriber.d.ts +49 -0
  18. package/lib/accounts/{webSocketClearingHouseAccountSubscriber.js → webSocketDriftClientAccountSubscriber.js} +47 -45
  19. package/lib/accounts/webSocketUserStatsAccountSubsriber.d.ts +20 -0
  20. package/lib/accounts/webSocketUserStatsAccountSubsriber.js +47 -0
  21. package/lib/addresses/marketAddresses.d.ts +1 -3
  22. package/lib/addresses/marketAddresses.js +1 -1
  23. package/lib/addresses/pda.d.ts +15 -9
  24. package/lib/addresses/pda.js +73 -35
  25. package/lib/adminClient.d.ts +65 -0
  26. package/lib/adminClient.js +637 -0
  27. package/lib/config.d.ts +9 -9
  28. package/lib/config.js +25 -21
  29. package/lib/constants/numericConstants.d.ts +30 -12
  30. package/lib/constants/numericConstants.js +41 -21
  31. package/lib/constants/perpMarkets.d.ts +18 -0
  32. package/lib/constants/{markets.js → perpMarkets.js} +7 -7
  33. package/lib/constants/spotMarkets.d.ts +19 -0
  34. package/lib/constants/spotMarkets.js +53 -0
  35. package/lib/dlob/DLOB.d.ts +82 -0
  36. package/lib/dlob/DLOB.js +696 -0
  37. package/lib/dlob/DLOBNode.d.ts +54 -0
  38. package/lib/dlob/DLOBNode.js +77 -0
  39. package/lib/dlob/NodeList.d.ts +27 -0
  40. package/lib/dlob/NodeList.js +144 -0
  41. package/lib/driftClient.d.ts +233 -0
  42. package/lib/driftClient.js +2096 -0
  43. package/lib/{clearingHouseConfig.d.ts → driftClientConfig.d.ts} +9 -9
  44. package/lib/{clearingHouseConfig.js → driftClientConfig.js} +0 -0
  45. package/lib/events/eventList.js +3 -0
  46. package/lib/events/eventSubscriber.d.ts +5 -2
  47. package/lib/events/eventSubscriber.js +25 -11
  48. package/lib/events/fetchLogs.d.ts +13 -2
  49. package/lib/events/fetchLogs.js +40 -12
  50. package/lib/events/pollingLogProvider.d.ts +2 -1
  51. package/lib/events/pollingLogProvider.js +7 -3
  52. package/lib/events/sort.js +8 -11
  53. package/lib/events/types.d.ts +9 -3
  54. package/lib/events/types.js +6 -0
  55. package/lib/events/webSocketLogProvider.js +1 -1
  56. package/lib/examples/makeTradeExample.js +30 -18
  57. package/lib/factory/bigNum.d.ts +8 -4
  58. package/lib/factory/bigNum.js +109 -19
  59. package/lib/idl/drift.json +8250 -0
  60. package/lib/idl/{mock_usdc_faucet.json → token_faucet.json} +46 -23
  61. package/lib/index.d.ts +30 -13
  62. package/lib/index.js +30 -13
  63. package/lib/math/amm.d.ts +9 -6
  64. package/lib/math/amm.js +91 -38
  65. package/lib/math/conversion.js +1 -1
  66. package/lib/math/exchangeStatus.d.ts +4 -0
  67. package/lib/math/exchangeStatus.js +18 -0
  68. package/lib/math/funding.d.ts +6 -6
  69. package/lib/math/funding.js +23 -21
  70. package/lib/math/insurance.d.ts +4 -0
  71. package/lib/math/insurance.js +27 -0
  72. package/lib/math/margin.d.ts +11 -0
  73. package/lib/math/margin.js +82 -0
  74. package/lib/math/market.d.ts +14 -9
  75. package/lib/math/market.js +70 -10
  76. package/lib/math/oracles.d.ts +4 -0
  77. package/lib/math/oracles.js +36 -8
  78. package/lib/math/orders.d.ts +14 -6
  79. package/lib/math/orders.js +90 -17
  80. package/lib/math/position.d.ts +27 -13
  81. package/lib/math/position.js +92 -36
  82. package/lib/math/repeg.js +17 -8
  83. package/lib/math/spotBalance.d.ts +22 -0
  84. package/lib/math/spotBalance.js +192 -0
  85. package/lib/math/spotMarket.d.ts +4 -0
  86. package/lib/math/spotMarket.js +8 -0
  87. package/lib/math/spotPosition.d.ts +6 -0
  88. package/lib/math/spotPosition.js +23 -0
  89. package/lib/math/trade.d.ts +10 -10
  90. package/lib/math/trade.js +27 -31
  91. package/lib/oracles/pythClient.js +1 -1
  92. package/lib/oracles/quoteAssetOracleClient.js +1 -1
  93. package/lib/oracles/switchboardClient.js +1 -1
  94. package/lib/orderParams.d.ts +4 -4
  95. package/lib/orderParams.js +12 -4
  96. package/lib/serum/serumFulfillmentConfigMap.d.ts +10 -0
  97. package/lib/serum/serumFulfillmentConfigMap.js +17 -0
  98. package/lib/serum/serumSubscriber.d.ts +27 -0
  99. package/lib/serum/serumSubscriber.js +56 -0
  100. package/lib/serum/types.d.ts +11 -0
  101. package/lib/{clearingHouseUserConfig.js → serum/types.js} +0 -0
  102. package/lib/slot/SlotSubscriber.d.ts +7 -0
  103. package/lib/slot/SlotSubscriber.js +3 -0
  104. package/lib/{mockUSDCFaucet.d.ts → tokenFaucet.d.ts} +8 -5
  105. package/lib/{mockUSDCFaucet.js → tokenFaucet.js} +63 -51
  106. package/lib/tx/retryTxSender.d.ts +1 -1
  107. package/lib/tx/retryTxSender.js +13 -4
  108. package/lib/tx/types.d.ts +1 -1
  109. package/lib/tx/utils.js +1 -1
  110. package/lib/types.d.ts +589 -196
  111. package/lib/types.js +108 -17
  112. package/lib/user.d.ts +226 -0
  113. package/lib/user.js +949 -0
  114. package/lib/userConfig.d.ts +14 -0
  115. package/lib/userConfig.js +2 -0
  116. package/lib/userMap/userMap.d.ts +41 -0
  117. package/lib/userMap/userMap.js +85 -0
  118. package/lib/userMap/userStatsMap.d.ts +19 -0
  119. package/lib/userMap/userStatsMap.js +68 -0
  120. package/lib/userName.d.ts +1 -0
  121. package/lib/userName.js +3 -2
  122. package/lib/userStats.d.ts +18 -0
  123. package/lib/userStats.js +49 -0
  124. package/lib/userStatsConfig.d.ts +14 -0
  125. package/lib/userStatsConfig.js +2 -0
  126. package/lib/util/computeUnits.js +1 -1
  127. package/lib/util/getTokenAddress.d.ts +2 -0
  128. package/lib/util/getTokenAddress.js +9 -0
  129. package/package.json +10 -3
  130. package/src/accounts/bulkAccountLoader.ts +44 -34
  131. package/src/accounts/bulkUserStatsSubscription.ts +33 -0
  132. package/src/accounts/bulkUserSubscription.ts +2 -3
  133. package/src/accounts/fetch.ts +27 -2
  134. package/src/accounts/{pollingClearingHouseAccountSubscriber.ts → pollingDriftClientAccountSubscriber.ts} +65 -75
  135. package/src/accounts/{pollingOracleSubscriber.ts → pollingOracleAccountSubscriber.ts} +2 -2
  136. package/src/accounts/pollingUserStatsAccountSubscriber.ts +172 -0
  137. package/src/accounts/types.ts +35 -15
  138. package/src/accounts/{webSocketClearingHouseAccountSubscriber.ts → webSocketDriftClientAccountSubscriber.ts} +78 -73
  139. package/src/accounts/webSocketUserStatsAccountSubsriber.ts +80 -0
  140. package/src/addresses/marketAddresses.ts +3 -4
  141. package/src/addresses/pda.ts +105 -33
  142. package/src/adminClient.ts +1207 -0
  143. package/src/config.ts +37 -31
  144. package/src/constants/numericConstants.ts +58 -24
  145. package/src/constants/{markets.ts → perpMarkets.ts} +10 -10
  146. package/src/constants/spotMarkets.ts +73 -0
  147. package/src/dlob/DLOB.ts +1123 -0
  148. package/src/dlob/DLOBNode.ts +155 -0
  149. package/src/dlob/NodeList.ts +195 -0
  150. package/src/driftClient.ts +3564 -0
  151. package/src/{clearingHouseConfig.ts → driftClientConfig.ts} +9 -8
  152. package/src/events/eventList.ts +3 -0
  153. package/src/events/eventSubscriber.ts +36 -14
  154. package/src/events/fetchLogs.ts +55 -13
  155. package/src/events/pollingLogProvider.ts +11 -3
  156. package/src/events/sort.ts +11 -15
  157. package/src/events/types.ts +21 -2
  158. package/src/events/webSocketLogProvider.ts +1 -1
  159. package/src/examples/makeTradeExample.ts +44 -28
  160. package/src/factory/bigNum.ts +150 -22
  161. package/src/idl/drift.json +8250 -0
  162. package/src/idl/pyth.json +98 -2
  163. package/src/idl/{mock_usdc_faucet.json → token_faucet.json} +46 -23
  164. package/src/index.ts +30 -13
  165. package/src/math/amm.ts +161 -48
  166. package/src/math/conversion.ts +2 -2
  167. package/src/math/exchangeStatus.ts +31 -0
  168. package/src/math/funding.ts +41 -31
  169. package/src/math/insurance.ts +35 -0
  170. package/src/math/margin.ts +133 -0
  171. package/src/math/market.ts +143 -14
  172. package/src/math/oracles.ts +63 -9
  173. package/src/math/orders.ts +163 -26
  174. package/src/math/position.ts +136 -58
  175. package/src/math/repeg.ts +19 -9
  176. package/src/math/spotBalance.ts +319 -0
  177. package/src/math/spotMarket.ts +9 -0
  178. package/src/math/spotPosition.ts +47 -0
  179. package/src/math/trade.ts +33 -37
  180. package/src/oracles/pythClient.ts +2 -2
  181. package/src/oracles/quoteAssetOracleClient.ts +2 -2
  182. package/src/oracles/switchboardClient.ts +2 -2
  183. package/src/orderParams.ts +16 -8
  184. package/src/serum/serumFulfillmentConfigMap.ts +26 -0
  185. package/src/serum/serumSubscriber.ts +99 -0
  186. package/src/serum/types.ts +13 -0
  187. package/src/slot/SlotSubscriber.ts +11 -1
  188. package/src/{mockUSDCFaucet.ts → tokenFaucet.ts} +82 -70
  189. package/src/tx/retryTxSender.ts +16 -5
  190. package/src/tx/types.ts +2 -1
  191. package/src/tx/utils.ts +1 -1
  192. package/src/types.ts +572 -178
  193. package/src/user.ts +1582 -0
  194. package/src/{clearingHouseUserConfig.ts → userConfig.ts} +5 -5
  195. package/src/userMap/userMap.ts +124 -0
  196. package/src/userMap/userStatsMap.ts +108 -0
  197. package/src/userName.ts +2 -1
  198. package/src/userStats.ts +75 -0
  199. package/src/userStatsConfig.ts +18 -0
  200. package/src/util/computeUnits.ts +1 -1
  201. package/src/util/getTokenAddress.ts +18 -0
  202. package/tests/bn/test.ts +46 -11
  203. package/tests/dlob/helpers.ts +611 -0
  204. package/tests/dlob/test.ts +4588 -0
  205. package/lib/accounts/webSocketClearingHouseAccountSubscriber.d.ts +0 -49
  206. package/lib/admin.d.ts +0 -44
  207. package/lib/admin.js +0 -433
  208. package/lib/clearingHouse.d.ts +0 -133
  209. package/lib/clearingHouse.js +0 -931
  210. package/lib/clearingHouseUser.d.ts +0 -187
  211. package/lib/clearingHouseUser.js +0 -643
  212. package/lib/clearingHouseUserConfig.d.ts +0 -14
  213. package/lib/constants/banks.d.ts +0 -16
  214. package/lib/constants/banks.js +0 -34
  215. package/lib/constants/markets.d.ts +0 -19
  216. package/lib/idl/clearing_house.json +0 -3998
  217. package/lib/math/bankBalance.d.ts +0 -9
  218. package/lib/math/bankBalance.js +0 -75
  219. package/lib/math/state.d.ts +0 -8
  220. package/lib/math/state.js +0 -15
  221. package/lib/orders.d.ts +0 -8
  222. package/lib/orders.js +0 -134
  223. package/src/admin.ts +0 -722
  224. package/src/clearingHouse.ts +0 -1451
  225. package/src/clearingHouseUser.ts +0 -989
  226. package/src/constants/banks.ts +0 -43
  227. package/src/idl/clearing_house.json +0 -3998
  228. package/src/math/bankBalance.ts +0 -112
  229. package/src/math/state.ts +0 -14
  230. package/src/math/utils.js +0 -27
  231. package/src/math/utils.js.map +0 -1
  232. package/src/orders.ts +0 -244
  233. package/src/util/computeUnits.js +0 -17
  234. package/src/util/computeUnits.js.map +0 -1
@@ -1,16 +1,16 @@
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.isLimitOrder = exports.isMarketOrder = exports.isOrderExpired = exports.calculateBaseAssetAmountToFillUpToLimitPrice = exports.calculateBaseAssetAmountForAmmToFulfill = exports.isFillableByVAMM = exports.hasLimitPrice = exports.getOptionalLimitPrice = 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
6
  const anchor_1 = require("@project-serum/anchor");
7
7
  const auction_1 = require("./auction");
8
- const market_1 = require("./market");
8
+ const amm_1 = require("./amm");
9
9
  function isOrderRiskIncreasing(user, order) {
10
10
  if ((0, types_1.isVariant)(order.status, 'init')) {
11
11
  return false;
12
12
  }
13
- const position = user.getUserPosition(order.marketIndex) ||
13
+ const position = user.getPerpPosition(order.marketIndex) ||
14
14
  user.getEmptyPosition(order.marketIndex);
15
15
  // if no position exists, it's risk increasing
16
16
  if (position.baseAssetAmount.eq(numericConstants_1.ZERO)) {
@@ -37,7 +37,7 @@ function isOrderRiskIncreasingInSameDirection(user, order) {
37
37
  if ((0, types_1.isVariant)(order.status, 'init')) {
38
38
  return false;
39
39
  }
40
- const position = user.getUserPosition(order.marketIndex) ||
40
+ const position = user.getPerpPosition(order.marketIndex) ||
41
41
  user.getEmptyPosition(order.marketIndex);
42
42
  // if no position exists, it's risk increasing
43
43
  if (position.baseAssetAmount.eq(numericConstants_1.ZERO)) {
@@ -59,7 +59,7 @@ function isOrderReduceOnly(user, order) {
59
59
  if ((0, types_1.isVariant)(order.status, 'init')) {
60
60
  return false;
61
61
  }
62
- const position = user.getUserPosition(order.marketIndex) ||
62
+ const position = user.getPerpPosition(order.marketIndex) ||
63
63
  user.getEmptyPosition(order.marketIndex);
64
64
  // if position is long and order is long
65
65
  if (position.baseAssetAmount.gte(numericConstants_1.ZERO) &&
@@ -79,27 +79,27 @@ function standardizeBaseAssetAmount(baseAssetAmount, stepSize) {
79
79
  return baseAssetAmount.sub(remainder);
80
80
  }
81
81
  exports.standardizeBaseAssetAmount = standardizeBaseAssetAmount;
82
- function getLimitPrice(order, market, oraclePriceData, slot) {
82
+ function getLimitPrice(order, oraclePriceData, slot) {
83
83
  let limitPrice;
84
- if (!order.oraclePriceOffset.eq(numericConstants_1.ZERO)) {
85
- limitPrice = oraclePriceData.price.add(order.oraclePriceOffset);
84
+ if (order.oraclePriceOffset !== 0) {
85
+ limitPrice = oraclePriceData.price.add(new anchor_1.BN(order.oraclePriceOffset));
86
86
  }
87
87
  else if ((0, types_1.isOneOfVariant)(order.orderType, ['market', 'triggerMarket'])) {
88
- if ((0, auction_1.isAuctionComplete)(order, slot)) {
88
+ if (!(0, auction_1.isAuctionComplete)(order, slot)) {
89
89
  limitPrice = (0, auction_1.getAuctionPrice)(order, slot);
90
90
  }
91
91
  else if (!order.price.eq(numericConstants_1.ZERO)) {
92
92
  limitPrice = order.price;
93
93
  }
94
- else if ((0, types_1.isVariant)(order.direction, 'long')) {
95
- const askPrice = (0, market_1.calculateAskPrice)(market, oraclePriceData);
96
- const delta = askPrice.div(new anchor_1.BN(market.amm.maxSlippageRatio));
97
- limitPrice = askPrice.add(delta);
98
- }
99
94
  else {
100
- const bidPrice = (0, market_1.calculateBidPrice)(market, oraclePriceData);
101
- const delta = bidPrice.div(new anchor_1.BN(market.amm.maxSlippageRatio));
102
- limitPrice = bidPrice.sub(delta);
95
+ // check oracle validity?
96
+ const oraclePrice1Pct = oraclePriceData.price.div(new anchor_1.BN(100));
97
+ if ((0, types_1.isVariant)(order.direction, 'long')) {
98
+ limitPrice = oraclePriceData.price.add(oraclePrice1Pct);
99
+ }
100
+ else {
101
+ limitPrice = oraclePriceData.price.sub(oraclePrice1Pct);
102
+ }
103
103
  }
104
104
  }
105
105
  else {
@@ -108,3 +108,76 @@ function getLimitPrice(order, market, oraclePriceData, slot) {
108
108
  return limitPrice;
109
109
  }
110
110
  exports.getLimitPrice = getLimitPrice;
111
+ function getOptionalLimitPrice(order, oraclePriceData, slot) {
112
+ if (hasLimitPrice(order, slot)) {
113
+ return getLimitPrice(order, oraclePriceData, slot);
114
+ }
115
+ else {
116
+ return undefined;
117
+ }
118
+ }
119
+ exports.getOptionalLimitPrice = getOptionalLimitPrice;
120
+ function hasLimitPrice(order, slot) {
121
+ return (order.price.gt(numericConstants_1.ZERO) ||
122
+ order.oraclePriceOffset != 0 ||
123
+ !(0, auction_1.isAuctionComplete)(order, slot));
124
+ }
125
+ exports.hasLimitPrice = hasLimitPrice;
126
+ function isFillableByVAMM(order, market, oraclePriceData, slot, ts) {
127
+ return (((0, auction_1.isAuctionComplete)(order, slot) &&
128
+ !calculateBaseAssetAmountForAmmToFulfill(order, market, oraclePriceData, slot).eq(numericConstants_1.ZERO)) ||
129
+ isOrderExpired(order, ts));
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 = getOptionalLimitPrice(order, oraclePriceData, slot);
138
+ let baseAssetAmount;
139
+ if (limitPrice !== undefined) {
140
+ baseAssetAmount = calculateBaseAssetAmountToFillUpToLimitPrice(order, market, limitPrice, oraclePriceData);
141
+ }
142
+ else {
143
+ baseAssetAmount = order.baseAssetAmount.sub(order.baseAssetAmountFilled);
144
+ }
145
+ const maxBaseAssetAmount = (0, amm_1.calculateMaxBaseAssetAmountFillable)(market.amm, order.direction);
146
+ return anchor_1.BN.min(maxBaseAssetAmount, baseAssetAmount);
147
+ }
148
+ exports.calculateBaseAssetAmountForAmmToFulfill = calculateBaseAssetAmountForAmmToFulfill;
149
+ function calculateBaseAssetAmountToFillUpToLimitPrice(order, market, limitPrice, oraclePriceData) {
150
+ const [maxAmountToTrade, direction] = (0, amm_1.calculateMaxBaseAssetAmountToTrade)(market.amm, limitPrice, order.direction, oraclePriceData);
151
+ const baseAssetAmount = standardizeBaseAssetAmount(maxAmountToTrade, market.amm.orderStepSize);
152
+ // Check that directions are the same
153
+ const sameDirection = isSameDirection(direction, order.direction);
154
+ if (!sameDirection) {
155
+ return numericConstants_1.ZERO;
156
+ }
157
+ const baseAssetAmountUnfilled = order.baseAssetAmount.sub(order.baseAssetAmountFilled);
158
+ return baseAssetAmount.gt(baseAssetAmountUnfilled)
159
+ ? baseAssetAmountUnfilled
160
+ : baseAssetAmount;
161
+ }
162
+ exports.calculateBaseAssetAmountToFillUpToLimitPrice = calculateBaseAssetAmountToFillUpToLimitPrice;
163
+ function isSameDirection(firstDirection, secondDirection) {
164
+ return (((0, types_1.isVariant)(firstDirection, 'long') && (0, types_1.isVariant)(secondDirection, 'long')) ||
165
+ ((0, types_1.isVariant)(firstDirection, 'short') && (0, types_1.isVariant)(secondDirection, 'short')));
166
+ }
167
+ function isOrderExpired(order, ts) {
168
+ if ((0, types_1.isOneOfVariant)(order.orderType, ['triggerMarket', 'triggerLimit']) ||
169
+ !(0, types_1.isVariant)(order.status, 'open') ||
170
+ order.maxTs.eq(numericConstants_1.ZERO)) {
171
+ return false;
172
+ }
173
+ return new anchor_1.BN(ts).gt(order.maxTs);
174
+ }
175
+ exports.isOrderExpired = isOrderExpired;
176
+ function isMarketOrder(order) {
177
+ return (0, types_1.isOneOfVariant)(order.orderType, ['market', 'triggerMarket']);
178
+ }
179
+ exports.isMarketOrder = isMarketOrder;
180
+ function isLimitOrder(order) {
181
+ return (0, types_1.isOneOfVariant)(order.orderType, ['limit', 'triggerLimit']);
182
+ }
183
+ exports.isLimitOrder = isLimitOrder;
@@ -1,7 +1,7 @@
1
1
  /// <reference types="bn.js" />
2
- import { BN } from '../';
2
+ import { BN, SpotMarketAccount } from '../';
3
3
  import { OraclePriceData } from '../oracles/types';
4
- import { MarketAccount, PositionDirection, UserPosition } from '../types';
4
+ import { PerpMarketAccount, PositionDirection, PerpPosition } from '../types';
5
5
  /**
6
6
  * calculateBaseAssetValue
7
7
  * = market value of closing entire position
@@ -10,30 +10,44 @@ import { MarketAccount, PositionDirection, UserPosition } from '../types';
10
10
  * @param oraclePriceData
11
11
  * @returns Base Asset Value. : Precision QUOTE_PRECISION
12
12
  */
13
- export declare function calculateBaseAssetValue(market: MarketAccount, userPosition: UserPosition, oraclePriceData: OraclePriceData): BN;
13
+ export declare function calculateBaseAssetValue(market: PerpMarketAccount, userPosition: PerpPosition, oraclePriceData: OraclePriceData, useSpread?: boolean, skipUpdate?: boolean): BN;
14
14
  /**
15
15
  * calculatePositionPNL
16
16
  * = BaseAssetAmount * (Avg Exit Price - Avg Entry Price)
17
17
  * @param market
18
- * @param marketPosition
18
+ * @param PerpPosition
19
19
  * @param withFunding (adds unrealized funding payment pnl to result)
20
+ * @param oraclePriceData
20
21
  * @returns BaseAssetAmount : Precision QUOTE_PRECISION
21
22
  */
22
- export declare function calculatePositionPNL(market: MarketAccount, marketPosition: UserPosition, withFunding: boolean, oraclePriceData: OraclePriceData): BN;
23
+ export declare function calculatePositionPNL(market: PerpMarketAccount, perpPosition: PerpPosition, withFunding: boolean, oraclePriceData: OraclePriceData): BN;
24
+ export declare function calculateClaimablePnl(market: PerpMarketAccount, spotMarket: SpotMarketAccount, perpPosition: PerpPosition, oraclePriceData: OraclePriceData): BN;
23
25
  /**
24
26
  *
25
27
  * @param market
26
- * @param marketPosition
28
+ * @param PerpPosition
27
29
  * @returns // TODO-PRECISION
28
30
  */
29
- export declare function calculatePositionFundingPNL(market: MarketAccount, marketPosition: UserPosition): BN;
30
- export declare function positionIsAvailable(position: UserPosition): boolean;
31
+ export declare function calculatePositionFundingPNL(market: PerpMarketAccount, perpPosition: PerpPosition): BN;
32
+ export declare function positionIsAvailable(position: PerpPosition): boolean;
33
+ /**
34
+ *
35
+ * @param userPosition
36
+ * @returns Precision: PRICE_PRECISION (10^6)
37
+ */
38
+ export declare function calculateBreakEvenPrice(userPosition: PerpPosition): BN;
39
+ /**
40
+ *
41
+ * @param userPosition
42
+ * @returns Precision: PRICE_PRECISION (10^6)
43
+ */
44
+ export declare function calculateEntryPrice(userPosition: PerpPosition): BN;
31
45
  /**
32
46
  *
33
47
  * @param userPosition
34
- * @returns Precision: MARK_PRICE_PRECISION (10^10)
48
+ * @returns Precision: PRICE_PRECISION (10^10)
35
49
  */
36
- export declare function calculateEntryPrice(userPosition: UserPosition): BN;
37
- export declare function findDirectionToClose(userPosition: UserPosition): PositionDirection;
38
- export declare function positionCurrentDirection(userPosition: UserPosition): PositionDirection;
39
- export declare function isEmptyPosition(userPosition: UserPosition): boolean;
50
+ export declare function calculateCostBasis(userPosition: PerpPosition): BN;
51
+ export declare function findDirectionToClose(userPosition: PerpPosition): PositionDirection;
52
+ export declare function positionCurrentDirection(userPosition: PerpPosition): PositionDirection;
53
+ export declare function isEmptyPosition(userPosition: PerpPosition): boolean;
@@ -1,10 +1,12 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.isEmptyPosition = exports.positionCurrentDirection = exports.findDirectionToClose = exports.calculateEntryPrice = exports.positionIsAvailable = exports.calculatePositionFundingPNL = exports.calculatePositionPNL = exports.calculateBaseAssetValue = void 0;
3
+ exports.isEmptyPosition = exports.positionCurrentDirection = exports.findDirectionToClose = exports.calculateCostBasis = exports.calculateEntryPrice = exports.calculateBreakEvenPrice = exports.positionIsAvailable = exports.calculatePositionFundingPNL = exports.calculateClaimablePnl = exports.calculatePositionPNL = exports.calculateBaseAssetValue = void 0;
4
4
  const __1 = require("../");
5
5
  const numericConstants_1 = require("../constants/numericConstants");
6
6
  const types_1 = require("../types");
7
7
  const amm_1 = require("./amm");
8
+ const margin_1 = require("./margin");
9
+ const market_1 = require("./market");
8
10
  /**
9
11
  * calculateBaseAssetValue
10
12
  * = market value of closing entire position
@@ -13,23 +15,28 @@ const amm_1 = require("./amm");
13
15
  * @param oraclePriceData
14
16
  * @returns Base Asset Value. : Precision QUOTE_PRECISION
15
17
  */
16
- function calculateBaseAssetValue(market, userPosition, oraclePriceData) {
18
+ function calculateBaseAssetValue(market, userPosition, oraclePriceData, useSpread = true, skipUpdate = false) {
17
19
  if (userPosition.baseAssetAmount.eq(numericConstants_1.ZERO)) {
18
20
  return numericConstants_1.ZERO;
19
21
  }
20
22
  const directionToClose = findDirectionToClose(userPosition);
21
23
  let prepegAmm;
22
- if (market.amm.baseSpread > 0) {
23
- const { baseAssetReserve, quoteAssetReserve, sqrtK, newPeg } = (0, amm_1.calculateUpdatedAMMSpreadReserves)(market.amm, directionToClose, oraclePriceData);
24
- prepegAmm = {
25
- baseAssetReserve,
26
- quoteAssetReserve,
27
- sqrtK: sqrtK,
28
- pegMultiplier: newPeg,
29
- };
24
+ if (!skipUpdate) {
25
+ if (market.amm.baseSpread > 0 && useSpread) {
26
+ const { baseAssetReserve, quoteAssetReserve, sqrtK, newPeg } = (0, amm_1.calculateUpdatedAMMSpreadReserves)(market.amm, directionToClose, oraclePriceData);
27
+ prepegAmm = {
28
+ baseAssetReserve,
29
+ quoteAssetReserve,
30
+ sqrtK: sqrtK,
31
+ pegMultiplier: newPeg,
32
+ };
33
+ }
34
+ else {
35
+ prepegAmm = (0, amm_1.calculateUpdatedAMM)(market.amm, oraclePriceData);
36
+ }
30
37
  }
31
38
  else {
32
- prepegAmm = (0, amm_1.calculateUpdatedAMM)(market.amm, oraclePriceData);
39
+ prepegAmm = market.amm;
33
40
  }
34
41
  const [newQuoteAssetReserve, _] = (0, amm_1.calculateAmmReservesAfterSwap)(prepegAmm, 'base', userPosition.baseAssetAmount.abs(), (0, amm_1.getSwapDirection)('base', directionToClose));
35
42
  switch (directionToClose) {
@@ -51,75 +58,124 @@ exports.calculateBaseAssetValue = calculateBaseAssetValue;
51
58
  * calculatePositionPNL
52
59
  * = BaseAssetAmount * (Avg Exit Price - Avg Entry Price)
53
60
  * @param market
54
- * @param marketPosition
61
+ * @param PerpPosition
55
62
  * @param withFunding (adds unrealized funding payment pnl to result)
63
+ * @param oraclePriceData
56
64
  * @returns BaseAssetAmount : Precision QUOTE_PRECISION
57
65
  */
58
- function calculatePositionPNL(market, marketPosition, withFunding = false, oraclePriceData) {
59
- if (marketPosition.baseAssetAmount.eq(numericConstants_1.ZERO)) {
60
- return numericConstants_1.ZERO;
61
- }
62
- const baseAssetValue = calculateBaseAssetValue(market, marketPosition, oraclePriceData);
63
- let pnl;
64
- if (marketPosition.baseAssetAmount.gt(numericConstants_1.ZERO)) {
65
- pnl = baseAssetValue.sub(marketPosition.quoteAssetAmount);
66
- }
67
- else {
68
- pnl = marketPosition.quoteAssetAmount.sub(baseAssetValue);
66
+ function calculatePositionPNL(market, perpPosition, withFunding = false, oraclePriceData) {
67
+ if (perpPosition.baseAssetAmount.eq(numericConstants_1.ZERO)) {
68
+ return perpPosition.quoteAssetAmount;
69
69
  }
70
+ const baseAssetValue = (0, margin_1.calculateBaseAssetValueWithOracle)(market, perpPosition, oraclePriceData);
71
+ const baseAssetValueSign = perpPosition.baseAssetAmount.isNeg()
72
+ ? new __1.BN(-1)
73
+ : new __1.BN(1);
74
+ let pnl = baseAssetValue
75
+ .mul(baseAssetValueSign)
76
+ .add(perpPosition.quoteAssetAmount);
70
77
  if (withFunding) {
71
- const fundingRatePnL = calculatePositionFundingPNL(market, marketPosition).div(numericConstants_1.PRICE_TO_QUOTE_PRECISION);
78
+ const fundingRatePnL = calculatePositionFundingPNL(market, perpPosition);
72
79
  pnl = pnl.add(fundingRatePnL);
73
80
  }
74
81
  return pnl;
75
82
  }
76
83
  exports.calculatePositionPNL = calculatePositionPNL;
84
+ function calculateClaimablePnl(market, spotMarket, perpPosition, oraclePriceData) {
85
+ const unrealizedPnl = calculatePositionPNL(market, perpPosition, true, oraclePriceData);
86
+ const fundingPnL = calculatePositionFundingPNL(market, perpPosition);
87
+ let unsettledPnl = unrealizedPnl.add(fundingPnL);
88
+ if (unrealizedPnl.gt(numericConstants_1.ZERO)) {
89
+ const excessPnlPool = __1.BN.max(numericConstants_1.ZERO, (0, market_1.calculateNetUserPnlImbalance)(market, spotMarket, oraclePriceData).mul(new __1.BN(-1)));
90
+ const maxPositivePnl = __1.BN.max(perpPosition.quoteAssetAmount
91
+ .sub(perpPosition.quoteEntryAmount)
92
+ .add(excessPnlPool), numericConstants_1.ZERO);
93
+ unsettledPnl = __1.BN.min(maxPositivePnl, unrealizedPnl);
94
+ }
95
+ return unsettledPnl;
96
+ }
97
+ exports.calculateClaimablePnl = calculateClaimablePnl;
77
98
  /**
78
99
  *
79
100
  * @param market
80
- * @param marketPosition
101
+ * @param PerpPosition
81
102
  * @returns // TODO-PRECISION
82
103
  */
83
- function calculatePositionFundingPNL(market, marketPosition) {
84
- if (marketPosition.baseAssetAmount.eq(numericConstants_1.ZERO)) {
104
+ function calculatePositionFundingPNL(market, perpPosition) {
105
+ if (perpPosition.baseAssetAmount.eq(numericConstants_1.ZERO)) {
85
106
  return numericConstants_1.ZERO;
86
107
  }
87
108
  let ammCumulativeFundingRate;
88
- if (marketPosition.baseAssetAmount.gt(numericConstants_1.ZERO)) {
109
+ if (perpPosition.baseAssetAmount.gt(numericConstants_1.ZERO)) {
89
110
  ammCumulativeFundingRate = market.amm.cumulativeFundingRateLong;
90
111
  }
91
112
  else {
92
113
  ammCumulativeFundingRate = market.amm.cumulativeFundingRateShort;
93
114
  }
94
115
  const perPositionFundingRate = ammCumulativeFundingRate
95
- .sub(marketPosition.lastCumulativeFundingRate)
96
- .mul(marketPosition.baseAssetAmount)
116
+ .sub(perpPosition.lastCumulativeFundingRate)
117
+ .mul(perpPosition.baseAssetAmount)
97
118
  .div(numericConstants_1.AMM_RESERVE_PRECISION)
98
- .div(numericConstants_1.FUNDING_PAYMENT_PRECISION)
119
+ .div(numericConstants_1.FUNDING_RATE_BUFFER_PRECISION)
99
120
  .mul(new __1.BN(-1));
100
121
  return perPositionFundingRate;
101
122
  }
102
123
  exports.calculatePositionFundingPNL = calculatePositionFundingPNL;
103
124
  function positionIsAvailable(position) {
104
- return position.baseAssetAmount.eq(numericConstants_1.ZERO) && position.openOrders.eq(numericConstants_1.ZERO);
125
+ return (position.baseAssetAmount.eq(numericConstants_1.ZERO) &&
126
+ position.openOrders === 0 &&
127
+ position.quoteAssetAmount.eq(numericConstants_1.ZERO) &&
128
+ position.lpShares.eq(numericConstants_1.ZERO));
105
129
  }
106
130
  exports.positionIsAvailable = positionIsAvailable;
107
131
  /**
108
132
  *
109
133
  * @param userPosition
110
- * @returns Precision: MARK_PRICE_PRECISION (10^10)
134
+ * @returns Precision: PRICE_PRECISION (10^6)
135
+ */
136
+ function calculateBreakEvenPrice(userPosition) {
137
+ if (userPosition.baseAssetAmount.eq(numericConstants_1.ZERO)) {
138
+ return numericConstants_1.ZERO;
139
+ }
140
+ return userPosition.quoteBreakEvenAmount
141
+ .mul(numericConstants_1.PRICE_PRECISION)
142
+ .mul(numericConstants_1.AMM_TO_QUOTE_PRECISION_RATIO)
143
+ .div(userPosition.baseAssetAmount)
144
+ .abs();
145
+ }
146
+ exports.calculateBreakEvenPrice = calculateBreakEvenPrice;
147
+ /**
148
+ *
149
+ * @param userPosition
150
+ * @returns Precision: PRICE_PRECISION (10^6)
111
151
  */
112
152
  function calculateEntryPrice(userPosition) {
113
153
  if (userPosition.baseAssetAmount.eq(numericConstants_1.ZERO)) {
114
154
  return numericConstants_1.ZERO;
115
155
  }
116
- return userPosition.quoteAssetAmount
117
- .mul(numericConstants_1.MARK_PRICE_PRECISION)
156
+ return userPosition.quoteEntryAmount
157
+ .mul(numericConstants_1.PRICE_PRECISION)
118
158
  .mul(numericConstants_1.AMM_TO_QUOTE_PRECISION_RATIO)
119
159
  .div(userPosition.baseAssetAmount)
120
160
  .abs();
121
161
  }
122
162
  exports.calculateEntryPrice = calculateEntryPrice;
163
+ /**
164
+ *
165
+ * @param userPosition
166
+ * @returns Precision: PRICE_PRECISION (10^10)
167
+ */
168
+ function calculateCostBasis(userPosition) {
169
+ if (userPosition.baseAssetAmount.eq(numericConstants_1.ZERO)) {
170
+ return numericConstants_1.ZERO;
171
+ }
172
+ return userPosition.quoteAssetAmount
173
+ .mul(numericConstants_1.PRICE_PRECISION)
174
+ .mul(numericConstants_1.AMM_TO_QUOTE_PRECISION_RATIO)
175
+ .div(userPosition.baseAssetAmount)
176
+ .abs();
177
+ }
178
+ exports.calculateCostBasis = calculateCostBasis;
123
179
  function findDirectionToClose(userPosition) {
124
180
  return userPosition.baseAssetAmount.gt(numericConstants_1.ZERO)
125
181
  ? types_1.PositionDirection.SHORT
@@ -133,6 +189,6 @@ function positionCurrentDirection(userPosition) {
133
189
  }
134
190
  exports.positionCurrentDirection = positionCurrentDirection;
135
191
  function isEmptyPosition(userPosition) {
136
- return (userPosition.baseAssetAmount.eq(numericConstants_1.ZERO) && userPosition.openOrders.eq(numericConstants_1.ZERO));
192
+ return userPosition.baseAssetAmount.eq(numericConstants_1.ZERO) && userPosition.openOrders === 0;
137
193
  }
138
194
  exports.isEmptyPosition = isEmptyPosition;
package/lib/math/repeg.js CHANGED
@@ -15,16 +15,16 @@ function calculateAdjustKCost(amm, numerator, denomenator) {
15
15
  // const k = market.amm.sqrtK.mul(market.amm.sqrtK);
16
16
  const x = amm.baseAssetReserve;
17
17
  const y = amm.quoteAssetReserve;
18
- const d = amm.netBaseAssetAmount;
18
+ const d = amm.baseAssetAmountWithAmm;
19
19
  const Q = amm.pegMultiplier;
20
20
  const quoteScale = y.mul(d).mul(Q); //.div(AMM_RESERVE_PRECISION);
21
- const p = numerator.mul(numericConstants_1.MARK_PRICE_PRECISION).div(denomenator);
21
+ const p = numerator.mul(numericConstants_1.PRICE_PRECISION).div(denomenator);
22
22
  const cost = quoteScale
23
23
  .div(x.add(d))
24
24
  .sub(quoteScale
25
25
  .mul(p)
26
- .div(numericConstants_1.MARK_PRICE_PRECISION)
27
- .div(x.mul(p).div(numericConstants_1.MARK_PRICE_PRECISION).add(d)))
26
+ .div(numericConstants_1.PRICE_PRECISION)
27
+ .div(x.mul(p).div(numericConstants_1.PRICE_PRECISION).add(d)))
28
28
  .div(numericConstants_1.AMM_TO_QUOTE_PRECISION_RATIO)
29
29
  .div(numericConstants_1.PEG_PRECISION);
30
30
  return cost.mul(new anchor_1.BN(-1));
@@ -71,6 +71,15 @@ function calculateBudgetedKBN(x, y, budget, Q, d) {
71
71
  .div(numericConstants_1.AMM_RESERVE_PRECISION)
72
72
  .div(numericConstants_1.QUOTE_PRECISION);
73
73
  const denom2 = pegged_y_d_d;
74
+ // protocol is spending to increase k
75
+ if (C.lt(numericConstants_1.ZERO)) {
76
+ // thus denom1 is negative and solution is unstable
77
+ if (denom1.abs().gt(denom2.abs())) {
78
+ console.log('denom1 > denom2', denom1.toString(), denom2.toString());
79
+ console.log('budget cost exceeds stable K solution');
80
+ return [new anchor_1.BN(10000), new anchor_1.BN(1)];
81
+ }
82
+ }
74
83
  const numerator = numer1.sub(numer2).div(numericConstants_1.AMM_TO_QUOTE_PRECISION_RATIO);
75
84
  const denominator = denom1.add(denom2).div(numericConstants_1.AMM_TO_QUOTE_PRECISION_RATIO);
76
85
  return [numerator, denominator];
@@ -92,7 +101,7 @@ function calculateBudgetedK(amm, cost) {
92
101
  // otherwise use: (y(1-p) + (kp^2/(x*p+d)) - k/(x+d)) * Q = C solve for p
93
102
  const x = amm.baseAssetReserve;
94
103
  const y = amm.quoteAssetReserve;
95
- const d = amm.netBaseAssetAmount;
104
+ const d = amm.baseAssetAmountWithAmm;
96
105
  const Q = amm.pegMultiplier;
97
106
  const [numerator, denominator] = calculateBudgetedKBN(x, y, cost, Q, d);
98
107
  return [numerator, denominator];
@@ -111,7 +120,7 @@ function calculateBudgetedPeg(amm, cost, targetPrice) {
111
120
  const k = amm.sqrtK.mul(amm.sqrtK);
112
121
  const x = amm.baseAssetReserve;
113
122
  const y = amm.quoteAssetReserve;
114
- const d = amm.netBaseAssetAmount;
123
+ const d = amm.baseAssetAmountWithAmm;
115
124
  const Q = amm.pegMultiplier;
116
125
  const C = cost.mul(new anchor_1.BN(-1));
117
126
  const deltaQuoteAssetReserves = y.sub(k.div(x.add(d)));
@@ -121,8 +130,8 @@ function calculateBudgetedPeg(amm, cost, targetPrice) {
121
130
  if (deltaQuoteAssetReserves.eq(numericConstants_1.ZERO) || useTargetPeg) {
122
131
  return targetPeg;
123
132
  }
124
- const deltaPegMultiplier = C.mul(numericConstants_1.MARK_PRICE_PRECISION).div(deltaQuoteAssetReserves.div(numericConstants_1.AMM_TO_QUOTE_PRECISION_RATIO));
125
- const newPeg = Q.sub(deltaPegMultiplier.mul(numericConstants_1.PEG_PRECISION).div(numericConstants_1.MARK_PRICE_PRECISION));
133
+ const deltaPegMultiplier = C.mul(numericConstants_1.PRICE_PRECISION).div(deltaQuoteAssetReserves.div(numericConstants_1.AMM_TO_QUOTE_PRECISION_RATIO));
134
+ const newPeg = Q.sub(deltaPegMultiplier.mul(numericConstants_1.PEG_PRECISION).div(numericConstants_1.PRICE_PRECISION));
126
135
  return newPeg;
127
136
  }
128
137
  exports.calculateBudgetedPeg = calculateBudgetedPeg;
@@ -0,0 +1,22 @@
1
+ /// <reference types="bn.js" />
2
+ import { SpotMarketAccount, SpotBalanceType, MarginCategory } from '../types';
3
+ import { BN } from '@project-serum/anchor';
4
+ import { OraclePriceData } from '../oracles/types';
5
+ export declare function getBalance(tokenAmount: BN, spotMarket: SpotMarketAccount, balanceType: SpotBalanceType): BN;
6
+ export declare function getTokenAmount(balanceAmount: BN, spotMarket: SpotMarketAccount, balanceType: SpotBalanceType): BN;
7
+ export declare function getSignedTokenAmount(tokenAmount: BN, balanceType: SpotBalanceType): BN;
8
+ export declare function getTokenValue(tokenAmount: BN, spotDecimals: number, oraclePriceData: OraclePriceData): BN;
9
+ export declare function calculateAssetWeight(balanceAmount: BN, spotMarket: SpotMarketAccount, marginCategory: MarginCategory): BN;
10
+ export declare function calculateLiabilityWeight(balanceAmount: BN, spotMarket: SpotMarketAccount, marginCategory: MarginCategory): BN;
11
+ export declare function calculateUtilization(bank: SpotMarketAccount): BN;
12
+ export declare function calculateInterestRate(bank: SpotMarketAccount): BN;
13
+ export declare function calculateDepositRate(bank: SpotMarketAccount): BN;
14
+ export declare function calculateBorrowRate(bank: SpotMarketAccount): BN;
15
+ export declare function calculateInterestAccumulated(bank: SpotMarketAccount, now: BN): {
16
+ borrowInterest: BN;
17
+ depositInterest: BN;
18
+ };
19
+ export declare function calculateWithdrawLimit(spotMarket: SpotMarketAccount, now: BN): {
20
+ borrowLimit: BN;
21
+ withdrawLimit: BN;
22
+ };