@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.
- 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 +4 -0
- package/lib/types.js +3 -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 +4 -0
- package/src/user.ts +171 -228
- package/tests/dlob/helpers.ts +10 -7
- package/tests/user/test.ts +77 -4
package/src/user.ts
CHANGED
|
@@ -73,12 +73,14 @@ import { UserConfig } from './userConfig';
|
|
|
73
73
|
import { PollingUserAccountSubscriber } from './accounts/pollingUserAccountSubscriber';
|
|
74
74
|
import { WebSocketUserAccountSubscriber } from './accounts/webSocketUserAccountSubscriber';
|
|
75
75
|
import {
|
|
76
|
+
calculateWeightedTokenValue,
|
|
76
77
|
getWorstCaseTokenAmounts,
|
|
77
78
|
isSpotPositionAvailable,
|
|
78
79
|
} from './math/spotPosition';
|
|
79
80
|
|
|
80
81
|
import { calculateLiveOracleTwap } from './math/oracles';
|
|
81
82
|
import { getPerpMarketTierNumber, getSpotMarketTierNumber } from './math/tiers';
|
|
83
|
+
import { StrictOraclePrice } from './oracles/strictOraclePrice';
|
|
82
84
|
|
|
83
85
|
export class User {
|
|
84
86
|
driftClient: DriftClient;
|
|
@@ -869,6 +871,20 @@ export class User {
|
|
|
869
871
|
spotPosition.marketIndex
|
|
870
872
|
);
|
|
871
873
|
|
|
874
|
+
let twap5min;
|
|
875
|
+
if (strict) {
|
|
876
|
+
twap5min = calculateLiveOracleTwap(
|
|
877
|
+
spotMarketAccount.historicalOracleData,
|
|
878
|
+
oraclePriceData,
|
|
879
|
+
now,
|
|
880
|
+
FIVE_MINUTE // 5MIN
|
|
881
|
+
);
|
|
882
|
+
}
|
|
883
|
+
const strictOraclePrice = new StrictOraclePrice(
|
|
884
|
+
oraclePriceData.price,
|
|
885
|
+
twap5min
|
|
886
|
+
);
|
|
887
|
+
|
|
872
888
|
if (
|
|
873
889
|
spotPosition.marketIndex === QUOTE_SPOT_MARKET_INDEX &&
|
|
874
890
|
countForQuote
|
|
@@ -885,23 +901,19 @@ export class User {
|
|
|
885
901
|
if (isVariant(spotPosition.balanceType, 'borrow')) {
|
|
886
902
|
const weightedTokenValue = this.getSpotLiabilityValue(
|
|
887
903
|
tokenAmount,
|
|
888
|
-
|
|
904
|
+
strictOraclePrice,
|
|
889
905
|
spotMarketAccount,
|
|
890
906
|
marginCategory,
|
|
891
|
-
liquidationBuffer
|
|
892
|
-
strict,
|
|
893
|
-
now
|
|
907
|
+
liquidationBuffer
|
|
894
908
|
).abs();
|
|
895
909
|
|
|
896
910
|
netQuoteValue = netQuoteValue.sub(weightedTokenValue);
|
|
897
911
|
} else {
|
|
898
912
|
const weightedTokenValue = this.getSpotAssetValue(
|
|
899
913
|
tokenAmount,
|
|
900
|
-
|
|
914
|
+
strictOraclePrice,
|
|
901
915
|
spotMarketAccount,
|
|
902
|
-
marginCategory
|
|
903
|
-
strict,
|
|
904
|
-
now
|
|
916
|
+
marginCategory
|
|
905
917
|
);
|
|
906
918
|
|
|
907
919
|
netQuoteValue = netQuoteValue.add(weightedTokenValue);
|
|
@@ -922,12 +934,10 @@ export class User {
|
|
|
922
934
|
);
|
|
923
935
|
const liabilityValue = this.getSpotLiabilityValue(
|
|
924
936
|
tokenAmount,
|
|
925
|
-
|
|
937
|
+
strictOraclePrice,
|
|
926
938
|
spotMarketAccount,
|
|
927
939
|
marginCategory,
|
|
928
|
-
liquidationBuffer
|
|
929
|
-
strict,
|
|
930
|
-
now
|
|
940
|
+
liquidationBuffer
|
|
931
941
|
).abs();
|
|
932
942
|
totalLiabilityValue = totalLiabilityValue.add(liabilityValue);
|
|
933
943
|
|
|
@@ -940,11 +950,9 @@ export class User {
|
|
|
940
950
|
);
|
|
941
951
|
const assetValue = this.getSpotAssetValue(
|
|
942
952
|
tokenAmount,
|
|
943
|
-
|
|
953
|
+
strictOraclePrice,
|
|
944
954
|
spotMarketAccount,
|
|
945
|
-
marginCategory
|
|
946
|
-
strict,
|
|
947
|
-
now
|
|
955
|
+
marginCategory
|
|
948
956
|
);
|
|
949
957
|
totalAssetValue = totalAssetValue.add(assetValue);
|
|
950
958
|
|
|
@@ -952,21 +960,22 @@ export class User {
|
|
|
952
960
|
}
|
|
953
961
|
}
|
|
954
962
|
|
|
955
|
-
const
|
|
956
|
-
|
|
957
|
-
|
|
958
|
-
|
|
959
|
-
|
|
960
|
-
|
|
963
|
+
const {
|
|
964
|
+
tokenAmount: worstCaseTokenAmount,
|
|
965
|
+
ordersValue: worstCaseQuoteTokenAmount,
|
|
966
|
+
} = getWorstCaseTokenAmounts(
|
|
967
|
+
spotPosition,
|
|
968
|
+
spotMarketAccount,
|
|
969
|
+
strictOraclePrice,
|
|
970
|
+
marginCategory
|
|
971
|
+
);
|
|
961
972
|
|
|
962
973
|
if (worstCaseTokenAmount.gt(ZERO) && countForBase) {
|
|
963
974
|
const baseAssetValue = this.getSpotAssetValue(
|
|
964
975
|
worstCaseTokenAmount,
|
|
965
|
-
|
|
976
|
+
strictOraclePrice,
|
|
966
977
|
spotMarketAccount,
|
|
967
|
-
marginCategory
|
|
968
|
-
strict,
|
|
969
|
-
now
|
|
978
|
+
marginCategory
|
|
970
979
|
);
|
|
971
980
|
|
|
972
981
|
totalAssetValue = totalAssetValue.add(baseAssetValue);
|
|
@@ -975,12 +984,10 @@ export class User {
|
|
|
975
984
|
if (worstCaseTokenAmount.lt(ZERO) && countForBase) {
|
|
976
985
|
const baseLiabilityValue = this.getSpotLiabilityValue(
|
|
977
986
|
worstCaseTokenAmount,
|
|
978
|
-
|
|
987
|
+
strictOraclePrice,
|
|
979
988
|
spotMarketAccount,
|
|
980
989
|
marginCategory,
|
|
981
|
-
liquidationBuffer
|
|
982
|
-
strict,
|
|
983
|
-
now
|
|
990
|
+
liquidationBuffer
|
|
984
991
|
).abs();
|
|
985
992
|
|
|
986
993
|
totalLiabilityValue = totalLiabilityValue.add(baseLiabilityValue);
|
|
@@ -1041,35 +1048,16 @@ export class User {
|
|
|
1041
1048
|
|
|
1042
1049
|
getSpotLiabilityValue(
|
|
1043
1050
|
tokenAmount: BN,
|
|
1044
|
-
|
|
1051
|
+
strictOraclePrice: StrictOraclePrice,
|
|
1045
1052
|
spotMarketAccount: SpotMarketAccount,
|
|
1046
1053
|
marginCategory?: MarginCategory,
|
|
1047
|
-
liquidationBuffer?: BN
|
|
1048
|
-
strict = false,
|
|
1049
|
-
now?: BN
|
|
1054
|
+
liquidationBuffer?: BN
|
|
1050
1055
|
): BN {
|
|
1051
|
-
let liabilityValue =
|
|
1052
|
-
|
|
1053
|
-
|
|
1054
|
-
|
|
1055
|
-
|
|
1056
|
-
oraclePriceData,
|
|
1057
|
-
now,
|
|
1058
|
-
FIVE_MINUTE // 5MIN
|
|
1059
|
-
);
|
|
1060
|
-
liabilityValue = getStrictTokenValue(
|
|
1061
|
-
tokenAmount,
|
|
1062
|
-
spotMarketAccount.decimals,
|
|
1063
|
-
oraclePriceData,
|
|
1064
|
-
estOracleTwap
|
|
1065
|
-
);
|
|
1066
|
-
} else {
|
|
1067
|
-
liabilityValue = getTokenValue(
|
|
1068
|
-
tokenAmount,
|
|
1069
|
-
spotMarketAccount.decimals,
|
|
1070
|
-
oraclePriceData
|
|
1071
|
-
);
|
|
1072
|
-
}
|
|
1056
|
+
let liabilityValue = getStrictTokenValue(
|
|
1057
|
+
tokenAmount,
|
|
1058
|
+
spotMarketAccount.decimals,
|
|
1059
|
+
strictOraclePrice
|
|
1060
|
+
);
|
|
1073
1061
|
|
|
1074
1062
|
if (marginCategory !== undefined) {
|
|
1075
1063
|
let weight = calculateLiabilityWeight(
|
|
@@ -1114,37 +1102,20 @@ export class User {
|
|
|
1114
1102
|
|
|
1115
1103
|
getSpotAssetValue(
|
|
1116
1104
|
tokenAmount: BN,
|
|
1117
|
-
|
|
1105
|
+
strictOraclePrice: StrictOraclePrice,
|
|
1118
1106
|
spotMarketAccount: SpotMarketAccount,
|
|
1119
|
-
marginCategory?: MarginCategory
|
|
1120
|
-
strict = false,
|
|
1121
|
-
now?: BN
|
|
1107
|
+
marginCategory?: MarginCategory
|
|
1122
1108
|
): BN {
|
|
1123
|
-
let assetValue =
|
|
1124
|
-
|
|
1125
|
-
|
|
1126
|
-
|
|
1127
|
-
|
|
1128
|
-
now,
|
|
1129
|
-
FIVE_MINUTE // 5MIN
|
|
1130
|
-
);
|
|
1131
|
-
assetValue = getStrictTokenValue(
|
|
1132
|
-
tokenAmount,
|
|
1133
|
-
spotMarketAccount.decimals,
|
|
1134
|
-
oraclePriceData,
|
|
1135
|
-
estOracleTwap
|
|
1136
|
-
);
|
|
1137
|
-
} else {
|
|
1138
|
-
assetValue = getTokenValue(
|
|
1139
|
-
tokenAmount,
|
|
1140
|
-
spotMarketAccount.decimals,
|
|
1141
|
-
oraclePriceData
|
|
1142
|
-
);
|
|
1143
|
-
}
|
|
1109
|
+
let assetValue = getStrictTokenValue(
|
|
1110
|
+
tokenAmount,
|
|
1111
|
+
spotMarketAccount.decimals,
|
|
1112
|
+
strictOraclePrice
|
|
1113
|
+
);
|
|
1144
1114
|
|
|
1145
1115
|
if (marginCategory !== undefined) {
|
|
1146
1116
|
const weight = calculateAssetWeight(
|
|
1147
1117
|
tokenAmount,
|
|
1118
|
+
strictOraclePrice.current,
|
|
1148
1119
|
spotMarketAccount,
|
|
1149
1120
|
marginCategory
|
|
1150
1121
|
);
|
|
@@ -2092,6 +2063,7 @@ export class User {
|
|
|
2092
2063
|
if (signedTokenAmount.gt(ZERO)) {
|
|
2093
2064
|
const assetWeight = calculateAssetWeight(
|
|
2094
2065
|
signedTokenAmount,
|
|
2066
|
+
this.driftClient.getOraclePriceDataAndSlot(market.oracle).data.price,
|
|
2095
2067
|
market,
|
|
2096
2068
|
'Maintenance'
|
|
2097
2069
|
);
|
|
@@ -2268,6 +2240,9 @@ export class User {
|
|
|
2268
2240
|
currentSpotMarketNetValue?: BN
|
|
2269
2241
|
): BN {
|
|
2270
2242
|
const market = this.driftClient.getSpotMarketAccount(targetMarketIndex);
|
|
2243
|
+
const oraclePrice = this.driftClient.getOraclePriceDataAndSlot(
|
|
2244
|
+
market.oracle
|
|
2245
|
+
).data.price;
|
|
2271
2246
|
|
|
2272
2247
|
currentQuoteAssetValue = this.getSpotMarketAssetValue(
|
|
2273
2248
|
QUOTE_SPOT_MARKET_INDEX
|
|
@@ -2279,6 +2254,7 @@ export class User {
|
|
|
2279
2254
|
let freeCollateral = this.getFreeCollateral();
|
|
2280
2255
|
const marginRatio = calculateSpotMarketMarginRatio(
|
|
2281
2256
|
market,
|
|
2257
|
+
oraclePrice,
|
|
2282
2258
|
'Initial',
|
|
2283
2259
|
ZERO,
|
|
2284
2260
|
isVariant(direction, 'long')
|
|
@@ -2293,6 +2269,7 @@ export class User {
|
|
|
2293
2269
|
tradeAmount = currentSpotMarketNetValue.abs();
|
|
2294
2270
|
const marginRatio = calculateSpotMarketMarginRatio(
|
|
2295
2271
|
market,
|
|
2272
|
+
oraclePrice,
|
|
2296
2273
|
'Initial',
|
|
2297
2274
|
this.getTokenAmount(targetMarketIndex).abs(),
|
|
2298
2275
|
SpotBalanceType.BORROW
|
|
@@ -2307,6 +2284,7 @@ export class User {
|
|
|
2307
2284
|
tradeAmount = currentSpotMarketNetValue;
|
|
2308
2285
|
const marginRatio = calculateSpotMarketMarginRatio(
|
|
2309
2286
|
market,
|
|
2287
|
+
oraclePrice,
|
|
2310
2288
|
'Initial',
|
|
2311
2289
|
this.getTokenAmount(targetMarketIndex),
|
|
2312
2290
|
SpotBalanceType.DEPOSIT
|
|
@@ -2354,9 +2332,13 @@ export class User {
|
|
|
2354
2332
|
const inMarket = this.driftClient.getSpotMarketAccount(inMarketIndex);
|
|
2355
2333
|
const outMarket = this.driftClient.getSpotMarketAccount(outMarketIndex);
|
|
2356
2334
|
|
|
2357
|
-
const
|
|
2358
|
-
const
|
|
2359
|
-
|
|
2335
|
+
const inOraclePriceData = this.getOracleDataForSpotMarket(inMarketIndex);
|
|
2336
|
+
const inOraclePrice = inOraclePriceData.price;
|
|
2337
|
+
const outOraclePriceData = this.getOracleDataForSpotMarket(outMarketIndex);
|
|
2338
|
+
const outOraclePrice = outOraclePriceData.price;
|
|
2339
|
+
|
|
2340
|
+
const inStrictOraclePrice = new StrictOraclePrice(inOraclePrice);
|
|
2341
|
+
const outStrictOraclePrice = new StrictOraclePrice(outOraclePrice);
|
|
2360
2342
|
|
|
2361
2343
|
const inPrecision = new BN(10 ** inMarket.decimals);
|
|
2362
2344
|
const outPrecision = new BN(10 ** outMarket.decimals);
|
|
@@ -2371,17 +2353,29 @@ export class User {
|
|
|
2371
2353
|
const freeCollateral = this.getFreeCollateral();
|
|
2372
2354
|
|
|
2373
2355
|
const inContributionInitial =
|
|
2374
|
-
this.calculateSpotPositionFreeCollateralContribution(
|
|
2356
|
+
this.calculateSpotPositionFreeCollateralContribution(
|
|
2357
|
+
inSpotPosition,
|
|
2358
|
+
inStrictOraclePrice
|
|
2359
|
+
);
|
|
2375
2360
|
const {
|
|
2376
2361
|
totalAssetValue: inTotalAssetValueInitial,
|
|
2377
2362
|
totalLiabilityValue: inTotalLiabilityValueInitial,
|
|
2378
|
-
} = this.calculateSpotPositionLeverageContribution(
|
|
2363
|
+
} = this.calculateSpotPositionLeverageContribution(
|
|
2364
|
+
inSpotPosition,
|
|
2365
|
+
inStrictOraclePrice
|
|
2366
|
+
);
|
|
2379
2367
|
const outContributionInitial =
|
|
2380
|
-
this.calculateSpotPositionFreeCollateralContribution(
|
|
2368
|
+
this.calculateSpotPositionFreeCollateralContribution(
|
|
2369
|
+
outSpotPosition,
|
|
2370
|
+
outStrictOraclePrice
|
|
2371
|
+
);
|
|
2381
2372
|
const {
|
|
2382
2373
|
totalAssetValue: outTotalAssetValueInitial,
|
|
2383
2374
|
totalLiabilityValue: outTotalLiabilityValueInitial,
|
|
2384
|
-
} = this.calculateSpotPositionLeverageContribution(
|
|
2375
|
+
} = this.calculateSpotPositionLeverageContribution(
|
|
2376
|
+
outSpotPosition,
|
|
2377
|
+
outStrictOraclePrice
|
|
2378
|
+
);
|
|
2385
2379
|
const initialContribution = inContributionInitial.add(
|
|
2386
2380
|
outContributionInitial
|
|
2387
2381
|
);
|
|
@@ -2441,10 +2435,14 @@ export class User {
|
|
|
2441
2435
|
);
|
|
2442
2436
|
|
|
2443
2437
|
const inContributionAfter =
|
|
2444
|
-
this.calculateSpotPositionFreeCollateralContribution(
|
|
2438
|
+
this.calculateSpotPositionFreeCollateralContribution(
|
|
2439
|
+
inPositionAfter,
|
|
2440
|
+
inStrictOraclePrice
|
|
2441
|
+
);
|
|
2445
2442
|
const outContributionAfter =
|
|
2446
2443
|
this.calculateSpotPositionFreeCollateralContribution(
|
|
2447
|
-
outPositionAfter
|
|
2444
|
+
outPositionAfter,
|
|
2445
|
+
outStrictOraclePrice
|
|
2448
2446
|
);
|
|
2449
2447
|
|
|
2450
2448
|
const contributionAfter = inContributionAfter.add(outContributionAfter);
|
|
@@ -2482,12 +2480,18 @@ export class User {
|
|
|
2482
2480
|
const {
|
|
2483
2481
|
totalAssetValue: inTotalAssetValueAfter,
|
|
2484
2482
|
totalLiabilityValue: inTotalLiabilityValueAfter,
|
|
2485
|
-
} = this.calculateSpotPositionLeverageContribution(
|
|
2483
|
+
} = this.calculateSpotPositionLeverageContribution(
|
|
2484
|
+
inPositionAfter,
|
|
2485
|
+
inStrictOraclePrice
|
|
2486
|
+
);
|
|
2486
2487
|
|
|
2487
2488
|
const {
|
|
2488
2489
|
totalAssetValue: outTotalAssetValueAfter,
|
|
2489
2490
|
totalLiabilityValue: outTotalLiabilityValueAfter,
|
|
2490
|
-
} = this.calculateSpotPositionLeverageContribution(
|
|
2491
|
+
} = this.calculateSpotPositionLeverageContribution(
|
|
2492
|
+
outPositionAfter,
|
|
2493
|
+
outStrictOraclePrice
|
|
2494
|
+
);
|
|
2491
2495
|
|
|
2492
2496
|
const spotAssetValueDelta = inTotalAssetValueAfter
|
|
2493
2497
|
.add(outTotalAssetValueAfter)
|
|
@@ -2564,108 +2568,54 @@ export class User {
|
|
|
2564
2568
|
}
|
|
2565
2569
|
|
|
2566
2570
|
calculateSpotPositionFreeCollateralContribution(
|
|
2567
|
-
spotPosition: SpotPosition
|
|
2571
|
+
spotPosition: SpotPosition,
|
|
2572
|
+
strictOraclePrice: StrictOraclePrice
|
|
2568
2573
|
): BN {
|
|
2569
|
-
let freeCollateralContribution = ZERO;
|
|
2570
|
-
const now = new BN(new Date().getTime() / 1000);
|
|
2571
|
-
const strict = true;
|
|
2572
2574
|
const marginCategory = 'Initial';
|
|
2573
2575
|
|
|
2574
2576
|
const spotMarketAccount: SpotMarketAccount =
|
|
2575
2577
|
this.driftClient.getSpotMarketAccount(spotPosition.marketIndex);
|
|
2576
2578
|
|
|
2577
|
-
const
|
|
2578
|
-
spotPosition
|
|
2579
|
+
const { freeCollateralContribution } = getWorstCaseTokenAmounts(
|
|
2580
|
+
spotPosition,
|
|
2581
|
+
spotMarketAccount,
|
|
2582
|
+
strictOraclePrice,
|
|
2583
|
+
marginCategory
|
|
2579
2584
|
);
|
|
2580
2585
|
|
|
2581
|
-
const [worstCaseTokenAmount, worstCaseQuoteTokenAmount] =
|
|
2582
|
-
getWorstCaseTokenAmounts(
|
|
2583
|
-
spotPosition,
|
|
2584
|
-
spotMarketAccount,
|
|
2585
|
-
oraclePriceData
|
|
2586
|
-
);
|
|
2587
|
-
|
|
2588
|
-
if (worstCaseTokenAmount.gt(ZERO)) {
|
|
2589
|
-
const baseAssetValue = this.getSpotAssetValue(
|
|
2590
|
-
worstCaseTokenAmount,
|
|
2591
|
-
oraclePriceData,
|
|
2592
|
-
spotMarketAccount,
|
|
2593
|
-
marginCategory,
|
|
2594
|
-
strict,
|
|
2595
|
-
now
|
|
2596
|
-
);
|
|
2597
|
-
|
|
2598
|
-
freeCollateralContribution =
|
|
2599
|
-
freeCollateralContribution.add(baseAssetValue);
|
|
2600
|
-
} else {
|
|
2601
|
-
const baseLiabilityValue = this.getSpotLiabilityValue(
|
|
2602
|
-
worstCaseTokenAmount,
|
|
2603
|
-
oraclePriceData,
|
|
2604
|
-
spotMarketAccount,
|
|
2605
|
-
marginCategory,
|
|
2606
|
-
undefined,
|
|
2607
|
-
strict,
|
|
2608
|
-
now
|
|
2609
|
-
).abs();
|
|
2610
|
-
|
|
2611
|
-
freeCollateralContribution =
|
|
2612
|
-
freeCollateralContribution.sub(baseLiabilityValue);
|
|
2613
|
-
}
|
|
2614
|
-
|
|
2615
|
-
freeCollateralContribution.add(worstCaseQuoteTokenAmount);
|
|
2616
|
-
|
|
2617
2586
|
return freeCollateralContribution;
|
|
2618
2587
|
}
|
|
2619
2588
|
|
|
2620
|
-
calculateSpotPositionLeverageContribution(
|
|
2589
|
+
calculateSpotPositionLeverageContribution(
|
|
2590
|
+
spotPosition: SpotPosition,
|
|
2591
|
+
strictOraclePrice: StrictOraclePrice
|
|
2592
|
+
): {
|
|
2621
2593
|
totalAssetValue: BN;
|
|
2622
2594
|
totalLiabilityValue: BN;
|
|
2623
2595
|
} {
|
|
2624
2596
|
let totalAssetValue = ZERO;
|
|
2625
2597
|
let totalLiabilityValue = ZERO;
|
|
2626
|
-
const now = new BN(new Date().getTime() / 1000);
|
|
2627
2598
|
|
|
2628
2599
|
const spotMarketAccount: SpotMarketAccount =
|
|
2629
2600
|
this.driftClient.getSpotMarketAccount(spotPosition.marketIndex);
|
|
2630
2601
|
|
|
2631
|
-
const
|
|
2632
|
-
spotPosition
|
|
2602
|
+
const { tokenValue, ordersValue } = getWorstCaseTokenAmounts(
|
|
2603
|
+
spotPosition,
|
|
2604
|
+
spotMarketAccount,
|
|
2605
|
+
strictOraclePrice,
|
|
2606
|
+
'Initial'
|
|
2633
2607
|
);
|
|
2634
2608
|
|
|
2635
|
-
|
|
2636
|
-
|
|
2637
|
-
spotPosition,
|
|
2638
|
-
spotMarketAccount,
|
|
2639
|
-
oraclePriceData
|
|
2640
|
-
);
|
|
2641
|
-
|
|
2642
|
-
if (worstCaseTokenAmount.gt(ZERO)) {
|
|
2643
|
-
totalAssetValue = this.getSpotAssetValue(
|
|
2644
|
-
worstCaseTokenAmount,
|
|
2645
|
-
oraclePriceData,
|
|
2646
|
-
spotMarketAccount,
|
|
2647
|
-
undefined,
|
|
2648
|
-
false,
|
|
2649
|
-
now
|
|
2650
|
-
);
|
|
2609
|
+
if (tokenValue.gte(ZERO)) {
|
|
2610
|
+
totalAssetValue = tokenValue;
|
|
2651
2611
|
} else {
|
|
2652
|
-
totalLiabilityValue =
|
|
2653
|
-
worstCaseTokenAmount,
|
|
2654
|
-
oraclePriceData,
|
|
2655
|
-
spotMarketAccount,
|
|
2656
|
-
undefined,
|
|
2657
|
-
undefined,
|
|
2658
|
-
false,
|
|
2659
|
-
now
|
|
2660
|
-
).abs();
|
|
2612
|
+
totalLiabilityValue = tokenValue.abs();
|
|
2661
2613
|
}
|
|
2662
2614
|
|
|
2663
|
-
if (
|
|
2664
|
-
totalAssetValue = totalAssetValue.add(
|
|
2615
|
+
if (ordersValue.gt(ZERO)) {
|
|
2616
|
+
totalAssetValue = totalAssetValue.add(ordersValue);
|
|
2665
2617
|
} else {
|
|
2666
|
-
totalLiabilityValue = totalLiabilityValue.add(
|
|
2667
|
-
worstCaseQuoteTokenAmount.abs()
|
|
2668
|
-
);
|
|
2618
|
+
totalLiabilityValue = totalLiabilityValue.add(ordersValue.abs());
|
|
2669
2619
|
}
|
|
2670
2620
|
|
|
2671
2621
|
return {
|
|
@@ -2695,6 +2645,13 @@ export class User {
|
|
|
2695
2645
|
const inMarket = this.driftClient.getSpotMarketAccount(inMarketIndex);
|
|
2696
2646
|
const outMarket = this.driftClient.getSpotMarketAccount(outMarketIndex);
|
|
2697
2647
|
|
|
2648
|
+
const inOraclePriceData = this.getOracleDataForSpotMarket(inMarketIndex);
|
|
2649
|
+
const inOraclePrice = inOraclePriceData.price;
|
|
2650
|
+
const outOraclePriceData = this.getOracleDataForSpotMarket(outMarketIndex);
|
|
2651
|
+
const outOraclePrice = outOraclePriceData.price;
|
|
2652
|
+
const inStrictOraclePrice = new StrictOraclePrice(inOraclePrice);
|
|
2653
|
+
const outStrictOraclePrice = new StrictOraclePrice(outOraclePrice);
|
|
2654
|
+
|
|
2698
2655
|
const inSpotPosition =
|
|
2699
2656
|
this.getSpotPosition(inMarketIndex) ||
|
|
2700
2657
|
this.getEmptySpotPosition(inMarketIndex);
|
|
@@ -2705,11 +2662,17 @@ export class User {
|
|
|
2705
2662
|
const {
|
|
2706
2663
|
totalAssetValue: inTotalAssetValueInitial,
|
|
2707
2664
|
totalLiabilityValue: inTotalLiabilityValueInitial,
|
|
2708
|
-
} = this.calculateSpotPositionLeverageContribution(
|
|
2665
|
+
} = this.calculateSpotPositionLeverageContribution(
|
|
2666
|
+
inSpotPosition,
|
|
2667
|
+
inStrictOraclePrice
|
|
2668
|
+
);
|
|
2709
2669
|
const {
|
|
2710
2670
|
totalAssetValue: outTotalAssetValueInitial,
|
|
2711
2671
|
totalLiabilityValue: outTotalLiabilityValueInitial,
|
|
2712
|
-
} = this.calculateSpotPositionLeverageContribution(
|
|
2672
|
+
} = this.calculateSpotPositionLeverageContribution(
|
|
2673
|
+
outSpotPosition,
|
|
2674
|
+
outStrictOraclePrice
|
|
2675
|
+
);
|
|
2713
2676
|
|
|
2714
2677
|
const { perpLiabilityValue, perpPnl, spotAssetValue, spotLiabilityValue } =
|
|
2715
2678
|
this.getLeverageComponents();
|
|
@@ -2728,12 +2691,18 @@ export class User {
|
|
|
2728
2691
|
const {
|
|
2729
2692
|
totalAssetValue: inTotalAssetValueAfter,
|
|
2730
2693
|
totalLiabilityValue: inTotalLiabilityValueAfter,
|
|
2731
|
-
} = this.calculateSpotPositionLeverageContribution(
|
|
2694
|
+
} = this.calculateSpotPositionLeverageContribution(
|
|
2695
|
+
inPositionAfter,
|
|
2696
|
+
inStrictOraclePrice
|
|
2697
|
+
);
|
|
2732
2698
|
|
|
2733
2699
|
const {
|
|
2734
2700
|
totalAssetValue: outTotalAssetValueAfter,
|
|
2735
2701
|
totalLiabilityValue: outTotalLiabilityValueAfter,
|
|
2736
|
-
} = this.calculateSpotPositionLeverageContribution(
|
|
2702
|
+
} = this.calculateSpotPositionLeverageContribution(
|
|
2703
|
+
outPositionAfter,
|
|
2704
|
+
outStrictOraclePrice
|
|
2705
|
+
);
|
|
2737
2706
|
|
|
2738
2707
|
const spotAssetValueDelta = inTotalAssetValueAfter
|
|
2739
2708
|
.add(outTotalAssetValueAfter)
|
|
@@ -2979,6 +2948,7 @@ export class User {
|
|
|
2979
2948
|
|
|
2980
2949
|
const assetWeight = calculateAssetWeight(
|
|
2981
2950
|
userDepositAmount,
|
|
2951
|
+
oracleData.price,
|
|
2982
2952
|
spotMarket,
|
|
2983
2953
|
'Initial'
|
|
2984
2954
|
);
|
|
@@ -3282,6 +3252,8 @@ export class User {
|
|
|
3282
3252
|
spotPosition.marketIndex
|
|
3283
3253
|
);
|
|
3284
3254
|
|
|
3255
|
+
const strictOraclePrice = new StrictOraclePrice(oraclePriceData.price);
|
|
3256
|
+
|
|
3285
3257
|
if (spotPosition.marketIndex === QUOTE_SPOT_MARKET_INDEX) {
|
|
3286
3258
|
const tokenAmount = getSignedTokenAmount(
|
|
3287
3259
|
getTokenAmount(
|
|
@@ -3296,42 +3268,25 @@ export class User {
|
|
|
3296
3268
|
continue;
|
|
3297
3269
|
}
|
|
3298
3270
|
|
|
3299
|
-
const
|
|
3300
|
-
|
|
3301
|
-
|
|
3302
|
-
|
|
3303
|
-
|
|
3304
|
-
|
|
3305
|
-
|
|
3306
|
-
|
|
3307
|
-
|
|
3308
|
-
|
|
3309
|
-
|
|
3310
|
-
spotMarketAccount.decimals,
|
|
3311
|
-
oraclePriceData
|
|
3271
|
+
const {
|
|
3272
|
+
tokenAmount: worstCaseTokenAmount,
|
|
3273
|
+
tokenValue: tokenValue,
|
|
3274
|
+
weight,
|
|
3275
|
+
weightedTokenValue: weightedTokenValue,
|
|
3276
|
+
ordersValue: ordersValue,
|
|
3277
|
+
} = getWorstCaseTokenAmounts(
|
|
3278
|
+
spotPosition,
|
|
3279
|
+
spotMarketAccount,
|
|
3280
|
+
strictOraclePrice,
|
|
3281
|
+
marginCategory
|
|
3312
3282
|
);
|
|
3313
|
-
const isLiability = isVariant(spotPosition.balanceType, 'borrow');
|
|
3314
3283
|
|
|
3315
|
-
|
|
3316
|
-
if (isLiability) {
|
|
3317
|
-
weight = calculateLiabilityWeight(
|
|
3318
|
-
worstCaseTokenAmount.abs(),
|
|
3319
|
-
spotMarketAccount,
|
|
3320
|
-
marginCategory
|
|
3321
|
-
);
|
|
3322
|
-
} else {
|
|
3323
|
-
weight = calculateAssetWeight(
|
|
3324
|
-
worstCaseTokenAmount,
|
|
3325
|
-
spotMarketAccount,
|
|
3326
|
-
marginCategory
|
|
3327
|
-
);
|
|
3328
|
-
}
|
|
3284
|
+
netQuoteValue = netQuoteValue.add(ordersValue);
|
|
3329
3285
|
|
|
3330
|
-
const
|
|
3331
|
-
|
|
3332
|
-
.div(SPOT_MARKET_WEIGHT_PRECISION);
|
|
3286
|
+
const baseAssetValue = tokenValue.abs();
|
|
3287
|
+
const weightedValue = weightedTokenValue.abs();
|
|
3333
3288
|
|
|
3334
|
-
if (
|
|
3289
|
+
if (weightedTokenValue.lt(ZERO)) {
|
|
3335
3290
|
healthComponents.borrows.push({
|
|
3336
3291
|
marketIndex: spotMarketAccount.marketIndex,
|
|
3337
3292
|
size: worstCaseTokenAmount,
|
|
@@ -3357,38 +3312,26 @@ export class User {
|
|
|
3357
3312
|
);
|
|
3358
3313
|
|
|
3359
3314
|
const baseAssetValue = getTokenValue(
|
|
3360
|
-
netQuoteValue
|
|
3315
|
+
netQuoteValue,
|
|
3361
3316
|
spotMarketAccount.decimals,
|
|
3362
3317
|
oraclePriceData
|
|
3363
3318
|
);
|
|
3364
|
-
const isLiability = netQuoteValue.lt(ZERO);
|
|
3365
|
-
|
|
3366
|
-
let weight;
|
|
3367
|
-
if (isLiability) {
|
|
3368
|
-
weight = calculateLiabilityWeight(
|
|
3369
|
-
netQuoteValue.abs(),
|
|
3370
|
-
spotMarketAccount,
|
|
3371
|
-
marginCategory
|
|
3372
|
-
);
|
|
3373
|
-
} else {
|
|
3374
|
-
weight = calculateAssetWeight(
|
|
3375
|
-
netQuoteValue,
|
|
3376
|
-
spotMarketAccount,
|
|
3377
|
-
marginCategory
|
|
3378
|
-
);
|
|
3379
|
-
}
|
|
3380
3319
|
|
|
3381
|
-
const
|
|
3382
|
-
|
|
3383
|
-
|
|
3320
|
+
const { weight, weightedTokenValue } = calculateWeightedTokenValue(
|
|
3321
|
+
netQuoteValue,
|
|
3322
|
+
baseAssetValue,
|
|
3323
|
+
oraclePriceData,
|
|
3324
|
+
spotMarketAccount,
|
|
3325
|
+
marginCategory
|
|
3326
|
+
);
|
|
3384
3327
|
|
|
3385
|
-
if (
|
|
3328
|
+
if (netQuoteValue.lt(ZERO)) {
|
|
3386
3329
|
healthComponents.borrows.push({
|
|
3387
3330
|
marketIndex: spotMarketAccount.marketIndex,
|
|
3388
3331
|
size: netQuoteValue,
|
|
3389
|
-
value: baseAssetValue,
|
|
3332
|
+
value: baseAssetValue.abs(),
|
|
3390
3333
|
weight: weight,
|
|
3391
|
-
weightedValue:
|
|
3334
|
+
weightedValue: weightedTokenValue.abs(),
|
|
3392
3335
|
});
|
|
3393
3336
|
} else {
|
|
3394
3337
|
healthComponents.deposits.push({
|
|
@@ -3396,7 +3339,7 @@ export class User {
|
|
|
3396
3339
|
size: netQuoteValue,
|
|
3397
3340
|
value: baseAssetValue,
|
|
3398
3341
|
weight: weight,
|
|
3399
|
-
weightedValue:
|
|
3342
|
+
weightedValue: weightedTokenValue,
|
|
3400
3343
|
});
|
|
3401
3344
|
}
|
|
3402
3345
|
}
|