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

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (208) hide show
  1. package/README.md +13 -13
  2. package/lib/accounts/bulkUserStatsSubscription.d.ts +7 -0
  3. package/lib/accounts/bulkUserStatsSubscription.js +21 -0
  4. package/lib/accounts/bulkUserSubscription.js +0 -1
  5. package/lib/accounts/fetch.d.ts +2 -1
  6. package/lib/accounts/fetch.js +9 -1
  7. package/lib/accounts/pollingClearingHouseAccountSubscriber.d.ts +16 -16
  8. package/lib/accounts/pollingClearingHouseAccountSubscriber.js +31 -28
  9. package/lib/accounts/pollingUserStatsAccountSubscriber.d.ts +27 -0
  10. package/lib/accounts/pollingUserStatsAccountSubscriber.js +113 -0
  11. package/lib/accounts/types.d.ts +22 -11
  12. package/lib/accounts/webSocketClearingHouseAccountSubscriber.d.ts +17 -17
  13. package/lib/accounts/webSocketClearingHouseAccountSubscriber.js +37 -35
  14. package/lib/accounts/webSocketUserStatsAccountSubsriber.d.ts +20 -0
  15. package/lib/accounts/webSocketUserStatsAccountSubsriber.js +47 -0
  16. package/lib/addresses/marketAddresses.d.ts +1 -3
  17. package/lib/addresses/pda.d.ts +10 -4
  18. package/lib/addresses/pda.js +51 -14
  19. package/lib/admin.d.ts +34 -22
  20. package/lib/admin.js +182 -73
  21. package/lib/clearingHouse.d.ts +120 -42
  22. package/lib/clearingHouse.js +1505 -254
  23. package/lib/clearingHouseConfig.d.ts +4 -4
  24. package/lib/clearingHouseUser.d.ts +50 -38
  25. package/lib/clearingHouseUser.js +410 -190
  26. package/lib/clearingHouseUserStats.d.ts +18 -0
  27. package/lib/clearingHouseUserStats.js +49 -0
  28. package/lib/clearingHouseUserStatsConfig.d.ts +14 -0
  29. package/lib/clearingHouseUserStatsConfig.js +2 -0
  30. package/lib/config.d.ts +7 -9
  31. package/lib/config.js +21 -21
  32. package/lib/constants/numericConstants.d.ts +18 -12
  33. package/lib/constants/numericConstants.js +28 -21
  34. package/lib/constants/perpMarkets.d.ts +18 -0
  35. package/lib/constants/{markets.js → perpMarkets.js} +7 -7
  36. package/lib/constants/spotMarkets.d.ts +19 -0
  37. package/lib/constants/spotMarkets.js +53 -0
  38. package/lib/dlob/DLOB.d.ts +73 -0
  39. package/lib/dlob/DLOB.js +553 -0
  40. package/lib/dlob/DLOBNode.d.ts +52 -0
  41. package/lib/dlob/DLOBNode.js +82 -0
  42. package/lib/dlob/NodeList.d.ts +26 -0
  43. package/lib/dlob/NodeList.js +138 -0
  44. package/lib/events/eventList.js +3 -0
  45. package/lib/events/eventSubscriber.d.ts +4 -2
  46. package/lib/events/eventSubscriber.js +16 -9
  47. package/lib/events/fetchLogs.d.ts +10 -1
  48. package/lib/events/fetchLogs.js +27 -7
  49. package/lib/events/pollingLogProvider.d.ts +2 -1
  50. package/lib/events/pollingLogProvider.js +6 -2
  51. package/lib/events/sort.js +8 -11
  52. package/lib/events/types.d.ts +7 -2
  53. package/lib/events/types.js +5 -0
  54. package/lib/examples/makeTradeExample.js +20 -8
  55. package/lib/factory/bigNum.d.ts +1 -0
  56. package/lib/factory/bigNum.js +34 -10
  57. package/lib/idl/clearing_house.json +4313 -1433
  58. package/lib/idl/{mock_usdc_faucet.json → token_faucet.json} +46 -23
  59. package/lib/index.d.ts +21 -6
  60. package/lib/index.js +25 -6
  61. package/lib/math/amm.d.ts +8 -5
  62. package/lib/math/amm.js +68 -46
  63. package/lib/math/auction.js +4 -1
  64. package/lib/math/conversion.js +1 -1
  65. package/lib/math/funding.d.ts +6 -6
  66. package/lib/math/funding.js +11 -10
  67. package/lib/math/insurance.d.ts +4 -0
  68. package/lib/math/insurance.js +27 -0
  69. package/lib/math/margin.d.ts +11 -0
  70. package/lib/math/margin.js +77 -0
  71. package/lib/math/market.d.ts +14 -9
  72. package/lib/math/market.js +69 -7
  73. package/lib/math/oracles.d.ts +4 -0
  74. package/lib/math/oracles.js +36 -8
  75. package/lib/math/orders.d.ts +6 -2
  76. package/lib/math/orders.js +78 -3
  77. package/lib/math/position.d.ts +21 -13
  78. package/lib/math/position.js +76 -36
  79. package/lib/math/repeg.js +14 -5
  80. package/lib/math/spotBalance.d.ts +22 -0
  81. package/lib/math/spotBalance.js +193 -0
  82. package/lib/math/spotMarket.d.ts +4 -0
  83. package/lib/math/spotMarket.js +8 -0
  84. package/lib/math/spotPosition.d.ts +6 -0
  85. package/lib/math/spotPosition.js +23 -0
  86. package/lib/math/trade.d.ts +10 -10
  87. package/lib/math/trade.js +22 -29
  88. package/lib/oracles/pythClient.js +1 -1
  89. package/lib/oracles/quoteAssetOracleClient.js +1 -1
  90. package/lib/oracles/switchboardClient.js +1 -1
  91. package/lib/orderParams.d.ts +14 -5
  92. package/lib/orderParams.js +12 -92
  93. package/lib/serum/serumSubscriber.d.ts +23 -0
  94. package/lib/serum/serumSubscriber.js +41 -0
  95. package/lib/serum/types.d.ts +11 -0
  96. package/lib/serum/types.js +2 -0
  97. package/lib/slot/SlotSubscriber.d.ts +7 -0
  98. package/lib/slot/SlotSubscriber.js +3 -0
  99. package/lib/{mockUSDCFaucet.d.ts → tokenFaucet.d.ts} +8 -5
  100. package/lib/{mockUSDCFaucet.js → tokenFaucet.js} +63 -51
  101. package/lib/tx/retryTxSender.d.ts +1 -1
  102. package/lib/tx/retryTxSender.js +13 -4
  103. package/lib/tx/types.d.ts +1 -1
  104. package/lib/tx/utils.js +1 -1
  105. package/lib/types.d.ts +474 -123
  106. package/lib/types.js +99 -5
  107. package/lib/userMap/userMap.d.ts +25 -0
  108. package/lib/userMap/userMap.js +73 -0
  109. package/lib/userMap/userStatsMap.d.ts +19 -0
  110. package/lib/userMap/userStatsMap.js +68 -0
  111. package/lib/util/computeUnits.js +1 -1
  112. package/lib/util/getTokenAddress.d.ts +2 -0
  113. package/lib/util/getTokenAddress.js +9 -0
  114. package/package.json +9 -5
  115. package/src/accounts/bulkUserStatsSubscription.ts +33 -0
  116. package/src/accounts/bulkUserSubscription.ts +0 -1
  117. package/src/accounts/fetch.ts +27 -2
  118. package/src/accounts/pollingClearingHouseAccountSubscriber.ts +46 -42
  119. package/src/accounts/pollingUserStatsAccountSubscriber.ts +172 -0
  120. package/src/accounts/types.ts +31 -11
  121. package/src/accounts/webSocketClearingHouseAccountSubscriber.ts +64 -59
  122. package/src/accounts/webSocketUserStatsAccountSubsriber.ts +80 -0
  123. package/src/addresses/marketAddresses.ts +1 -2
  124. package/src/addresses/pda.ts +88 -14
  125. package/src/admin.ts +333 -128
  126. package/src/assert/assert.js +9 -0
  127. package/src/clearingHouse.ts +2464 -458
  128. package/src/clearingHouseConfig.ts +4 -3
  129. package/src/clearingHouseUser.ts +747 -291
  130. package/src/clearingHouseUserStats.ts +75 -0
  131. package/src/clearingHouseUserStatsConfig.ts +18 -0
  132. package/src/config.ts +30 -31
  133. package/src/constants/numericConstants.ts +41 -25
  134. package/src/constants/{markets.ts → perpMarkets.ts} +10 -10
  135. package/src/constants/spotMarkets.ts +72 -0
  136. package/src/dlob/DLOB.ts +868 -0
  137. package/src/dlob/DLOBNode.ts +162 -0
  138. package/src/dlob/NodeList.ts +185 -0
  139. package/src/events/eventList.js +77 -0
  140. package/src/events/eventList.ts +3 -0
  141. package/src/events/eventSubscriber.ts +20 -12
  142. package/src/events/fetchLogs.ts +35 -8
  143. package/src/events/pollingLogProvider.ts +10 -2
  144. package/src/events/sort.ts +11 -15
  145. package/src/events/types.ts +16 -1
  146. package/src/examples/makeTradeExample.js +157 -0
  147. package/src/examples/makeTradeExample.ts +32 -14
  148. package/src/factory/bigNum.ts +42 -13
  149. package/src/idl/clearing_house.json +4313 -1433
  150. package/src/idl/{mock_usdc_faucet.json → token_faucet.json} +46 -23
  151. package/src/index.ts +21 -6
  152. package/src/math/amm.ts +136 -66
  153. package/src/math/auction.ts +5 -1
  154. package/src/math/conversion.ts +2 -2
  155. package/src/math/funding.ts +20 -18
  156. package/src/math/insurance.ts +35 -0
  157. package/src/math/margin.ts +127 -0
  158. package/src/math/market.ts +138 -12
  159. package/src/math/oracles.ts +63 -9
  160. package/src/math/orders.ts +138 -4
  161. package/src/math/position.ts +119 -58
  162. package/src/math/repeg.ts +16 -6
  163. package/src/math/spotBalance.ts +316 -0
  164. package/src/math/spotMarket.ts +9 -0
  165. package/src/math/spotPosition.ts +47 -0
  166. package/src/math/trade.ts +43 -49
  167. package/src/oracles/pythClient.ts +2 -2
  168. package/src/oracles/quoteAssetOracleClient.ts +2 -2
  169. package/src/oracles/switchboardClient.ts +2 -2
  170. package/src/orderParams.ts +24 -137
  171. package/src/serum/serumSubscriber.ts +80 -0
  172. package/src/serum/types.ts +13 -0
  173. package/src/slot/SlotSubscriber.ts +11 -1
  174. package/src/token/index.js +38 -0
  175. package/src/{mockUSDCFaucet.ts → tokenFaucet.ts} +82 -70
  176. package/src/tx/retryTxSender.ts +16 -5
  177. package/src/tx/types.js +2 -0
  178. package/src/tx/types.ts +2 -1
  179. package/src/tx/utils.js +17 -0
  180. package/src/tx/utils.ts +1 -1
  181. package/src/types.ts +477 -125
  182. package/src/userMap/userMap.ts +100 -0
  183. package/src/userMap/userStatsMap.ts +110 -0
  184. package/src/util/computeUnits.js +21 -11
  185. package/src/util/computeUnits.ts +1 -1
  186. package/src/util/getTokenAddress.js +9 -0
  187. package/src/util/getTokenAddress.ts +18 -0
  188. package/src/util/promiseTimeout.js +14 -0
  189. package/src/util/tps.js +27 -0
  190. package/tests/bn/test.ts +12 -3
  191. package/tests/dlob/helpers.ts +374 -0
  192. package/tests/dlob/test.ts +2865 -0
  193. package/lib/constants/banks.d.ts +0 -16
  194. package/lib/constants/banks.js +0 -34
  195. package/lib/constants/markets.d.ts +0 -19
  196. package/lib/math/bankBalance.d.ts +0 -9
  197. package/lib/math/bankBalance.js +0 -75
  198. package/lib/math/state.d.ts +0 -8
  199. package/lib/math/state.js +0 -15
  200. package/lib/orders.d.ts +0 -8
  201. package/lib/orders.js +0 -134
  202. package/src/constants/banks.ts +0 -43
  203. package/src/math/bankBalance.ts +0 -112
  204. package/src/math/state.ts +0 -14
  205. package/src/math/utils.js +0 -27
  206. package/src/math/utils.js.map +0 -1
  207. package/src/orders.ts +0 -244
  208. package/src/util/computeUnits.js.map +0 -1
