@drift-labs/sdk 2.13.0-beta.0 → 2.13.0-beta.1

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.
@@ -51,6 +51,8 @@ export declare const AMM_TIMES_PEG_TO_QUOTE_PRECISION_RATIO: BN;
51
51
  export declare const MARGIN_PRECISION: BN;
52
52
  export declare const BID_ASK_SPREAD_PRECISION: BN;
53
53
  export declare const LIQUIDATION_PCT_PRECISION: BN;
54
+ export declare const FIVE_MINUTE: BN;
55
+ export declare const ONE_HOUR: BN;
54
56
  export declare const ONE_YEAR: BN;
55
57
  export declare const QUOTE_SPOT_MARKET_INDEX = 0;
56
58
  export declare const LAMPORTS_PRECISION: BN;
@@ -1,7 +1,7 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.BID_ASK_SPREAD_PRECISION = exports.MARGIN_PRECISION = exports.AMM_TIMES_PEG_TO_QUOTE_PRECISION_RATIO = exports.PRICE_TO_QUOTE_PRECISION = exports.PRICE_DIV_PEG = exports.AMM_TO_QUOTE_PRECISION_RATIO = exports.BASE_PRECISION_EXP = exports.BASE_PRECISION = exports.AMM_RESERVE_PRECISION = exports.PEG_PRECISION = exports.FUNDING_RATE_BUFFER_PRECISION = exports.FUNDING_RATE_PRECISION = exports.PRICE_PRECISION = exports.QUOTE_PRECISION = exports.LIQUIDATION_FEE_PRECISION = exports.SPOT_MARKET_IMF_PRECISION = exports.SPOT_MARKET_IMF_PRECISION_EXP = exports.SPOT_MARKET_BALANCE_PRECISION = exports.SPOT_MARKET_BALANCE_PRECISION_EXP = exports.SPOT_MARKET_WEIGHT_PRECISION = exports.SPOT_MARKET_UTILIZATION_PRECISION = exports.SPOT_MARKET_UTILIZATION_PRECISION_EXP = exports.SPOT_MARKET_CUMULATIVE_INTEREST_PRECISION = exports.SPOT_MARKET_CUMULATIVE_INTEREST_PRECISION_EXP = exports.SPOT_MARKET_RATE_PRECISION = exports.SPOT_MARKET_RATE_PRECISION_EXP = exports.AMM_RESERVE_PRECISION_EXP = exports.PEG_PRECISION_EXP = exports.FUNDING_RATE_PRECISION_EXP = exports.PRICE_PRECISION_EXP = exports.FUNDING_RATE_BUFFER_PRECISION_EXP = exports.QUOTE_PRECISION_EXP = exports.CONCENTRATION_PRECISION = exports.PERCENTAGE_PRECISION = exports.PERCENTAGE_PRECISION_EXP = exports.MAX_LEVERAGE = exports.TEN_MILLION = exports.BN_MAX = exports.TEN_THOUSAND = exports.TEN = exports.NINE = exports.EIGHT = exports.SEVEN = exports.SIX = exports.FIVE = exports.FOUR = exports.THREE = exports.TWO = exports.ONE = exports.ZERO = void 0;
4
- exports.DEFAULT_REVENUE_SINCE_LAST_FUNDING_SPREAD_RETREAT = exports.OPEN_ORDER_MARGIN_REQUIREMENT = exports.LAMPORTS_EXP = exports.LAMPORTS_PRECISION = exports.QUOTE_SPOT_MARKET_INDEX = exports.ONE_YEAR = exports.LIQUIDATION_PCT_PRECISION = void 0;
4
+ exports.DEFAULT_REVENUE_SINCE_LAST_FUNDING_SPREAD_RETREAT = exports.OPEN_ORDER_MARGIN_REQUIREMENT = exports.LAMPORTS_EXP = exports.LAMPORTS_PRECISION = exports.QUOTE_SPOT_MARKET_INDEX = exports.ONE_YEAR = exports.ONE_HOUR = exports.FIVE_MINUTE = exports.LIQUIDATION_PCT_PRECISION = void 0;
5
5
  const web3_js_1 = require("@solana/web3.js");
