@drift-labs/sdk 0.1.23-master.2 → 0.1.24

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 (45) hide show
  1. package/lib/accounts/bulkAccountLoader.d.ts +1 -0
  2. package/lib/accounts/bulkAccountLoader.js +14 -13
  3. package/lib/accounts/pollingClearingHouseAccountSubscriber.js +3 -3
  4. package/lib/accounts/pollingTokenAccountSubscriber.js +2 -2
  5. package/lib/accounts/pollingUserAccountSubscriber.js +4 -4
  6. package/lib/accounts/webSocketAccountSubscriber.js +2 -2
  7. package/lib/accounts/webSocketClearingHouseAccountSubscriber.js +1 -1
  8. package/lib/accounts/webSocketUserAccountSubscriber.js +2 -2
  9. package/lib/admin.d.ts +2 -2
  10. package/lib/admin.js +12 -11
  11. package/lib/clearingHouse.js +19 -19
  12. package/lib/clearingHouseUser.d.ts +12 -17
  13. package/lib/clearingHouseUser.js +125 -228
  14. package/lib/constants/numericConstants.d.ts +1 -2
  15. package/lib/constants/numericConstants.js +2 -3
  16. package/lib/examples/makeTradeExample.js +6 -6
  17. package/lib/idl/clearing_house.json +42 -4
  18. package/lib/math/amm.js +12 -12
  19. package/lib/math/conversion.js +1 -1
  20. package/lib/math/funding.js +1 -1
  21. package/lib/math/market.js +2 -2
  22. package/lib/math/orders.d.ts +2 -0
  23. package/lib/math/orders.js +44 -4
  24. package/lib/math/position.js +1 -1
  25. package/lib/math/trade.js +18 -18
  26. package/lib/orders.d.ts +3 -1
  27. package/lib/orders.js +47 -19
  28. package/lib/pythClient.js +1 -1
  29. package/lib/tx/retryTxSender.js +1 -1
  30. package/lib/types.d.ts +4 -1
  31. package/package.json +1 -1
  32. package/src/accounts/bulkAccountLoader.ts +18 -13
  33. package/src/accounts/types.js +10 -0
  34. package/src/accounts/utils.js +7 -0
  35. package/src/accounts/webSocketAccountSubscriber.js +76 -0
  36. package/src/addresses.js +83 -0
  37. package/src/admin.ts +13 -4
  38. package/src/clearingHouseUser.ts +161 -330
  39. package/src/constants/numericConstants.ts +1 -2
  40. package/src/idl/clearing_house.json +42 -4
  41. package/src/math/orders.ts +61 -0
  42. package/src/mockUSDCFaucet.js +171 -0
  43. package/src/orders.ts +56 -3
  44. package/src/types.js +60 -0
  45. package/src/types.ts +5 -1
@@ -211,6 +211,18 @@
211
211
  {
212
212
  "name": "ammPegMultiplier",
213
213
  "type": "u128"
214
+ },
215
+ {
216
+ "name": "marginRatioInitial",
217
+ "type": "u32"
218
+ },
219
+ {
220
+ "name": "marginRatioPartial",
221
+ "type": "u32"
222
+ },
223
+ {
224
+ "name": "marginRatioMaintenance",
225
+ "type": "u32"
214
226
  }
215
227
  ]
216
228
  },
@@ -1526,22 +1538,31 @@
1526
1538
  },
1527
1539
  {
1528
1540
  "name": "state",
1541
+ "isMut": false,
1542
+ "isSigner": false
1543
+ },
1544
+ {
1545
+ "name": "markets",
1529
1546
  "isMut": true,
1530
1547
  "isSigner": false
1531
1548
  }
1532
1549
  ],
1533
1550
  "args": [
1551
+ {
1552
+ "name": "marketIndex",
1553
+ "type": "u64"
1554
+ },
1534
1555
  {
1535
1556
  "name": "marginRatioInitial",
1536
- "type": "u128"
1557
+ "type": "u32"
1537
1558
  },
1538
1559
  {
1539
1560
  "name": "marginRatioPartial",
1540
- "type": "u128"
1561
+ "type": "u32"
1541
1562
  },
1542
1563
  {
1543
1564
  "name": "marginRatioMaintenance",
1544
- "type": "u128"
1565
+ "type": "u32"
1545
1566
  }
1546
1567
  ]
1547
1568
  },
@@ -3028,9 +3049,21 @@
3028
3049
  "defined": "AMM"
3029
3050
  }
3030
3051
  },
3052
+ {
3053
+ "name": "marginRatioInitial",
3054
+ "type": "u32"
3055
+ },
3056
+ {
3057
+ "name": "marginRatioPartial",
3058
+ "type": "u32"
3059
+ },
3060
+ {
3061
+ "name": "marginRatioMaintenance",
3062
+ "type": "u32"
3063
+ },
3031
3064
  {
3032
3065
  "name": "padding0",
3033
- "type": "u128"
3066
+ "type": "u32"
3034
3067
  },
3035
3068
  {
3036
3069
  "name": "padding1",
@@ -4132,6 +4165,11 @@
4132
4165
  "code": 6056,
4133
4166
  "name": "NoPositionsLiquidatable",
4134
4167
  "msg": "No positions liquidatable"
4168
+ },
4169
+ {
4170
+ "code": 6057,
4171
+ "name": "InvalidMarginRatio",
4172
+ "msg": "Invalid Margin Ratio"
4135
4173
  }
