@drift-labs/sdk 2.38.1-beta.7 → 2.38.1-beta.9

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.
@@ -1,22 +1,38 @@
1
- import { SpotMarketAccount, SpotPosition } from '../types';
2
- import { ZERO } from '../constants/numericConstants';
1
+ import { MarginCategory, SpotMarketAccount, SpotPosition } from '../types';
2
+ import {
3
+ SPOT_MARKET_WEIGHT_PRECISION,
4
+ ZERO,
5
+ } from '../constants/numericConstants';
3
6
  import { BN } from '@coral-xyz/anchor';
4
7
  import {
8
+ calculateAssetWeight,
9
+ calculateLiabilityWeight,
5
10
  getSignedTokenAmount,
11
+ getStrictTokenValue,
6
12
  getTokenAmount,
7
13
  getTokenValue,
8
14
  } from './spotBalance';
9
- import { OraclePriceData } from '../oracles/types';
15
+ import { StrictOraclePrice } from '../oracles/strictOraclePrice';
10
16
 
11
17
  export function isSpotPositionAvailable(position: SpotPosition): boolean {
12
18
  return position.scaledBalance.eq(ZERO) && position.openOrders === 0;
13
19
  }
14
20
 
21
+ export type OrderFillSimulation = {
22
+ tokenAmount: BN;
23
+ ordersValue: BN;
24
+ tokenValue: BN;
25
+ weight: BN;
26
+ weightedTokenValue: BN;
27
+ freeCollateralContribution;
28
+ };
29
+
15
30
  export function getWorstCaseTokenAmounts(
16
31
  spotPosition: SpotPosition,
17
32
  spotMarketAccount: SpotMarketAccount,
18
- oraclePriceData: OraclePriceData
19
- ): [BN, BN] {
33
+ strictOraclePrice: StrictOraclePrice,
34
+ marginCategory: MarginCategory
35
+ ): OrderFillSimulation {
20
36
  const tokenAmount = getSignedTokenAmount(
21
37
  getTokenAmount(
22
38
  spotPosition.scaledBalance,
@@ -26,22 +42,121 @@ export function getWorstCaseTokenAmounts(
26
42
  spotPosition.balanceType
27
43
  );
28
44
 
29
- const tokenAmountAllBidsFill = tokenAmount.add(spotPosition.openBids);
30
- const tokenAmountAllAsksFill = tokenAmount.add(spotPosition.openAsks);
45
+ const tokenValue = getStrictTokenValue(
46
+ tokenAmount,
47
+ spotMarketAccount.decimals,
48
+ strictOraclePrice
49
+ );
31
50
 
32
- if (tokenAmountAllBidsFill.abs().gt(tokenAmountAllAsksFill.abs())) {
33
- const worstCaseQuoteTokenAmount = getTokenValue(
34
- spotPosition.openBids.neg(),
35
- spotMarketAccount.decimals,
36
- oraclePriceData
51
+ if (spotPosition.openBids.eq(ZERO) && spotPosition.openAsks.eq(ZERO)) {
52
+ const { weight, weightedTokenValue } = calculateWeightedTokenValue(
53
+ tokenAmount,
54
+ tokenValue,
55
+ strictOraclePrice.current,
56
+ spotMarketAccount,
57
+ marginCategory
37
58
  );
38
- return [tokenAmountAllBidsFill, worstCaseQuoteTokenAmount];
59
+ return {
60
+ tokenAmount,
61
+ ordersValue: ZERO,
62
+ tokenValue,
63
+ weight,
64
+ weightedTokenValue,
65
+ freeCollateralContribution: weightedTokenValue,
66
+ };
67
+ }
68
+
69
+ const bidsSimulation = simulateOrderFill(
70
+ tokenAmount,
71
+ tokenValue,
72
+ spotPosition.openBids,
73
+ strictOraclePrice,
74
+ spotMarketAccount,
75
+ marginCategory
76
+ );
77
+ const asksSimulation = simulateOrderFill(
78
+ tokenAmount,
79
+ tokenValue,
80
+ spotPosition.openAsks,
81
+ strictOraclePrice,
82
+ spotMarketAccount,
83
+ marginCategory
84
+ );
85
+
86
+ if (
87
+ asksSimulation.freeCollateralContribution.lt(
88
+ bidsSimulation.freeCollateralContribution
89
+ )
90
+ ) {
91
+ return asksSimulation;
39
92
  } else {
40
- const worstCaseQuoteTokenAmount = getTokenValue(
41
- spotPosition.openAsks.neg(),
42
- spotMarketAccount.decimals,
43
- oraclePriceData
93
+ return bidsSimulation;
94
+ }
95
+ }
96
+
97
+ export function calculateWeightedTokenValue(
98
+ tokenAmount: BN,
99
+ tokenValue: BN,
100
+ oraclePrice: BN,
101
+ spotMarket: SpotMarketAccount,
102
+ marginCategory: MarginCategory
103
+ ): { weight: BN; weightedTokenValue: BN } {
104
+ let weight: BN;
105
+ if (tokenValue.gte(ZERO)) {
106
+ weight = calculateAssetWeight(
107
+ tokenAmount,
108
+ oraclePrice,
109
+ spotMarket,
110
+ marginCategory
111
+ );
112
+ } else {
113
+ weight = calculateLiabilityWeight(
114
+ tokenAmount.abs(),
115
+ spotMarket,
116
+ marginCategory
44
117
  );
45
- return [tokenAmountAllAsksFill, worstCaseQuoteTokenAmount];
46
118
  }
119
+
120
+ return {
121
+ weight: weight,
122
+ weightedTokenValue: tokenValue
123
+ .mul(weight)
124
+ .div(SPOT_MARKET_WEIGHT_PRECISION),
125
+ };
126
+ }
127
+
128
+ export function simulateOrderFill(
129
+ tokenAmount: BN,
130
+ tokenValue: BN,
131
+ openOrders: BN,
132
+ strictOraclePrice: StrictOraclePrice,
133
+ spotMarket: SpotMarketAccount,
134
+ marginCategory: MarginCategory
135
+ ): OrderFillSimulation {
136
+ const ordersValue = getTokenValue(openOrders.neg(), spotMarket.decimals, {
137
+ price: strictOraclePrice.max(),
138
+ });
139
+ const tokenAmountAfterFill = tokenAmount.add(openOrders);
140
+ const tokenValueAfterFill = tokenValue.add(ordersValue.neg());
141
+
142
+ const { weight, weightedTokenValue: weightedTokenValueAfterFill } =
143
+ calculateWeightedTokenValue(
144
+ tokenAmountAfterFill,
145
+ tokenValueAfterFill,
146
+ strictOraclePrice.current,
147
+ spotMarket,
148
+ marginCategory
149
+ );
150
+
151
+ const freeCollateralContribution =
152
+ weightedTokenValueAfterFill.add(ordersValue);
153
+
154
+ return {
155
+ tokenAmount: tokenAmountAfterFill,
156
+ ordersValue: ordersValue,
157
+ tokenValue: tokenValueAfterFill,
158
+ weight,
159
+ weightedTokenValue: weightedTokenValueAfterFill,
160
+ freeCollateralContribution,
161
+ };
47
162
  }
@@ -0,0 +1,19 @@
1
+ import { BN } from '@coral-xyz/anchor';
2
+
3
+ export class StrictOraclePrice {
4
+ current: BN;
5
+ twap?: BN;
6
+
7
+ constructor(current: BN, twap?: BN) {
8
+ this.current = current;
9
+ this.twap = twap;
10
+ }
11
+
12
+ public max(): BN {
13
+ return this.twap ? BN.max(this.twap, this.current) : this.current;
14
+ }
15
+
16
+ public min(): BN {
17
+ return this.twap ? BN.min(this.twap, this.current) : this.current;
18
+ }
19
+ }
package/src/types.ts CHANGED
@@ -155,6 +155,9 @@ export class OrderActionExplanation {
155
155
  static readonly ORDER_FILLED_WITH_SERUM = {
156
156
  orderFillWithSerum: {},
157
157
  };
158
+ static readonly ORDER_FILLED_WITH_PHOENIX = {
159
+ orderFillWithPhoenix: {},
160
+ };
158
161
  static readonly REDUCE_ONLY_ORDER_INCREASED_POSITION = {
159
162
  reduceOnlyOrderIncreasedPosition: {},
160
163
  };
@@ -652,6 +655,7 @@ export type SpotMarketAccount = {
652
655
  maintenanceLiabilityWeight: number;
653
656
  liquidatorFee: number;
654
657
  imfFactor: number;
658
+ scaleInitialAssetWeightStart: BN;
655
659
 
656
660
  withdrawGuardThreshold: BN;
657
661
  depositTokenTwap: BN;