@@ -1,23 +1,23 @@
1
1
  {
2
- "version": "0.0.0",
3
- "name": "mock_usdc_faucet",
2
+ "version": "0.1.0",
3
+ "name": "token_faucet",
4
4
  "instructions": [
5
5
  {
6
6
  "name": "initialize",
7
7
  "accounts": [
8
8
  {
9
- "name": "mockUsdcFaucetState",
9
+ "name": "faucetConfig",
10
10
  "isMut": true,
11
11
  "isSigner": false
12
12
  },
13
13
  {
14
14
  "name": "admin",
15
- "isMut": false,
15
+ "isMut": true,
16
16
  "isSigner": true
17
17
  },
18
18
  {
19
19
  "name": "mintAccount",
20
- "isMut": false,
20
+ "isMut": true,
21
21
  "isSigner": false
22
22
  },
23
23
  {
@@ -29,20 +29,20 @@
29
29
  "name": "systemProgram",
30
30
  "isMut": false,
31
31
  "isSigner": false
32
- }
33
- ],
34
- "args": [
32
+ },
35
33
  {
36
- "name": "mockUsdcFaucetNonce",
37
- "type": "u8"
34
+ "name": "tokenProgram",
35
+ "isMut": false,
36
+ "isSigner": false
38
37
  }
39
- ]
38
+ ],
39
+ "args": []
40
40
  },