6
6
  const __1 = require("../");
7
7
  exports.ZERO = new __1.BN(0);
@@ -55,6 +55,8 @@ exports.AMM_TIMES_PEG_TO_QUOTE_PRECISION_RATIO = exports.AMM_RESERVE_PRECISION.m
55
55
  exports.MARGIN_PRECISION = exports.TEN_THOUSAND;
56
56
  exports.BID_ASK_SPREAD_PRECISION = new __1.BN(1000000); // 10^6
57
57
  exports.LIQUIDATION_PCT_PRECISION = exports.TEN_THOUSAND;
58
+ exports.FIVE_MINUTE = new __1.BN(60 * 5);
59
+ exports.ONE_HOUR = new __1.BN(60 * 60);
58
60
  exports.ONE_YEAR = new __1.BN(31536000);
59
61
  exports.QUOTE_SPOT_MARKET_INDEX = 0;
60
62
  exports.LAMPORTS_PRECISION = new __1.BN(web3_js_1.LAMPORTS_PER_SOL);
@@ -219,6 +219,15 @@ export declare class DriftClient {
219
219
  * @returns
220
220
  */
221
221
  modifyPerpOrder(orderId: number, newBaseAmount?: BN, newLimitPrice?: BN, newOraclePriceOffset?: number): Promise<TransactionSignature>;
222
+ /**
223
+ * Modifies an open order by closing it and replacing it with a new order.
224
+ * @param userOrderId: The open order to modify
225
+ * @param newBaseAmount: The new base amount for the order. One of [newBaseAmount|newLimitPrice|newOraclePriceOffset] must be provided.
226
+ * @param newLimitPice: The new limit price for the order. One of [newBaseAmount|newLimitPrice|newOraclePriceOffset] must be provided.
227
+ * @param newOraclePriceOffset: The new oracle price offset for the order. One of [newBaseAmount|newLimitPrice|newOraclePriceOffset] must be provided.
228
+ * @returns
229
+ */
230
+ modifyPerpOrderByUserOrderId(userOrderId: number, newBaseAmount?: BN, newLimitPrice?: BN, newOraclePriceOffset?: number): Promise<TransactionSignature>;
222
231
  settlePNLs(users: {
223
232
  settleeUserAccountPublicKey: PublicKey;
224
233
  settleeUserAccount: UserAccount;
@@ -1777,6 +1777,55 @@ class DriftClient {
1777
1777
  maxTs: openOrder.maxTs,
1778
1778
  auctionStartPrice: openOrder.auctionStartPrice,
1779
1779
  auctionEndPrice: openOrder.auctionEndPrice,
1780
+ userOrderId: openOrder.userOrderId,
1781
+ };
1782
+ const placeOrderIx = await this.getPlacePerpOrderIx(newOrderParams);
1783
+ const tx = new web3_js_1.Transaction();
1784
+ tx.add(web3_js_1.ComputeBudgetProgram.requestUnits({
1785
+ units: 1000000,
1786
+ additionalFee: 0,
1787
+ }));
1788
+ tx.add(cancelOrderIx);
1789
+ tx.add(placeOrderIx);
1790
+ const { txSig, slot } = await this.sendTransaction(tx, [], this.opts);
1791
+ this.perpMarketLastSlotCache.set(newOrderParams.marketIndex, slot);
1792
+ return txSig;
1793
+ }
1794
+ /**
1795
+ * Modifies an open order by closing it and replacing it with a new order.
1796
+ * @param userOrderId: The open order to modify
1797
+ * @param newBaseAmount: The new base amount for the order. One of [newBaseAmount|newLimitPrice|newOraclePriceOffset] must be provided.
1798
+ * @param newLimitPice: The new limit price for the order. One of [newBaseAmount|newLimitPrice|newOraclePriceOffset] must be provided.
1799
+ * @param newOraclePriceOffset: The new oracle price offset for the order. One of [newBaseAmount|newLimitPrice|newOraclePriceOffset] must be provided.
1800
+ * @returns
1801
+ */
1802
+ async modifyPerpOrderByUserOrderId(userOrderId, newBaseAmount, newLimitPrice, newOraclePriceOffset) {
1803
+ if (!newBaseAmount && !newLimitPrice && !newOraclePriceOffset) {
1804
+ throw new Error(`Must provide newBaseAmount or newLimitPrice or newOraclePriceOffset to modify order`);
1805
+ }
1806
+ const openOrder = this.getUser().getOrderByUserOrderId(userOrderId);
1807
+ if (!openOrder) {
1808
+ throw new Error(`No open order with user order id ${userOrderId.toString()}`);
1809
+ }
1810
+ const cancelOrderIx = await this.getCancelOrderIx(openOrder.orderId);
1811
+ const newOrderParams = {
1812
+ orderType: openOrder.orderType,
1813
+ marketType: openOrder.marketType,
1814
+ direction: openOrder.direction,
1815
+ baseAssetAmount: newBaseAmount || openOrder.baseAssetAmount,
1816
+ price: newLimitPrice || openOrder.price,
1817
+ marketIndex: openOrder.marketIndex,
1818
+ reduceOnly: openOrder.reduceOnly,
1819
+ postOnly: openOrder.postOnly,
1820
+ immediateOrCancel: openOrder.immediateOrCancel,
1821
+ triggerPrice: openOrder.triggerPrice,
1822
+ triggerCondition: openOrder.triggerCondition,
1823
+ oraclePriceOffset: newOraclePriceOffset || openOrder.oraclePriceOffset,
1824
+ auctionDuration: openOrder.auctionDuration,
1825
+ maxTs: openOrder.maxTs,
1826
+ auctionStartPrice: openOrder.auctionStartPrice,
1827
+ auctionEndPrice: openOrder.auctionEndPrice,
1828
+ userOrderId: openOrder.userOrderId,
1780
1829
  };
1781
1830
  const placeOrderIx = await this.getPlacePerpOrderIx(newOrderParams);
1782
1831
  const tx = new web3_js_1.Transaction();
@@ -1,5 +1,5 @@
1
1
  {
2
- "version": "2.13.0-beta.0",
2
+ "version": "2.13.0-beta.1",
3
3
  "name": "drift",
4
4
  "instructions": [
5
5
  {
@@ -2,6 +2,7 @@
2
2
  import { BN } from '@project-serum/anchor';
3
3
  import { PerpMarketAccount, PositionDirection, MarginCategory, SpotMarketAccount } from '../types';
4
4
  import { OraclePriceData } from '../oracles/types';
5
+ import { DLOB } from '../dlob/DLOB';
5
6
  /**
6
7
  * Calculates market mark price
7
8
  *
@@ -31,3 +32,7 @@ export declare function calculateUnrealizedAssetWeight(market: PerpMarketAccount
31
32
  export declare function calculateMarketAvailablePNL(perpMarket: PerpMarketAccount, spotMarket: SpotMarketAccount): BN;
32
33
  export declare function calculateNetUserPnl(perpMarket: PerpMarketAccount, oraclePriceData: OraclePriceData): BN;
33
34
  export declare function calculateNetUserPnlImbalance(perpMarket: PerpMarketAccount, spotMarket: SpotMarketAccount, oraclePriceData: OraclePriceData): BN;
35
+ export declare function calculateAvailablePerpLiquidity(market: PerpMarketAccount, oraclePriceData: OraclePriceData, dlob: DLOB, slot: number): {
36
+ bids: BN;
37
+ asks: BN;
38
+ };
@@ -1,6 +1,6 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.calculateNetUserPnlImbalance = exports.calculateNetUserPnl = exports.calculateMarketAvailablePNL = exports.calculateUnrealizedAssetWeight = exports.calculateMarketMarginRatio = exports.calculateOracleSpread = exports.calculateOracleReserveSpread = exports.calculateNewMarketAfterTrade = exports.calculateAskPrice = exports.calculateBidPrice = exports.calculateReservePrice = void 0;
3
+ exports.calculateAvailablePerpLiquidity = exports.calculateNetUserPnlImbalance = exports.calculateNetUserPnl = exports.calculateMarketAvailablePNL = exports.calculateUnrealizedAssetWeight = exports.calculateMarketMarginRatio = exports.calculateOracleSpread = exports.calculateOracleReserveSpread = exports.calculateNewMarketAfterTrade = exports.calculateAskPrice = exports.calculateBidPrice = exports.calculateReservePrice = void 0;
4
4
  const anchor_1 = require("@project-serum/anchor");
5
5
  const types_1 = require("../types");
6
6
  const amm_1 = require("./amm");
@@ -115,3 +115,20 @@ function calculateNetUserPnlImbalance(perpMarket, spotMarket, oraclePriceData) {
115
115
  return imbalance;
116
116
  }
117
117
  exports.calculateNetUserPnlImbalance = calculateNetUserPnlImbalance;
118
+ function calculateAvailablePerpLiquidity(market, oraclePriceData, dlob, slot) {
119
+ let [bids, asks] = amm_1.calculateMarketOpenBidAsk(market.amm.baseAssetReserve, market.amm.minBaseAssetReserve, market.amm.maxBaseAssetReserve, market.amm.orderStepSize);
120
+ asks = asks.abs();
121
+ const bidPrice = calculateBidPrice(market, oraclePriceData);
122
+ const askPrice = calculateAskPrice(market, oraclePriceData);
123
+ for (const bid of dlob.getMakerLimitBids(market.marketIndex, slot, types_1.MarketType.PERP, oraclePriceData, askPrice)) {
124
+ bids = bids.add(bid.order.baseAssetAmount.sub(bid.order.baseAssetAmountFilled));
125
+ }
126
+ for (const ask of dlob.getMakerLimitAsks(market.marketIndex, slot, types_1.MarketType.PERP, oraclePriceData, bidPrice)) {
127
+ asks = asks.add(ask.order.baseAssetAmount.sub(ask.order.baseAssetAmountFilled));
128
+ }
129
+ return {
130
+ bids: bids,
131
+ asks: asks,
132
+ };
133
+ }
134
+ exports.calculateAvailablePerpLiquidity = calculateAvailablePerpLiquidity;
@@ -1,9 +1,9 @@
1
1
  /// <reference types="bn.js" />
2
2
  import { AMM, OracleGuardRails } from '../types';
3
3
  import { OraclePriceData } from '../oracles/types';
4
- import { BN, PerpMarketAccount } from '../index';
4
+ import { BN, HistoricalOracleData, PerpMarketAccount } from '../index';
5
5
  export declare function oraclePriceBands(market: PerpMarketAccount, oraclePriceData: OraclePriceData): [BN, BN];
6
6
  export declare function isOracleValid(amm: AMM, oraclePriceData: OraclePriceData, oracleGuardRails: OracleGuardRails, slot: number): boolean;
7
7
  export declare function isOracleTooDivergent(amm: AMM, oraclePriceData: OraclePriceData, oracleGuardRails: OracleGuardRails, now: BN): boolean;
8
- export declare function calculateLiveOracleTwap(amm: AMM, oraclePriceData: OraclePriceData, now: BN): BN;
8
+ export declare function calculateLiveOracleTwap(histOracleData: HistoricalOracleData, oraclePriceData: OraclePriceData, now: BN, period: BN): BN;
9
9
  export declare function calculateLiveOracleStd(amm: AMM, oraclePriceData: OraclePriceData, now: BN): BN;
@@ -38,7 +38,7 @@ function isOracleValid(amm, oraclePriceData, oracleGuardRails, slot) {
38
38
  exports.isOracleValid = isOracleValid;
39
39
  function isOracleTooDivergent(amm, oraclePriceData, oracleGuardRails, now) {
40
40
  const sinceLastUpdate = now.sub(amm.historicalOracleData.lastOraclePriceTwapTs);
41
- const sinceStart = index_1.BN.max(numericConstants_1.ZERO, new index_1.BN(60 * 5).sub(sinceLastUpdate));
41
+ const sinceStart = index_1.BN.max(numericConstants_1.ZERO, numericConstants_1.FIVE_MINUTE.sub(sinceLastUpdate));
42
42
  const oracleTwap5min = amm.historicalOracleData.lastOraclePriceTwap5Min
43
43
  .mul(sinceStart)
44
44
  .add(oraclePriceData.price)
@@ -52,12 +52,24 @@ function isOracleTooDivergent(amm, oraclePriceData, oracleGuardRails, now) {
52
52
  return tooDivergent;
53
53
  }
54
54
  exports.isOracleTooDivergent = isOracleTooDivergent;
55
- function calculateLiveOracleTwap(amm, oraclePriceData, now) {
56
- const sinceLastUpdate = index_1.BN.max(numericConstants_1.ONE, now.sub(amm.historicalOracleData.lastOraclePriceTwapTs));
57
- const sinceStart = index_1.BN.max(numericConstants_1.ZERO, amm.fundingPeriod.sub(sinceLastUpdate));
58
- const clampRange = amm.historicalOracleData.lastOraclePriceTwap.div(new index_1.BN(3));
59
- const clampedOraclePrice = index_1.BN.min(amm.historicalOracleData.lastOraclePriceTwap.add(clampRange), index_1.BN.max(oraclePriceData.price, amm.historicalOracleData.lastOraclePriceTwap.sub(clampRange)));
60
- const newOracleTwap = amm.historicalOracleData.lastOraclePriceTwap
55
+ function calculateLiveOracleTwap(histOracleData, oraclePriceData, now, period) {
56
+ let oracleTwap = undefined;
57
+ if (period.eq(numericConstants_1.ONE_HOUR)) {
58
+ //todo: assumes its 1hr
59
+ // period = amm.fundingPeriod;
60
+ oracleTwap = histOracleData.lastOraclePriceTwap;
61
+ }
62
+ else if (period.eq(numericConstants_1.FIVE_MINUTE)) {
63
+ histOracleData.lastOraclePriceTwap5Min;
64
+ }
65
+ else {
66
+ throw Error('unsupported twap period passed');
67
+ }
68
+ const sinceLastUpdate = index_1.BN.max(numericConstants_1.ONE, now.sub(histOracleData.lastOraclePriceTwapTs));
69
+ const sinceStart = index_1.BN.max(numericConstants_1.ZERO, period.sub(sinceLastUpdate));
70
+ const clampRange = oracleTwap.div(new index_1.BN(3));
71
+ const clampedOraclePrice = index_1.BN.min(oracleTwap.add(clampRange), index_1.BN.max(oraclePriceData.price, oracleTwap.sub(clampRange)));
72
+ const newOracleTwap = oracleTwap
61
73
  .mul(sinceStart)
62
74
  .add(clampedOraclePrice.mul(sinceLastUpdate))
63
75
  .div(sinceStart.add(sinceLastUpdate));
@@ -67,7 +79,7 @@ exports.calculateLiveOracleTwap = calculateLiveOracleTwap;
67
79
  function calculateLiveOracleStd(amm, oraclePriceData, now) {
68
80
  const sinceLastUpdate = index_1.BN.max(numericConstants_1.ONE, now.sub(amm.historicalOracleData.lastOraclePriceTwapTs));
69
81
  const sinceStart = index_1.BN.max(numericConstants_1.ZERO, amm.fundingPeriod.sub(sinceLastUpdate));
70
- const liveOracleTwap = calculateLiveOracleTwap(amm, oraclePriceData, now);
82
+ const liveOracleTwap = calculateLiveOracleTwap(amm.historicalOracleData, oraclePriceData, now, amm.fundingPeriod);
71
83
  const priceDeltaVsTwap = oraclePriceData.price.sub(liveOracleTwap).abs();
72
84
  const oracleStd = priceDeltaVsTwap.add(amm.oracleStd.mul(sinceStart).div(sinceStart.add(sinceLastUpdate)));
73
85
  return oracleStd;
@@ -108,7 +108,7 @@ function hasAuctionPrice(order, slot) {
108
108
  exports.hasAuctionPrice = hasAuctionPrice;
109
109
  function isFillableByVAMM(order, market, oraclePriceData, slot, ts) {
110
110
  return ((auction_1.isAuctionComplete(order, slot) &&
111
- !calculateBaseAssetAmountForAmmToFulfill(order, market, oraclePriceData, slot).eq(numericConstants_1.ZERO)) ||
111
+ calculateBaseAssetAmountForAmmToFulfill(order, market, oraclePriceData, slot).gte(market.amm.minOrderSize)) ||
112
112
  isOrderExpired(order, ts));
113
113
  }
114
114
  exports.isFillableByVAMM = isFillableByVAMM;
@@ -5,6 +5,7 @@ import { OraclePriceData } from '../oracles/types';
5
5
  export declare function getBalance(tokenAmount: BN, spotMarket: SpotMarketAccount, balanceType: SpotBalanceType): BN;
6
6
  export declare function getTokenAmount(balanceAmount: BN, spotMarket: SpotMarketAccount, balanceType: SpotBalanceType): BN;
7
7
  export declare function getSignedTokenAmount(tokenAmount: BN, balanceType: SpotBalanceType): BN;
8
+ export declare function getStrictTokenValue(tokenAmount: BN, spotDecimals: number, oraclePriceData: OraclePriceData, oraclePriceTwap: BN): BN;
8
9
  export declare function getTokenValue(tokenAmount: BN, spotDecimals: number, oraclePriceData: OraclePriceData): BN;
9
10
  export declare function calculateAssetWeight(balanceAmount: BN, spotMarket: SpotMarketAccount, marginCategory: MarginCategory): BN;
10
11
  export declare function calculateLiabilityWeight(balanceAmount: BN, spotMarket: SpotMarketAccount, marginCategory: MarginCategory): BN;
@@ -19,4 +20,8 @@ export declare function calculateInterestAccumulated(bank: SpotMarketAccount, no
19
20
  export declare function calculateWithdrawLimit(spotMarket: SpotMarketAccount, now: BN): {
20
21
  borrowLimit: BN;
21
22
  withdrawLimit: BN;
23
+ minDepositAmount: BN;
24
+ maxBorrowAmount: BN;
25
+ currentDepositAmount: any;
26
+ currentBorrowAmount: any;
22
27
  };
@@ -1,6 +1,6 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.calculateWithdrawLimit = exports.calculateInterestAccumulated = exports.calculateBorrowRate = exports.calculateDepositRate = exports.calculateInterestRate = exports.calculateUtilization = exports.calculateLiabilityWeight = exports.calculateAssetWeight = exports.getTokenValue = exports.getSignedTokenAmount = exports.getTokenAmount = exports.getBalance = void 0;
3
+ exports.calculateWithdrawLimit = exports.calculateInterestAccumulated = exports.calculateBorrowRate = exports.calculateDepositRate = exports.calculateInterestRate = exports.calculateUtilization = exports.calculateLiabilityWeight = exports.calculateAssetWeight = exports.getTokenValue = exports.getStrictTokenValue = exports.getSignedTokenAmount = 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");
@@ -35,6 +35,21 @@ function getSignedTokenAmount(tokenAmount, balanceType) {
35
35
  }
36
36
  }
37
37
  exports.getSignedTokenAmount = getSignedTokenAmount;
38
+ function getStrictTokenValue(tokenAmount, spotDecimals, oraclePriceData, oraclePriceTwap) {
39
+ if (tokenAmount.eq(numericConstants_1.ZERO)) {
40
+ return numericConstants_1.ZERO;
41
+ }
42
+ let price = oraclePriceData.price;
43
+ if (tokenAmount.gt(numericConstants_1.ZERO)) {
44
+ price = anchor_1.BN.min(oraclePriceData.price, oraclePriceTwap);
45
+ }
46
+ else {
47
+ price = anchor_1.BN.max(oraclePriceData.price, oraclePriceTwap);
48
+ }
49
+ const precisionDecrease = numericConstants_1.TEN.pow(new anchor_1.BN(spotDecimals));
50
+ return tokenAmount.mul(price).div(precisionDecrease);
51
+ }
52
+ exports.getStrictTokenValue = getStrictTokenValue;
38
53
  function getTokenValue(tokenAmount, spotDecimals, oraclePriceData) {
39
54
  if (tokenAmount.eq(numericConstants_1.ZERO)) {
40
55
  return numericConstants_1.ZERO;
@@ -187,9 +202,21 @@ function calculateWithdrawLimit(spotMarket, now) {
187
202
  .div(sinceLast.add(sinceStart));
188
203
  const maxBorrowTokens = anchor_1.BN.min(anchor_1.BN.max(marketDepositTokenAmount.div(new anchor_1.BN(6)), borrowTokenTwapLive.add(borrowTokenTwapLive.div(new anchor_1.BN(5)))), marketDepositTokenAmount.sub(marketDepositTokenAmount.div(new anchor_1.BN(5)))); // between ~15-80% utilization with friction on twap
189
204
  const minDepositTokens = depositTokenTwapLive.sub(anchor_1.BN.min(anchor_1.BN.max(depositTokenTwapLive.div(new anchor_1.BN(5)), spotMarket.withdrawGuardThreshold), depositTokenTwapLive));
205
+ let withdrawLimit = anchor_1.BN.max(marketDepositTokenAmount.sub(minDepositTokens), numericConstants_1.ZERO);
206
+ let borrowLimit = anchor_1.BN.max(maxBorrowTokens.sub(marketBorrowTokenAmount), numericConstants_1.ZERO);
207
+ if (borrowLimit.eq(numericConstants_1.ZERO)) {
208
+ withdrawLimit = numericConstants_1.ZERO;
209
+ }
210
+ if (withdrawLimit.eq(numericConstants_1.ZERO)) {
211
+ borrowLimit = numericConstants_1.ZERO;
212
+ }
190
213
  return {
191
- borrowLimit: maxBorrowTokens.sub(marketBorrowTokenAmount),
192
- withdrawLimit: marketDepositTokenAmount.sub(minDepositTokens),
214
+ borrowLimit,
215
+ withdrawLimit,
216
+ maxBorrowAmount: maxBorrowTokens,
217
+ minDepositAmount: minDepositTokens,
218
+ currentDepositAmount: marketDepositTokenAmount,
219
+ currentBorrowAmount: marketBorrowTokenAmount,
193
220
  };
194
221
  }
195
222
  exports.calculateWithdrawLimit = calculateWithdrawLimit;
package/lib/math/trade.js CHANGED
@@ -338,7 +338,10 @@ function calculateEstimatedPerpEntryPrice(assetType, amount, direction, market,
338
338
  break;
339
339
  }
340
340
  }
341
- if (limitOrder && usersToSkip.has(limitOrder.userAccount)) {
341
+ if (!limitOrder) {
342
+ continue;
343
+ }
344
+ if (usersToSkip.has(limitOrder.userAccount)) {
342
345
  continue;
343
346
  }
344
347
  const baseFilled = anchor_1.BN.min(limitOrder.order.baseAssetAmount.sub(limitOrder.order.baseAssetAmountFilled), amount.sub(cumulativeBaseFilled));
@@ -388,7 +391,10 @@ function calculateEstimatedPerpEntryPrice(assetType, amount, direction, market,
388
391
  break;
389
392
  }
390
393
  }
391
- if (limitOrder && usersToSkip.has(limitOrder.userAccount)) {
394
+ if (!limitOrder) {
395
+ continue;
396
+ }
397
+ if (usersToSkip.has(limitOrder.userAccount)) {
392
398
  continue;
393
399
  }
394
400
  const quoteFilled = anchor_1.BN.min(limitOrder.order.baseAssetAmount
package/lib/user.d.ts CHANGED
@@ -89,7 +89,7 @@ export declare class User {
89
89
  /**
90
90
  * @returns The margin requirement of a certain type (Initial or Maintenance) in USDC. : QUOTE_PRECISION
91
91
  */
92
- getMarginRequirement(marginCategory: MarginCategory, liquidationBuffer?: BN): BN;
92
+ getMarginRequirement(marginCategory: MarginCategory, liquidationBuffer?: BN, strict?: boolean): BN;
93
93
  /**
94
94
  * @returns The initial margin requirement in USDC. : QUOTE_PRECISION
95
95
  */
@@ -109,10 +109,10 @@ export declare class User {
109
109
  * @returns : Precision QUOTE_PRECISION
110
110
  */
111
111
  getUnrealizedFundingPNL(marketIndex?: number): BN;
112
- getSpotMarketLiabilityValue(marketIndex?: number, marginCategory?: MarginCategory, liquidationBuffer?: BN, includeOpenOrders?: boolean): BN;
113
- getSpotLiabilityValue(tokenAmount: BN, oraclePriceData: OraclePriceData, spotMarketAccount: SpotMarketAccount, marginCategory?: MarginCategory, liquidationBuffer?: BN): BN;
114
- getSpotMarketAssetValue(marketIndex?: number, marginCategory?: MarginCategory, includeOpenOrders?: boolean): BN;
115
- getSpotAssetValue(tokenAmount: BN, oraclePriceData: OraclePriceData, spotMarketAccount: SpotMarketAccount, marginCategory?: MarginCategory): BN;
112
+ getSpotMarketLiabilityValue(marketIndex?: number, marginCategory?: MarginCategory, liquidationBuffer?: BN, includeOpenOrders?: boolean, strict?: boolean, now?: BN): BN;
113
+ getSpotLiabilityValue(tokenAmount: BN, oraclePriceData: OraclePriceData, spotMarketAccount: SpotMarketAccount, marginCategory?: MarginCategory, liquidationBuffer?: BN, strict?: boolean, now?: BN): BN;
114
+ getSpotMarketAssetValue(marketIndex?: number, marginCategory?: MarginCategory, includeOpenOrders?: boolean, strict?: boolean, now?: BN): BN;
115
+ getSpotAssetValue(tokenAmount: BN, oraclePriceData: OraclePriceData, spotMarketAccount: SpotMarketAccount, marginCategory?: MarginCategory, strict?: boolean, now?: BN): BN;
116
116
  getNetSpotMarketValue(withWeightMarginCategory?: MarginCategory): BN;
117
117
  /**
118
118
  * calculates TotalCollateral: collateral + unrealized pnl
@@ -141,7 +141,7 @@ export declare class User {
141
141
  */
142
142
  getPositionEstimatedExitPriceAndPnl(position: PerpPosition, amountToClose?: BN, useAMMClose?: boolean): [BN, BN];
143
143
  /**
144
- * calculates current user leverage across all positions
144
+ * calculates current user leverage which is (total liability size) / (net asset value)
145
145
  * @returns : Precision TEN_THOUSAND
146
146
  */
147
147
  getLeverage(): BN;
@@ -232,6 +232,12 @@ export declare class User {
232
232
  * @returns withdrawalLimit : Precision is the token precision for the chosen SpotMarket
233
233
  */
234
234
  getWithdrawalLimit(marketIndex: number, reduceOnly?: boolean): BN;
235
+ canBypassWithdrawLimits(marketIndex: number): {
236
+ canBypass: boolean;
237
+ netDeposits: BN;
238
+ depositAmount: BN;
239
+ maxDepositAmount: BN;
240
+ };
235
241
  /**
236
242
  * Get the total position value, excluding any position coming from the given target market
237
243
  * @param marketToIgnore