@drift-labs/sdk 0.2.0-master.2 → 0.2.0-master.20

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 (152) hide show
  1. package/lib/accounts/bulkUserStatsSubscription.d.ts +7 -0
  2. package/lib/accounts/bulkUserStatsSubscription.js +21 -0
  3. package/lib/accounts/bulkUserSubscription.js +0 -1
  4. package/lib/accounts/fetch.d.ts +2 -1
  5. package/lib/accounts/fetch.js +9 -1
  6. package/lib/accounts/pollingUserStatsAccountSubscriber.d.ts +27 -0
  7. package/lib/accounts/pollingUserStatsAccountSubscriber.js +113 -0
  8. package/lib/accounts/types.d.ts +14 -1
  9. package/lib/accounts/webSocketUserStatsAccountSubsriber.d.ts +20 -0
  10. package/lib/accounts/webSocketUserStatsAccountSubsriber.js +47 -0
  11. package/lib/addresses/pda.d.ts +1 -0
  12. package/lib/addresses/pda.js +8 -1
  13. package/lib/admin.d.ts +9 -5
  14. package/lib/admin.js +52 -11
  15. package/lib/clearingHouse.d.ts +52 -23
  16. package/lib/clearingHouse.js +727 -197
  17. package/lib/clearingHouseConfig.d.ts +1 -0
  18. package/lib/clearingHouseUser.d.ts +17 -17
  19. package/lib/clearingHouseUser.js +186 -101
  20. package/lib/clearingHouseUserStats.d.ts +18 -0
  21. package/lib/clearingHouseUserStats.js +49 -0
  22. package/lib/clearingHouseUserStatsConfig.d.ts +14 -0
  23. package/lib/clearingHouseUserStatsConfig.js +2 -0
  24. package/lib/config.js +1 -1
  25. package/lib/constants/banks.d.ts +2 -2
  26. package/lib/constants/banks.js +12 -4
  27. package/lib/constants/numericConstants.d.ts +5 -0
  28. package/lib/constants/numericConstants.js +8 -3
  29. package/lib/events/eventList.js +3 -0
  30. package/lib/events/types.d.ts +3 -1
  31. package/lib/events/types.js +2 -0
  32. package/lib/factory/bigNum.d.ts +1 -0
  33. package/lib/factory/bigNum.js +34 -10
  34. package/lib/idl/clearing_house.json +1609 -388
  35. package/lib/idl/{mock_usdc_faucet.json → token_faucet.json} +46 -23
  36. package/lib/index.d.ts +9 -3
  37. package/lib/index.js +13 -3
  38. package/lib/math/amm.d.ts +1 -0
  39. package/lib/math/amm.js +22 -38
  40. package/lib/math/auction.js +4 -1
  41. package/lib/math/bankBalance.d.ts +7 -1
  42. package/lib/math/bankBalance.js +77 -2
  43. package/lib/math/margin.d.ts +11 -0
  44. package/lib/math/margin.js +72 -0
  45. package/lib/math/market.d.ts +4 -1
  46. package/lib/math/market.js +35 -1
  47. package/lib/math/oracles.d.ts +3 -0
  48. package/lib/math/oracles.js +25 -5
  49. package/lib/math/orders.d.ts +5 -2
  50. package/lib/math/orders.js +53 -12
  51. package/lib/math/position.d.ts +8 -0
  52. package/lib/math/position.js +45 -12
  53. package/lib/math/trade.d.ts +1 -1
  54. package/lib/math/trade.js +7 -10
  55. package/lib/orderParams.d.ts +14 -5
  56. package/lib/orderParams.js +8 -96
  57. package/lib/slot/SlotSubscriber.d.ts +7 -0
  58. package/lib/slot/SlotSubscriber.js +3 -0
  59. package/lib/{mockUSDCFaucet.d.ts → tokenFaucet.d.ts} +8 -5
  60. package/lib/{mockUSDCFaucet.js → tokenFaucet.js} +63 -51
  61. package/lib/tx/retryTxSender.js +9 -2
  62. package/lib/tx/utils.js +1 -1
  63. package/lib/types.d.ts +233 -26
  64. package/lib/types.js +64 -1
  65. package/lib/util/computeUnits.js +1 -1
  66. package/lib/util/getTokenAddress.d.ts +2 -0
  67. package/lib/util/getTokenAddress.js +9 -0
  68. package/package.json +3 -3
  69. package/src/accounts/bulkUserStatsSubscription.ts +33 -0
  70. package/src/accounts/bulkUserSubscription.ts +0 -1
  71. package/src/accounts/fetch.ts +27 -2
  72. package/src/accounts/pollingUserStatsAccountSubscriber.ts +172 -0
  73. package/src/accounts/types.ts +18 -0
  74. package/src/accounts/webSocketUserStatsAccountSubsriber.ts +80 -0
  75. package/src/addresses/marketAddresses.js +26 -0
  76. package/src/addresses/pda.ts +13 -0
  77. package/src/admin.ts +82 -15
  78. package/src/assert/assert.js +9 -0
  79. package/src/clearingHouse.ts +1224 -319
  80. package/src/clearingHouseConfig.ts +1 -0
  81. package/src/clearingHouseUser.ts +311 -148
  82. package/src/clearingHouseUserStats.ts +75 -0
  83. package/src/clearingHouseUserStatsConfig.ts +18 -0
  84. package/src/config.ts +1 -1
  85. package/src/constants/banks.js +42 -0
  86. package/src/constants/banks.ts +14 -4
  87. package/src/constants/markets.js +42 -0
  88. package/src/constants/numericConstants.js +41 -0
  89. package/src/constants/numericConstants.ts +14 -2
  90. package/src/events/eventList.js +77 -0
  91. package/src/events/eventList.ts +3 -0
  92. package/src/events/eventSubscriber.js +139 -0
  93. package/src/events/fetchLogs.js +50 -0
  94. package/src/events/pollingLogProvider.js +64 -0
  95. package/src/events/sort.js +44 -0
  96. package/src/events/txEventCache.js +71 -0
  97. package/src/events/types.ts +6 -0
  98. package/src/events/webSocketLogProvider.js +41 -0
  99. package/src/examples/makeTradeExample.js +80 -0
  100. package/src/factory/bigNum.js +390 -0
  101. package/src/factory/bigNum.ts +42 -13
  102. package/src/factory/oracleClient.js +20 -0
  103. package/src/idl/clearing_house.json +1609 -388
  104. package/src/idl/{mock_usdc_faucet.json → token_faucet.json} +46 -23
  105. package/src/index.ts +9 -3
  106. package/src/math/amm.ts +54 -55
  107. package/src/math/auction.js +42 -0
  108. package/src/math/auction.ts +5 -1
  109. package/src/math/bankBalance.ts +148 -2
  110. package/src/math/conversion.js +11 -0
  111. package/src/math/funding.js +248 -0
  112. package/src/math/margin.ts +124 -0
  113. package/src/math/market.ts +66 -1
  114. package/src/math/oracles.js +26 -0
  115. package/src/math/oracles.ts +42 -5
  116. package/src/math/orders.ts +112 -13
  117. package/src/math/position.ts +64 -9
  118. package/src/math/repeg.js +128 -0
  119. package/src/math/state.js +15 -0
  120. package/src/math/trade.js +253 -0
  121. package/src/math/trade.ts +23 -25
  122. package/src/math/utils.js +0 -1
  123. package/src/oracles/oracleClientCache.js +19 -0
  124. package/src/oracles/pythClient.js +46 -0
  125. package/src/oracles/quoteAssetOracleClient.js +32 -0
  126. package/src/oracles/switchboardClient.js +69 -0
  127. package/src/oracles/types.js +2 -0
  128. package/src/orderParams.js +20 -0
  129. package/src/orderParams.ts +20 -141
  130. package/src/slot/SlotSubscriber.js +39 -0
  131. package/src/slot/SlotSubscriber.ts +11 -1
  132. package/src/token/index.js +38 -0
  133. package/src/tokenFaucet.js +189 -0
  134. package/src/{mockUSDCFaucet.ts → tokenFaucet.ts} +82 -70
  135. package/src/tx/retryTxSender.ts +11 -3
  136. package/src/tx/types.js +2 -0
  137. package/src/tx/utils.js +17 -0
  138. package/src/tx/utils.ts +1 -1
  139. package/src/types.ts +236 -27
  140. package/src/userName.js +20 -0
  141. package/src/util/computeUnits.js +21 -11
  142. package/src/util/computeUnits.ts +1 -1
  143. package/src/util/getTokenAddress.js +9 -0
  144. package/src/util/getTokenAddress.ts +18 -0
  145. package/src/util/promiseTimeout.js +14 -0
  146. package/src/util/tps.js +27 -0
  147. package/src/wallet.js +35 -0
  148. package/tests/bn/test.ts +10 -0
  149. package/lib/orders.d.ts +0 -8
  150. package/lib/orders.js +0 -142
  151. package/src/orders.ts +0 -251
  152. 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/lib/index.d.ts CHANGED