4136
4174
  ]
4137
4175
  }
package/lib/math/amm.js CHANGED
@@ -36,7 +36,7 @@ exports.calculatePrice = calculatePrice;
36
36
  * @returns quoteAssetReserve and baseAssetReserve after swap. : Precision AMM_RESERVE_PRECISION
37
37
  */
38
38
  function calculateAmmReservesAfterSwap(amm, inputAssetType, swapAmount, swapDirection) {
39
- (0, assert_1.assert)(swapAmount.gte(numericConstants_1.ZERO), 'swapAmount must be greater than 0');
39
+ assert_1.assert(swapAmount.gte(numericConstants_1.ZERO), 'swapAmount must be greater than 0');
40
40
  let newQuoteAssetReserve;
41
41
  let newBaseAssetReserve;
42
42
  if (inputAssetType === 'quote') {
@@ -79,10 +79,10 @@ exports.calculateSwapOutput = calculateSwapOutput;
79
79
  * @param positionDirection
80
80
  */
81
81
  function getSwapDirection(inputAssetType, positionDirection) {
82
- if ((0, types_1.isVariant)(positionDirection, 'long') && inputAssetType === 'base') {
82
+ if (types_1.isVariant(positionDirection, 'long') && inputAssetType === 'base') {
83
83
  return types_1.SwapDirection.REMOVE;
84
84
  }
85
- if ((0, types_1.isVariant)(positionDirection, 'short') && inputAssetType === 'quote') {
85
+ if (types_1.isVariant(positionDirection, 'short') && inputAssetType === 'quote') {
86
86
  return types_1.SwapDirection.REMOVE;
87
87
  }
88
88
  return types_1.SwapDirection.ADD;
@@ -104,7 +104,7 @@ function calculateAdjustKCost(market, marketIndex, numerator, denomenator) {
104
104
  quoteAssetAmount: new anchor_1.BN(0),
105
105
  openOrders: new anchor_1.BN(0),
106
106
  };
107
- const currentValue = (0, position_1.calculateBaseAssetValue)(market, netUserPosition);
107
+ const currentValue = position_1.calculateBaseAssetValue(market, netUserPosition);
108
108
  const marketNewK = Object.assign({}, market);
109
109
  marketNewK.amm = Object.assign({}, market.amm);
110
110
  marketNewK.amm.baseAssetReserve = market.amm.baseAssetReserve
@@ -115,7 +115,7 @@ function calculateAdjustKCost(market, marketIndex, numerator, denomenator) {
115
115
  .div(denomenator);
116
116
  marketNewK.amm.sqrtK = market.amm.sqrtK.mul(numerator).div(denomenator);
117
117
  netUserPosition.quoteAssetAmount = currentValue;
118
- const cost = (0, __1.calculatePositionPNL)(marketNewK, netUserPosition);
118
+ const cost = __1.calculatePositionPNL(marketNewK, netUserPosition);
119
119
  const p = numericConstants_1.PEG_PRECISION.mul(numerator).div(denomenator);
120
120
  const x = market.amm.baseAssetReserve;
121
121
  const y = market.amm.quoteAssetReserve;
@@ -134,7 +134,7 @@ function calculateAdjustKCost(market, marketIndex, numerator, denomenator) {
134
134
  .sub(numer1)
135
135
  .mul(market.amm.pegMultiplier)
136
136
  .div(numericConstants_1.AMM_TIMES_PEG_TO_QUOTE_PRECISION_RATIO);
137
- console.log((0, __1.convertToNumber)(formulaCost, numericConstants_1.QUOTE_PRECISION));
137
+ console.log(__1.convertToNumber(formulaCost, numericConstants_1.QUOTE_PRECISION));
138
138
  // p.div(p.mul(x).add(delta)).sub()
139
139
  return cost;
140
140
  }
@@ -155,22 +155,22 @@ function calculateRepegCost(market, marketIndex, newPeg) {
155
155
  quoteAssetAmount: new anchor_1.BN(0),
156
156
  openOrders: new anchor_1.BN(0),
157
157
  };
158
- const currentValue = (0, position_1.calculateBaseAssetValue)(market, netUserPosition);
158
+ const currentValue = position_1.calculateBaseAssetValue(market, netUserPosition);
159
159
  netUserPosition.quoteAssetAmount = currentValue;
160
- const prevMarketPrice = (0, __1.calculateMarkPrice)(market);
160
+ const prevMarketPrice = __1.calculateMarkPrice(market);
161
161
  const marketNewPeg = Object.assign({}, market);
162
162
  marketNewPeg.amm = Object.assign({}, market.amm);
163
163
  // const marketNewPeg = JSON.parse(JSON.stringify(market));
164
164
  marketNewPeg.amm.pegMultiplier = newPeg;
165
- console.log('Price moves from', (0, __1.convertToNumber)(prevMarketPrice), 'to', (0, __1.convertToNumber)((0, __1.calculateMarkPrice)(marketNewPeg)));
166
- const cost = (0, __1.calculatePositionPNL)(marketNewPeg, netUserPosition);
165
+ console.log('Price moves from', __1.convertToNumber(prevMarketPrice), 'to', __1.convertToNumber(__1.calculateMarkPrice(marketNewPeg)));
166
+ const cost = __1.calculatePositionPNL(marketNewPeg, netUserPosition);
167
167
  const k = market.amm.sqrtK.mul(market.amm.sqrtK);
168
168
  const newQuoteAssetReserve = k.div(market.amm.baseAssetReserve.add(netUserPosition.baseAssetAmount));
169
169
  const deltaQuoteAssetReserves = newQuoteAssetReserve.sub(market.amm.quoteAssetReserve);
170
170
  const cost2 = deltaQuoteAssetReserves
171
171
  .mul(market.amm.pegMultiplier.sub(newPeg))
172
172
  .div(numericConstants_1.AMM_TIMES_PEG_TO_QUOTE_PRECISION_RATIO);
173
- console.log((0, __1.convertToNumber)(cost2, numericConstants_1.QUOTE_PRECISION));
173
+ console.log(__1.convertToNumber(cost2, numericConstants_1.QUOTE_PRECISION));
174
174
  return cost;
175
175
  }
176
176
  exports.calculateRepegCost = calculateRepegCost;
@@ -200,7 +200,7 @@ function calculateMaxBaseAssetAmountToTrade(amm, limit_price) {
200
200
  .mul(amm.pegMultiplier)
201
201
  .div(limit_price)
202
202
  .div(numericConstants_1.PEG_PRECISION);
203
- const newBaseAssetReserve = (0, __1.squareRootBN)(newBaseAssetReserveSquared);
203
+ const newBaseAssetReserve = __1.squareRootBN(newBaseAssetReserveSquared);
204
204
  if (newBaseAssetReserve.gt(amm.baseAssetReserve)) {
205
205
  return [
206
206
  newBaseAssetReserve.sub(amm.baseAssetReserve),
@@ -10,6 +10,6 @@ const convertToNumber = (bigNumber, precision = numericConstants_1.MARK_PRICE_PR
10
10
  };
11
11
  exports.convertToNumber = convertToNumber;
12
12
  const convertBaseAssetAmountToNumber = (baseAssetAmount) => {
13
- return (0, exports.convertToNumber)(baseAssetAmount, numericConstants_1.MARK_PRICE_PRECISION.mul(numericConstants_1.PEG_PRECISION));
13
+ return exports.convertToNumber(baseAssetAmount, numericConstants_1.MARK_PRICE_PRECISION.mul(numericConstants_1.PEG_PRECISION));
14
14
  };
15
15
  exports.convertBaseAssetAmountToNumber = convertBaseAssetAmountToNumber;
@@ -40,7 +40,7 @@ function calculateAllEstimatedFundingRate(market, oraclePriceData, periodAdjustm
40
40
  const lastMarkPriceTwapTs = market.amm.lastMarkPriceTwapTs;
41
41
  const timeSinceLastMarkChange = now.sub(lastMarkPriceTwapTs);
42
42
  const markTwapTimeSinceLastUpdate = anchor_1.BN.max(secondsInHour, secondsInHour.sub(timeSinceLastMarkChange));
43
- const baseAssetPriceWithMantissa = (0, market_1.calculateMarkPrice)(market);
43
+ const baseAssetPriceWithMantissa = market_1.calculateMarkPrice(market);
44
44
  const markTwapWithMantissa = markTwapTimeSinceLastUpdate
45
45
  .mul(lastMarkTwapWithMantissa)
46
46
  .add(timeSinceLastMarkChange.mul(baseAssetPriceWithMantissa))
@@ -9,11 +9,11 @@ const amm_1 = require("./amm");
9
9
  * @return markPrice : Precision MARK_PRICE_PRECISION
10
10
  */
11
11
  function calculateMarkPrice(market) {
12
- return (0, amm_1.calculatePrice)(market.amm.baseAssetReserve, market.amm.quoteAssetReserve, market.amm.pegMultiplier);
12
+ return amm_1.calculatePrice(market.amm.baseAssetReserve, market.amm.quoteAssetReserve, market.amm.pegMultiplier);
13
13
  }
14
14
  exports.calculateMarkPrice = calculateMarkPrice;
15
15
  function calculateNewMarketAfterTrade(baseAssetAmount, direction, market) {
16
- const [newQuoteAssetReserve, newBaseAssetReserve] = (0, amm_1.calculateAmmReservesAfterSwap)(market.amm, 'base', baseAssetAmount.abs(), (0, amm_1.getSwapDirection)('base', direction));
16
+ const [newQuoteAssetReserve, newBaseAssetReserve] = amm_1.calculateAmmReservesAfterSwap(market.amm, 'base', baseAssetAmount.abs(), amm_1.getSwapDirection('base', direction));
17
17
  const newAmm = Object.assign({}, market.amm);
18
18
  const newMarket = Object.assign({}, market);
19
19
  newMarket.amm = newAmm;
@@ -1,3 +1,5 @@
1
1
  import { ClearingHouseUser } from '../clearingHouseUser';
2
2
  import { Order } from '../types';
3
3
  export declare function isOrderRiskIncreasing(user: ClearingHouseUser, order: Order): boolean;
4
+ export declare function isOrderRiskIncreasingInSameDirection(user: ClearingHouseUser, order: Order): boolean;
5
+ export declare function isOrderReduceOnly(user: ClearingHouseUser, order: Order): boolean;
@@ -1,10 +1,10 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.isOrderRiskIncreasing = void 0;
3
+ 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
  function isOrderRiskIncreasing(user, order) {
7
- if ((0, types_1.isVariant)(order.status, 'init')) {
7
+ if (types_1.isVariant(order.status, 'init')) {
8
8
  return false;
9
9
  }
10
10
  const position = user.getUserPosition(order.marketIndex) ||
@@ -14,12 +14,12 @@ function isOrderRiskIncreasing(user, order) {
14
14
  return true;
15
15
  }
16
16
  // if position is long and order is long
17
- if (position.baseAssetAmount.gt(numericConstants_1.ZERO) && (0, types_1.isVariant)(order.direction, 'long')) {
17
+ if (position.baseAssetAmount.gt(numericConstants_1.ZERO) && types_1.isVariant(order.direction, 'long')) {
18
18
  return true;
19
19
  }
20
20
  // if position is short and order is short
21
21
  if (position.baseAssetAmount.lt(numericConstants_1.ZERO) &&
22
- (0, types_1.isVariant)(order.direction, 'short')) {
22
+ types_1.isVariant(order.direction, 'short')) {
23
23
  return true;
24
24
  }
25
25
  const baseAssetAmountToFill = order.baseAssetAmount.sub(order.baseAssetAmountFilled);
@@ -30,3 +30,43 @@ function isOrderRiskIncreasing(user, order) {
30
30
  return false;
31
31
  }
32
32
  exports.isOrderRiskIncreasing = isOrderRiskIncreasing;
33
+ function isOrderRiskIncreasingInSameDirection(user, order) {
34
+ if (types_1.isVariant(order.status, 'init')) {
35
+ return false;
36
+ }
37
+ const position = user.getUserPosition(order.marketIndex) ||
38
+ user.getEmptyPosition(order.marketIndex);
39
+ // if no position exists, it's risk increasing
40
+ if (position.baseAssetAmount.eq(numericConstants_1.ZERO)) {
41
+ return true;
42
+ }
43
+ // if position is long and order is long
44
+ if (position.baseAssetAmount.gt(numericConstants_1.ZERO) && types_1.isVariant(order.direction, 'long')) {
45
+ return true;
46
+ }
47
+ // if position is short and order is short
48
+ if (position.baseAssetAmount.lt(numericConstants_1.ZERO) &&
49
+ types_1.isVariant(order.direction, 'short')) {
50
+ return true;
51
+ }
52
+ return false;
53
+ }
54
+ exports.isOrderRiskIncreasingInSameDirection = isOrderRiskIncreasingInSameDirection;
55
+ function isOrderReduceOnly(user, order) {
56
+ if (types_1.isVariant(order.status, 'init')) {
57
+ return false;
58
+ }
59
+ const position = user.getUserPosition(order.marketIndex) ||
60
+ user.getEmptyPosition(order.marketIndex);
61
+ // if position is long and order is long
62
+ if (position.baseAssetAmount.gt(numericConstants_1.ZERO) && types_1.isVariant(order.direction, 'long')) {
63
+ return false;
64
+ }
65
+ // if position is short and order is short
66
+ if (position.baseAssetAmount.lt(numericConstants_1.ZERO) &&
67
+ types_1.isVariant(order.direction, 'short')) {
68
+ return false;
69
+ }
70
+ return order.baseAssetAmount.abs().lte(position.baseAssetAmount.abs());
71
+ }
72
+ exports.isOrderReduceOnly = isOrderReduceOnly;
@@ -17,7 +17,7 @@ function calculateBaseAssetValue(market, userPosition) {
17
17
  return numericConstants_1.ZERO;
18
18
  }
19
19
  const directionToClose = findDirectionToClose(userPosition);
20
- const [newQuoteAssetReserve, _] = (0, amm_1.calculateAmmReservesAfterSwap)(market.amm, 'base', userPosition.baseAssetAmount.abs(), (0, amm_1.getSwapDirection)('base', directionToClose));
20
+ const [newQuoteAssetReserve, _] = amm_1.calculateAmmReservesAfterSwap(market.amm, 'base', userPosition.baseAssetAmount.abs(), amm_1.getSwapDirection('base', directionToClose));
21
21
  switch (directionToClose) {
22
22
  case types_1.PositionDirection.SHORT:
23
23
  return market.amm.quoteAssetReserve
package/lib/math/trade.js CHANGED
@@ -25,18 +25,18 @@ const MAXPCT = new anchor_1.BN(1000); //percentage units are [0,1000] => [0,1]
25
25
  * 'newPrice' => the price of the asset after the trade : Precision MARK_PRICE_PRECISION
26
26
  */
27
27
  function calculateTradeSlippage(direction, amount, market, inputAssetType = 'quote') {
28
- const oldPrice = (0, market_1.calculateMarkPrice)(market);
28
+ const oldPrice = market_1.calculateMarkPrice(market);
29
29
  if (amount.eq(numericConstants_1.ZERO)) {
30
30
  return [numericConstants_1.ZERO, numericConstants_1.ZERO, oldPrice, oldPrice];
31
31
  }
32
32
  const [acquiredBase, acquiredQuote] = calculateTradeAcquiredAmounts(direction, amount, market, inputAssetType);
33
- const entryPrice = (0, amm_1.calculatePrice)(acquiredBase, acquiredQuote, market.amm.pegMultiplier).mul(new anchor_1.BN(-1));
34
- const newPrice = (0, amm_1.calculatePrice)(market.amm.baseAssetReserve.sub(acquiredBase), market.amm.quoteAssetReserve.sub(acquiredQuote), market.amm.pegMultiplier);
33
+ const entryPrice = amm_1.calculatePrice(acquiredBase, acquiredQuote, market.amm.pegMultiplier).mul(new anchor_1.BN(-1));
34
+ const newPrice = amm_1.calculatePrice(market.amm.baseAssetReserve.sub(acquiredBase), market.amm.quoteAssetReserve.sub(acquiredQuote), market.amm.pegMultiplier);
35
35
  if (direction == types_1.PositionDirection.SHORT) {
36
- (0, assert_1.assert)(newPrice.lt(oldPrice));
36
+ assert_1.assert(newPrice.lt(oldPrice));
37
37
  }
38
38
  else {
39
- (0, assert_1.assert)(oldPrice.lt(newPrice));
39
+ assert_1.assert(oldPrice.lt(newPrice));
40
40
  }
41
41
  const pctMaxSlippage = newPrice
42
42
  .sub(oldPrice)
@@ -64,11 +64,11 @@ function calculateTradeAcquiredAmounts(direction, amount, market, inputAssetType
64
64
  if (amount.eq(numericConstants_1.ZERO)) {
65
65
  return [numericConstants_1.ZERO, numericConstants_1.ZERO];
66
66
  }
67
- const swapDirection = (0, amm_1.getSwapDirection)(inputAssetType, direction);
68
- const [newQuoteAssetReserve, newBaseAssetReserve] = (0, amm_1.calculateAmmReservesAfterSwap)(market.amm, inputAssetType, amount, swapDirection);
67
+ const swapDirection = amm_1.getSwapDirection(inputAssetType, direction);
68
+ const [newQuoteAssetReserve, newBaseAssetReserve] = amm_1.calculateAmmReservesAfterSwap(market.amm, inputAssetType, amount, swapDirection);
69
69
  const acquiredBase = market.amm.baseAssetReserve.sub(newBaseAssetReserve);
70
70
  let acquiredQuote = market.amm.quoteAssetReserve.sub(newQuoteAssetReserve);
71
- if (inputAssetType === 'base' && (0, types_1.isVariant)(swapDirection, 'remove')) {
71
+ if (inputAssetType === 'base' && types_1.isVariant(swapDirection, 'remove')) {
72
72
  acquiredQuote = acquiredQuote.sub(numericConstants_1.ONE);
73
73
  }
74
74
  return [acquiredBase, acquiredQuote];
@@ -90,10 +90,10 @@ exports.calculateTradeAcquiredAmounts = calculateTradeAcquiredAmounts;
90
90
  * ]
91
91
  */
92
92
  function calculateTargetPriceTrade(market, targetPrice, pct = MAXPCT, outputAssetType = 'quote') {
93
- (0, assert_1.assert)(market.amm.baseAssetReserve.gt(numericConstants_1.ZERO));
94
- (0, assert_1.assert)(targetPrice.gt(numericConstants_1.ZERO));
95
- (0, assert_1.assert)(pct.lte(MAXPCT) && pct.gt(numericConstants_1.ZERO));
96
- const markPriceBefore = (0, market_1.calculateMarkPrice)(market);
93
+ assert_1.assert(market.amm.baseAssetReserve.gt(numericConstants_1.ZERO));
94
+ assert_1.assert(targetPrice.gt(numericConstants_1.ZERO));
95
+ assert_1.assert(pct.lte(MAXPCT) && pct.gt(numericConstants_1.ZERO));
96
+ const markPriceBefore = market_1.calculateMarkPrice(market);
97
97
  if (targetPrice.gt(markPriceBefore)) {
98
98
  const priceGap = targetPrice.sub(markPriceBefore);
99
99
  const priceGapScaled = priceGap.mul(pct).div(MAXPCT);
@@ -118,11 +118,11 @@ function calculateTargetPriceTrade(market, targetPrice, pct = MAXPCT, outputAsse
118
118
  let markPriceAfter;
119
119
  if (markPriceBefore.gt(targetPrice)) {
120
120
  // overestimate y2
121
- baseAssetReserveAfter = (0, utils_1.squareRootBN)(k.div(targetPrice).mul(peg).div(numericConstants_1.PEG_PRECISION).sub(biasModifier)).sub(new anchor_1.BN(1));
121
+ baseAssetReserveAfter = utils_1.squareRootBN(k.div(targetPrice).mul(peg).div(numericConstants_1.PEG_PRECISION).sub(biasModifier)).sub(new anchor_1.BN(1));
122
122
  quoteAssetReserveAfter = k
123
123
  .div(numericConstants_1.MARK_PRICE_PRECISION)
124
124
  .div(baseAssetReserveAfter);
125
- markPriceAfter = (0, amm_1.calculatePrice)(baseAssetReserveAfter, quoteAssetReserveAfter, peg);
125
+ markPriceAfter = amm_1.calculatePrice(baseAssetReserveAfter, quoteAssetReserveAfter, peg);
126
126
  direction = types_1.PositionDirection.SHORT;
127
127
  tradeSize = quoteAssetReserveBefore
128
128
  .sub(quoteAssetReserveAfter)
@@ -133,11 +133,11 @@ function calculateTargetPriceTrade(market, targetPrice, pct = MAXPCT, outputAsse
133
133
  }
134
134
  else if (markPriceBefore.lt(targetPrice)) {
135
135
  // underestimate y2
136
- baseAssetReserveAfter = (0, utils_1.squareRootBN)(k.div(targetPrice).mul(peg).div(numericConstants_1.PEG_PRECISION).add(biasModifier)).add(new anchor_1.BN(1));
136
+ baseAssetReserveAfter = utils_1.squareRootBN(k.div(targetPrice).mul(peg).div(numericConstants_1.PEG_PRECISION).add(biasModifier)).add(new anchor_1.BN(1));
137
137
  quoteAssetReserveAfter = k
138
138
  .div(numericConstants_1.MARK_PRICE_PRECISION)
139
139
  .div(baseAssetReserveAfter);
140
- markPriceAfter = (0, amm_1.calculatePrice)(baseAssetReserveAfter, quoteAssetReserveAfter, peg);
140
+ markPriceAfter = amm_1.calculatePrice(baseAssetReserveAfter, quoteAssetReserveAfter, peg);
141
141
  direction = types_1.PositionDirection.LONG;
142
142
  tradeSize = quoteAssetReserveAfter
143
143
  .sub(quoteAssetReserveBefore)
@@ -164,8 +164,8 @@ function calculateTargetPriceTrade(market, targetPrice, pct = MAXPCT, outputAsse
164
164
  .mul(numericConstants_1.AMM_TO_QUOTE_PRECISION_RATIO)
165
165
  .mul(numericConstants_1.MARK_PRICE_PRECISION)
166
166
  .div(baseSize.abs());
167
- (0, assert_1.assert)(tp1.sub(tp2).lte(originalDiff), 'Target Price Calculation incorrect');
168
- (0, assert_1.assert)(tp2.lte(tp1) || tp2.sub(tp1).abs() < 100000, 'Target Price Calculation incorrect' +
167
+ assert_1.assert(tp1.sub(tp2).lte(originalDiff), 'Target Price Calculation incorrect');
168
+ assert_1.assert(tp2.lte(tp1) || tp2.sub(tp1).abs() < 100000, 'Target Price Calculation incorrect' +
169
169
  tp2.toString() +
170
170
  '>=' +
171
171
  tp1.toString() +
package/lib/orders.d.ts CHANGED
@@ -1,6 +1,8 @@
1
1
  /// <reference types="bn.js" />
2
2
  import { Market, Order, UserAccount, UserPosition } from './types';
3
- import { BN } from '.';
3
+ import { BN, ClearingHouseUser } from '.';
4
4
  export declare function calculateNewStateAfterOrder(userAccount: UserAccount, userPosition: UserPosition, market: Market, order: Order): [UserAccount, UserPosition, Market] | null;
5
+ export declare function calculateBaseAssetAmountMarketCanExecute(market: Market, order: Order): BN;
5
6
  export declare function calculateAmountToTradeForLimit(market: Market, order: Order): BN;
6
7
  export declare function calculateAmountToTradeForTriggerLimit(market: Market, order: Order): BN;
8
+ export declare function calculateBaseAssetAmountUserCanExecute(market: Market, order: Order, user: ClearingHouseUser): BN;
package/lib/orders.js CHANGED
@@ -1,26 +1,27 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.calculateAmountToTradeForTriggerLimit = exports.calculateAmountToTradeForLimit = exports.calculateNewStateAfterOrder = void 0;
3
+ exports.calculateBaseAssetAmountUserCanExecute = exports.calculateAmountToTradeForTriggerLimit = exports.calculateAmountToTradeForLimit = exports.calculateBaseAssetAmountMarketCanExecute = exports.calculateNewStateAfterOrder = void 0;
4
4
  const types_1 = require("./types");
5
+ const _1 = require(".");
5
6
  const market_1 = require("./math/market");
6
7
  const numericConstants_1 = require("./constants/numericConstants");
7
8
  const amm_1 = require("./math/amm");
8
9
  const position_1 = require("./math/position");
9
10
  function calculateNewStateAfterOrder(userAccount, userPosition, market, order) {
10
- if ((0, types_1.isVariant)(order.status, 'init')) {
11
+ if (types_1.isVariant(order.status, 'init')) {
11
12
  return null;
12
13
  }
13
- const baseAssetAmountToTrade = calculateAmountToTrade(market, order);
14
+ const baseAssetAmountToTrade = calculateBaseAssetAmountMarketCanExecute(market, order);
14
15
  if (baseAssetAmountToTrade.lt(market.amm.minimumBaseAssetTradeSize)) {
15
16
  return null;
16
17
  }
17
18
  const userAccountAfter = Object.assign({}, userAccount);
18
19
  const userPositionAfter = Object.assign({}, userPosition);
19
- const currentPositionDirection = (0, position_1.positionCurrentDirection)(userPosition);
20
+ const currentPositionDirection = position_1.positionCurrentDirection(userPosition);
20
21
  const increasePosition = userPosition.baseAssetAmount.eq(numericConstants_1.ZERO) ||
21
22
  isSameDirection(order.direction, currentPositionDirection);
22
23
  if (increasePosition) {
23
- const marketAfter = (0, market_1.calculateNewMarketAfterTrade)(baseAssetAmountToTrade, order.direction, market);
24
+ const marketAfter = market_1.calculateNewMarketAfterTrade(baseAssetAmountToTrade, order.direction, market);
24
25
  const { quoteAssetAmountSwapped, baseAssetAmountSwapped } = calculateAmountSwapped(market, marketAfter);
25
26
  userPositionAfter.baseAssetAmount = userPositionAfter.baseAssetAmount.add(baseAssetAmountSwapped);
26
27
  userPositionAfter.quoteAssetAmount = userPositionAfter.quoteAssetAmount.add(quoteAssetAmountSwapped);
@@ -29,10 +30,10 @@ function calculateNewStateAfterOrder(userAccount, userPosition, market, order) {
29
30
  else {
30
31
  const reversePosition = baseAssetAmountToTrade.gt(userPosition.baseAssetAmount.abs());
31
32
  if (reversePosition) {
32
- const intermediateMarket = (0, market_1.calculateNewMarketAfterTrade)(userPosition.baseAssetAmount, (0, position_1.findDirectionToClose)(userPosition), market);
33
+ const intermediateMarket = market_1.calculateNewMarketAfterTrade(userPosition.baseAssetAmount, position_1.findDirectionToClose(userPosition), market);
33
34
  const { quoteAssetAmountSwapped: baseAssetValue } = calculateAmountSwapped(market, intermediateMarket);
34
35
  let pnl;
35
- if ((0, types_1.isVariant)(currentPositionDirection, 'long')) {
36
+ if (types_1.isVariant(currentPositionDirection, 'long')) {
36
37
  pnl = baseAssetValue.sub(userPosition.quoteAssetAmount);
37
38
  }
38
39
  else {
@@ -40,20 +41,20 @@ function calculateNewStateAfterOrder(userAccount, userPosition, market, order) {
40
41
  }
41
42
  userAccountAfter.collateral = userAccountAfter.collateral.add(pnl);
42
43
  const baseAssetAmountLeft = baseAssetAmountToTrade.sub(userPosition.baseAssetAmount.abs());
43
- const marketAfter = (0, market_1.calculateNewMarketAfterTrade)(baseAssetAmountLeft, order.direction, intermediateMarket);
44
+ const marketAfter = market_1.calculateNewMarketAfterTrade(baseAssetAmountLeft, order.direction, intermediateMarket);
44
45
  const { quoteAssetAmountSwapped, baseAssetAmountSwapped } = calculateAmountSwapped(intermediateMarket, marketAfter);
45
46
  userPositionAfter.quoteAssetAmount = quoteAssetAmountSwapped;
46
47
  userPositionAfter.baseAssetAmount = baseAssetAmountSwapped;
47
48
  return [userAccountAfter, userPositionAfter, marketAfter];
48
49
  }
49
50
  else {
50
- const marketAfter = (0, market_1.calculateNewMarketAfterTrade)(baseAssetAmountToTrade, order.direction, market);
51
+ const marketAfter = market_1.calculateNewMarketAfterTrade(baseAssetAmountToTrade, order.direction, market);
51
52
  const { quoteAssetAmountSwapped: baseAssetValue, baseAssetAmountSwapped, } = calculateAmountSwapped(market, marketAfter);
52
53
  const costBasisRealized = userPosition.quoteAssetAmount
53
54
  .mul(baseAssetAmountSwapped.abs())
54
55
  .div(userPosition.baseAssetAmount.abs());
55
56
  let pnl;
56
- if ((0, types_1.isVariant)(currentPositionDirection, 'long')) {
57
+ if (types_1.isVariant(currentPositionDirection, 'long')) {
57
58
  pnl = baseAssetValue.sub(costBasisRealized);
58
59
  }
59
60
  else {
@@ -79,14 +80,14 @@ function calculateAmountSwapped(marketBefore, marketAfter) {
79
80
  baseAssetAmountSwapped: marketBefore.amm.baseAssetReserve.sub(marketAfter.amm.baseAssetReserve),
80
81
  };
81
82
  }
82
- function calculateAmountToTrade(market, order) {
83
- if ((0, types_1.isVariant)(order.orderType, 'limit')) {
83
+ function calculateBaseAssetAmountMarketCanExecute(market, order) {
84
+ if (types_1.isVariant(order.orderType, 'limit')) {
84
85
  return calculateAmountToTradeForLimit(market, order);
85
86
  }
86
- else if ((0, types_1.isVariant)(order.orderType, 'triggerLimit')) {
87
+ else if (types_1.isVariant(order.orderType, 'triggerLimit')) {
87
88
  return calculateAmountToTradeForTriggerLimit(market, order);
88
89
  }
89
- else if ((0, types_1.isVariant)(order.orderType, 'market')) {
90
+ else if (types_1.isVariant(order.orderType, 'market')) {
90
91
  // should never be a market order queued
91
92
  return numericConstants_1.ZERO;
92
93
  }
@@ -94,8 +95,9 @@ function calculateAmountToTrade(market, order) {
94
95
  return calculateAmountToTradeForTriggerMarket(market, order);
95
96
  }
96
97
  }
98
+ exports.calculateBaseAssetAmountMarketCanExecute = calculateBaseAssetAmountMarketCanExecute;
97
99
  function calculateAmountToTradeForLimit(market, order) {
98
- const [maxAmountToTrade, direction] = (0, amm_1.calculateMaxBaseAssetAmountToTrade)(market.amm, order.price);
100
+ const [maxAmountToTrade, direction] = amm_1.calculateMaxBaseAssetAmountToTrade(market.amm, order.price);
99
101
  // Check that directions are the same
100
102
  const sameDirection = isSameDirection(direction, order.direction);
101
103
  if (!sameDirection) {
@@ -117,8 +119,8 @@ function calculateAmountToTradeForTriggerLimit(market, order) {
117
119
  }
118
120
  exports.calculateAmountToTradeForTriggerLimit = calculateAmountToTradeForTriggerLimit;
119
121
  function isSameDirection(firstDirection, secondDirection) {
120
- return (((0, types_1.isVariant)(firstDirection, 'long') && (0, types_1.isVariant)(secondDirection, 'long')) ||
121
- ((0, types_1.isVariant)(firstDirection, 'short') && (0, types_1.isVariant)(secondDirection, 'short')));
122
+ return ((types_1.isVariant(firstDirection, 'long') && types_1.isVariant(secondDirection, 'long')) ||
123
+ (types_1.isVariant(firstDirection, 'short') && types_1.isVariant(secondDirection, 'short')));
122
124
  }
123
125
  function calculateAmountToTradeForTriggerMarket(market, order) {
124
126
  return isTriggerConditionSatisfied(market, order)
@@ -126,11 +128,37 @@ function calculateAmountToTradeForTriggerMarket(market, order) {
126
128
  : numericConstants_1.ZERO;
127
129
  }
128
130
  function isTriggerConditionSatisfied(market, order) {
129
- const markPrice = (0, market_1.calculateMarkPrice)(market);
130
- if ((0, types_1.isVariant)(order.triggerCondition, 'above')) {
131
+ const markPrice = market_1.calculateMarkPrice(market);
132
+ if (types_1.isVariant(order.triggerCondition, 'above')) {
131
133
  return markPrice.gt(order.triggerPrice);
132
134
  }
133
135
  else {
134
136
  return markPrice.lt(order.triggerPrice);
135
137
  }
136
138
  }
139
+ function calculateBaseAssetAmountUserCanExecute(market, order, user) {
140
+ const maxLeverage = user.getMaxLeverage(order.marketIndex, 'Initial');
141
+ const freeCollateral = user.getFreeCollateral();
142
+ let quoteAssetAmount;
143
+ if (_1.isOrderRiskIncreasingInSameDirection(user, order)) {
144
+ quoteAssetAmount = freeCollateral.mul(maxLeverage).div(_1.TEN_THOUSAND);
145
+ }
146
+ else {
147
+ const position = user.getUserPosition(order.marketIndex) ||
148
+ user.getEmptyPosition(order.marketIndex);
149
+ const positionValue = _1.calculateBaseAssetValue(market, position);
150
+ quoteAssetAmount = freeCollateral
151
+ .mul(maxLeverage)
152
+ .div(_1.TEN_THOUSAND)
153
+ .add(positionValue.mul(numericConstants_1.TWO));
154
+ }
155
+ if (quoteAssetAmount.lte(numericConstants_1.ZERO)) {
156
+ return numericConstants_1.ZERO;
157
+ }
158
+ const baseAssetReservesBefore = market.amm.baseAssetReserve;
159
+ const [_, baseAssetReservesAfter] = _1.calculateAmmReservesAfterSwap(market.amm, 'quote', quoteAssetAmount, types_1.isVariant(order.direction, 'long')
160
+ ? types_1.SwapDirection.ADD
161
+ : types_1.SwapDirection.REMOVE);
162
+ return baseAssetReservesBefore.sub(baseAssetReservesAfter).abs();
163
+ }
164
+ exports.calculateBaseAssetAmountUserCanExecute = calculateBaseAssetAmountUserCanExecute;
package/lib/pythClient.js CHANGED
@@ -18,7 +18,7 @@ class PythClient {
18
18
  getPriceData(pricePublicKey) {
19
19
  return __awaiter(this, void 0, void 0, function* () {
20
20
  const account = yield this.connection.getAccountInfo(pricePublicKey);
21
- return (0, client_1.parsePriceData)(account.data);
21
+ return client_1.parsePriceData(account.data);
22
22
  });
23
23
  }
24
24
  }
@@ -93,7 +93,7 @@ class RetryTxSender {
93
93
  catch (err) {
94
94
  throw new Error('signature must be base58 encoded: ' + signature);
95
95
  }
96
- (0, assert_1.default)(decodedSignature.length === 64, 'signature has invalid length');
96
+ assert_1.default(decodedSignature.length === 64, 'signature has invalid length');
97
97
  const start = Date.now();
98
98
  const subscriptionCommitment = commitment || this.provider.opts.commitment;
99
99
  let subscriptionId;
package/lib/types.d.ts CHANGED
@@ -272,7 +272,6 @@ export declare type OrderStateAccount = {
272
272
  minOrderQuoteAssetAmount: BN;
273
273
  };
274
274
  export declare type MarketsAccount = {
275
- accountIndex: BN;
276
275
  markets: Market[];
277
276
  };
278
277
  export declare type Market = {
@@ -282,6 +281,9 @@ export declare type Market = {
282
281
  baseAssetAmountShort: BN;
283
282
  initialized: boolean;
284
283
  openInterest: BN;
284
+ marginRatioInitial: number;
285
+ marginRatioMaintenance: number;
286
+ marginRatioPartial: number;
285
287
  };
286
288
  export declare type AMM = {
287
289
  baseAssetReserve: BN;
@@ -434,3 +436,4 @@ export declare type OrderFillerRewardStructure = {
434
436
  rewardDenominator: BN;
435
437
  timeBasedRewardLowerBound: BN;
436
438
  };
439
+ export declare type MarginCategory = 'Initial' | 'Partial' | 'Maintenance';
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@drift-labs/sdk",
3
- "version": "0.1.23-master.2",
3
+ "version": "0.1.24",
4
4
  "main": "lib/index.js",
5
5
  "types": "lib/index.d.ts",
6
6
  "author": "crispheaney",