@drift-labs/sdk 2.60.0-beta.9 → 2.61.0-beta.0
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.
- package/VERSION +1 -1
- package/lib/accounts/webSocketProgramAccountSubscriber.js +4 -0
- package/lib/auctionSubscriber/auctionSubscriber.js +1 -1
- package/lib/idl/drift.json +10 -5
- package/lib/math/trade.d.ts +2 -1
- package/lib/math/trade.js +15 -1
- package/lib/types.d.ts +9 -0
- package/lib/types.js +5 -0
- package/lib/user.d.ts +7 -6
- package/lib/user.js +23 -25
- package/package.json +1 -1
- package/src/accounts/webSocketProgramAccountSubscriber.ts +6 -0
- package/src/auctionSubscriber/auctionSubscriber.ts +1 -1
- package/src/idl/drift.json +10 -5
- package/src/math/trade.ts +27 -0
- package/src/types.ts +5 -0
- package/src/user.ts +43 -38
package/VERSION
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
2.
|
|
1
|
+
2.61.0-beta.0
|
|
@@ -12,6 +12,9 @@ class WebSocketProgramAccountSubscriber {
|
|
|
12
12
|
this.program = program;
|
|
13
13
|
this.decodeBuffer = decodeBufferFn;
|
|
14
14
|
this.resubTimeoutMs = resubTimeoutMs;
|
|
15
|
+
if (this.resubTimeoutMs < 1000) {
|
|
16
|
+
console.log('resubTimeoutMs should be at least 1000ms to avoid spamming resub');
|
|
17
|
+
}
|
|
15
18
|
this.options = options;
|
|
16
19
|
this.receivingData = false;
|
|
17
20
|
}
|
|
@@ -33,6 +36,7 @@ class WebSocketProgramAccountSubscriber {
|
|
|
33
36
|
}
|
|
34
37
|
}, (_a = this.options.commitment) !== null && _a !== void 0 ? _a : this.program.provider.opts.commitment, this.options.filters);
|
|
35
38
|
if (this.resubTimeoutMs) {
|
|
39
|
+
this.receivingData = true;
|
|
36
40
|
this.setTimeout();
|
|
37
41
|
}
|
|
38
42
|
}
|
|
@@ -15,7 +15,7 @@ class AuctionSubscriber {
|
|
|
15
15
|
if (!this.subscriber) {
|
|
16
16
|
this.subscriber = new webSocketProgramAccountSubscriber_1.WebSocketProgramAccountSubscriber('AuctionSubscriber', 'User', this.driftClient.program, this.driftClient.program.account.user.coder.accounts.decode.bind(this.driftClient.program.account.user.coder.accounts), {
|
|
17
17
|
filters: [(0, memcmp_1.getUserFilter)(), (0, memcmp_1.getUserWithAuctionFilter)()],
|
|
18
|
-
commitment: this.
|
|
18
|
+
commitment: this.opts.commitment,
|
|
19
19
|
}, this.resubTimeoutMs);
|
|
20
20
|
}
|
|
21
21
|
await this.subscriber.subscribe((accountId, data, context) => {
|
package/lib/idl/drift.json
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
{
|
|
2
|
-
"version": "2.
|
|
2
|
+
"version": "2.60.0",
|
|
3
3
|
"name": "drift",
|
|
4
4
|
"instructions": [
|
|
5
5
|
{
|
|
@@ -8364,6 +8364,9 @@
|
|
|
8364
8364
|
},
|
|
8365
8365
|
{
|
|
8366
8366
|
"name": "Borrow"
|
|
8367
|
+
},
|
|
8368
|
+
{
|
|
8369
|
+
"name": "RepayBorrow"
|
|
8367
8370
|
}
|
|
8368
8371
|
]
|
|
8369
8372
|
}
|
|
@@ -8463,6 +8466,9 @@
|
|
|
8463
8466
|
},
|
|
8464
8467
|
{
|
|
8465
8468
|
"name": "OrderFilledWithLPJit"
|
|
8469
|
+
},
|
|
8470
|
+
{
|
|
8471
|
+
"name": "DeriskLp"
|
|
8466
8472
|
}
|
|
8467
8473
|
]
|
|
8468
8474
|
}
|
|
@@ -8480,6 +8486,9 @@
|
|
|
8480
8486
|
},
|
|
8481
8487
|
{
|
|
8482
8488
|
"name": "SettleLiquidity"
|
|
8489
|
+
},
|
|
8490
|
+
{
|
|
8491
|
+
"name": "RemoveLiquidityDerisk"
|
|
8483
8492
|
}
|
|
8484
8493
|
]
|
|
8485
8494
|
}
|
|
@@ -8621,10 +8630,6 @@
|
|
|
8621
8630
|
{
|
|
8622
8631
|
"name": "Liquidation",
|
|
8623
8632
|
"fields": [
|
|
8624
|
-
{
|
|
8625
|
-
"name": "margin_buffer",
|
|
8626
|
-
"type": "u128"
|
|
8627
|
-
},
|
|
8628
8633
|
{
|
|
8629
8634
|
"name": "market_to_track_margin_requirement",
|
|
8630
8635
|
"type": {
|
package/lib/math/trade.d.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
/// <reference types="bn.js" />
|
|
2
|
-
import { PerpMarketAccount, PositionDirection, SpotMarketAccount } from '../types';
|
|
2
|
+
import { PerpMarketAccount, PositionDirection, SpotMarketAccount, UserStatsAccount } from '../types';
|
|
3
3
|
import { BN } from '@coral-xyz/anchor';
|
|
4
4
|
import { AssetType } from './amm';
|
|
5
5
|
import { OraclePriceData } from '../oracles/types';
|
|
@@ -114,3 +114,4 @@ export declare function calculateEstimatedEntryPriceWithL2(assetType: AssetType,
|
|
|
114
114
|
baseFilled: BN;
|
|
115
115
|
quoteFilled: BN;
|
|
116
116
|
};
|
|
117
|
+
export declare function getUser30dRollingVolumeEstimate(userStatsAccount: UserStatsAccount, now?: BN): BN;
|
package/lib/math/trade.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.calculateEstimatedEntryPriceWithL2 = exports.calculateEstimatedSpotEntryPrice = exports.calculateEstimatedPerpEntryPrice = exports.calculateTargetPriceTrade = exports.calculateTradeAcquiredAmounts = exports.calculateTradeSlippage = void 0;
|
|
3
|
+
exports.getUser30dRollingVolumeEstimate = exports.calculateEstimatedEntryPriceWithL2 = exports.calculateEstimatedSpotEntryPrice = exports.calculateEstimatedPerpEntryPrice = exports.calculateTargetPriceTrade = exports.calculateTradeAcquiredAmounts = exports.calculateTradeSlippage = void 0;
|
|
4
4
|
const types_1 = require("../types");
|
|
5
5
|
const anchor_1 = require("@coral-xyz/anchor");
|
|
6
6
|
const assert_1 = require("../assert/assert");
|
|
@@ -621,3 +621,17 @@ function calculateEstimatedEntryPriceWithL2(assetType, amount, direction, basePr
|
|
|
621
621
|
};
|
|
622
622
|
}
|
|
623
623
|
exports.calculateEstimatedEntryPriceWithL2 = calculateEstimatedEntryPriceWithL2;
|
|
624
|
+
function getUser30dRollingVolumeEstimate(userStatsAccount, now) {
|
|
625
|
+
now = now || new anchor_1.BN(new Date().getTime() / 1000);
|
|
626
|
+
const sinceLastTaker = anchor_1.BN.max(now.sub(userStatsAccount.lastTakerVolume30DTs), numericConstants_1.ZERO);
|
|
627
|
+
const sinceLastMaker = anchor_1.BN.max(now.sub(userStatsAccount.lastMakerVolume30DTs), numericConstants_1.ZERO);
|
|
628
|
+
const thirtyDaysInSeconds = new anchor_1.BN(60 * 60 * 24 * 30);
|
|
629
|
+
const last30dVolume = userStatsAccount.takerVolume30D
|
|
630
|
+
.mul(anchor_1.BN.max(thirtyDaysInSeconds.sub(sinceLastTaker), numericConstants_1.ZERO))
|
|
631
|
+
.div(thirtyDaysInSeconds)
|
|
632
|
+
.add(userStatsAccount.makerVolume30D
|
|
633
|
+
.mul(anchor_1.BN.max(thirtyDaysInSeconds.sub(sinceLastMaker), numericConstants_1.ZERO))
|
|
634
|
+
.div(thirtyDaysInSeconds));
|
|
635
|
+
return last30dVolume;
|
|
636
|
+
}
|
|
637
|
+
exports.getUser30dRollingVolumeEstimate = getUser30dRollingVolumeEstimate;
|
package/lib/types.d.ts
CHANGED
|
@@ -252,6 +252,9 @@ export declare class OrderActionExplanation {
|
|
|
252
252
|
static readonly REDUCE_ONLY_ORDER_INCREASED_POSITION: {
|
|
253
253
|
reduceOnlyOrderIncreasedPosition: {};
|
|
254
254
|
};
|
|
255
|
+
static readonly DERISK_LP: {
|
|
256
|
+
deriskLp: {};
|
|
257
|
+
};
|
|
255
258
|
}
|
|
256
259
|
export declare class OrderTriggerCondition {
|
|
257
260
|
static readonly ABOVE: {
|
|
@@ -293,6 +296,9 @@ export declare class DepositExplanation {
|
|
|
293
296
|
static readonly BORROW: {
|
|
294
297
|
borrow: {};
|
|
295
298
|
};
|
|
299
|
+
static readonly REPAY_BORROW: {
|
|
300
|
+
repayBorrow: {};
|
|
301
|
+
};
|
|
296
302
|
}
|
|
297
303
|
export declare class SettlePnlExplanation {
|
|
298
304
|
static readonly NONE: {
|
|
@@ -447,6 +453,9 @@ export declare class LPAction {
|
|
|
447
453
|
static readonly SETTLE_LIQUIDITY: {
|
|
448
454
|
settleLiquidity: {};
|
|
449
455
|
};
|
|
456
|
+
static readonly REMOVE_LIQUIDITY_DERISK: {
|
|
457
|
+
removeLiquidityDerisk: {};
|
|
458
|
+
};
|
|
450
459
|
}
|
|
451
460
|
export type FundingRateRecord = {
|
|
452
461
|
ts: BN;
|
package/lib/types.js
CHANGED
|
@@ -175,6 +175,9 @@ OrderActionExplanation.ORDER_FILLED_WITH_PHOENIX = {
|
|
|
175
175
|
OrderActionExplanation.REDUCE_ONLY_ORDER_INCREASED_POSITION = {
|
|
176
176
|
reduceOnlyOrderIncreasedPosition: {},
|
|
177
177
|
};
|
|
178
|
+
OrderActionExplanation.DERISK_LP = {
|
|
179
|
+
deriskLp: {},
|
|
180
|
+
};
|
|
178
181
|
class OrderTriggerCondition {
|
|
179
182
|
}
|
|
180
183
|
exports.OrderTriggerCondition = OrderTriggerCondition;
|
|
@@ -198,6 +201,7 @@ exports.DepositExplanation = DepositExplanation;
|
|
|
198
201
|
DepositExplanation.NONE = { none: {} };
|
|
199
202
|
DepositExplanation.TRANSFER = { transfer: {} };
|
|
200
203
|
DepositExplanation.BORROW = { borrow: {} };
|
|
204
|
+
DepositExplanation.REPAY_BORROW = { repayBorrow: {} };
|
|
201
205
|
class SettlePnlExplanation {
|
|
202
206
|
}
|
|
203
207
|
exports.SettlePnlExplanation = SettlePnlExplanation;
|
|
@@ -243,6 +247,7 @@ exports.LPAction = LPAction;
|
|
|
243
247
|
LPAction.ADD_LIQUIDITY = { addLiquidity: {} };
|
|
244
248
|
LPAction.REMOVE_LIQUIDITY = { removeLiquidity: {} };
|
|
245
249
|
LPAction.SETTLE_LIQUIDITY = { settleLiquidity: {} };
|
|
250
|
+
LPAction.REMOVE_LIQUIDITY_DERISK = { removeLiquidityDerisk: {} };
|
|
246
251
|
class LiquidationType {
|
|
247
252
|
}
|
|
248
253
|
exports.LiquidationType = LiquidationType;
|
package/lib/user.d.ts
CHANGED
|
@@ -111,7 +111,7 @@ export declare class User {
|
|
|
111
111
|
/**
|
|
112
112
|
* @returns The margin requirement of a certain type (Initial or Maintenance) in USDC. : QUOTE_PRECISION
|
|
113
113
|
*/
|
|
114
|
-
getMarginRequirement(marginCategory: MarginCategory, liquidationBuffer?: BN, strict?: boolean): BN;
|
|
114
|
+
getMarginRequirement(marginCategory: MarginCategory, liquidationBuffer?: BN, strict?: boolean, includeOpenOrders?: boolean): BN;
|
|
115
115
|
/**
|
|
116
116
|
* @returns The initial margin requirement in USDC. : QUOTE_PRECISION
|
|
117
117
|
*/
|
|
@@ -246,19 +246,20 @@ export declare class User {
|
|
|
246
246
|
* Calculate the liquidation price of a perp position, with optional parameter to calculate the liquidation price after a trade
|
|
247
247
|
* @param marketIndex
|
|
248
248
|
* @param positionBaseSizeChange // change in position size to calculate liquidation price for : Precision 10^13
|
|
249
|
+
* @param marginCategory // allow Initial to be passed in if we are trying to calculate price for DLP de-risking
|
|
249
250
|
* @returns Precision : PRICE_PRECISION
|
|
250
251
|
*/
|
|
251
|
-
liquidationPrice(marketIndex: number, positionBaseSizeChange?: BN, estimatedEntryPrice?: BN): BN;
|
|
252
|
+
liquidationPrice(marketIndex: number, positionBaseSizeChange?: BN, estimatedEntryPrice?: BN, marginCategory?: MarginCategory): BN;
|
|
252
253
|
calculateEntriesEffectOnFreeCollateral(market: PerpMarketAccount, oraclePrice: BN, perpPosition: PerpPosition, positionBaseSizeChange: BN, estimatedEntryPrice: BN): BN;
|
|
253
|
-
calculateFreeCollateralDeltaForPerp(market: PerpMarketAccount, perpPosition: PerpPosition, positionBaseSizeChange: BN): BN | undefined;
|
|
254
|
-
calculateFreeCollateralDeltaForSpot(market: SpotMarketAccount, signedTokenAmount: BN): BN;
|
|
254
|
+
calculateFreeCollateralDeltaForPerp(market: PerpMarketAccount, perpPosition: PerpPosition, positionBaseSizeChange: BN, marginCategory?: MarginCategory): BN | undefined;
|
|
255
|
+
calculateFreeCollateralDeltaForSpot(market: SpotMarketAccount, signedTokenAmount: BN, marginCategory?: MarginCategory): BN;
|
|
255
256
|
/**
|
|
256
257
|
* Calculates the estimated liquidation price for a position after closing a quote amount of the position.
|
|
257
258
|
* @param positionMarketIndex
|
|
258
259
|
* @param closeQuoteAmount
|
|
259
260
|
* @returns : Precision PRICE_PRECISION
|
|
260
261
|
*/
|
|
261
|
-
liquidationPriceAfterClose(positionMarketIndex: number, closeQuoteAmount: BN): BN;
|
|
262
|
+
liquidationPriceAfterClose(positionMarketIndex: number, closeQuoteAmount: BN, estimatedEntryPrice?: BN): BN;
|
|
262
263
|
/**
|
|
263
264
|
* Get the maximum trade size for a given market, taking into account the user's current leverage, positions, collateral, etc.
|
|
264
265
|
*
|
|
@@ -339,7 +340,7 @@ export declare class User {
|
|
|
339
340
|
* @returns leverageRatio : Precision TEN_THOUSAND
|
|
340
341
|
*/
|
|
341
342
|
accountLeverageRatioAfterTrade(targetMarketIndex: number, targetMarketType: MarketType, tradeQuoteAmount: BN, tradeSide: PositionDirection, includeOpenOrders?: boolean): BN;
|
|
342
|
-
getUserFeeTier(marketType: MarketType): import("./types").FeeTier;
|
|
343
|
+
getUserFeeTier(marketType: MarketType, now?: BN): import("./types").FeeTier;
|
|
343
344
|
/**
|
|
344
345
|
* Calculates taker / maker fee (as a percentage, e.g. .001 = 10 basis points) for particular marketType
|
|
345
346
|
* @param marketType
|
package/lib/user.js
CHANGED
|
@@ -432,8 +432,8 @@ class User {
|
|
|
432
432
|
/**
|
|
433
433
|
* @returns The margin requirement of a certain type (Initial or Maintenance) in USDC. : QUOTE_PRECISION
|
|
434
434
|
*/
|
|
435
|
-
getMarginRequirement(marginCategory, liquidationBuffer, strict = false) {
|
|
436
|
-
return this.getTotalPerpPositionValue(marginCategory, liquidationBuffer,
|
|
435
|
+
getMarginRequirement(marginCategory, liquidationBuffer, strict = false, includeOpenOrders = true) {
|
|
436
|
+
return this.getTotalPerpPositionValue(marginCategory, liquidationBuffer, includeOpenOrders, strict).add(this.getSpotMarketLiabilityValue(undefined, marginCategory, liquidationBuffer, includeOpenOrders, strict));
|
|
437
437
|
}
|
|
438
438
|
/**
|
|
439
439
|
* @returns The initial margin requirement in USDC. : QUOTE_PRECISION
|
|
@@ -1080,12 +1080,13 @@ class User {
|
|
|
1080
1080
|
* Calculate the liquidation price of a perp position, with optional parameter to calculate the liquidation price after a trade
|
|
1081
1081
|
* @param marketIndex
|
|
1082
1082
|
* @param positionBaseSizeChange // change in position size to calculate liquidation price for : Precision 10^13
|
|
1083
|
+
* @param marginCategory // allow Initial to be passed in if we are trying to calculate price for DLP de-risking
|
|
1083
1084
|
* @returns Precision : PRICE_PRECISION
|
|
1084
1085
|
*/
|
|
1085
|
-
liquidationPrice(marketIndex, positionBaseSizeChange = numericConstants_1.ZERO, estimatedEntryPrice = numericConstants_1.ZERO) {
|
|
1086
|
-
const totalCollateral = this.getTotalCollateral(
|
|
1087
|
-
const
|
|
1088
|
-
let freeCollateral = _1.BN.max(numericConstants_1.ZERO, totalCollateral.sub(
|
|
1086
|
+
liquidationPrice(marketIndex, positionBaseSizeChange = numericConstants_1.ZERO, estimatedEntryPrice = numericConstants_1.ZERO, marginCategory = 'Maintenance') {
|
|
1087
|
+
const totalCollateral = this.getTotalCollateral(marginCategory);
|
|
1088
|
+
const marginRequirement = this.getMarginRequirement(marginCategory, undefined, false);
|
|
1089
|
+
let freeCollateral = _1.BN.max(numericConstants_1.ZERO, totalCollateral.sub(marginRequirement));
|
|
1089
1090
|
const oracle = this.driftClient.getPerpMarketAccount(marketIndex).amm.oracle;
|
|
1090
1091
|
const oraclePrice = this.driftClient.getOracleDataForPerpMarket(marketIndex).price;
|
|
1091
1092
|
const market = this.driftClient.getPerpMarketAccount(marketIndex);
|
|
@@ -1094,7 +1095,7 @@ class User {
|
|
|
1094
1095
|
positionBaseSizeChange = (0, _1.standardizeBaseAssetAmount)(positionBaseSizeChange, market.amm.orderStepSize);
|
|
1095
1096
|
const freeCollateralChangeFromNewPosition = this.calculateEntriesEffectOnFreeCollateral(market, oraclePrice, currentPerpPosition, positionBaseSizeChange, estimatedEntryPrice);
|
|
1096
1097
|
freeCollateral = freeCollateral.add(freeCollateralChangeFromNewPosition);
|
|
1097
|
-
let freeCollateralDelta = this.calculateFreeCollateralDeltaForPerp(market, currentPerpPosition, positionBaseSizeChange);
|
|
1098
|
+
let freeCollateralDelta = this.calculateFreeCollateralDeltaForPerp(market, currentPerpPosition, positionBaseSizeChange, marginCategory);
|
|
1098
1099
|
if (!freeCollateralDelta) {
|
|
1099
1100
|
return new _1.BN(-1);
|
|
1100
1101
|
}
|
|
@@ -1105,7 +1106,7 @@ class User {
|
|
|
1105
1106
|
const spotPosition = this.getSpotPosition(spotMarketWithSameOracle.marketIndex);
|
|
1106
1107
|
if (spotPosition) {
|
|
1107
1108
|
const signedTokenAmount = (0, _1.getSignedTokenAmount)((0, spotBalance_1.getTokenAmount)(spotPosition.scaledBalance, spotMarketWithSameOracle, spotPosition.balanceType), spotPosition.balanceType);
|
|
1108
|
-
const spotFreeCollateralDelta = this.calculateFreeCollateralDeltaForSpot(spotMarketWithSameOracle, signedTokenAmount);
|
|
1109
|
+
const spotFreeCollateralDelta = this.calculateFreeCollateralDeltaForSpot(spotMarketWithSameOracle, signedTokenAmount, marginCategory);
|
|
1109
1110
|
freeCollateralDelta = freeCollateralDelta.add(spotFreeCollateralDelta || numericConstants_1.ZERO);
|
|
1110
1111
|
}
|
|
1111
1112
|
}
|
|
@@ -1135,6 +1136,8 @@ class User {
|
|
|
1135
1136
|
freeCollateralChange = costBasis.sub(newPositionValue);
|
|
1136
1137
|
}
|
|
1137
1138
|
else {
|
|
1139
|
+
console.log('newPositionValue', newPositionValue.toString());
|
|
1140
|
+
console.log('costBasis', costBasis.toString());
|
|
1138
1141
|
freeCollateralChange = newPositionValue.sub(costBasis);
|
|
1139
1142
|
}
|
|
1140
1143
|
// assume worst fee tier
|
|
@@ -1145,30 +1148,25 @@ class User {
|
|
|
1145
1148
|
freeCollateralChange = freeCollateralChange.sub(takerFee);
|
|
1146
1149
|
}
|
|
1147
1150
|
const worstCaseBaseAssetAmount = (0, margin_1.calculateWorstCaseBaseAssetAmount)(perpPosition);
|
|
1148
|
-
const marginRatioBefore = (0, _1.calculateMarketMarginRatio)(market, worstCaseBaseAssetAmount.abs(), 'Maintenance');
|
|
1149
1151
|
const newWorstCaseBaseAssetAmount = worstCaseBaseAssetAmount.add(positionBaseSizeChange);
|
|
1150
1152
|
const newMarginRatio = (0, _1.calculateMarketMarginRatio)(market, newWorstCaseBaseAssetAmount.abs(), 'Maintenance');
|
|
1151
|
-
// update free collateral to account for change in margin ratio from position change
|
|
1152
|
-
freeCollateralChange = freeCollateralChange.sub(worstCaseBaseAssetAmount
|
|
1153
|
-
.mul(oraclePrice)
|
|
1154
|
-
.div(numericConstants_1.BASE_PRECISION)
|
|
1155
|
-
.mul(new _1.BN(newMarginRatio - marginRatioBefore))
|
|
1156
|
-
.div(numericConstants_1.MARGIN_PRECISION));
|
|
1157
1153
|
// update free collateral to account for new margin requirement from position change
|
|
1158
|
-
freeCollateralChange = freeCollateralChange.sub(
|
|
1154
|
+
freeCollateralChange = freeCollateralChange.sub(newWorstCaseBaseAssetAmount
|
|
1155
|
+
.abs()
|
|
1156
|
+
.sub(worstCaseBaseAssetAmount.abs())
|
|
1159
1157
|
.mul(oraclePrice)
|
|
1160
1158
|
.div(numericConstants_1.BASE_PRECISION)
|
|
1161
1159
|
.mul(new _1.BN(newMarginRatio))
|
|
1162
1160
|
.div(numericConstants_1.MARGIN_PRECISION));
|
|
1163
1161
|
return freeCollateralChange;
|
|
1164
1162
|
}
|
|
1165
|
-
calculateFreeCollateralDeltaForPerp(market, perpPosition, positionBaseSizeChange) {
|
|
1163
|
+
calculateFreeCollateralDeltaForPerp(market, perpPosition, positionBaseSizeChange, marginCategory = 'Maintenance') {
|
|
1166
1164
|
const currentBaseAssetAmount = perpPosition.baseAssetAmount;
|
|
1167
1165
|
const worstCaseBaseAssetAmount = (0, margin_1.calculateWorstCaseBaseAssetAmount)(perpPosition);
|
|
1168
1166
|
const orderBaseAssetAmount = worstCaseBaseAssetAmount.sub(currentBaseAssetAmount);
|
|
1169
1167
|
const proposedBaseAssetAmount = currentBaseAssetAmount.add(positionBaseSizeChange);
|
|
1170
1168
|
const proposedWorstCaseBaseAssetAmount = worstCaseBaseAssetAmount.add(positionBaseSizeChange);
|
|
1171
|
-
const marginRatio = (0, _1.calculateMarketMarginRatio)(market, proposedWorstCaseBaseAssetAmount.abs(),
|
|
1169
|
+
const marginRatio = (0, _1.calculateMarketMarginRatio)(market, proposedWorstCaseBaseAssetAmount.abs(), marginCategory, this.getUserAccount().maxMarginRatio);
|
|
1172
1170
|
const marginRatioQuotePrecision = new _1.BN(marginRatio)
|
|
1173
1171
|
.mul(numericConstants_1.QUOTE_PRECISION)
|
|
1174
1172
|
.div(numericConstants_1.MARGIN_PRECISION);
|
|
@@ -1194,17 +1192,17 @@ class User {
|
|
|
1194
1192
|
}
|
|
1195
1193
|
return freeCollateralDelta;
|
|
1196
1194
|
}
|
|
1197
|
-
calculateFreeCollateralDeltaForSpot(market, signedTokenAmount) {
|
|
1195
|
+
calculateFreeCollateralDeltaForSpot(market, signedTokenAmount, marginCategory = 'Maintenance') {
|
|
1198
1196
|
const tokenPrecision = new _1.BN(Math.pow(10, market.decimals));
|
|
1199
1197
|
if (signedTokenAmount.gt(numericConstants_1.ZERO)) {
|
|
1200
|
-
const assetWeight = (0, spotBalance_1.calculateAssetWeight)(signedTokenAmount, this.driftClient.getOraclePriceDataAndSlot(market.oracle).data.price, market,
|
|
1198
|
+
const assetWeight = (0, spotBalance_1.calculateAssetWeight)(signedTokenAmount, this.driftClient.getOraclePriceDataAndSlot(market.oracle).data.price, market, marginCategory);
|
|
1201
1199
|
return numericConstants_1.QUOTE_PRECISION.mul(assetWeight)
|
|
1202
1200
|
.div(numericConstants_1.SPOT_MARKET_WEIGHT_PRECISION)
|
|
1203
1201
|
.mul(signedTokenAmount)
|
|
1204
1202
|
.div(tokenPrecision);
|
|
1205
1203
|
}
|
|
1206
1204
|
else {
|
|
1207
|
-
const liabilityWeight = (0, spotBalance_1.calculateLiabilityWeight)(signedTokenAmount.abs(), market,
|
|
1205
|
+
const liabilityWeight = (0, spotBalance_1.calculateLiabilityWeight)(signedTokenAmount.abs(), market, marginCategory);
|
|
1208
1206
|
return numericConstants_1.QUOTE_PRECISION.neg()
|
|
1209
1207
|
.mul(liabilityWeight)
|
|
1210
1208
|
.div(numericConstants_1.SPOT_MARKET_WEIGHT_PRECISION)
|
|
@@ -1218,7 +1216,7 @@ class User {
|
|
|
1218
1216
|
* @param closeQuoteAmount
|
|
1219
1217
|
* @returns : Precision PRICE_PRECISION
|
|
1220
1218
|
*/
|
|
1221
|
-
liquidationPriceAfterClose(positionMarketIndex, closeQuoteAmount) {
|
|
1219
|
+
liquidationPriceAfterClose(positionMarketIndex, closeQuoteAmount, estimatedEntryPrice = numericConstants_1.ZERO) {
|
|
1222
1220
|
const currentPosition = this.getPerpPositionWithLPSettle(positionMarketIndex, undefined, true)[0] || this.getEmptyPosition(positionMarketIndex);
|
|
1223
1221
|
const closeBaseAmount = currentPosition.baseAssetAmount
|
|
1224
1222
|
.mul(closeQuoteAmount)
|
|
@@ -1227,7 +1225,7 @@ class User {
|
|
|
1227
1225
|
.mul(closeQuoteAmount)
|
|
1228
1226
|
.mod(currentPosition.quoteAssetAmount.abs()))
|
|
1229
1227
|
.neg();
|
|
1230
|
-
return this.liquidationPrice(positionMarketIndex, closeBaseAmount);
|
|
1228
|
+
return this.liquidationPrice(positionMarketIndex, closeBaseAmount, estimatedEntryPrice);
|
|
1231
1229
|
}
|
|
1232
1230
|
/**
|
|
1233
1231
|
* Get the maximum trade size for a given market, taking into account the user's current leverage, positions, collateral, etc.
|
|
@@ -1642,14 +1640,14 @@ class User {
|
|
|
1642
1640
|
.div(netAssetValue);
|
|
1643
1641
|
return newLeverage;
|
|
1644
1642
|
}
|
|
1645
|
-
getUserFeeTier(marketType) {
|
|
1643
|
+
getUserFeeTier(marketType, now) {
|
|
1646
1644
|
const state = this.driftClient.getStateAccount();
|
|
1647
1645
|
let feeTierIndex = 0;
|
|
1648
1646
|
if ((0, types_1.isVariant)(marketType, 'perp')) {
|
|
1649
1647
|
const userStatsAccount = this.driftClient
|
|
1650
1648
|
.getUserStats()
|
|
1651
1649
|
.getAccount();
|
|
1652
|
-
const total30dVolume =
|
|
1650
|
+
const total30dVolume = (0, _1.getUser30dRollingVolumeEstimate)(userStatsAccount, now);
|
|
1653
1651
|
const stakedQuoteAssetAmount = userStatsAccount.ifStakedQuoteAssetAmount;
|
|
1654
1652
|
const volumeTiers = [
|
|
1655
1653
|
new _1.BN(100000000).mul(numericConstants_1.QUOTE_PRECISION),
|
package/package.json
CHANGED
|
@@ -42,6 +42,11 @@ export class WebSocketProgramAccountSubscriber<T>
|
|
|
42
42
|
this.program = program;
|
|
43
43
|
this.decodeBuffer = decodeBufferFn;
|
|
44
44
|
this.resubTimeoutMs = resubTimeoutMs;
|
|
45
|
+
if (this.resubTimeoutMs < 1000) {
|
|
46
|
+
console.log(
|
|
47
|
+
'resubTimeoutMs should be at least 1000ms to avoid spamming resub'
|
|
48
|
+
);
|
|
49
|
+
}
|
|
45
50
|
this.options = options;
|
|
46
51
|
this.receivingData = false;
|
|
47
52
|
}
|
|
@@ -73,6 +78,7 @@ export class WebSocketProgramAccountSubscriber<T>
|
|
|
73
78
|
);
|
|
74
79
|
|
|
75
80
|
if (this.resubTimeoutMs) {
|
|
81
|
+
this.receivingData = true;
|
|
76
82
|
this.setTimeout();
|
|
77
83
|
}
|
|
78
84
|
}
|
package/src/idl/drift.json
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
{
|
|
2
|
-
"version": "2.
|
|
2
|
+
"version": "2.60.0",
|
|
3
3
|
"name": "drift",
|
|
4
4
|
"instructions": [
|
|
5
5
|
{
|
|
@@ -8364,6 +8364,9 @@
|
|
|
8364
8364
|
},
|
|
8365
8365
|
{
|
|
8366
8366
|
"name": "Borrow"
|
|
8367
|
+
},
|
|
8368
|
+
{
|
|
8369
|
+
"name": "RepayBorrow"
|
|
8367
8370
|
}
|
|
8368
8371
|
]
|
|
8369
8372
|
}
|
|
@@ -8463,6 +8466,9 @@
|
|
|
8463
8466
|
},
|
|
8464
8467
|
{
|
|
8465
8468
|
"name": "OrderFilledWithLPJit"
|
|
8469
|
+
},
|
|
8470
|
+
{
|
|
8471
|
+
"name": "DeriskLp"
|
|
8466
8472
|
}
|
|
8467
8473
|
]
|
|
8468
8474
|
}
|
|
@@ -8480,6 +8486,9 @@
|
|
|
8480
8486
|
},
|
|
8481
8487
|
{
|
|
8482
8488
|
"name": "SettleLiquidity"
|
|
8489
|
+
},
|
|
8490
|
+
{
|
|
8491
|
+
"name": "RemoveLiquidityDerisk"
|
|
8483
8492
|
}
|
|
8484
8493
|
]
|
|
8485
8494
|
}
|
|
@@ -8621,10 +8630,6 @@
|
|
|
8621
8630
|
{
|
|
8622
8631
|
"name": "Liquidation",
|
|
8623
8632
|
"fields": [
|
|
8624
|
-
{
|
|
8625
|
-
"name": "margin_buffer",
|
|
8626
|
-
"type": "u128"
|
|
8627
|
-
},
|
|
8628
8633
|
{
|
|
8629
8634
|
"name": "market_to_track_margin_requirement",
|
|
8630
8635
|
"type": {
|
package/src/math/trade.ts
CHANGED
|
@@ -3,6 +3,7 @@ import {
|
|
|
3
3
|
PerpMarketAccount,
|
|
4
4
|
PositionDirection,
|
|
5
5
|
SpotMarketAccount,
|
|
6
|
+
UserStatsAccount,
|
|
6
7
|
} from '../types';
|
|
7
8
|
import { BN } from '@coral-xyz/anchor';
|
|
8
9
|
import { assert } from '../assert/assert';
|
|
@@ -964,3 +965,29 @@ export function calculateEstimatedEntryPriceWithL2(
|
|
|
964
965
|
quoteFilled: cumulativeQuoteFilled,
|
|
965
966
|
};
|
|
966
967
|
}
|
|
968
|
+
|
|
969
|
+
export function getUser30dRollingVolumeEstimate(
|
|
970
|
+
userStatsAccount: UserStatsAccount,
|
|
971
|
+
now?: BN
|
|
972
|
+
) {
|
|
973
|
+
now = now || new BN(new Date().getTime() / 1000);
|
|
974
|
+
const sinceLastTaker = BN.max(
|
|
975
|
+
now.sub(userStatsAccount.lastTakerVolume30DTs),
|
|
976
|
+
ZERO
|
|
977
|
+
);
|
|
978
|
+
const sinceLastMaker = BN.max(
|
|
979
|
+
now.sub(userStatsAccount.lastMakerVolume30DTs),
|
|
980
|
+
ZERO
|
|
981
|
+
);
|
|
982
|
+
const thirtyDaysInSeconds = new BN(60 * 60 * 24 * 30);
|
|
983
|
+
const last30dVolume = userStatsAccount.takerVolume30D
|
|
984
|
+
.mul(BN.max(thirtyDaysInSeconds.sub(sinceLastTaker), ZERO))
|
|
985
|
+
.div(thirtyDaysInSeconds)
|
|
986
|
+
.add(
|
|
987
|
+
userStatsAccount.makerVolume30D
|
|
988
|
+
.mul(BN.max(thirtyDaysInSeconds.sub(sinceLastMaker), ZERO))
|
|
989
|
+
.div(thirtyDaysInSeconds)
|
|
990
|
+
);
|
|
991
|
+
|
|
992
|
+
return last30dVolume;
|
|
993
|
+
}
|
package/src/types.ts
CHANGED
|
@@ -174,6 +174,9 @@ export class OrderActionExplanation {
|
|
|
174
174
|
static readonly REDUCE_ONLY_ORDER_INCREASED_POSITION = {
|
|
175
175
|
reduceOnlyOrderIncreasedPosition: {},
|
|
176
176
|
};
|
|
177
|
+
static readonly DERISK_LP = {
|
|
178
|
+
deriskLp: {},
|
|
179
|
+
};
|
|
177
180
|
}
|
|
178
181
|
|
|
179
182
|
export class OrderTriggerCondition {
|
|
@@ -197,6 +200,7 @@ export class DepositExplanation {
|
|
|
197
200
|
static readonly NONE = { none: {} };
|
|
198
201
|
static readonly TRANSFER = { transfer: {} };
|
|
199
202
|
static readonly BORROW = { borrow: {} };
|
|
203
|
+
static readonly REPAY_BORROW = { repayBorrow: {} };
|
|
200
204
|
}
|
|
201
205
|
|
|
202
206
|
export class SettlePnlExplanation {
|
|
@@ -357,6 +361,7 @@ export class LPAction {
|
|
|
357
361
|
static readonly ADD_LIQUIDITY = { addLiquidity: {} };
|
|
358
362
|
static readonly REMOVE_LIQUIDITY = { removeLiquidity: {} };
|
|
359
363
|
static readonly SETTLE_LIQUIDITY = { settleLiquidity: {} };
|
|
364
|
+
static readonly REMOVE_LIQUIDITY_DERISK = { removeLiquidityDerisk: {} };
|
|
360
365
|
}
|
|
361
366
|
|
|
362
367
|
export type FundingRateRecord = {
|
package/src/user.ts
CHANGED
|
@@ -55,6 +55,7 @@ import {
|
|
|
55
55
|
getSignedTokenAmount,
|
|
56
56
|
getStrictTokenValue,
|
|
57
57
|
getTokenValue,
|
|
58
|
+
getUser30dRollingVolumeEstimate,
|
|
58
59
|
MarketType,
|
|
59
60
|
PositionDirection,
|
|
60
61
|
sigNum,
|
|
@@ -674,19 +675,20 @@ export class User {
|
|
|
674
675
|
public getMarginRequirement(
|
|
675
676
|
marginCategory: MarginCategory,
|
|
676
677
|
liquidationBuffer?: BN,
|
|
677
|
-
strict = false
|
|
678
|
+
strict = false,
|
|
679
|
+
includeOpenOrders = true
|
|
678
680
|
): BN {
|
|
679
681
|
return this.getTotalPerpPositionValue(
|
|
680
682
|
marginCategory,
|
|
681
683
|
liquidationBuffer,
|
|
682
|
-
|
|
684
|
+
includeOpenOrders,
|
|
683
685
|
strict
|
|
684
686
|
).add(
|
|
685
687
|
this.getSpotMarketLiabilityValue(
|
|
686
688
|
undefined,
|
|
687
689
|
marginCategory,
|
|
688
690
|
liquidationBuffer,
|
|
689
|
-
|
|
691
|
+
includeOpenOrders,
|
|
690
692
|
strict
|
|
691
693
|
)
|
|
692
694
|
);
|
|
@@ -1970,19 +1972,22 @@ export class User {
|
|
|
1970
1972
|
* Calculate the liquidation price of a perp position, with optional parameter to calculate the liquidation price after a trade
|
|
1971
1973
|
* @param marketIndex
|
|
1972
1974
|
* @param positionBaseSizeChange // change in position size to calculate liquidation price for : Precision 10^13
|
|
1975
|
+
* @param marginCategory // allow Initial to be passed in if we are trying to calculate price for DLP de-risking
|
|
1973
1976
|
* @returns Precision : PRICE_PRECISION
|
|
1974
1977
|
*/
|
|
1975
1978
|
public liquidationPrice(
|
|
1976
1979
|
marketIndex: number,
|
|
1977
1980
|
positionBaseSizeChange: BN = ZERO,
|
|
1978
|
-
estimatedEntryPrice: BN = ZERO
|
|
1981
|
+
estimatedEntryPrice: BN = ZERO,
|
|
1982
|
+
marginCategory: MarginCategory = 'Maintenance'
|
|
1979
1983
|
): BN {
|
|
1980
|
-
const totalCollateral = this.getTotalCollateral(
|
|
1981
|
-
const
|
|
1982
|
-
|
|
1983
|
-
|
|
1984
|
-
|
|
1984
|
+
const totalCollateral = this.getTotalCollateral(marginCategory);
|
|
1985
|
+
const marginRequirement = this.getMarginRequirement(
|
|
1986
|
+
marginCategory,
|
|
1987
|
+
undefined,
|
|
1988
|
+
false
|
|
1985
1989
|
);
|
|
1990
|
+
let freeCollateral = BN.max(ZERO, totalCollateral.sub(marginRequirement));
|
|
1986
1991
|
|
|
1987
1992
|
const oracle =
|
|
1988
1993
|
this.driftClient.getPerpMarketAccount(marketIndex).amm.oracle;
|
|
@@ -2014,7 +2019,8 @@ export class User {
|
|
|
2014
2019
|
let freeCollateralDelta = this.calculateFreeCollateralDeltaForPerp(
|
|
2015
2020
|
market,
|
|
2016
2021
|
currentPerpPosition,
|
|
2017
|
-
positionBaseSizeChange
|
|
2022
|
+
positionBaseSizeChange,
|
|
2023
|
+
marginCategory
|
|
2018
2024
|
);
|
|
2019
2025
|
|
|
2020
2026
|
if (!freeCollateralDelta) {
|
|
@@ -2041,7 +2047,8 @@ export class User {
|
|
|
2041
2047
|
const spotFreeCollateralDelta =
|
|
2042
2048
|
this.calculateFreeCollateralDeltaForSpot(
|
|
2043
2049
|
spotMarketWithSameOracle,
|
|
2044
|
-
signedTokenAmount
|
|
2050
|
+
signedTokenAmount,
|
|
2051
|
+
marginCategory
|
|
2045
2052
|
);
|
|
2046
2053
|
freeCollateralDelta = freeCollateralDelta.add(
|
|
2047
2054
|
spotFreeCollateralDelta || ZERO
|
|
@@ -2086,6 +2093,8 @@ export class User {
|
|
|
2086
2093
|
if (positionBaseSizeChange.gt(ZERO)) {
|
|
2087
2094
|
freeCollateralChange = costBasis.sub(newPositionValue);
|
|
2088
2095
|
} else {
|
|
2096
|
+
console.log('newPositionValue', newPositionValue.toString());
|
|
2097
|
+
console.log('costBasis', costBasis.toString());
|
|
2089
2098
|
freeCollateralChange = newPositionValue.sub(costBasis);
|
|
2090
2099
|
}
|
|
2091
2100
|
|
|
@@ -2101,12 +2110,6 @@ export class User {
|
|
|
2101
2110
|
const worstCaseBaseAssetAmount =
|
|
2102
2111
|
calculateWorstCaseBaseAssetAmount(perpPosition);
|
|
2103
2112
|
|
|
2104
|
-
const marginRatioBefore = calculateMarketMarginRatio(
|
|
2105
|
-
market,
|
|
2106
|
-
worstCaseBaseAssetAmount.abs(),
|
|
2107
|
-
'Maintenance'
|
|
2108
|
-
);
|
|
2109
|
-
|
|
2110
2113
|
const newWorstCaseBaseAssetAmount = worstCaseBaseAssetAmount.add(
|
|
2111
2114
|
positionBaseSizeChange
|
|
2112
2115
|
);
|
|
@@ -2117,18 +2120,11 @@ export class User {
|
|
|
2117
2120
|
'Maintenance'
|
|
2118
2121
|
);
|
|
2119
2122
|
|
|
2120
|
-
// update free collateral to account for change in margin ratio from position change
|
|
2121
|
-
freeCollateralChange = freeCollateralChange.sub(
|
|
2122
|
-
worstCaseBaseAssetAmount
|
|
2123
|
-
.mul(oraclePrice)
|
|
2124
|
-
.div(BASE_PRECISION)
|
|
2125
|
-
.mul(new BN(newMarginRatio - marginRatioBefore))
|
|
2126
|
-
.div(MARGIN_PRECISION)
|
|
2127
|
-
);
|
|
2128
|
-
|
|
2129
2123
|
// update free collateral to account for new margin requirement from position change
|
|
2130
2124
|
freeCollateralChange = freeCollateralChange.sub(
|
|
2131
|
-
|
|
2125
|
+
newWorstCaseBaseAssetAmount
|
|
2126
|
+
.abs()
|
|
2127
|
+
.sub(worstCaseBaseAssetAmount.abs())
|
|
2132
2128
|
.mul(oraclePrice)
|
|
2133
2129
|
.div(BASE_PRECISION)
|
|
2134
2130
|
.mul(new BN(newMarginRatio))
|
|
@@ -2141,7 +2137,8 @@ export class User {
|
|
|
2141
2137
|
calculateFreeCollateralDeltaForPerp(
|
|
2142
2138
|
market: PerpMarketAccount,
|
|
2143
2139
|
perpPosition: PerpPosition,
|
|
2144
|
-
positionBaseSizeChange: BN
|
|
2140
|
+
positionBaseSizeChange: BN,
|
|
2141
|
+
marginCategory: MarginCategory = 'Maintenance'
|
|
2145
2142
|
): BN | undefined {
|
|
2146
2143
|
const currentBaseAssetAmount = perpPosition.baseAssetAmount;
|
|
2147
2144
|
|
|
@@ -2160,7 +2157,8 @@ export class User {
|
|
|
2160
2157
|
const marginRatio = calculateMarketMarginRatio(
|
|
2161
2158
|
market,
|
|
2162
2159
|
proposedWorstCaseBaseAssetAmount.abs(),
|
|
2163
|
-
|
|
2160
|
+
marginCategory,
|
|
2161
|
+
this.getUserAccount().maxMarginRatio
|
|
2164
2162
|
);
|
|
2165
2163
|
const marginRatioQuotePrecision = new BN(marginRatio)
|
|
2166
2164
|
.mul(QUOTE_PRECISION)
|
|
@@ -2195,7 +2193,8 @@ export class User {
|
|
|
2195
2193
|
|
|
2196
2194
|
calculateFreeCollateralDeltaForSpot(
|
|
2197
2195
|
market: SpotMarketAccount,
|
|
2198
|
-
signedTokenAmount: BN
|
|
2196
|
+
signedTokenAmount: BN,
|
|
2197
|
+
marginCategory: MarginCategory = 'Maintenance'
|
|
2199
2198
|
): BN {
|
|
2200
2199
|
const tokenPrecision = new BN(Math.pow(10, market.decimals));
|
|
2201
2200
|
|
|
@@ -2204,7 +2203,7 @@ export class User {
|
|
|
2204
2203
|
signedTokenAmount,
|
|
2205
2204
|
this.driftClient.getOraclePriceDataAndSlot(market.oracle).data.price,
|
|
2206
2205
|
market,
|
|
2207
|
-
|
|
2206
|
+
marginCategory
|
|
2208
2207
|
);
|
|
2209
2208
|
|
|
2210
2209
|
return QUOTE_PRECISION.mul(assetWeight)
|
|
@@ -2215,7 +2214,7 @@ export class User {
|
|
|
2215
2214
|
const liabilityWeight = calculateLiabilityWeight(
|
|
2216
2215
|
signedTokenAmount.abs(),
|
|
2217
2216
|
market,
|
|
2218
|
-
|
|
2217
|
+
marginCategory
|
|
2219
2218
|
);
|
|
2220
2219
|
|
|
2221
2220
|
return QUOTE_PRECISION.neg()
|
|
@@ -2234,7 +2233,8 @@ export class User {
|
|
|
2234
2233
|
*/
|
|
2235
2234
|
public liquidationPriceAfterClose(
|
|
2236
2235
|
positionMarketIndex: number,
|
|
2237
|
-
closeQuoteAmount: BN
|
|
2236
|
+
closeQuoteAmount: BN,
|
|
2237
|
+
estimatedEntryPrice: BN = ZERO
|
|
2238
2238
|
): BN {
|
|
2239
2239
|
const currentPosition =
|
|
2240
2240
|
this.getPerpPositionWithLPSettle(
|
|
@@ -2253,7 +2253,11 @@ export class User {
|
|
|
2253
2253
|
)
|
|
2254
2254
|
.neg();
|
|
2255
2255
|
|
|
2256
|
-
return this.liquidationPrice(
|
|
2256
|
+
return this.liquidationPrice(
|
|
2257
|
+
positionMarketIndex,
|
|
2258
|
+
closeBaseAmount,
|
|
2259
|
+
estimatedEntryPrice
|
|
2260
|
+
);
|
|
2257
2261
|
}
|
|
2258
2262
|
|
|
2259
2263
|
/**
|
|
@@ -3056,7 +3060,7 @@ export class User {
|
|
|
3056
3060
|
return newLeverage;
|
|
3057
3061
|
}
|
|
3058
3062
|
|
|
3059
|
-
public getUserFeeTier(marketType: MarketType) {
|
|
3063
|
+
public getUserFeeTier(marketType: MarketType, now?: BN) {
|
|
3060
3064
|
const state = this.driftClient.getStateAccount();
|
|
3061
3065
|
|
|
3062
3066
|
let feeTierIndex = 0;
|
|
@@ -3065,9 +3069,10 @@ export class User {
|
|
|
3065
3069
|
.getUserStats()
|
|
3066
3070
|
.getAccount();
|
|
3067
3071
|
|
|
3068
|
-
const total30dVolume =
|
|
3069
|
-
userStatsAccount
|
|
3070
|
-
|
|
3072
|
+
const total30dVolume = getUser30dRollingVolumeEstimate(
|
|
3073
|
+
userStatsAccount,
|
|
3074
|
+
now
|
|
3075
|
+
);
|
|
3071
3076
|
|
|
3072
3077
|
const stakedQuoteAssetAmount = userStatsAccount.ifStakedQuoteAssetAmount;
|
|
3073
3078
|
const volumeTiers = [
|