@@ -1,6 +1,7 @@
1
1
  import { BN } from '@project-serum/anchor';
2
2
  import { PublicKey } from '@solana/web3.js';
3
- export * from './mockUSDCFaucet';
3
+ import pyth from '@pythnetwork/client';
4
+ export * from './tokenFaucet';
4
5
  export * from './oracles/types';
5
6
  export * from './oracles/pythClient';
6
7
  export * from './oracles/switchboardClient';
@@ -10,14 +11,19 @@ export * from './accounts/fetch';
10
11
  export * from './accounts/webSocketClearingHouseAccountSubscriber';
11
12
  export * from './accounts/bulkAccountLoader';
12
13
  export * from './accounts/bulkUserSubscription';
14
+ export * from './accounts/bulkUserStatsSubscription';
13
15
  export * from './accounts/pollingClearingHouseAccountSubscriber';
14
16
  export * from './accounts/pollingOracleSubscriber';
15
17
  export * from './accounts/pollingTokenAccountSubscriber';
18
+ export * from './accounts/pollingUserAccountSubscriber';
19
+ export * from './accounts/pollingUserStatsAccountSubscriber';
16
20
  export * from './accounts/types';
17
21
  export * from './addresses/pda';
18
22
  export * from './admin';
19
23
  export * from './clearingHouseUser';
20
24
  export * from './clearingHouseUserConfig';
25
+ export * from './clearingHouseUserStats';
26
+ export * from './clearingHouseUserStatsConfig';
21
27
  export * from './clearingHouse';
22
28
  export * from './factory/oracleClient';
23
29
  export * from './factory/bigNum';
@@ -33,7 +39,7 @@ export * from './math/amm';
33
39
  export * from './math/trade';
34
40
  export * from './math/orders';
35
41
  export * from './math/repeg';
36
- export * from './orders';
42
+ export * from './math/margin';
37
43
  export * from './orderParams';
38
44
  export * from './slot/SlotSubscriber';
39
45
  export * from './wallet';
@@ -47,4 +53,4 @@ export * from './util/tps';
47
53
  export * from './math/bankBalance';
48
54
  export * from './constants/banks';
49
55
  export * from './clearingHouseConfig';
