@drift-labs/sdk 2.38.1-beta.8 → 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.
- package/VERSION +1 -1
- package/lib/adminClient.d.ts +1 -0
- package/lib/adminClient.js +11 -0
- package/lib/idl/drift.json +36 -1
- package/lib/index.d.ts +2 -0
- package/lib/index.js +2 -0
- package/lib/math/spotBalance.d.ts +6 -5
- package/lib/math/spotBalance.js +28 -11
- package/lib/math/spotMarket.d.ts +1 -1
- package/lib/math/spotMarket.js +2 -2
- package/lib/math/spotPosition.d.ts +16 -3
- package/lib/math/spotPosition.js +53 -9
- package/lib/oracles/strictOraclePrice.d.ts +8 -0
- package/lib/oracles/strictOraclePrice.js +17 -0
- package/lib/types.d.ts +1 -0
- package/lib/user.d.ts +5 -4
- package/lib/user.js +71 -105
- package/package.json +1 -1
- package/src/adminClient.ts +23 -0
- package/src/idl/drift.json +36 -1
- package/src/index.ts +2 -0
- package/src/math/spotBalance.ts +37 -11
- package/src/math/spotMarket.ts +7 -1
- package/src/math/spotPosition.ts +133 -18
- package/src/oracles/strictOraclePrice.ts +19 -0
- package/src/types.ts +1 -0
- package/src/user.ts +171 -228
- package/tests/dlob/helpers.ts +10 -7
- package/tests/user/test.ts +77 -4
package/src/math/spotPosition.ts
CHANGED
|
@@ -1,22 +1,38 @@
|
|
|
1
|
-
import { SpotMarketAccount, SpotPosition } from '../types';
|
|
2
|
-
import {
|
|
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 {
|
|
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
|
-
|
|
19
|
-
|
|
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
|
|
30
|
-
|
|
45
|
+
const tokenValue = getStrictTokenValue(
|
|
46
|
+
tokenAmount,
|
|
47
|
+
spotMarketAccount.decimals,
|
|
48
|
+
strictOraclePrice
|
|
49
|
+
);
|
|
31
50
|
|
|
32
|
-
if (
|
|
33
|
-
const
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
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
|
|
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
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
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
|
+
}
|