@drift-labs/sdk 2.13.0 → 2.14.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/lib/constants/numericConstants.d.ts +1 -0
- package/lib/constants/numericConstants.js +3 -2
- package/lib/constants/perpMarkets.js +10 -0
- package/lib/dlob/DLOB.js +1 -1
- package/lib/driftClient.d.ts +33 -33
- package/lib/driftClient.js +68 -68
- package/lib/events/types.d.ts +1 -0
- package/lib/idl/drift.json +1 -1
- package/lib/math/funding.d.ts +1 -1
- package/lib/math/funding.js +6 -6
- package/lib/math/spotBalance.js +2 -2
- package/lib/token/index.js +1 -1
- package/lib/user.d.ts +8 -9
- package/lib/user.js +108 -113
- package/package.json +3 -3
- package/src/constants/numericConstants.ts +1 -0
- package/src/constants/perpMarkets.ts +10 -0
- package/src/dlob/DLOB.ts +1 -1
- package/src/driftClient.ts +209 -68
- package/src/events/types.ts +15 -0
- package/src/idl/drift.json +1 -1
- package/src/math/funding.ts +7 -8
- package/src/math/spotBalance.ts +14 -7
- package/src/token/index.ts +1 -1
- package/src/user.ts +187 -184
package/lib/math/funding.js
CHANGED
|
@@ -12,7 +12,7 @@ const amm_1 = require("./amm");
|
|
|
12
12
|
* @param periodAdjustment
|
|
13
13
|
* @returns Estimated funding rate. : Precision //TODO-PRECISION
|
|
14
14
|
*/
|
|
15
|
-
async function calculateAllEstimatedFundingRate(market, oraclePriceData, periodAdjustment = new anchor_1.BN(1)) {
|
|
15
|
+
async function calculateAllEstimatedFundingRate(market, oraclePriceData, periodAdjustment = new anchor_1.BN(1), now) {
|
|
16
16
|
// periodAdjustment
|
|
17
17
|
// 1: hourly
|
|
18
18
|
// 24: daily
|
|
@@ -25,7 +25,7 @@ async function calculateAllEstimatedFundingRate(market, oraclePriceData, periodA
|
|
|
25
25
|
}
|
|
26
26
|
const payFreq = new anchor_1.BN(market.amm.fundingPeriod);
|
|
27
27
|
// todo: sufficiently differs from blockchain timestamp?
|
|
28
|
-
|
|
28
|
+
now = now || new anchor_1.BN((Date.now() / 1000).toFixed(0));
|
|
29
29
|
const timeSinceLastUpdate = now.sub(market.amm.lastFundingRateTs);
|
|
30
30
|
// calculate real-time mark twap
|
|
31
31
|
const lastMarkTwapWithMantissa = market.amm.lastMarkPriceTwap;
|
|
@@ -55,8 +55,8 @@ async function calculateAllEstimatedFundingRate(market, oraclePriceData, periodA
|
|
|
55
55
|
.mul(numericConstants_1.PRICE_PRECISION)
|
|
56
56
|
.mul(new anchor_1.BN(100))
|
|
57
57
|
.div(lastOracleTwapWithMantissa);
|
|
58
|
-
// verify pyth live input is within
|
|
59
|
-
if (oracleLiveVsTwap.lte(numericConstants_1.PRICE_PRECISION.mul(new anchor_1.BN(
|
|
58
|
+
// verify pyth live input is within 20% of last twap for live update
|
|
59
|
+
if (oracleLiveVsTwap.lte(numericConstants_1.PRICE_PRECISION.mul(new anchor_1.BN(20)))) {
|
|
60
60
|
oracleTwapWithMantissa = oracleTwapTimeSinceLastUpdate
|
|
61
61
|
.mul(lastOracleTwapWithMantissa)
|
|
62
62
|
.add(timeSinceLastMarkChange.mul(oraclePrice))
|
|
@@ -64,10 +64,10 @@ async function calculateAllEstimatedFundingRate(market, oraclePriceData, periodA
|
|
|
64
64
|
}
|
|
65
65
|
}
|
|
66
66
|
const shrunkLastOracleTwapwithMantissa = oracleTwapTimeSinceLastUpdate
|
|
67
|
-
.mul(
|
|
67
|
+
.mul(oracleTwapWithMantissa)
|
|
68
68
|
.add(oracleInvalidDuration.mul(lastMarkTwapWithMantissa))
|
|
69
69
|
.div(oracleTwapTimeSinceLastUpdate.add(oracleInvalidDuration));
|
|
70
|
-
const twapSpread =
|
|
70
|
+
const twapSpread = markTwapWithMantissa.sub(shrunkLastOracleTwapwithMantissa);
|
|
71
71
|
const twapSpreadPct = twapSpread
|
|
72
72
|
.mul(numericConstants_1.PRICE_PRECISION)
|
|
73
73
|
.mul(new anchor_1.BN(100))
|
package/lib/math/spotBalance.js
CHANGED
|
@@ -75,7 +75,7 @@ function calculateAssetWeight(balanceAmount, spotMarket, marginCategory) {
|
|
|
75
75
|
assetWeight = margin_1.calculateSizeDiscountAssetWeight(sizeInAmmReservePrecision, new anchor_1.BN(spotMarket.imfFactor), new anchor_1.BN(spotMarket.initialAssetWeight));
|
|
76
76
|
break;
|
|
77
77
|
case 'Maintenance':
|
|
78
|
-
assetWeight = new anchor_1.BN(spotMarket.maintenanceAssetWeight);
|
|
78
|
+
assetWeight = margin_1.calculateSizeDiscountAssetWeight(sizeInAmmReservePrecision, new anchor_1.BN(spotMarket.imfFactor), new anchor_1.BN(spotMarket.maintenanceAssetWeight));
|
|
79
79
|
break;
|
|
80
80
|
default:
|
|
81
81
|
assetWeight = new anchor_1.BN(spotMarket.initialAssetWeight);
|
|
@@ -200,7 +200,7 @@ function calculateWithdrawLimit(spotMarket, now) {
|
|
|
200
200
|
.mul(sinceStart)
|
|
201
201
|
.add(marketDepositTokenAmount.mul(sinceLast))
|
|
202
202
|
.div(sinceLast.add(sinceStart));
|
|
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
|
|
203
|
+
const maxBorrowTokens = anchor_1.BN.max(spotMarket.withdrawGuardThreshold, 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
|
|
204
204
|
const minDepositTokens = depositTokenTwapLive.sub(anchor_1.BN.min(anchor_1.BN.max(depositTokenTwapLive.div(new anchor_1.BN(5)), spotMarket.withdrawGuardThreshold), depositTokenTwapLive));
|
|
205
205
|
let withdrawLimit = anchor_1.BN.max(marketDepositTokenAmount.sub(minDepositTokens), numericConstants_1.ZERO);
|
|
206
206
|
let borrowLimit = anchor_1.BN.max(maxBorrowTokens.sub(marketBorrowTokenAmount), numericConstants_1.ZERO);
|
package/lib/token/index.js
CHANGED
|
@@ -11,7 +11,7 @@ function parseTokenAccount(data) {
|
|
|
11
11
|
if (accountInfo.delegateOption === 0) {
|
|
12
12
|
accountInfo.delegate = null;
|
|
13
13
|
// eslint-disable-next-line new-cap
|
|
14
|
-
accountInfo.delegatedAmount =
|
|
14
|
+
accountInfo.delegatedAmount = spl_token_1.u64.fromBuffer(Buffer.from('0'));
|
|
15
15
|
}
|
|
16
16
|
else {
|
|
17
17
|
accountInfo.delegate = new web3_js_1.PublicKey(accountInfo.delegate);
|
package/lib/user.d.ts
CHANGED
|
@@ -4,7 +4,7 @@ import { PublicKey } from '@solana/web3.js';
|
|
|
4
4
|
import { EventEmitter } from 'events';
|
|
5
5
|
import StrictEventEmitter from 'strict-event-emitter-types';
|
|
6
6
|
import { DriftClient } from './driftClient';
|
|
7
|
-
import { MarginCategory, Order, UserAccount, PerpPosition, SpotPosition } from './types';
|
|
7
|
+
import { MarginCategory, Order, UserAccount, PerpPosition, SpotPosition, PerpMarketAccount } from './types';
|
|
8
8
|
import { UserAccountSubscriber, UserAccountEvents, DataAndSlot } from './accounts/types';
|
|
9
9
|
import { PositionDirection, BN, SpotMarketAccount } from '.';
|
|
10
10
|
import { OraclePriceData } from './oracles/types';
|
|
@@ -168,21 +168,20 @@ export declare class User {
|
|
|
168
168
|
*/
|
|
169
169
|
needsToSettleFundingPayment(): boolean;
|
|
170
170
|
/**
|
|
171
|
-
* Calculate the liquidation price of a
|
|
172
|
-
* @param
|
|
173
|
-
* @param positionBaseSizeChange // change in position size to calculate liquidation price for : Precision 10^13
|
|
174
|
-
* @param partial
|
|
171
|
+
* Calculate the liquidation price of a spot position
|
|
172
|
+
* @param marketIndex
|
|
175
173
|
* @returns Precision : PRICE_PRECISION
|
|
176
174
|
*/
|
|
177
|
-
spotLiquidationPrice(
|
|
175
|
+
spotLiquidationPrice(marketIndex: number): BN;
|
|
178
176
|
/**
|
|
179
177
|
* Calculate the liquidation price of a perp position, with optional parameter to calculate the liquidation price after a trade
|
|
180
|
-
* @param
|
|
178
|
+
* @param marketIndex
|
|
181
179
|
* @param positionBaseSizeChange // change in position size to calculate liquidation price for : Precision 10^13
|
|
182
|
-
* @param partial
|
|
183
180
|
* @returns Precision : PRICE_PRECISION
|
|
184
181
|
*/
|
|
185
|
-
liquidationPrice(
|
|
182
|
+
liquidationPrice(marketIndex: number, positionBaseSizeChange?: BN): BN;
|
|
183
|
+
calculateFreeCollateralDeltaForPerp(market: PerpMarketAccount, perpPosition: PerpPosition, positionBaseSizeChange: BN): BN | undefined;
|
|
184
|
+
calculateFreeCollateralDeltaForSpot(market: SpotMarketAccount, signedTokenAmount: BN): BN;
|
|
186
185
|
/**
|
|
187
186
|
* Calculates the estimated liquidation price for a position after closing a quote amount of the position.
|
|
188
187
|
* @param positionMarketIndex
|
package/lib/user.js
CHANGED
|
@@ -724,139 +724,136 @@ class User {
|
|
|
724
724
|
return false;
|
|
725
725
|
}
|
|
726
726
|
/**
|
|
727
|
-
* Calculate the liquidation price of a
|
|
728
|
-
* @param
|
|
729
|
-
* @param positionBaseSizeChange // change in position size to calculate liquidation price for : Precision 10^13
|
|
730
|
-
* @param partial
|
|
727
|
+
* Calculate the liquidation price of a spot position
|
|
728
|
+
* @param marketIndex
|
|
731
729
|
* @returns Precision : PRICE_PRECISION
|
|
732
730
|
*/
|
|
733
|
-
spotLiquidationPrice(
|
|
734
|
-
const currentSpotPosition = this.getSpotPosition(
|
|
731
|
+
spotLiquidationPrice(marketIndex) {
|
|
732
|
+
const currentSpotPosition = this.getSpotPosition(marketIndex);
|
|
735
733
|
if (!currentSpotPosition) {
|
|
736
734
|
return new _1.BN(-1);
|
|
737
735
|
}
|
|
738
|
-
const
|
|
739
|
-
const
|
|
740
|
-
const
|
|
741
|
-
const
|
|
742
|
-
const
|
|
743
|
-
|
|
744
|
-
.mul(numericConstants_1.QUOTE_PRECISION)
|
|
745
|
-
.div(new _1.BN(10 ** currentSpotMarket.decimals));
|
|
746
|
-
if (tokenAmountQP.abs().eq(numericConstants_1.ZERO)) {
|
|
736
|
+
const totalCollateral = this.getTotalCollateral('Maintenance');
|
|
737
|
+
const maintenanceMarginRequirement = this.getMaintenanceMarginRequirement();
|
|
738
|
+
const freeCollateral = _1.BN.max(numericConstants_1.ZERO, totalCollateral.sub(maintenanceMarginRequirement));
|
|
739
|
+
const market = this.driftClient.getSpotMarketAccount(marketIndex);
|
|
740
|
+
const signedTokenAmount = _1.getSignedTokenAmount(spotBalance_1.getTokenAmount(currentSpotPosition.scaledBalance, market, currentSpotPosition.balanceType), currentSpotPosition.balanceType);
|
|
741
|
+
if (signedTokenAmount.eq(numericConstants_1.ZERO)) {
|
|
747
742
|
return new _1.BN(-1);
|
|
748
743
|
}
|
|
749
|
-
let
|
|
750
|
-
|
|
751
|
-
|
|
752
|
-
|
|
753
|
-
|
|
754
|
-
|
|
755
|
-
|
|
744
|
+
let freeCollateralDelta = this.calculateFreeCollateralDeltaForSpot(market, signedTokenAmount);
|
|
745
|
+
const oracle = market.oracle;
|
|
746
|
+
const perpMarketWithSameOracle = this.driftClient
|
|
747
|
+
.getPerpMarketAccounts()
|
|
748
|
+
.find((market) => market.amm.oracle.equals(oracle));
|
|
749
|
+
if (perpMarketWithSameOracle) {
|
|
750
|
+
const perpPosition = this.getPerpPosition(perpMarketWithSameOracle.marketIndex);
|
|
751
|
+
if (perpPosition) {
|
|
752
|
+
const freeCollateralDeltaForPerp = this.calculateFreeCollateralDeltaForPerp(perpMarketWithSameOracle, perpPosition, numericConstants_1.ZERO);
|
|
753
|
+
freeCollateralDelta = freeCollateralDelta.add(freeCollateralDeltaForPerp || numericConstants_1.ZERO);
|
|
754
|
+
}
|
|
756
755
|
}
|
|
757
|
-
|
|
758
|
-
|
|
759
|
-
|
|
760
|
-
|
|
761
|
-
|
|
762
|
-
|
|
763
|
-
|
|
756
|
+
if (freeCollateralDelta.eq(numericConstants_1.ZERO)) {
|
|
757
|
+
return new _1.BN(-1);
|
|
758
|
+
}
|
|
759
|
+
const oraclePrice = this.driftClient.getOracleDataForSpotMarket(marketIndex).price;
|
|
760
|
+
const liqPriceDelta = freeCollateral
|
|
761
|
+
.mul(numericConstants_1.QUOTE_PRECISION)
|
|
762
|
+
.div(freeCollateralDelta);
|
|
763
|
+
const liqPrice = oraclePrice.sub(liqPriceDelta);
|
|
764
|
+
if (liqPrice.lt(numericConstants_1.ZERO)) {
|
|
765
|
+
return new _1.BN(-1);
|
|
764
766
|
}
|
|
765
|
-
const currentPrice = this.driftClient.getOracleDataForSpotMarket(spotPosition.marketIndex).price;
|
|
766
|
-
const liqPrice = currentPrice.add(liqPriceDelta);
|
|
767
767
|
return liqPrice;
|
|
768
768
|
}
|
|
769
769
|
/**
|
|
770
770
|
* Calculate the liquidation price of a perp position, with optional parameter to calculate the liquidation price after a trade
|
|
771
|
-
* @param
|
|
771
|
+
* @param marketIndex
|
|
772
772
|
* @param positionBaseSizeChange // change in position size to calculate liquidation price for : Precision 10^13
|
|
773
|
-
* @param partial
|
|
774
773
|
* @returns Precision : PRICE_PRECISION
|
|
775
774
|
*/
|
|
776
|
-
liquidationPrice(
|
|
777
|
-
// solves formula for example canBeLiquidated below
|
|
778
|
-
/* example: assume BTC price is $40k (examine 10% up/down)
|
|
779
|
-
|
|
780
|
-
if 10k deposit and levered 10x short BTC => BTC up $400 means:
|
|
781
|
-
1. higher base_asset_value (+$4k)
|
|
782
|
-
2. lower collateral (-$4k)
|
|
783
|
-
3. (10k - 4k)/(100k + 4k) => 6k/104k => .0576
|
|
784
|
-
|
|
785
|
-
for 10x long, BTC down $400:
|
|
786
|
-
3. (10k - 4k) / (100k - 4k) = 6k/96k => .0625 */
|
|
775
|
+
liquidationPrice(marketIndex, positionBaseSizeChange = numericConstants_1.ZERO) {
|
|
787
776
|
const totalCollateral = this.getTotalCollateral('Maintenance');
|
|
788
|
-
|
|
789
|
-
const
|
|
790
|
-
const
|
|
791
|
-
|
|
792
|
-
|
|
793
|
-
|
|
794
|
-
// calculate position for current market after trade
|
|
795
|
-
const proposedPerpPosition = {
|
|
796
|
-
marketIndex: perpPosition.marketIndex,
|
|
797
|
-
baseAssetAmount: proposedBaseAssetAmount,
|
|
798
|
-
remainderBaseAssetAmount: 0,
|
|
799
|
-
quoteAssetAmount: currentPerpPosition.quoteAssetAmount,
|
|
800
|
-
lastCumulativeFundingRate: numericConstants_1.ZERO,
|
|
801
|
-
quoteBreakEvenAmount: new _1.BN(0),
|
|
802
|
-
quoteEntryAmount: new _1.BN(0),
|
|
803
|
-
openOrders: 0,
|
|
804
|
-
openBids: currentPerpPosition.openBids,
|
|
805
|
-
openAsks: currentPerpPosition.openAsks,
|
|
806
|
-
settledPnl: numericConstants_1.ZERO,
|
|
807
|
-
lpShares: numericConstants_1.ZERO,
|
|
808
|
-
lastBaseAssetAmountPerLp: numericConstants_1.ZERO,
|
|
809
|
-
lastQuoteAssetAmountPerLp: numericConstants_1.ZERO,
|
|
810
|
-
};
|
|
811
|
-
if (proposedBaseAssetAmount.eq(numericConstants_1.ZERO))
|
|
777
|
+
const maintenanceMarginRequirement = this.getMaintenanceMarginRequirement();
|
|
778
|
+
const freeCollateral = _1.BN.max(numericConstants_1.ZERO, totalCollateral.sub(maintenanceMarginRequirement));
|
|
779
|
+
const market = this.driftClient.getPerpMarketAccount(marketIndex);
|
|
780
|
+
const currentPerpPosition = this.getPerpPosition(marketIndex);
|
|
781
|
+
let freeCollateralDelta = this.calculateFreeCollateralDeltaForPerp(market, currentPerpPosition, positionBaseSizeChange);
|
|
782
|
+
if (!freeCollateralDelta) {
|
|
812
783
|
return new _1.BN(-1);
|
|
813
|
-
|
|
814
|
-
const
|
|
815
|
-
|
|
816
|
-
|
|
817
|
-
|
|
818
|
-
|
|
819
|
-
|
|
820
|
-
|
|
821
|
-
|
|
822
|
-
|
|
823
|
-
|
|
824
|
-
|
|
825
|
-
|
|
826
|
-
|
|
784
|
+
}
|
|
785
|
+
const oracle = this.driftClient.getPerpMarketAccount(marketIndex).amm.oracle;
|
|
786
|
+
const spotMarketWithSameOracle = this.driftClient
|
|
787
|
+
.getSpotMarketAccounts()
|
|
788
|
+
.find((market) => market.oracle.equals(oracle));
|
|
789
|
+
if (spotMarketWithSameOracle) {
|
|
790
|
+
const spotPosition = this.getSpotPosition(spotMarketWithSameOracle.marketIndex);
|
|
791
|
+
if (spotPosition) {
|
|
792
|
+
const signedTokenAmount = _1.getSignedTokenAmount(spotBalance_1.getTokenAmount(spotPosition.scaledBalance, spotMarketWithSameOracle, spotPosition.balanceType), spotPosition.balanceType);
|
|
793
|
+
const spotFreeCollateralDelta = this.calculateFreeCollateralDeltaForSpot(spotMarketWithSameOracle, signedTokenAmount);
|
|
794
|
+
freeCollateralDelta = freeCollateralDelta.add(spotFreeCollateralDelta || numericConstants_1.ZERO);
|
|
795
|
+
}
|
|
796
|
+
}
|
|
797
|
+
if (freeCollateralDelta.eq(numericConstants_1.ZERO)) {
|
|
827
798
|
return new _1.BN(-1);
|
|
828
799
|
}
|
|
829
|
-
const
|
|
830
|
-
const
|
|
831
|
-
.mul(
|
|
800
|
+
const oraclePrice = this.driftClient.getOracleDataForPerpMarket(marketIndex).price;
|
|
801
|
+
const liqPriceDelta = freeCollateral
|
|
802
|
+
.mul(numericConstants_1.QUOTE_PRECISION)
|
|
803
|
+
.div(freeCollateralDelta);
|
|
804
|
+
const liqPrice = oraclePrice.sub(liqPriceDelta);
|
|
805
|
+
if (liqPrice.lt(numericConstants_1.ZERO)) {
|
|
806
|
+
return new _1.BN(-1);
|
|
807
|
+
}
|
|
808
|
+
return liqPrice;
|
|
809
|
+
}
|
|
810
|
+
calculateFreeCollateralDeltaForPerp(market, perpPosition, positionBaseSizeChange) {
|
|
811
|
+
const currentBaseAssetAmount = perpPosition.baseAssetAmount;
|
|
812
|
+
const worstCaseBaseAssetAmount = margin_1.calculateWorstCaseBaseAssetAmount(perpPosition);
|
|
813
|
+
const orderBaseAssetAmount = worstCaseBaseAssetAmount.sub(currentBaseAssetAmount);
|
|
814
|
+
const proposedBaseAssetAmount = currentBaseAssetAmount.add(positionBaseSizeChange);
|
|
815
|
+
const proposedWorstCaseBaseAssetAmount = worstCaseBaseAssetAmount.add(positionBaseSizeChange);
|
|
816
|
+
const marginRatio = _1.calculateMarketMarginRatio(market, proposedWorstCaseBaseAssetAmount.abs(), 'Maintenance');
|
|
817
|
+
const marginRatioQuotePrecision = new _1.BN(marginRatio)
|
|
818
|
+
.mul(numericConstants_1.QUOTE_PRECISION)
|
|
832
819
|
.div(numericConstants_1.MARGIN_PRECISION);
|
|
833
|
-
|
|
834
|
-
|
|
835
|
-
|
|
836
|
-
|
|
837
|
-
|
|
838
|
-
|
|
839
|
-
|
|
840
|
-
.
|
|
841
|
-
.div(marketMaxMaintLeverage.add(numericConstants_1.TEN_THOUSAND))
|
|
842
|
-
.mul(numericConstants_1.PRICE_TO_QUOTE_PRECISION)
|
|
843
|
-
.mul(numericConstants_1.AMM_RESERVE_PRECISION)
|
|
844
|
-
.div(proposedBaseAssetAmount);
|
|
820
|
+
if (proposedWorstCaseBaseAssetAmount.eq(numericConstants_1.ZERO)) {
|
|
821
|
+
return undefined;
|
|
822
|
+
}
|
|
823
|
+
let freeCollateralDelta = numericConstants_1.ZERO;
|
|
824
|
+
if (proposedBaseAssetAmount.gt(numericConstants_1.ZERO)) {
|
|
825
|
+
freeCollateralDelta = numericConstants_1.QUOTE_PRECISION.sub(marginRatioQuotePrecision)
|
|
826
|
+
.mul(proposedBaseAssetAmount)
|
|
827
|
+
.div(numericConstants_1.BASE_PRECISION);
|
|
845
828
|
}
|
|
846
829
|
else {
|
|
847
|
-
|
|
848
|
-
.
|
|
849
|
-
.
|
|
850
|
-
.
|
|
851
|
-
|
|
852
|
-
|
|
853
|
-
|
|
854
|
-
|
|
855
|
-
|
|
856
|
-
|
|
857
|
-
|
|
830
|
+
freeCollateralDelta = numericConstants_1.QUOTE_PRECISION.neg()
|
|
831
|
+
.sub(marginRatioQuotePrecision)
|
|
832
|
+
.mul(proposedBaseAssetAmount.abs())
|
|
833
|
+
.div(numericConstants_1.BASE_PRECISION);
|
|
834
|
+
}
|
|
835
|
+
if (!orderBaseAssetAmount.eq(numericConstants_1.ZERO)) {
|
|
836
|
+
freeCollateralDelta = freeCollateralDelta.sub(marginRatioQuotePrecision);
|
|
837
|
+
}
|
|
838
|
+
return freeCollateralDelta;
|
|
839
|
+
}
|
|
840
|
+
calculateFreeCollateralDeltaForSpot(market, signedTokenAmount) {
|
|
841
|
+
const tokenPrecision = new _1.BN(Math.pow(10, market.decimals));
|
|
842
|
+
if (signedTokenAmount.gt(numericConstants_1.ZERO)) {
|
|
843
|
+
const assetWeight = spotBalance_1.calculateAssetWeight(signedTokenAmount, market, 'Maintenance');
|
|
844
|
+
return numericConstants_1.QUOTE_PRECISION.mul(assetWeight)
|
|
845
|
+
.div(numericConstants_1.SPOT_MARKET_WEIGHT_PRECISION)
|
|
846
|
+
.mul(signedTokenAmount)
|
|
847
|
+
.div(tokenPrecision);
|
|
848
|
+
}
|
|
849
|
+
else {
|
|
850
|
+
const liabilityWeight = spotBalance_1.calculateLiabilityWeight(signedTokenAmount.abs(), market, 'Maintenance');
|
|
851
|
+
return numericConstants_1.QUOTE_PRECISION.neg()
|
|
852
|
+
.mul(liabilityWeight)
|
|
853
|
+
.div(numericConstants_1.SPOT_MARKET_WEIGHT_PRECISION)
|
|
854
|
+
.mul(signedTokenAmount.abs())
|
|
855
|
+
.div(tokenPrecision);
|
|
858
856
|
}
|
|
859
|
-
return currentPrice.sub(priceDelta);
|
|
860
857
|
}
|
|
861
858
|
/**
|
|
862
859
|
* Calculates the estimated liquidation price for a position after closing a quote amount of the position.
|
|
@@ -874,9 +871,7 @@ class User {
|
|
|
874
871
|
.mul(closeQuoteAmount)
|
|
875
872
|
.mod(currentPosition.quoteAssetAmount.abs()))
|
|
876
873
|
.neg();
|
|
877
|
-
return this.liquidationPrice(
|
|
878
|
-
marketIndex: positionMarketIndex,
|
|
879
|
-
}, closeBaseAmount);
|
|
874
|
+
return this.liquidationPrice(positionMarketIndex, closeBaseAmount);
|
|
880
875
|
}
|
|
881
876
|
/**
|
|
882
877
|
* Get the maximum trade size for a given market, taking into account the user's current leverage, positions, collateral, etc.
|
|
@@ -1073,7 +1068,7 @@ class User {
|
|
|
1073
1068
|
return {
|
|
1074
1069
|
canBypass: false,
|
|
1075
1070
|
maxDepositAmount,
|
|
1076
|
-
depositAmount
|
|
1071
|
+
depositAmount,
|
|
1077
1072
|
netDeposits,
|
|
1078
1073
|
};
|
|
1079
1074
|
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@drift-labs/sdk",
|
|
3
|
-
"version": "2.
|
|
3
|
+
"version": "2.14.0",
|
|
4
4
|
"main": "lib/index.js",
|
|
5
5
|
"types": "lib/index.d.ts",
|
|
6
6
|
"author": "crispheaney",
|
|
@@ -37,7 +37,7 @@
|
|
|
37
37
|
"@project-serum/serum": "^0.13.38",
|
|
38
38
|
"@pythnetwork/client": "2.5.3",
|
|
39
39
|
"@solana/spl-token": "^0.1.6",
|
|
40
|
-
"@solana/web3.js": "1.
|
|
40
|
+
"@solana/web3.js": "1.73.2",
|
|
41
41
|
"strict-event-emitter-types": "^2.0.0",
|
|
42
42
|
"uuid": "^8.3.2"
|
|
43
43
|
},
|
|
@@ -59,4 +59,4 @@
|
|
|
59
59
|
"engines": {
|
|
60
60
|
"node": ">=12"
|
|
61
61
|
}
|
|
62
|
-
}
|
|
62
|
+
}
|
|
@@ -17,6 +17,7 @@ export const BN_MAX = new BN(Number.MAX_SAFE_INTEGER);
|
|
|
17
17
|
export const TEN_MILLION = TEN_THOUSAND.mul(TEN_THOUSAND);
|
|
18
18
|
|
|
19
19
|
export const MAX_LEVERAGE = new BN(5);
|
|
20
|
+
export const MAX_LEVERAGE_ORDER_SIZE = new BN('18446744073709551615');
|
|
20
21
|
|
|
21
22
|
export const PERCENTAGE_PRECISION_EXP = new BN(6);
|
|
22
23
|
export const PERCENTAGE_PRECISION = new BN(10).pow(PERCENTAGE_PRECISION_EXP);
|
|
@@ -44,6 +44,16 @@ export const DevnetPerpMarkets: PerpMarketConfig[] = [
|
|
|
44
44
|
launchTs: 1637691133472,
|
|
45
45
|
oracleSource: OracleSource.PYTH,
|
|
46
46
|
},
|
|
47
|
+
{
|
|
48
|
+
fullName: 'Aptos',
|
|
49
|
+
category: ['L1', 'Infra'],
|
|
50
|
+
symbol: 'APT-PERP',
|
|
51
|
+
baseAssetSymbol: 'APT',
|
|
52
|
+
marketIndex: 3,
|
|
53
|
+
oracle: new PublicKey('5d2QJ6u2NveZufmJ4noHja5EHs3Bv1DUMPLG5xfasSVs'),
|
|
54
|
+
launchTs: 1675610186000,
|
|
55
|
+
oracleSource: OracleSource.PYTH,
|
|
56
|
+
},
|
|
47
57
|
];
|
|
48
58
|
|
|
49
59
|
export const MainnetPerpMarkets: PerpMarketConfig[] = [
|
package/src/dlob/DLOB.ts
CHANGED
|
@@ -951,7 +951,7 @@ export class DLOB {
|
|
|
951
951
|
}
|
|
952
952
|
|
|
953
953
|
isRestingLimitOrder(order: Order, slot: number): boolean {
|
|
954
|
-
return order.postOnly || new BN(slot).sub(order.slot).gte(new BN(
|
|
954
|
+
return order.postOnly || new BN(slot).sub(order.slot).gte(new BN(45));
|
|
955
955
|
}
|
|
956
956
|
|
|
957
957
|
*getLimitBids(
|