50
- export { BN, PublicKey };
56
+ export { BN, PublicKey, pyth };
package/lib/index.js CHANGED
@@ -13,13 +13,18 @@ var __createBinding = (this && this.__createBinding) || (Object.create ? (functi
13
13
  var __exportStar = (this && this.__exportStar) || function(m, exports) {
14
14
  for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
15
15
  };
16
+ var __importDefault = (this && this.__importDefault) || function (mod) {
17
+ return (mod && mod.__esModule) ? mod : { "default": mod };
18
+ };
16
19
  Object.defineProperty(exports, "__esModule", { value: true });
17
- exports.PublicKey = exports.BN = void 0;
20
+ exports.pyth = exports.PublicKey = exports.BN = void 0;
18
21
  const anchor_1 = require("@project-serum/anchor");
19
22
  Object.defineProperty(exports, "BN", { enumerable: true, get: function () { return anchor_1.BN; } });
20
23
  const web3_js_1 = require("@solana/web3.js");
21
24
  Object.defineProperty(exports, "PublicKey", { enumerable: true, get: function () { return web3_js_1.PublicKey; } });
22
- __exportStar(require("./mockUSDCFaucet"), exports);
25
+ const client_1 = __importDefault(require("@pythnetwork/client"));
26
+ exports.pyth = client_1.default;
27
+ __exportStar(require("./tokenFaucet"), exports);
23
28
  __exportStar(require("./oracles/types"), exports);
24
29
  __exportStar(require("./oracles/pythClient"), exports);
25
30
  __exportStar(require("./oracles/switchboardClient"), exports);
@@ -29,14 +34,19 @@ __exportStar(require("./accounts/fetch"), exports);
29
34
  __exportStar(require("./accounts/webSocketClearingHouseAccountSubscriber"), exports);
30
35
  __exportStar(require("./accounts/bulkAccountLoader"), exports);
31
36
  __exportStar(require("./accounts/bulkUserSubscription"), exports);
37
+ __exportStar(require("./accounts/bulkUserStatsSubscription"), exports);
32
38
  __exportStar(require("./accounts/pollingClearingHouseAccountSubscriber"), exports);
33
39
  __exportStar(require("./accounts/pollingOracleSubscriber"), exports);
34
40
  __exportStar(require("./accounts/pollingTokenAccountSubscriber"), exports);
41
+ __exportStar(require("./accounts/pollingUserAccountSubscriber"), exports);
42
+ __exportStar(require("./accounts/pollingUserStatsAccountSubscriber"), exports);
35
43
  __exportStar(require("./accounts/types"), exports);
36
44
  __exportStar(require("./addresses/pda"), exports);
37
45
  __exportStar(require("./admin"), exports);
38
46
  __exportStar(require("./clearingHouseUser"), exports);
39
47
  __exportStar(require("./clearingHouseUserConfig"), exports);
48
+ __exportStar(require("./clearingHouseUserStats"), exports);
49
+ __exportStar(require("./clearingHouseUserStatsConfig"), exports);
40
50
  __exportStar(require("./clearingHouse"), exports);
41
51
  __exportStar(require("./factory/oracleClient"), exports);
42
52
  __exportStar(require("./factory/bigNum"), exports);
@@ -52,7 +62,7 @@ __exportStar(require("./math/amm"), exports);
52
62
  __exportStar(require("./math/trade"), exports);
53
63
  __exportStar(require("./math/orders"), exports);
54
64
  __exportStar(require("./math/repeg"), exports);
55
- __exportStar(require("./orders"), exports);
65
+ __exportStar(require("./math/margin"), exports);
56
66
  __exportStar(require("./orderParams"), exports);
57
67
  __exportStar(require("./slot/SlotSubscriber"), exports);
58
68
  __exportStar(require("./wallet"), exports);
package/lib/math/amm.d.ts CHANGED
@@ -67,3 +67,4 @@ export declare function getSwapDirection(inputAssetType: AssetType, positionDire
67
67
  export declare function calculateTerminalPrice(market: MarketAccount): BN;
68
68
  export declare function calculateMaxBaseAssetAmountToTrade(amm: AMM, limit_price: BN, direction: PositionDirection, oraclePriceData?: OraclePriceData): [BN, PositionDirection];
69
69
  export declare function calculateQuoteAssetAmountSwapped(quoteAssetReserves: BN, pegMultiplier: BN, swapDirection: SwapDirection): BN;
70
+ export declare function calculateMaxBaseAssetAmountFillable(amm: AMM, orderDirection: PositionDirection): BN;
package/lib/math/amm.js CHANGED
@@ -1,6 +1,6 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.calculateQuoteAssetAmountSwapped = exports.calculateMaxBaseAssetAmountToTrade = exports.calculateTerminalPrice = exports.getSwapDirection = exports.calculateSwapOutput = exports.calculateSpreadReserves = exports.calculateSpread = exports.calculateSpreadBN = exports.calculateMaxSpread = exports.calculateEffectiveLeverage = exports.calculateAmmReservesAfterSwap = exports.calculatePrice = exports.calculateBidAskPrice = exports.calculateUpdatedAMMSpreadReserves = exports.calculateUpdatedAMM = exports.calculateNewAmm = exports.calculateOptimalPegAndBudget = exports.calculatePegFromTargetPrice = void 0;
3
+ exports.calculateMaxBaseAssetAmountFillable = exports.calculateQuoteAssetAmountSwapped = exports.calculateMaxBaseAssetAmountToTrade = exports.calculateTerminalPrice = exports.getSwapDirection = exports.calculateSwapOutput = exports.calculateSpreadReserves = exports.calculateSpread = exports.calculateSpreadBN = exports.calculateMaxSpread = exports.calculateEffectiveLeverage = exports.calculateAmmReservesAfterSwap = exports.calculatePrice = exports.calculateBidAskPrice = exports.calculateUpdatedAMMSpreadReserves = exports.calculateUpdatedAMM = exports.calculateNewAmm = exports.calculateOptimalPegAndBudget = exports.calculatePegFromTargetPrice = void 0;
4
4
  const anchor_1 = require("@project-serum/anchor");
5
5
  const numericConstants_1 = require("../constants/numericConstants");
6
6
  const types_1 = require("../types");
@@ -8,11 +8,11 @@ const assert_1 = require("../assert/assert");
8
8
  const __1 = require("..");
9
9
  const repeg_1 = require("./repeg");
10
10
  function calculatePegFromTargetPrice(targetPrice, baseAssetReserve, quoteAssetReserve) {
11
- return targetPrice
11
+ return anchor_1.BN.max(targetPrice
12
12
  .mul(baseAssetReserve)
13
13
  .div(quoteAssetReserve)
14
14
  .add(numericConstants_1.PRICE_DIV_PEG.div(new anchor_1.BN(2)))
15
- .div(numericConstants_1.PRICE_DIV_PEG);
15
+ .div(numericConstants_1.PRICE_DIV_PEG), numericConstants_1.ONE);
16
16
  }
17
17
  exports.calculatePegFromTargetPrice = calculatePegFromTargetPrice;
18
18
  function calculateOptimalPegAndBudget(amm, oraclePriceData) {
@@ -227,9 +227,8 @@ function calculateSpreadBN(baseSpread, lastOracleMarkSpreadPct, lastOracleConfPc
227
227
  }
228
228
  exports.calculateSpreadBN = calculateSpreadBN;
229
229
  function calculateSpread(amm, direction, oraclePriceData) {
230
- let spread = amm.baseSpread / 2;
231
230
  if (amm.baseSpread == 0 || amm.curveUpdateIntensity == 0) {
232
- return spread;
231
+ return amm.baseSpread / 2;
233
232
  }
234
233
  const markPrice = calculatePrice(amm.baseAssetReserve, amm.quoteAssetReserve, amm.pegMultiplier);
235
234
  const targetPrice = (oraclePriceData === null || oraclePriceData === void 0 ? void 0 : oraclePriceData.price) || markPrice;
@@ -241,40 +240,13 @@ function calculateSpread(amm, direction, oraclePriceData) {
241
240
  const confIntervalPct = confInterval
242
241
  .mul(numericConstants_1.BID_ASK_SPREAD_PRECISION)
243
242
  .div(markPrice);
244
- // oracle retreat
245
- if (((0, types_1.isVariant)(direction, 'long') && targetMarkSpreadPct.lt(numericConstants_1.ZERO)) ||
246
- ((0, types_1.isVariant)(direction, 'short') && targetMarkSpreadPct.gt(numericConstants_1.ZERO))) {
247
- spread = Math.max(spread, targetMarkSpreadPct.abs().toNumber() + confIntervalPct.abs().toNumber());
243
+ const [longSpread, shortSpread] = calculateSpreadBN(amm.baseSpread, targetMarkSpreadPct, confIntervalPct, amm.maxSpread, amm.quoteAssetReserve, amm.terminalQuoteAssetReserve, amm.pegMultiplier, amm.netBaseAssetAmount, markPrice, amm.totalFeeMinusDistributions);
244
+ let spread;
245
+ if ((0, types_1.isVariant)(direction, 'long')) {
246
+ spread = longSpread;
248
247
  }
249
- // inventory skew
250
- const MAX_INVENTORY_SKEW = 5;
251
- if ((amm.netBaseAssetAmount.gt(numericConstants_1.ZERO) && (0, types_1.isVariant)(direction, 'long')) ||
252
- (amm.netBaseAssetAmount.lt(numericConstants_1.ZERO) && (0, types_1.isVariant)(direction, 'short')) ||
253
- amm.totalFeeMinusDistributions.eq(numericConstants_1.ZERO)) {
254
- const netCostBasis = amm.quoteAssetAmountLong.sub(amm.quoteAssetAmountShort);
255
- const netBaseAssetValue = amm.quoteAssetReserve
256
- .sub(amm.terminalQuoteAssetReserve)
257
- .mul(amm.pegMultiplier)
258
- .div(numericConstants_1.AMM_TIMES_PEG_TO_QUOTE_PRECISION_RATIO);
259
- const localBaseAssetValue = amm.netBaseAssetAmount
260
- .mul(markPrice)
261
- .div(numericConstants_1.AMM_TO_QUOTE_PRECISION_RATIO.mul(numericConstants_1.MARK_PRICE_PRECISION));
262
- const netPnl = netBaseAssetValue.sub(netCostBasis);
263
- const localPnl = localBaseAssetValue.sub(netCostBasis);
264
- let effectiveLeverage = MAX_INVENTORY_SKEW;
265
- if (amm.totalFeeMinusDistributions.gt(numericConstants_1.ZERO)) {
266
- effectiveLeverage =
267
- localPnl.sub(netPnl).toNumber() /
268
- (amm.totalFeeMinusDistributions.toNumber() + 1);
269
- }
270
- let spreadScale = Math.min(MAX_INVENTORY_SKEW, 1 + effectiveLeverage);
271
- const maxTargetSpread = numericConstants_1.BID_ASK_SPREAD_PRECISION.toNumber() / 50; // 2%
272
- // cap the scale to attempt to only scale up to maxTargetSpread
273
- // always let the oracle retreat methods go through 100%
274
- if (spreadScale * spread > maxTargetSpread) {
275
- spreadScale = Math.max(1.05, maxTargetSpread / spread);
276
- }
277
- spread *= spreadScale;
248
+ else {
249
+ spread = shortSpread;
278
250
  }
279
251
  return spread;
280
252
  }
@@ -395,3 +367,15 @@ function calculateQuoteAssetAmountSwapped(quoteAssetReserves, pegMultiplier, swa
395
367
  return quoteAssetAmount;
396
368
  }
397
369
  exports.calculateQuoteAssetAmountSwapped = calculateQuoteAssetAmountSwapped;
370
+ function calculateMaxBaseAssetAmountFillable(amm, orderDirection) {
371
+ const maxFillSize = amm.baseAssetReserve.div(new anchor_1.BN(amm.maxBaseAssetAmountRatio));
372
+ let maxBaseAssetAmountOnSide;
373
+ if ((0, types_1.isVariant)(orderDirection, 'long')) {
374
+ maxBaseAssetAmountOnSide = anchor_1.BN.max(numericConstants_1.ZERO, amm.maxBaseAssetReserve.sub(amm.baseAssetReserve));
375
+ }
376
+ else {
377
+ maxBaseAssetAmountOnSide = anchor_1.BN.max(numericConstants_1.ZERO, amm.baseAssetReserve.sub(amm.minBaseAssetReserve));
378
+ }
379
+ return (0, __1.standardizeBaseAssetAmount)(anchor_1.BN.min(maxFillSize, maxBaseAssetAmountOnSide), amm.baseAssetAmountStepSize);
380
+ }
381
+ exports.calculateMaxBaseAssetAmountFillable = calculateMaxBaseAssetAmountFillable;
@@ -4,7 +4,10 @@ exports.getAuctionPrice = exports.isAuctionComplete = void 0;
4
4
  const types_1 = require("../types");
5
5
  const _1 = require("../.");
6
6
  function isAuctionComplete(order, slot) {
7
- return new _1.BN(slot).sub(order.slot).gte(new _1.BN(order.auctionDuration));
7
+ if (order.auctionDuration === 0) {
8
+ return true;
9
+ }
10
+ return new _1.BN(slot).sub(order.slot).gt(new _1.BN(order.auctionDuration));
8
11
  }
9
12
  exports.isAuctionComplete = isAuctionComplete;
10
13
  function getAuctionPrice(order, slot) {
@@ -1,9 +1,15 @@
1
1
  /// <reference types="bn.js" />
2
- import { BankAccount, BankBalanceType } from '../types';
2
+ import { BankAccount, BankBalanceType, MarginCategory } from '../types';
3
3
  import { BN } from '@project-serum/anchor';
4
4
  export declare function getBalance(tokenAmount: BN, bank: BankAccount, balanceType: BankBalanceType): BN;
5
5
  export declare function getTokenAmount(balanceAmount: BN, bank: BankAccount, balanceType: BankBalanceType): BN;
6
+ export declare function calculateAssetWeight(balanceAmount: BN, bank: BankAccount, marginCategory: MarginCategory): BN;
7
+ export declare function calculateLiabilityWeight(balanceAmount: BN, bank: BankAccount, marginCategory: MarginCategory): BN;
6
8
  export declare function calculateInterestAccumulated(bank: BankAccount, now: BN): {
7
9
  borrowInterest: BN;
8
10
  depositInterest: BN;
9
11
  };
12
+ export declare function calculateWithdrawLimit(bank: BankAccount, now: BN): {
13
+ borrowLimit: BN;
14
+ withdrawLimit: BN;
15
+ };
@@ -1,9 +1,10 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.calculateInterestAccumulated = exports.getTokenAmount = exports.getBalance = void 0;
3
+ exports.calculateWithdrawLimit = exports.calculateInterestAccumulated = exports.calculateLiabilityWeight = exports.calculateAssetWeight = exports.getTokenAmount = exports.getBalance = void 0;
4
4
  const types_1 = require("../types");
5
5
  const anchor_1 = require("@project-serum/anchor");
6
6
  const numericConstants_1 = require("../constants/numericConstants");
7
+ const margin_1 = require("./margin");
7
8
  function getBalance(tokenAmount, bank, balanceType) {
8
9
  const precisionIncrease = numericConstants_1.TEN.pow(new anchor_1.BN(16 - bank.decimals));
9
10
  const cumulativeInterest = (0, types_1.isVariant)(balanceType, 'deposit')
@@ -24,6 +25,58 @@ function getTokenAmount(balanceAmount, bank, balanceType) {
24
25
  return balanceAmount.mul(cumulativeInterest).div(precisionDecrease);
25
26
  }
26
27
  exports.getTokenAmount = getTokenAmount;
28
+ function calculateAssetWeight(balanceAmount, bank, marginCategory) {
29
+ const sizePrecision = numericConstants_1.TEN.pow(new anchor_1.BN(bank.decimals));
30
+ let sizeInAmmReservePrecision;
31
+ if (sizePrecision.gt(numericConstants_1.AMM_RESERVE_PRECISION)) {
32
+ sizeInAmmReservePrecision = balanceAmount.div(sizePrecision.div(numericConstants_1.AMM_RESERVE_PRECISION));
33
+ }
34
+ else {
35
+ sizeInAmmReservePrecision = balanceAmount
36
+ .mul(numericConstants_1.AMM_RESERVE_PRECISION)
37
+ .div(sizePrecision);
38
+ }
39
+ let assetWeight;
40
+ switch (marginCategory) {
41
+ case 'Initial':
42
+ assetWeight = (0, margin_1.calculateSizeDiscountAssetWeight)(sizeInAmmReservePrecision, bank.imfFactor, bank.initialAssetWeight);
43
+ break;
44
+ case 'Maintenance':
45
+ assetWeight = (0, margin_1.calculateSizeDiscountAssetWeight)(sizeInAmmReservePrecision, bank.imfFactor, bank.maintenanceAssetWeight);
46
+ break;
47
+ default:
48
+ assetWeight = bank.initialAssetWeight;
49
+ break;
50
+ }
51
+ return assetWeight;
52
+ }
53
+ exports.calculateAssetWeight = calculateAssetWeight;
54
+ function calculateLiabilityWeight(balanceAmount, bank, marginCategory) {
55
+ const sizePrecision = numericConstants_1.TEN.pow(new anchor_1.BN(bank.decimals));
56
+ let sizeInAmmReservePrecision;
57
+ if (sizePrecision.gt(numericConstants_1.AMM_RESERVE_PRECISION)) {
58
+ sizeInAmmReservePrecision = balanceAmount.div(sizePrecision.div(numericConstants_1.AMM_RESERVE_PRECISION));
59
+ }
60
+ else {
61
+ sizeInAmmReservePrecision = balanceAmount
62
+ .mul(numericConstants_1.AMM_RESERVE_PRECISION)
63
+ .div(sizePrecision);
64
+ }
65
+ let assetWeight;
66
+ switch (marginCategory) {
67
+ case 'Initial':
68
+ assetWeight = (0, margin_1.calculateSizePremiumLiabilityWeight)(sizeInAmmReservePrecision, bank.imfFactor, bank.initialLiabilityWeight, numericConstants_1.BANK_WEIGHT_PRECISION);
69
+ break;
70
+ case 'Maintenance':
71
+ assetWeight = (0, margin_1.calculateSizePremiumLiabilityWeight)(sizeInAmmReservePrecision, bank.imfFactor, bank.maintenanceLiabilityWeight, numericConstants_1.BANK_WEIGHT_PRECISION);
72
+ break;
73
+ default:
74
+ assetWeight = bank.initialLiabilityWeight;
75
+ break;
76
+ }
77
+ return assetWeight;
78
+ }
79
+ exports.calculateLiabilityWeight = calculateLiabilityWeight;
27
80
  function calculateInterestAccumulated(bank, now) {
28
81
  const token_deposit_amount = getTokenAmount(bank.depositBalance, bank, types_1.BankBalanceType.DEPOSIT);
29
82
  const token_borrow_amount = getTokenAmount(bank.borrowBalance, bank, types_1.BankBalanceType.BORROW);
@@ -56,7 +109,7 @@ function calculateInterestAccumulated(bank, now) {
56
109
  .mul(borrowRateSlope)
57
110
  .div(numericConstants_1.BANK_UTILIZATION_PRECISION);
58
111
  }
59
- const timeSinceLastUpdate = now.sub(bank.lastUpdated);
112
+ const timeSinceLastUpdate = now.sub(bank.lastInterestTs);
60
113
  const modifiedBorrowRate = interest_rate.mul(timeSinceLastUpdate);
61
114
  const modifiedDepositRate = modifiedBorrowRate
62
115
  .mul(utilization)
@@ -73,3 +126,25 @@ function calculateInterestAccumulated(bank, now) {
73
126
  return { borrowInterest, depositInterest };
74
127
  }
75
128
  exports.calculateInterestAccumulated = calculateInterestAccumulated;
129
+ function calculateWithdrawLimit(bank, now) {
130
+ const bankDepositTokenAmount = getTokenAmount(bank.depositBalance, bank, types_1.BankBalanceType.DEPOSIT);
131
+ const bankBorrowTokenAmount = getTokenAmount(bank.borrowBalance, bank, types_1.BankBalanceType.BORROW);
132
+ const twentyFourHours = new anchor_1.BN(60 * 60 * 24);
133
+ const sinceLast = now.sub(bank.lastTwapTs);
134
+ const sinceStart = anchor_1.BN.max(numericConstants_1.ZERO, twentyFourHours.sub(sinceLast));
135
+ const borrowTokenTwapLive = bank.borrowTokenTwap
136
+ .mul(sinceStart)
137
+ .add(bankBorrowTokenAmount.mul(sinceLast))
138
+ .div(sinceLast.add(sinceLast));
139
+ const depositTokenTwapLive = bank.depositTokenTwap
140
+ .mul(sinceStart)
141
+ .add(bankDepositTokenAmount.mul(sinceLast))
142
+ .div(sinceLast.add(sinceLast));
143
+ const maxBorrowTokens = anchor_1.BN.min(anchor_1.BN.max(bankDepositTokenAmount.div(new anchor_1.BN(6)), borrowTokenTwapLive.add(borrowTokenTwapLive.div(new anchor_1.BN(5)))), bankDepositTokenAmount.sub(bankDepositTokenAmount.div(new anchor_1.BN(10)))); // between ~15-90% utilization with friction on twap
144
+ const minDepositTokens = depositTokenTwapLive.sub(anchor_1.BN.min(anchor_1.BN.max(depositTokenTwapLive.div(new anchor_1.BN(5)), bank.withdrawGuardThreshold), depositTokenTwapLive));
145
+ return {
146
+ borrowLimit: maxBorrowTokens.sub(bankBorrowTokenAmount),
147
+ withdrawLimit: bankDepositTokenAmount.sub(minDepositTokens),
148
+ };
149
+ }
150
+ exports.calculateWithdrawLimit = calculateWithdrawLimit;
@@ -0,0 +1,11 @@
1
+ /// <reference types="bn.js" />
2
+ import { BN } from '@project-serum/anchor';
3
+ import { OraclePriceData } from '../oracles/types';
4
+ import { MarketAccount, UserPosition } from '..';
5
+ export declare function calculateSizePremiumLiabilityWeight(size: BN, // AMM_RESERVE_PRECISION
6
+ imfFactor: BN, liabilityWeight: BN, precision: BN): BN;
7
+ export declare function calculateSizeDiscountAssetWeight(size: BN, // AMM_RESERVE_PRECISION
8
+ imfFactor: BN, assetWeight: BN): BN;
9
+ export declare function calculateOraclePriceForPerpMargin(marketPosition: UserPosition, market: MarketAccount, oraclePriceData: OraclePriceData): BN;
10
+ export declare function calculateMarginBaseAssetValue(market: MarketAccount, marketPosition: UserPosition, oraclePriceData: OraclePriceData): BN;
11
+ export declare function calculateWorstCaseBaseAssetAmount(marketPosition: UserPosition): BN;
@@ -0,0 +1,72 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.calculateWorstCaseBaseAssetAmount = exports.calculateMarginBaseAssetValue = exports.calculateOraclePriceForPerpMargin = exports.calculateSizeDiscountAssetWeight = exports.calculateSizePremiumLiabilityWeight = void 0;
4
+ const utils_1 = require("./utils");
5
+ const numericConstants_1 = require("../constants/numericConstants");
6
+ const anchor_1 = require("@project-serum/anchor");
7
+ function calculateSizePremiumLiabilityWeight(size, // AMM_RESERVE_PRECISION
8
+ imfFactor, liabilityWeight, precision) {
9
+ if (imfFactor.eq(numericConstants_1.ZERO)) {
10
+ return liabilityWeight;
11
+ }
12
+ const sizeSqrt = (0, utils_1.squareRootBN)(size.div(new anchor_1.BN(1000)).add(new anchor_1.BN(1))); //1e13 -> 1e10 -> 1e5
13
+ const liabilityWeightNumerator = liabilityWeight.sub(liabilityWeight.div(anchor_1.BN.max(new anchor_1.BN(1), numericConstants_1.BANK_IMF_PRECISION.div(imfFactor))));
14
+ const sizePremiumLiabilityWeight = liabilityWeightNumerator.add(sizeSqrt // 1e5
15
+ .mul(imfFactor)
16
+ .div(new anchor_1.BN(100000).mul(numericConstants_1.BANK_IMF_PRECISION).div(precision)) // 1e5
17
+ );
18
+ const maxLiabilityWeight = anchor_1.BN.max(liabilityWeight, sizePremiumLiabilityWeight);
19
+ return maxLiabilityWeight;
20
+ }
21
+ exports.calculateSizePremiumLiabilityWeight = calculateSizePremiumLiabilityWeight;
22
+ function calculateSizeDiscountAssetWeight(size, // AMM_RESERVE_PRECISION
23
+ imfFactor, assetWeight) {
24
+ if (imfFactor.eq(numericConstants_1.ZERO)) {
25
+ return assetWeight;
26
+ }
27
+ const sizeSqrt = (0, utils_1.squareRootBN)(size.div(new anchor_1.BN(1000)).add(new anchor_1.BN(1))); //1e13 -> 1e10 -> 1e5
28
+ const imfNumerator = numericConstants_1.BANK_IMF_PRECISION.add(numericConstants_1.BANK_IMF_PRECISION.div(new anchor_1.BN(10)));
29
+ const sizeDiscountAssetWeight = imfNumerator.mul(numericConstants_1.BANK_WEIGHT_PRECISION).div(numericConstants_1.BANK_IMF_PRECISION.add(sizeSqrt // 1e5
30
+ .mul(imfFactor)
31
+ .div(new anchor_1.BN(100000)) // 1e5
32
+ ));
33
+ const minAssetWeight = anchor_1.BN.min(assetWeight, sizeDiscountAssetWeight);
34
+ return minAssetWeight;
35
+ }
36
+ exports.calculateSizeDiscountAssetWeight = calculateSizeDiscountAssetWeight;
37
+ function calculateOraclePriceForPerpMargin(marketPosition, market, oraclePriceData) {
38
+ const oraclePriceOffset = anchor_1.BN.min(new anchor_1.BN(market.amm.maxSpread)
39
+ .mul(oraclePriceData.price)
40
+ .div(numericConstants_1.BID_ASK_SPREAD_PRECISION), oraclePriceData.confidence.add(new anchor_1.BN(market.amm.baseSpread)
41
+ .mul(oraclePriceData.price)
42
+ .div(numericConstants_1.BID_ASK_SPREAD_PRECISION)));
43
+ let marginPrice;
44
+ if (marketPosition.baseAssetAmount.gt(numericConstants_1.ZERO)) {
45
+ marginPrice = oraclePriceData.price.sub(oraclePriceOffset);
46
+ }
47
+ else {
48
+ marginPrice = oraclePriceData.price.add(oraclePriceOffset);
49
+ }
50
+ return marginPrice;
51
+ }
52
+ exports.calculateOraclePriceForPerpMargin = calculateOraclePriceForPerpMargin;
53
+ function calculateMarginBaseAssetValue(market, marketPosition, oraclePriceData) {
54
+ const marginPrice = calculateOraclePriceForPerpMargin(marketPosition, market, oraclePriceData);
55
+ const baseAssetValue = marketPosition.baseAssetAmount
56
+ .abs()
57
+ .mul(marginPrice)
58
+ .div(numericConstants_1.AMM_TO_QUOTE_PRECISION_RATIO.mul(numericConstants_1.MARK_PRICE_PRECISION));
59
+ return baseAssetValue;
60
+ }
61
+ exports.calculateMarginBaseAssetValue = calculateMarginBaseAssetValue;
62
+ function calculateWorstCaseBaseAssetAmount(marketPosition) {
63
+ const allBids = marketPosition.baseAssetAmount.add(marketPosition.openBids);
64
+ const allAsks = marketPosition.baseAssetAmount.add(marketPosition.openAsks);
65
+ if (allBids.abs().gt(allAsks.abs())) {
66
+ return allBids;
67
+ }
68
+ else {
69
+ return allAsks;
70
+ }
71
+ }
72
+ exports.calculateWorstCaseBaseAssetAmount = calculateWorstCaseBaseAssetAmount;
@@ -1,6 +1,6 @@
1
1
  /// <reference types="bn.js" />
2
2
  import { BN } from '@project-serum/anchor';
3
- import { MarketAccount, PositionDirection } from '../types';
3
+ import { MarketAccount, PositionDirection, MarginCategory, BankAccount } from '../types';
4
4
  import { OraclePriceData } from '../oracles/types';
5
5
  /**
6
6
  * Calculates market mark price
@@ -26,3 +26,6 @@ export declare function calculateAskPrice(market: MarketAccount, oraclePriceData
26
26
  export declare function calculateNewMarketAfterTrade(baseAssetAmount: BN, direction: PositionDirection, market: MarketAccount): MarketAccount;
27
27
  export declare function calculateMarkOracleSpread(market: MarketAccount, oraclePriceData: OraclePriceData): BN;
28
28
  export declare function calculateOracleSpread(price: BN, oraclePriceData: OraclePriceData): BN;
29
+ export declare function calculateMarketMarginRatio(market: MarketAccount, size: BN, marginCategory: MarginCategory): number;
30
+ export declare function calculateUnrealizedAssetWeight(market: MarketAccount, unrealizedPnl: BN, marginCategory: MarginCategory): BN;
31
+ export declare function calculateMarketAvailablePNL(market: MarketAccount, bank: BankAccount): BN;
@@ -1,8 +1,12 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.calculateOracleSpread = exports.calculateMarkOracleSpread = exports.calculateNewMarketAfterTrade = exports.calculateAskPrice = exports.calculateBidPrice = exports.calculateMarkPrice = void 0;
3
+ exports.calculateMarketAvailablePNL = exports.calculateUnrealizedAssetWeight = exports.calculateMarketMarginRatio = exports.calculateOracleSpread = exports.calculateMarkOracleSpread = exports.calculateNewMarketAfterTrade = exports.calculateAskPrice = exports.calculateBidPrice = exports.calculateMarkPrice = void 0;
4
+ const anchor_1 = require("@project-serum/anchor");
4
5
  const types_1 = require("../types");
5
6
  const amm_1 = require("./amm");
7
+ const margin_1 = require("./margin");
8
+ const numericConstants_1 = require("../constants/numericConstants");
9
+ const bankBalance_1 = require("./bankBalance");
6
10
  /**
7
11
  * Calculates market mark price
8
12
  *
@@ -55,3 +59,33 @@ function calculateOracleSpread(price, oraclePriceData) {
55
59
  return price.sub(oraclePriceData.price);
56
60
  }
57
61
  exports.calculateOracleSpread = calculateOracleSpread;
62
+ function calculateMarketMarginRatio(market, size, marginCategory) {
63
+ let marginRatio;
64
+ switch (marginCategory) {
65
+ case 'Initial':
66
+ marginRatio = (0, margin_1.calculateSizePremiumLiabilityWeight)(size, market.imfFactor, new anchor_1.BN(market.marginRatioInitial), numericConstants_1.MARGIN_PRECISION).toNumber();
67
+ break;
68
+ case 'Maintenance':
69
+ marginRatio = market.marginRatioMaintenance;
70
+ break;
71
+ }
72
+ return marginRatio;
73
+ }
74
+ exports.calculateMarketMarginRatio = calculateMarketMarginRatio;
75
+ function calculateUnrealizedAssetWeight(market, unrealizedPnl, marginCategory) {
76
+ let assetWeight;
77
+ switch (marginCategory) {
78
+ case 'Initial':
79
+ assetWeight = (0, margin_1.calculateSizeDiscountAssetWeight)(unrealizedPnl, market.unrealizedImfFactor, new anchor_1.BN(market.unrealizedInitialAssetWeight));
80
+ break;
81
+ case 'Maintenance':
82
+ assetWeight = new anchor_1.BN(market.unrealizedMaintenanceAssetWeight);
83
+ break;
84
+ }
85
+ return assetWeight;
86
+ }
87
+ exports.calculateUnrealizedAssetWeight = calculateUnrealizedAssetWeight;
88
+ function calculateMarketAvailablePNL(market, bank) {
89
+ return (0, bankBalance_1.getTokenAmount)(market.pnlPool.balance, bank, types_1.BankBalanceType.DEPOSIT);
90
+ }
91
+ exports.calculateMarketAvailablePNL = calculateMarketAvailablePNL;
@@ -1,3 +1,6 @@
1
+ /// <reference types="bn.js" />
1
2
  import { AMM, OracleGuardRails } from '../types';
2
3
  import { OraclePriceData } from '../oracles/types';
4
+ import { BN } from '../index';
3
5
  export declare function isOracleValid(amm: AMM, oraclePriceData: OraclePriceData, oracleGuardRails: OracleGuardRails, slot: number): boolean;
6
+ export declare function isOracleTooDivergent(amm: AMM, oraclePriceData: OraclePriceData, oracleGuardRails: OracleGuardRails, now: BN): boolean;