41
41
  {
42
42
  "name": "mintToUser",
43
43
  "accounts": [
44
44
  {
45
- "name": "mockUsdcFaucetState",
45
+ "name": "faucetConfig",
46
46
  "isMut": false,
47
47
  "isSigner": false
48
48
  },
@@ -73,11 +73,42 @@
73
73
  "type": "u64"
74
74
  }
75
75
  ]
76
+ },
77
+ {
78
+ "name": "transferMintAuthority",
79
+ "accounts": [
80
+ {
81
+ "name": "faucetConfig",
82
+ "isMut": false,
83
+ "isSigner": false
84
+ },
85
+ {
86
+ "name": "admin",
87
+ "isMut": true,
88
+ "isSigner": true
89
+ },
90
+ {
91
+ "name": "mintAccount",
92
+ "isMut": true,
93
+ "isSigner": false
94
+ },
95
+ {
96
+ "name": "mintAuthority",
97
+ "isMut": false,
98
+ "isSigner": false
99
+ },
100
+ {
101
+ "name": "tokenProgram",
102
+ "isMut": false,
103
+ "isSigner": false
104
+ }
105
+ ],
106
+ "args": []
76
107
  }
77
108
  ],
78
109
  "accounts": [
79
110
  {
80
- "name": "MockUSDCFaucetState",
111
+ "name": "FaucetConfig",
81
112
  "type": {
82
113
  "kind": "struct",
83
114
  "fields": [
@@ -103,17 +134,9 @@
103
134
  ],
104
135
  "errors": [
105
136
  {
106
- "code": 300,
137
+ "code": 6000,
107
138
  "name": "InvalidMintAccountAuthority",
108
139
  "msg": "Program not mint authority"
109
- },
110
- {
111
- "code": 301,
112
- "name": "Unauthorized",
113
- "msg": "Signer must be MockUSDCFaucet admin"
114
140
  }
115
- ],
116
- "metadata": {
117
- "address": "2z2DLVD3tBWc86pbvvy5qN31v1NXprM6zA5MDr2FMx64"
118
- }
141
+ ]
119
142
  }
package/src/index.ts CHANGED
@@ -1,30 +1,38 @@
1
1
  import { BN } from '@project-serum/anchor';
2
2
  import { PublicKey } from '@solana/web3.js';
3
+ import pyth from '@pythnetwork/client';
3
4
 
4
- export * from './mockUSDCFaucet';
5
+ export * from './tokenFaucet';
5
6
  export * from './oracles/types';
6
7
  export * from './oracles/pythClient';
7
8
  export * from './oracles/switchboardClient';
8
9
  export * from './types';
9
- export * from './constants/markets';
10
+ export * from './constants/perpMarkets';
10
11
  export * from './accounts/fetch';
11
12
  export * from './accounts/webSocketClearingHouseAccountSubscriber';
12
13
  export * from './accounts/bulkAccountLoader';
13
14
  export * from './accounts/bulkUserSubscription';
15
+ export * from './accounts/bulkUserStatsSubscription';
14
16
  export * from './accounts/pollingClearingHouseAccountSubscriber';
15
17
  export * from './accounts/pollingOracleSubscriber';
16
18
  export * from './accounts/pollingTokenAccountSubscriber';
19
+ export * from './accounts/pollingUserAccountSubscriber';
20
+ export * from './accounts/pollingUserStatsAccountSubscriber';
17
21
  export * from './accounts/types';
18
22
  export * from './addresses/pda';
19
23
  export * from './admin';
20
24
  export * from './clearingHouseUser';
21
25
  export * from './clearingHouseUserConfig';
26
+ export * from './clearingHouseUserStats';
27
+ export * from './clearingHouseUserStatsConfig';
22
28
  export * from './clearingHouse';
23
29
  export * from './factory/oracleClient';
24
30
  export * from './factory/bigNum';
25
31
  export * from './events/types';
26
32
  export * from './events/eventSubscriber';
33
+ export * from './events/fetchLogs';
27
34
  export * from './math/auction';
35
+ export * from './math/spotMarket';
28
36
  export * from './math/conversion';
29
37
  export * from './math/funding';
30
38
  export * from './math/market';
@@ -34,7 +42,8 @@ export * from './math/amm';
34
42
  export * from './math/trade';
35
43
  export * from './math/orders';
36
44
  export * from './math/repeg';
37
- export * from './orders';
45
+ export * from './math/margin';
46
+ export * from './math/insurance';
38
47
  export * from './orderParams';
39
48
  export * from './slot/SlotSubscriber';
40
49
  export * from './wallet';
@@ -42,11 +51,17 @@ export * from './types';
42
51
  export * from './math/utils';
43
52
  export * from './config';
44
53
  export * from './constants/numericConstants';
54
+ export * from './serum/serumSubscriber';
45
55
  export * from './tx/retryTxSender';
46
56
  export * from './util/computeUnits';
47
57
  export * from './util/tps';
48
- export * from './math/bankBalance';
49
- export * from './constants/banks';
58
+ export * from './math/spotBalance';
59
+ export * from './constants/spotMarkets';
50
60
  export * from './clearingHouseConfig';
61
+ export * from './dlob/DLOB';
62
+ export * from './dlob/DLOBNode';
63
+ export * from './dlob/NodeList';
64
+ export * from './userMap/userMap';
65
+ export * from './userMap/userStatsMap';
51
66
 
52
- export { BN, PublicKey };
67
+ export { BN, PublicKey, pyth };
package/src/math/amm.ts CHANGED
@@ -1,7 +1,7 @@
1
1
  import { BN } from '@project-serum/anchor';
2
2
  import {
3
3
  AMM_TIMES_PEG_TO_QUOTE_PRECISION_RATIO,
4
- MARK_PRICE_PRECISION,
4
+ PRICE_PRECISION,
5
5
  PEG_PRECISION,
6
6
  ZERO,
7
7
  BID_ASK_SPREAD_PRECISION,
@@ -15,11 +15,11 @@ 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';
22
- import { squareRootBN } from '..';
22
+ import { squareRootBN, standardizeBaseAssetAmount } from '..';
23
23
 
24
24
  import { OraclePriceData } from '../oracles/types';
25
25
  import {
@@ -33,11 +33,14 @@ export function calculatePegFromTargetPrice(
33
33
  baseAssetReserve: BN,
34
34
  quoteAssetReserve: BN
35
35
  ): BN {
36
- return targetPrice
37
- .mul(baseAssetReserve)
38
- .div(quoteAssetReserve)
39
- .add(PRICE_DIV_PEG.div(new BN(2)))
40
- .div(PRICE_DIV_PEG);
36
+ return BN.max(
37
+ targetPrice
38
+ .mul(baseAssetReserve)
39
+ .div(quoteAssetReserve)
40
+ .add(PRICE_DIV_PEG.div(new BN(2)))
41
+ .div(PRICE_DIV_PEG),
42
+ ONE
43
+ );
41
44
  }
42
45
 
43
46
  export function calculateOptimalPegAndBudget(
@@ -68,6 +71,7 @@ export function calculateOptimalPegAndBudget(
68
71
  let newOptimalPeg: BN;
69
72
  let newBudget: BN;
70
73
  const targetPriceGap = markPriceBefore.sub(targetPrice);
74
+
71
75
  if (targetPriceGap.abs().gt(maxPriceSpread)) {
72
76
  const markAdj = targetPriceGap.abs().sub(maxPriceSpread);
73
77
 
@@ -238,7 +242,7 @@ export function calculateBidAskPrice(
238
242
  * @param baseAssetReserves
239
243
  * @param quoteAssetReserves
240
244
  * @param pegMultiplier
241
- * @returns price : Precision MARK_PRICE_PRECISION
245
+ * @returns price : Precision PRICE_PRECISION
242
246
  */
243
247
  export function calculatePrice(
244
248
  baseAssetReserves: BN,
@@ -250,7 +254,7 @@ export function calculatePrice(
250
254
  }
251
255
 
252
256
  return quoteAssetReserves
253
- .mul(MARK_PRICE_PRECISION)
257
+ .mul(PRICE_PRECISION)
254
258
  .mul(pegMultiplier)
255
259
  .div(PEG_PRECISION)
256
260
  .div(baseAssetReserves);
@@ -304,6 +308,54 @@ export function calculateAmmReservesAfterSwap(
304
308
  return [newQuoteAssetReserve, newBaseAssetReserve];
305
309
  }
306
310
 
311
+ export function calculateMarketOpenBidAsk(
312
+ baseAssetReserve: BN,
313
+ minBaseAssetReserve: BN,
314
+ maxBaseAssetReserve: BN
315
+ ): [BN, BN] {
316
+ // open orders
317
+ let openAsks;
318
+ if (maxBaseAssetReserve > baseAssetReserve) {
319
+ openAsks = maxBaseAssetReserve.sub(baseAssetReserve).mul(new BN(-1));
320
+ } else {
321
+ openAsks = ZERO;
322
+ }
323
+
324
+ let openBids;
325
+ if (minBaseAssetReserve < baseAssetReserve) {
326
+ openBids = baseAssetReserve.sub(minBaseAssetReserve);
327
+ } else {
328
+ openBids = ZERO;
329
+ }
330
+ return [openBids, openAsks];
331
+ }
332
+
333
+ export function calculateInventoryScale(
334
+ netBaseAssetAmount: BN,
335
+ baseAssetReserve: BN,
336
+ minBaseAssetReserve: BN,
337
+ maxBaseAssetReserve: BN
338
+ ): number {
339
+ // inventory skew
340
+ const [openBids, openAsks] = calculateMarketOpenBidAsk(
341
+ baseAssetReserve,
342
+ minBaseAssetReserve,
343
+ maxBaseAssetReserve
344
+ );
345
+
346
+ const minSideLiquidity = BN.max(
347
+ new BN(1),
348
+ BN.min(openBids.abs(), openAsks.abs())
349
+ );
350
+ const inventoryScale =
351
+ BN.min(netBaseAssetAmount.abs(), minSideLiquidity)
352
+ .mul(BID_ASK_SPREAD_PRECISION.mul(new BN(10)))
353
+ .div(minSideLiquidity)
354
+ .toNumber() / BID_ASK_SPREAD_PRECISION.toNumber();
355
+
356
+ return inventoryScale;
357
+ }
358
+
307
359
  export function calculateEffectiveLeverage(
308
360
  baseSpread: number,
309
361
  quoteAssetReserve: BN,
@@ -321,7 +373,7 @@ export function calculateEffectiveLeverage(
321
373
 
322
374
  const localBaseAssetValue = netBaseAssetAmount
323
375
  .mul(markPrice)
324
- .div(AMM_TO_QUOTE_PRECISION_RATIO.mul(MARK_PRICE_PRECISION));
376
+ .div(AMM_TO_QUOTE_PRECISION_RATIO.mul(PRICE_PRECISION));
325
377
 
326
378
  const effectiveLeverage =
327
379
  localBaseAssetValue.sub(netBaseAssetValue).toNumber() /
@@ -349,7 +401,10 @@ export function calculateSpreadBN(
349
401
  pegMultiplier: BN,
350
402
  netBaseAssetAmount: BN,
351
403
  markPrice: BN,
352
- totalFeeMinusDistributions: BN
404
+ totalFeeMinusDistributions: BN,
405
+ baseAssetReserve: BN,
406
+ minBaseAssetReserve: BN,
407
+ maxBaseAssetReserve: BN
353
408
  ): [number, number] {
354
409
  let longSpread = baseSpread / 2;
355
410
  let shortSpread = baseSpread / 2;
@@ -366,10 +421,27 @@ export function calculateSpreadBN(
366
421
  );
367
422
  }
368
423
 
369
- const maxTargetSpread: number = maxSpread;
424
+ const maxTargetSpread: number = Math.max(
425
+ maxSpread,
426
+ lastOracleMarkSpreadPct.abs().toNumber()
427
+ );
370
428
 
371
429
  const MAX_INVENTORY_SKEW = 5;
372
430
 
431
+ const inventoryScale = calculateInventoryScale(
432
+ netBaseAssetAmount,
433
+ baseAssetReserve,
434
+ minBaseAssetReserve,
435
+ maxBaseAssetReserve
436
+ );
437
+ const inventorySpreadScale = Math.min(MAX_INVENTORY_SKEW, 1 + inventoryScale);
438
+
439
+ if (netBaseAssetAmount.gt(ZERO)) {
440
+ longSpread *= inventorySpreadScale;
441
+ } else if (netBaseAssetAmount.lt(ZERO)) {
442
+ shortSpread *= inventorySpreadScale;
443
+ }
444
+
373
445
  const effectiveLeverage = calculateEffectiveLeverage(
374
446
  baseSpread,
375
447
  quoteAssetReserve,
@@ -411,10 +483,8 @@ export function calculateSpread(
411
483
  direction: PositionDirection,
412
484
  oraclePriceData: OraclePriceData
413
485
  ): number {
414
- let spread = amm.baseSpread / 2;
415
-
416
486
  if (amm.baseSpread == 0 || amm.curveUpdateIntensity == 0) {
417
- return spread;
487
+ return amm.baseSpread / 2;
418
488
  }
419
489
 
420
490
  const markPrice = calculatePrice(
@@ -435,54 +505,28 @@ export function calculateSpread(
435
505
  .mul(BID_ASK_SPREAD_PRECISION)
436
506
  .div(markPrice);
437
507
 
438
- // oracle retreat
439
- if (
440
- (isVariant(direction, 'long') && targetMarkSpreadPct.lt(ZERO)) ||
441
- (isVariant(direction, 'short') && targetMarkSpreadPct.gt(ZERO))
442
- ) {
443
- spread = Math.max(
444
- spread,
445
- targetMarkSpreadPct.abs().toNumber() + confIntervalPct.abs().toNumber()
446
- );
447
- }
448
-
449
- // inventory skew
450
- const MAX_INVENTORY_SKEW = 5;
451
- if (
452
- (amm.netBaseAssetAmount.gt(ZERO) && isVariant(direction, 'long')) ||
453
- (amm.netBaseAssetAmount.lt(ZERO) && isVariant(direction, 'short')) ||
454
- amm.totalFeeMinusDistributions.eq(ZERO)
455
- ) {
456
- const netCostBasis = amm.quoteAssetAmountLong.sub(
457
- amm.quoteAssetAmountShort
458
- );
459
- const netBaseAssetValue = amm.quoteAssetReserve
460
- .sub(amm.terminalQuoteAssetReserve)
461
- .mul(amm.pegMultiplier)
462
- .div(AMM_TIMES_PEG_TO_QUOTE_PRECISION_RATIO);
463
-
464
- const localBaseAssetValue = amm.netBaseAssetAmount
465
- .mul(markPrice)
466
- .div(AMM_TO_QUOTE_PRECISION_RATIO.mul(MARK_PRICE_PRECISION));
467
- const netPnl = netBaseAssetValue.sub(netCostBasis);
468
- const localPnl = localBaseAssetValue.sub(netCostBasis);
469
-
470
- let effectiveLeverage = MAX_INVENTORY_SKEW;
471
- if (amm.totalFeeMinusDistributions.gt(ZERO)) {
472
- effectiveLeverage =
473
- localPnl.sub(netPnl).toNumber() /
474
- (amm.totalFeeMinusDistributions.toNumber() + 1);
475
- }
508
+ const [longSpread, shortSpread] = calculateSpreadBN(
509
+ amm.baseSpread,
510
+ targetMarkSpreadPct,
511
+ confIntervalPct,
512
+ amm.maxSpread,
513
+ amm.quoteAssetReserve,
514
+ amm.terminalQuoteAssetReserve,
515
+ amm.pegMultiplier,
516
+ amm.netBaseAssetAmount,
517
+ markPrice,
518
+ amm.totalFeeMinusDistributions,
519
+ amm.baseAssetReserve,
520
+ amm.minBaseAssetReserve,
521
+ amm.maxBaseAssetReserve
522
+ );
476
523
 
477
- let spreadScale = Math.min(MAX_INVENTORY_SKEW, 1 + effectiveLeverage);
478
- const maxTargetSpread = BID_ASK_SPREAD_PRECISION.toNumber() / 50; // 2%
479
- // cap the scale to attempt to only scale up to maxTargetSpread
480
- // always let the oracle retreat methods go through 100%
481
- if (spreadScale * spread > maxTargetSpread) {
482
- spreadScale = Math.max(1.05, maxTargetSpread / spread);
483
- }
524
+ let spread: number;
484
525
 
485
- spread *= spreadScale;
526
+ if (isVariant(direction, 'long')) {
527
+ spread = longSpread;
528
+ } else {
529
+ spread = shortSpread;
486
530
  }
487
531
 
488
532
  return spread;
@@ -573,9 +617,9 @@ export function getSwapDirection(
573
617
  * Helper function calculating terminal price of amm
574
618
  *
575
619
  * @param market
576
- * @returns cost : Precision MARK_PRICE_PRECISION
620
+ * @returns cost : Precision PRICE_PRECISION
577
621
  */
578
- export function calculateTerminalPrice(market: MarketAccount) {
622
+ export function calculateTerminalPrice(market: PerpMarketAccount) {
579
623
  const directionToClose = market.amm.netBaseAssetAmount.gt(ZERO)
580
624
  ? PositionDirection.SHORT
581
625
  : PositionDirection.LONG;
@@ -589,7 +633,7 @@ export function calculateTerminalPrice(market: MarketAccount) {
589
633
  );
590
634
 
591
635
  const terminalPrice = newQuoteAssetReserve
592
- .mul(MARK_PRICE_PRECISION)
636
+ .mul(PRICE_PRECISION)
593
637
  .mul(market.amm.pegMultiplier)
594
638
  .div(PEG_PRECISION)
595
639
  .div(newBaseAssetReserve);
@@ -606,7 +650,7 @@ export function calculateMaxBaseAssetAmountToTrade(
606
650
  const invariant = amm.sqrtK.mul(amm.sqrtK);
607
651
 
608
652
  const newBaseAssetReserveSquared = invariant
609
- .mul(MARK_PRICE_PRECISION)
653
+ .mul(PRICE_PRECISION)
610
654
  .mul(amm.pegMultiplier)
611
655
  .div(limit_price)
612
656
  .div(PEG_PRECISION);
@@ -650,3 +694,29 @@ export function calculateQuoteAssetAmountSwapped(
650
694
 
651
695
  return quoteAssetAmount;
652
696
  }
697
+
698
+ export function calculateMaxBaseAssetAmountFillable(
699
+ amm: AMM,
700
+ orderDirection: PositionDirection
701
+ ): BN {
702
+ const maxFillSize = amm.baseAssetReserve.div(
703
+ new BN(amm.maxBaseAssetAmountRatio)
704
+ );
705
+ let maxBaseAssetAmountOnSide: BN;
706
+ if (isVariant(orderDirection, 'long')) {
707
+ maxBaseAssetAmountOnSide = BN.max(
708
+ ZERO,
709
+ amm.baseAssetReserve.sub(amm.minBaseAssetReserve)
710
+ );
711
+ } else {
712
+ maxBaseAssetAmountOnSide = BN.max(
713
+ ZERO,
714
+ amm.maxBaseAssetReserve.sub(amm.baseAssetReserve)
715
+ );
716
+ }
717
+
718
+ return standardizeBaseAssetAmount(
719
+ BN.min(maxFillSize, maxBaseAssetAmountOnSide),
720
+ amm.baseAssetAmountStepSize
721
+ );
722
+ }
@@ -2,7 +2,11 @@ import { isVariant, Order } from '../types';
2
2
  import { BN, ZERO } from '../.';
3
3
 
4
4
  export function isAuctionComplete(order: Order, slot: number): boolean {
5
- return new BN(slot).sub(order.slot).gte(new BN(order.auctionDuration));
5
+ if (order.auctionDuration === 0) {
6
+ return true;
7
+ }
8
+
9
+ return new BN(slot).sub(order.slot).gt(new BN(order.auctionDuration));
6
10
  }
7
11
 
8
12
  export function getAuctionPrice(order: Order, slot: number): BN {
@@ -1,9 +1,9 @@
1
1
  import { BN } from '../';
2
- import { MARK_PRICE_PRECISION } from '../constants/numericConstants';
2
+ import { PRICE_PRECISION } from '../constants/numericConstants';
3
3
 
4
4
  export const convertToNumber = (
5
5
  bigNumber: BN,
6
- precision: BN = MARK_PRICE_PRECISION
6
+ precision: BN = PRICE_PRECISION
7
7
  ) => {
8
8
  if (!bigNumber) return 0;
9
9
  return (
@@ -1,12 +1,12 @@
1
1
  import { BN } from '@project-serum/anchor';
2
2
  import {
3
3
  AMM_RESERVE_PRECISION,
4
- MARK_PRICE_PRECISION,
4
+ PRICE_PRECISION,
5
5
  QUOTE_PRECISION,
6
6
  ZERO,
7
7
  } from '../constants/numericConstants';
8
- import { MarketAccount } from '../types';
9
- import { calculateMarkPrice } from './market';
8
+ import { PerpMarketAccount, isVariant } from '../types';
9
+ import { calculateReservePrice } from './market';
10
10
  import { OraclePriceData } from '../oracles/types';
11
11
 
12
12
  /**
@@ -17,7 +17,7 @@ import { OraclePriceData } from '../oracles/types';
17
17
  * @returns Estimated funding rate. : Precision //TODO-PRECISION
18
18
  */
19
19
  export async function calculateAllEstimatedFundingRate(
20
- market: MarketAccount,
20
+ market: PerpMarketAccount,
21
21
  oraclePriceData?: OraclePriceData,
22
22
  periodAdjustment: BN = new BN(1)
23
23
  ): Promise<[BN, BN, BN, BN, BN]> {
@@ -29,7 +29,7 @@ export async function calculateAllEstimatedFundingRate(
29
29
  const hoursInDay = new BN(24);
30
30
  const ONE = new BN(1);
31
31
 
32
- if (!market.initialized) {
32
+ if (isVariant(market.status, 'uninitialized')) {
33
33
  return [ZERO, ZERO, ZERO, ZERO, ZERO];
34
34
  }
35
35
 
@@ -48,7 +48,7 @@ export async function calculateAllEstimatedFundingRate(
48
48
  secondsInHour,
49
49
  BN.max(ZERO, secondsInHour.sub(timeSinceLastMarkChange))
50
50
  );
51
- const baseAssetPriceWithMantissa = calculateMarkPrice(
51
+ const baseAssetPriceWithMantissa = calculateReservePrice(
52
52
  market,
53
53
  oraclePriceData
54
54
  );
@@ -60,8 +60,10 @@ export async function calculateAllEstimatedFundingRate(
60
60
 
61
61
  // calculate real-time (predicted) oracle twap
62
62
  // note: oracle twap depends on `when the chord is struck` (market is trade)
63
- const lastOracleTwapWithMantissa = market.amm.lastOraclePriceTwap;
64
- const lastOraclePriceTwapTs = market.amm.lastOraclePriceTwapTs;
63
+ const lastOracleTwapWithMantissa =
64
+ market.amm.historicalOracleData.lastOraclePriceTwap;
65
+ const lastOraclePriceTwapTs =
66
+ market.amm.historicalOracleData.lastOraclePriceTwapTs;
65
67
 
66
68
  const oracleInvalidDuration = BN.max(
67
69
  ZERO,
@@ -85,12 +87,12 @@ export async function calculateAllEstimatedFundingRate(
85
87
  const oracleLiveVsTwap = oraclePrice
86
88
  .sub(lastOracleTwapWithMantissa)
87
89
  .abs()
88
- .mul(MARK_PRICE_PRECISION)
90
+ .mul(PRICE_PRECISION)
89
91
  .mul(new BN(100))
90
92
  .div(lastOracleTwapWithMantissa);
91
93
 
92
94
  // verify pyth live input is within 10% of last twap for live update
93
- if (oracleLiveVsTwap.lte(MARK_PRICE_PRECISION.mul(new BN(10)))) {
95
+ if (oracleLiveVsTwap.lte(PRICE_PRECISION.mul(new BN(10)))) {
94
96
  oracleTwapWithMantissa = oracleTwapTimeSinceLastUpdate
95
97
  .mul(lastOracleTwapWithMantissa)
96
98
  .add(timeSinceLastMarkChange.mul(oraclePrice))
@@ -108,7 +110,7 @@ export async function calculateAllEstimatedFundingRate(
108
110
  );
109
111
 
110
112
  const twapSpreadPct = twapSpread
111
- .mul(MARK_PRICE_PRECISION)
113
+ .mul(PRICE_PRECISION)
112
114
  .mul(new BN(100))
113
115
  .div(shrunkLastOracleTwapwithMantissa);
114
116
 
@@ -125,7 +127,7 @@ export async function calculateAllEstimatedFundingRate(
125
127
  const interpRateQuote = twapSpreadPct
126
128
  .mul(periodAdjustment)
127
129
  .div(hoursInDay)
128
- .div(MARK_PRICE_PRECISION.div(QUOTE_PRECISION));
130
+ .div(PRICE_PRECISION.div(QUOTE_PRECISION));
129
131
 
130
132
  let feePoolSize = calculateFundingPool(market);
131
133
  if (interpRateQuote.lt(new BN(0))) {
@@ -173,12 +175,12 @@ export async function calculateAllEstimatedFundingRate(
173
175
  // funding smaller flow
174
176
  cappedAltEst = smallerSide.mul(twapSpread).div(hoursInDay);
175
177
  const feePoolTopOff = feePoolSize
176
- .mul(MARK_PRICE_PRECISION.div(QUOTE_PRECISION))
178
+ .mul(PRICE_PRECISION.div(QUOTE_PRECISION))
177
179
  .mul(AMM_RESERVE_PRECISION);
178
180
  cappedAltEst = cappedAltEst.add(feePoolTopOff).div(largerSide);
179
181
 
180
182
  cappedAltEst = cappedAltEst
181
- .mul(MARK_PRICE_PRECISION)
183
+ .mul(PRICE_PRECISION)
182
184
  .mul(new BN(100))
183
185
  .div(oracleTwapWithMantissa)
184
186
  .mul(periodAdjustment);
@@ -208,7 +210,7 @@ export async function calculateAllEstimatedFundingRate(
208
210
  * @returns Estimated funding rate. : Precision //TODO-PRECISION
209
211
  */
210
212
  export async function calculateEstimatedFundingRate(
211
- market: MarketAccount,
213
+ market: PerpMarketAccount,
212
214
  oraclePriceData?: OraclePriceData,
213
215
  periodAdjustment: BN = new BN(1),
214
216
  estimationMethod?: 'interpolated' | 'lowerbound' | 'capped'
@@ -238,7 +240,7 @@ export async function calculateEstimatedFundingRate(
238
240
  * @returns Estimated funding rate. : Precision //TODO-PRECISION
239
241
  */
240
242
  export async function calculateLongShortFundingRate(
241
- market: MarketAccount,
243
+ market: PerpMarketAccount,
242
244
  oraclePriceData?: OraclePriceData,
243
245
  periodAdjustment: BN = new BN(1)
244
246
  ): Promise<[BN, BN]> {
@@ -266,7 +268,7 @@ export async function calculateLongShortFundingRate(
266
268
  * @returns Estimated funding rate. : Precision //TODO-PRECISION
267
269
  */
268
270
  export async function calculateLongShortFundingRateAndLiveTwaps(
269
- market: MarketAccount,
271
+ market: PerpMarketAccount,
270
272
  oraclePriceData?: OraclePriceData,
271
273
  periodAdjustment: BN = new BN(1)
272
274
  ): Promise<[BN, BN, BN, BN]> {
@@ -291,7 +293,7 @@ export async function calculateLongShortFundingRateAndLiveTwaps(
291
293
  * @param market
292
294
  * @returns Estimated fee pool size
293
295
  */
294
- export function calculateFundingPool(market: MarketAccount): BN {
296
+ export function calculateFundingPool(market: PerpMarketAccount): BN {
295
297
  // todo
296
298
  const totalFeeLB = market.amm.totalExchangeFee.div(new BN(2));
297
299
  const feePool = BN.max(