@drift-labs/sdk 2.15.0-beta.0 → 2.16.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/lib/constants/perpMarkets.js +10 -0
- package/lib/events/fetchLogs.js +4 -4
- package/lib/idl/drift.json +1 -1
- package/lib/math/market.d.ts +1 -0
- package/lib/math/market.js +14 -3
- package/lib/math/spotBalance.d.ts +1 -1
- package/lib/math/spotBalance.js +8 -8
- package/lib/math/spotMarket.d.ts +2 -1
- package/lib/math/spotMarket.js +15 -1
- package/lib/math/spotPosition.js +3 -3
- package/lib/user.d.ts +41 -10
- package/lib/user.js +229 -95
- package/package.json +1 -1
- package/src/constants/perpMarkets.ts +10 -0
- package/src/events/fetchLogs.ts +4 -4
- package/src/idl/drift.json +1 -1
- package/src/math/market.ts +25 -2
- package/src/math/spotBalance.ts +8 -8
- package/src/math/spotMarket.ts +27 -1
- package/src/math/spotPosition.ts +3 -3
- package/src/user.ts +544 -234
package/lib/user.js
CHANGED
|
@@ -242,15 +242,15 @@ class User {
|
|
|
242
242
|
* calculates Buying Power = free collateral / initial margin ratio
|
|
243
243
|
* @returns : Precision QUOTE_PRECISION
|
|
244
244
|
*/
|
|
245
|
-
|
|
245
|
+
getPerpBuyingPower(marketIndex) {
|
|
246
246
|
const perpPosition = this.getPerpPosition(marketIndex);
|
|
247
247
|
const worstCaseBaseAssetAmount = perpPosition
|
|
248
248
|
? margin_1.calculateWorstCaseBaseAssetAmount(perpPosition)
|
|
249
249
|
: numericConstants_1.ZERO;
|
|
250
250
|
const freeCollateral = this.getFreeCollateral();
|
|
251
|
-
return this.
|
|
251
|
+
return this.getPerpBuyingPowerFromFreeCollateralAndBaseAssetAmount(marketIndex, freeCollateral, worstCaseBaseAssetAmount);
|
|
252
252
|
}
|
|
253
|
-
|
|
253
|
+
getPerpBuyingPowerFromFreeCollateralAndBaseAssetAmount(marketIndex, freeCollateral, baseAssetAmount) {
|
|
254
254
|
const marginRatio = _1.calculateMarketMarginRatio(this.driftClient.getPerpMarketAccount(marketIndex), baseAssetAmount, 'Initial');
|
|
255
255
|
return freeCollateral.mul(numericConstants_1.MARGIN_PRECISION).div(new _1.BN(marginRatio));
|
|
256
256
|
}
|
|
@@ -325,16 +325,23 @@ class User {
|
|
|
325
325
|
return pnl.add(_1.calculatePositionFundingPNL(market, perpPosition));
|
|
326
326
|
}, numericConstants_1.ZERO);
|
|
327
327
|
}
|
|
328
|
-
|
|
328
|
+
getSpotMarketAssetAndLiabilityValue(marketIndex, marginCategory, liquidationBuffer, includeOpenOrders, strict = false, now) {
|
|
329
329
|
now = now || new _1.BN(new Date().getTime() / 1000);
|
|
330
|
-
|
|
330
|
+
let netQuoteValue = numericConstants_1.ZERO;
|
|
331
|
+
let totalAssetValue = numericConstants_1.ZERO;
|
|
332
|
+
let totalLiabilityValue = numericConstants_1.ZERO;
|
|
333
|
+
for (const spotPosition of this.getUserAccount().spotPositions) {
|
|
334
|
+
const countForBase = marketIndex === undefined || spotPosition.marketIndex === marketIndex;
|
|
335
|
+
const countForQuote = marketIndex === undefined ||
|
|
336
|
+
marketIndex === numericConstants_1.QUOTE_SPOT_MARKET_INDEX ||
|
|
337
|
+
(includeOpenOrders && spotPosition.openOrders !== 0);
|
|
331
338
|
if (spotPosition_1.isSpotPositionAvailable(spotPosition) ||
|
|
332
|
-
(
|
|
333
|
-
|
|
334
|
-
return totalLiabilityValue;
|
|
339
|
+
(!countForBase && !countForQuote)) {
|
|
340
|
+
continue;
|
|
335
341
|
}
|
|
336
342
|
const spotMarketAccount = this.driftClient.getSpotMarketAccount(spotPosition.marketIndex);
|
|
337
|
-
if (spotPosition.marketIndex === numericConstants_1.QUOTE_SPOT_MARKET_INDEX
|
|
343
|
+
if (spotPosition.marketIndex === numericConstants_1.QUOTE_SPOT_MARKET_INDEX &&
|
|
344
|
+
countForQuote) {
|
|
338
345
|
if (types_1.isVariant(spotPosition.balanceType, 'borrow')) {
|
|
339
346
|
const tokenAmount = spotBalance_1.getTokenAmount(spotPosition.scaledBalance, spotMarketAccount, spotPosition.balanceType);
|
|
340
347
|
let weight = numericConstants_1.SPOT_MARKET_WEIGHT_PRECISION;
|
|
@@ -344,31 +351,43 @@ class User {
|
|
|
344
351
|
const weightedTokenValue = tokenAmount
|
|
345
352
|
.mul(weight)
|
|
346
353
|
.div(numericConstants_1.SPOT_MARKET_WEIGHT_PRECISION);
|
|
347
|
-
|
|
354
|
+
netQuoteValue = netQuoteValue.sub(weightedTokenValue);
|
|
355
|
+
continue;
|
|
348
356
|
}
|
|
349
357
|
else {
|
|
350
|
-
|
|
358
|
+
const tokenAmount = spotBalance_1.getTokenAmount(spotPosition.scaledBalance, spotMarketAccount, spotPosition.balanceType);
|
|
359
|
+
netQuoteValue = netQuoteValue.add(tokenAmount);
|
|
360
|
+
continue;
|
|
351
361
|
}
|
|
352
362
|
}
|
|
353
363
|
const oraclePriceData = this.getOracleDataForSpotMarket(spotPosition.marketIndex);
|
|
354
|
-
if (!includeOpenOrders) {
|
|
364
|
+
if (!includeOpenOrders && countForBase) {
|
|
355
365
|
if (types_1.isVariant(spotPosition.balanceType, 'borrow')) {
|
|
356
366
|
const tokenAmount = spotBalance_1.getTokenAmount(spotPosition.scaledBalance, spotMarketAccount, spotPosition.balanceType);
|
|
357
367
|
const liabilityValue = this.getSpotLiabilityValue(tokenAmount, oraclePriceData, spotMarketAccount, marginCategory, liquidationBuffer, strict, now);
|
|
358
|
-
|
|
368
|
+
totalLiabilityValue = totalLiabilityValue.add(liabilityValue);
|
|
369
|
+
continue;
|
|
359
370
|
}
|
|
360
371
|
else {
|
|
361
|
-
|
|
372
|
+
const tokenAmount = spotBalance_1.getTokenAmount(spotPosition.scaledBalance, spotMarketAccount, spotPosition.balanceType);
|
|
373
|
+
const assetValue = this.getSpotAssetValue(tokenAmount, oraclePriceData, spotMarketAccount, marginCategory, strict, now);
|
|
374
|
+
totalAssetValue = totalAssetValue.add(assetValue);
|
|
375
|
+
continue;
|
|
362
376
|
}
|
|
363
377
|
}
|
|
364
378
|
const [worstCaseTokenAmount, worstCaseQuoteTokenAmount] = spotPosition_1.getWorstCaseTokenAmounts(spotPosition, spotMarketAccount, this.getOracleDataForSpotMarket(spotPosition.marketIndex));
|
|
365
|
-
|
|
366
|
-
|
|
379
|
+
if (worstCaseTokenAmount.gt(numericConstants_1.ZERO) && countForBase) {
|
|
380
|
+
const baseAssetValue = this.getSpotAssetValue(worstCaseTokenAmount, oraclePriceData, spotMarketAccount, marginCategory, strict, now);
|
|
381
|
+
totalAssetValue = totalAssetValue.add(baseAssetValue);
|
|
382
|
+
}
|
|
383
|
+
if (worstCaseTokenAmount.lt(numericConstants_1.ZERO) && countForBase) {
|
|
367
384
|
const baseLiabilityValue = this.getSpotLiabilityValue(worstCaseTokenAmount.abs(), oraclePriceData, spotMarketAccount, marginCategory, liquidationBuffer, strict, now);
|
|
368
|
-
|
|
369
|
-
newTotalLiabilityValue.add(baseLiabilityValue);
|
|
385
|
+
totalLiabilityValue = totalLiabilityValue.add(baseLiabilityValue);
|
|
370
386
|
}
|
|
371
|
-
if (worstCaseQuoteTokenAmount.
|
|
387
|
+
if (worstCaseQuoteTokenAmount.gt(numericConstants_1.ZERO) && countForQuote) {
|
|
388
|
+
netQuoteValue = netQuoteValue.add(worstCaseQuoteTokenAmount);
|
|
389
|
+
}
|
|
390
|
+
if (worstCaseQuoteTokenAmount.lt(numericConstants_1.ZERO) && countForQuote) {
|
|
372
391
|
let weight = numericConstants_1.SPOT_MARKET_WEIGHT_PRECISION;
|
|
373
392
|
if (marginCategory === 'Initial') {
|
|
374
393
|
weight = _1.BN.max(weight, new _1.BN(this.getUserAccount().maxMarginRatio));
|
|
@@ -377,12 +396,21 @@ class User {
|
|
|
377
396
|
.abs()
|
|
378
397
|
.mul(weight)
|
|
379
398
|
.div(numericConstants_1.SPOT_MARKET_WEIGHT_PRECISION);
|
|
380
|
-
|
|
381
|
-
newTotalLiabilityValue.add(weightedTokenValue);
|
|
399
|
+
netQuoteValue = netQuoteValue.sub(weightedTokenValue);
|
|
382
400
|
}
|
|
383
|
-
|
|
384
|
-
|
|
385
|
-
|
|
401
|
+
totalLiabilityValue = totalLiabilityValue.add(new _1.BN(spotPosition.openOrders).mul(numericConstants_1.OPEN_ORDER_MARGIN_REQUIREMENT));
|
|
402
|
+
}
|
|
403
|
+
if (netQuoteValue.gt(numericConstants_1.ZERO)) {
|
|
404
|
+
totalAssetValue = totalAssetValue.add(netQuoteValue);
|
|
405
|
+
}
|
|
406
|
+
else {
|
|
407
|
+
totalLiabilityValue = totalLiabilityValue.add(netQuoteValue.abs());
|
|
408
|
+
}
|
|
409
|
+
return { totalAssetValue, totalLiabilityValue };
|
|
410
|
+
}
|
|
411
|
+
getSpotMarketLiabilityValue(marketIndex, marginCategory, liquidationBuffer, includeOpenOrders, strict = false, now) {
|
|
412
|
+
const { totalLiabilityValue } = this.getSpotMarketAssetAndLiabilityValue(marketIndex, marginCategory, liquidationBuffer, includeOpenOrders, strict, now);
|
|
413
|
+
return totalLiabilityValue;
|
|
386
414
|
}
|
|
387
415
|
getSpotLiabilityValue(tokenAmount, oraclePriceData, spotMarketAccount, marginCategory, liquidationBuffer, strict = false, now) {
|
|
388
416
|
let liabilityValue = null;
|
|
@@ -409,46 +437,8 @@ class User {
|
|
|
409
437
|
return liabilityValue;
|
|
410
438
|
}
|
|
411
439
|
getSpotMarketAssetValue(marketIndex, marginCategory, includeOpenOrders, strict = false, now) {
|
|
412
|
-
|
|
413
|
-
return
|
|
414
|
-
if (spotPosition_1.isSpotPositionAvailable(spotPosition) ||
|
|
415
|
-
(marketIndex !== undefined &&
|
|
416
|
-
spotPosition.marketIndex !== marketIndex)) {
|
|
417
|
-
return totalAssetValue;
|
|
418
|
-
}
|
|
419
|
-
// Todo this needs to account for whether it's based on initial or maintenance requirements
|
|
420
|
-
const spotMarketAccount = this.driftClient.getSpotMarketAccount(spotPosition.marketIndex);
|
|
421
|
-
if (spotPosition.marketIndex === numericConstants_1.QUOTE_SPOT_MARKET_INDEX) {
|
|
422
|
-
if (types_1.isVariant(spotPosition.balanceType, 'deposit')) {
|
|
423
|
-
const tokenAmount = spotBalance_1.getTokenAmount(spotPosition.scaledBalance, spotMarketAccount, spotPosition.balanceType);
|
|
424
|
-
return totalAssetValue.add(tokenAmount);
|
|
425
|
-
}
|
|
426
|
-
else {
|
|
427
|
-
return totalAssetValue;
|
|
428
|
-
}
|
|
429
|
-
}
|
|
430
|
-
const oraclePriceData = this.getOracleDataForSpotMarket(spotPosition.marketIndex);
|
|
431
|
-
if (!includeOpenOrders) {
|
|
432
|
-
if (types_1.isVariant(spotPosition.balanceType, 'deposit')) {
|
|
433
|
-
const tokenAmount = spotBalance_1.getTokenAmount(spotPosition.scaledBalance, spotMarketAccount, spotPosition.balanceType);
|
|
434
|
-
const assetValue = this.getSpotAssetValue(tokenAmount, oraclePriceData, spotMarketAccount, marginCategory, strict, now);
|
|
435
|
-
return totalAssetValue.add(assetValue);
|
|
436
|
-
}
|
|
437
|
-
else {
|
|
438
|
-
return totalAssetValue;
|
|
439
|
-
}
|
|
440
|
-
}
|
|
441
|
-
const [worstCaseTokenAmount, worstCaseQuoteTokenAmount] = spotPosition_1.getWorstCaseTokenAmounts(spotPosition, spotMarketAccount, this.getOracleDataForSpotMarket(spotPosition.marketIndex));
|
|
442
|
-
let newTotalAssetValue = totalAssetValue;
|
|
443
|
-
if (worstCaseTokenAmount.gt(numericConstants_1.ZERO)) {
|
|
444
|
-
const baseAssetValue = this.getSpotAssetValue(worstCaseTokenAmount, oraclePriceData, spotMarketAccount, marginCategory, strict, now);
|
|
445
|
-
newTotalAssetValue = newTotalAssetValue.add(baseAssetValue);
|
|
446
|
-
}
|
|
447
|
-
if (worstCaseQuoteTokenAmount.gt(numericConstants_1.ZERO)) {
|
|
448
|
-
newTotalAssetValue = newTotalAssetValue.add(worstCaseQuoteTokenAmount);
|
|
449
|
-
}
|
|
450
|
-
return newTotalAssetValue;
|
|
451
|
-
}, numericConstants_1.ZERO);
|
|
440
|
+
const { totalAssetValue } = this.getSpotMarketAssetAndLiabilityValue(marketIndex, marginCategory, undefined, includeOpenOrders, strict, now);
|
|
441
|
+
return totalAssetValue;
|
|
452
442
|
}
|
|
453
443
|
getSpotAssetValue(tokenAmount, oraclePriceData, spotMarketAccount, marginCategory, strict = false, now) {
|
|
454
444
|
let assetValue = null;
|
|
@@ -466,8 +456,17 @@ class User {
|
|
|
466
456
|
}
|
|
467
457
|
return assetValue;
|
|
468
458
|
}
|
|
459
|
+
getSpotTokenAmount(marketIndex) {
|
|
460
|
+
const spotPosition = this.getSpotPosition(marketIndex);
|
|
461
|
+
return spotBalance_1.getTokenAmount(spotPosition.scaledBalance, this.driftClient.getSpotMarketAccount(marketIndex), spotPosition.balanceType);
|
|
462
|
+
}
|
|
463
|
+
getSpotPositionValue(marketIndex, marginCategory, includeOpenOrders, strict = false, now) {
|
|
464
|
+
const { totalAssetValue, totalLiabilityValue } = this.getSpotMarketAssetAndLiabilityValue(marketIndex, marginCategory, undefined, includeOpenOrders, strict, now);
|
|
465
|
+
return totalAssetValue.sub(totalLiabilityValue);
|
|
466
|
+
}
|
|
469
467
|
getNetSpotMarketValue(withWeightMarginCategory) {
|
|
470
|
-
|
|
468
|
+
const { totalAssetValue, totalLiabilityValue } = this.getSpotMarketAssetAndLiabilityValue(undefined, withWeightMarginCategory);
|
|
469
|
+
return totalAssetValue.sub(totalLiabilityValue);
|
|
471
470
|
}
|
|
472
471
|
/**
|
|
473
472
|
* calculates TotalCollateral: collateral + unrealized pnl
|
|
@@ -625,16 +624,27 @@ class User {
|
|
|
625
624
|
* @returns : Precision TEN_THOUSAND
|
|
626
625
|
*/
|
|
627
626
|
getLeverage() {
|
|
628
|
-
|
|
629
|
-
const
|
|
630
|
-
const totalLiabilityValue =
|
|
631
|
-
const totalAssetValue =
|
|
632
|
-
const netAssetValue = totalAssetValue.sub(
|
|
627
|
+
// get leverage components
|
|
628
|
+
const { perpLiabilityValue, perpPnl, spotAssetValue, spotLiabilityValue } = this.getLeverageComponents();
|
|
629
|
+
const totalLiabilityValue = perpLiabilityValue.add(spotLiabilityValue);
|
|
630
|
+
const totalAssetValue = spotAssetValue.add(perpPnl);
|
|
631
|
+
const netAssetValue = totalAssetValue.sub(spotLiabilityValue);
|
|
633
632
|
if (netAssetValue.eq(numericConstants_1.ZERO)) {
|
|
634
633
|
return numericConstants_1.ZERO;
|
|
635
634
|
}
|
|
636
635
|
return totalLiabilityValue.mul(numericConstants_1.TEN_THOUSAND).div(netAssetValue);
|
|
637
636
|
}
|
|
637
|
+
getLeverageComponents() {
|
|
638
|
+
const perpLiability = this.getTotalPerpPositionValue(undefined, undefined, true);
|
|
639
|
+
const perpPnl = this.getUnrealizedPNL(true);
|
|
640
|
+
const { totalAssetValue: spotAssetValue, totalLiabilityValue: spotLiabilityValue, } = this.getSpotMarketAssetAndLiabilityValue(undefined, undefined, undefined, true);
|
|
641
|
+
return {
|
|
642
|
+
perpLiabilityValue: perpLiability,
|
|
643
|
+
perpPnl,
|
|
644
|
+
spotAssetValue,
|
|
645
|
+
spotLiabilityValue,
|
|
646
|
+
};
|
|
647
|
+
}
|
|
638
648
|
getTotalLiabilityValue(marginCategory) {
|
|
639
649
|
return this.getTotalPerpPositionValue(marginCategory, undefined, true).add(this.getSpotMarketLiabilityValue(undefined, marginCategory, undefined, true));
|
|
640
650
|
}
|
|
@@ -646,19 +656,16 @@ class User {
|
|
|
646
656
|
* @params category {Initial, Maintenance}
|
|
647
657
|
* @returns : Precision TEN_THOUSAND
|
|
648
658
|
*/
|
|
649
|
-
|
|
650
|
-
const market = this.driftClient.getPerpMarketAccount(
|
|
651
|
-
const
|
|
652
|
-
const
|
|
653
|
-
const
|
|
654
|
-
const netAssetValue = totalAssetValue.sub(totalSpotLiability);
|
|
659
|
+
getMaxLeverageForPerp(perpMarketIndex, category = 'Initial') {
|
|
660
|
+
const market = this.driftClient.getPerpMarketAccount(perpMarketIndex);
|
|
661
|
+
const { perpLiabilityValue, perpPnl, spotAssetValue, spotLiabilityValue } = this.getLeverageComponents();
|
|
662
|
+
const totalAssetValue = spotAssetValue.add(perpPnl);
|
|
663
|
+
const netAssetValue = totalAssetValue.sub(spotLiabilityValue);
|
|
655
664
|
if (netAssetValue.eq(numericConstants_1.ZERO)) {
|
|
656
665
|
return numericConstants_1.ZERO;
|
|
657
666
|
}
|
|
658
|
-
const totalLiabilityValue =
|
|
659
|
-
const marginRatio = _1.calculateMarketMarginRatio(market,
|
|
660
|
-
// worstCaseBaseAssetAmount.abs(),
|
|
661
|
-
numericConstants_1.ZERO, // todo
|
|
667
|
+
const totalLiabilityValue = perpLiabilityValue.add(spotLiabilityValue);
|
|
668
|
+
const marginRatio = _1.calculateMarketMarginRatio(market, numericConstants_1.ZERO, // todo
|
|
662
669
|
category);
|
|
663
670
|
const freeCollateral = this.getFreeCollateral();
|
|
664
671
|
// how much more liabilities can be opened w remaining free collateral
|
|
@@ -671,18 +678,60 @@ class User {
|
|
|
671
678
|
.div(netAssetValue);
|
|
672
679
|
}
|
|
673
680
|
/**
|
|
674
|
-
* calculates
|
|
681
|
+
* calculates max allowable leverage exceeding hitting requirement category
|
|
682
|
+
* @param spotMarketIndex
|
|
683
|
+
* @param direction
|
|
684
|
+
* @returns : Precision TEN_THOUSAND
|
|
685
|
+
*/
|
|
686
|
+
getMaxLeverageForSpot(spotMarketIndex, direction) {
|
|
687
|
+
const { perpLiabilityValue, perpPnl, spotAssetValue, spotLiabilityValue } = this.getLeverageComponents();
|
|
688
|
+
const totalLiabilityValue = perpLiabilityValue.add(spotLiabilityValue);
|
|
689
|
+
const totalAssetValue = spotAssetValue.add(perpPnl);
|
|
690
|
+
const netAssetValue = totalAssetValue.sub(spotLiabilityValue);
|
|
691
|
+
if (netAssetValue.eq(numericConstants_1.ZERO)) {
|
|
692
|
+
return numericConstants_1.ZERO;
|
|
693
|
+
}
|
|
694
|
+
const currentQuoteAssetValue = this.getSpotMarketAssetValue(numericConstants_1.QUOTE_SPOT_MARKET_INDEX);
|
|
695
|
+
const currentQuoteLiabilityValue = this.getSpotMarketLiabilityValue(numericConstants_1.QUOTE_SPOT_MARKET_INDEX);
|
|
696
|
+
const currentQuoteValue = currentQuoteAssetValue.sub(currentQuoteLiabilityValue);
|
|
697
|
+
const currentSpotMarketAssetValue = this.getSpotMarketAssetValue(spotMarketIndex);
|
|
698
|
+
const currentSpotMarketLiabilityValue = this.getSpotMarketLiabilityValue(spotMarketIndex);
|
|
699
|
+
const currentSpotMarketNetValue = currentSpotMarketAssetValue.sub(currentSpotMarketLiabilityValue);
|
|
700
|
+
const tradeQuoteAmount = this.getMaxTradeSizeUSDCForSpot(spotMarketIndex, direction, currentQuoteAssetValue, currentSpotMarketNetValue);
|
|
701
|
+
let assetValueToAdd = numericConstants_1.ZERO;
|
|
702
|
+
let liabilityValueToAdd = numericConstants_1.ZERO;
|
|
703
|
+
const newQuoteNetValue = types_1.isVariant(direction, 'short')
|
|
704
|
+
? currentQuoteValue.add(tradeQuoteAmount)
|
|
705
|
+
: currentQuoteValue.sub(tradeQuoteAmount);
|
|
706
|
+
const newQuoteAssetValue = _1.BN.max(newQuoteNetValue, numericConstants_1.ZERO);
|
|
707
|
+
const newQuoteLiabilityValue = _1.BN.min(newQuoteNetValue, numericConstants_1.ZERO).abs();
|
|
708
|
+
assetValueToAdd = assetValueToAdd.add(newQuoteAssetValue.sub(currentQuoteAssetValue));
|
|
709
|
+
liabilityValueToAdd = liabilityValueToAdd.add(newQuoteLiabilityValue.sub(currentQuoteLiabilityValue));
|
|
710
|
+
const newSpotMarketNetValue = types_1.isVariant(direction, 'long')
|
|
711
|
+
? currentSpotMarketNetValue.add(tradeQuoteAmount)
|
|
712
|
+
: currentSpotMarketNetValue.sub(tradeQuoteAmount);
|
|
713
|
+
const newSpotMarketAssetValue = _1.BN.max(newSpotMarketNetValue, numericConstants_1.ZERO);
|
|
714
|
+
const newSpotMarketLiabilityValue = _1.BN.min(newSpotMarketNetValue, numericConstants_1.ZERO).abs();
|
|
715
|
+
assetValueToAdd = assetValueToAdd.add(newSpotMarketAssetValue.sub(currentSpotMarketAssetValue));
|
|
716
|
+
liabilityValueToAdd = liabilityValueToAdd.add(newSpotMarketLiabilityValue.sub(currentSpotMarketLiabilityValue));
|
|
717
|
+
const finalTotalAssetValue = totalAssetValue.add(assetValueToAdd);
|
|
718
|
+
const finalTotalSpotLiability = spotLiabilityValue.add(liabilityValueToAdd);
|
|
719
|
+
const finalTotalLiabilityValue = totalLiabilityValue.add(liabilityValueToAdd);
|
|
720
|
+
const finalNetAssetValue = finalTotalAssetValue.sub(finalTotalSpotLiability);
|
|
721
|
+
return finalTotalLiabilityValue.mul(numericConstants_1.TEN_THOUSAND).div(finalNetAssetValue);
|
|
722
|
+
}
|
|
723
|
+
/**
|
|
724
|
+
* calculates margin ratio: 1 / leverage
|
|
675
725
|
* @returns : Precision TEN_THOUSAND
|
|
676
726
|
*/
|
|
677
|
-
getMarginRatio(
|
|
678
|
-
const
|
|
679
|
-
const
|
|
680
|
-
const
|
|
727
|
+
getMarginRatio() {
|
|
728
|
+
const { perpLiabilityValue, perpPnl, spotAssetValue, spotLiabilityValue } = this.getLeverageComponents();
|
|
729
|
+
const totalLiabilityValue = perpLiabilityValue.add(spotLiabilityValue);
|
|
730
|
+
const totalAssetValue = spotAssetValue.add(perpPnl);
|
|
681
731
|
if (totalLiabilityValue.eq(numericConstants_1.ZERO)) {
|
|
682
732
|
return numericConstants_1.BN_MAX;
|
|
683
733
|
}
|
|
684
|
-
const
|
|
685
|
-
const netAssetValue = totalAssetValue.sub(totalSpotLiability);
|
|
734
|
+
const netAssetValue = totalAssetValue.sub(spotLiabilityValue);
|
|
686
735
|
return netAssetValue.mul(numericConstants_1.TEN_THOUSAND).div(totalLiabilityValue);
|
|
687
736
|
}
|
|
688
737
|
canBeLiquidated() {
|
|
@@ -728,7 +777,7 @@ class User {
|
|
|
728
777
|
* @param marketIndex
|
|
729
778
|
* @returns Precision : PRICE_PRECISION
|
|
730
779
|
*/
|
|
731
|
-
spotLiquidationPrice(marketIndex) {
|
|
780
|
+
spotLiquidationPrice(marketIndex, positionBaseSizeChange = numericConstants_1.ZERO) {
|
|
732
781
|
const currentSpotPosition = this.getSpotPosition(marketIndex);
|
|
733
782
|
if (!currentSpotPosition) {
|
|
734
783
|
return new _1.BN(-1);
|
|
@@ -737,7 +786,8 @@ class User {
|
|
|
737
786
|
const maintenanceMarginRequirement = this.getMaintenanceMarginRequirement();
|
|
738
787
|
const freeCollateral = _1.BN.max(numericConstants_1.ZERO, totalCollateral.sub(maintenanceMarginRequirement));
|
|
739
788
|
const market = this.driftClient.getSpotMarketAccount(marketIndex);
|
|
740
|
-
|
|
789
|
+
let signedTokenAmount = _1.getSignedTokenAmount(spotBalance_1.getTokenAmount(currentSpotPosition.scaledBalance, market, currentSpotPosition.balanceType), currentSpotPosition.balanceType);
|
|
790
|
+
signedTokenAmount = signedTokenAmount.add(positionBaseSizeChange);
|
|
741
791
|
if (signedTokenAmount.eq(numericConstants_1.ZERO)) {
|
|
742
792
|
return new _1.BN(-1);
|
|
743
793
|
}
|
|
@@ -894,7 +944,7 @@ class User {
|
|
|
894
944
|
* @param tradeSide
|
|
895
945
|
* @returns tradeSizeAllowed : Precision QUOTE_PRECISION
|
|
896
946
|
*/
|
|
897
|
-
|
|
947
|
+
getMaxTradeSizeUSDCForPerp(targetMarketIndex, tradeSide) {
|
|
898
948
|
const currentPosition = this.getPerpPosition(targetMarketIndex) ||
|
|
899
949
|
this.getEmptyPosition(targetMarketIndex);
|
|
900
950
|
const targetSide = types_1.isVariant(tradeSide, 'short') ? 'short' : 'long';
|
|
@@ -909,7 +959,7 @@ class User {
|
|
|
909
959
|
const oppositeSizeValueUSDC = targetingSameSide
|
|
910
960
|
? numericConstants_1.ZERO
|
|
911
961
|
: this.getPerpPositionValue(targetMarketIndex, oracleData);
|
|
912
|
-
let maxPositionSize = this.
|
|
962
|
+
let maxPositionSize = this.getPerpBuyingPower(targetMarketIndex);
|
|
913
963
|
if (maxPositionSize.gte(numericConstants_1.ZERO)) {
|
|
914
964
|
if (oppositeSizeValueUSDC.eq(numericConstants_1.ZERO)) {
|
|
915
965
|
// case 1 : Regular trade where current total position less than max, and no opposite position to account for
|
|
@@ -936,7 +986,7 @@ class User {
|
|
|
936
986
|
}
|
|
937
987
|
else {
|
|
938
988
|
const freeCollateralAfterClose = totalCollateral.sub(marginRequirementAfterClosing);
|
|
939
|
-
const buyingPowerAfterClose = this.
|
|
989
|
+
const buyingPowerAfterClose = this.getPerpBuyingPowerFromFreeCollateralAndBaseAssetAmount(targetMarketIndex, freeCollateralAfterClose, numericConstants_1.ZERO);
|
|
940
990
|
maxPositionSize = perpPositionValue.add(buyingPowerAfterClose);
|
|
941
991
|
}
|
|
942
992
|
}
|
|
@@ -949,15 +999,99 @@ class User {
|
|
|
949
999
|
const oneMilli = maxPositionSize.div(numericConstants_1.QUOTE_PRECISION);
|
|
950
1000
|
return maxPositionSize.sub(oneMilli);
|
|
951
1001
|
}
|
|
1002
|
+
/**
|
|
1003
|
+
* Get the maximum trade size for a given market, taking into account the user's current leverage, positions, collateral, etc.
|
|
1004
|
+
*
|
|
1005
|
+
* @param targetMarketIndex
|
|
1006
|
+
* @param direction
|
|
1007
|
+
* @param currentQuoteAssetValue
|
|
1008
|
+
* @param currentSpotMarketNetValue
|
|
1009
|
+
* @returns tradeSizeAllowed : Precision QUOTE_PRECISION
|
|
1010
|
+
*/
|
|
1011
|
+
getMaxTradeSizeUSDCForSpot(targetMarketIndex, direction, currentQuoteAssetValue, currentSpotMarketNetValue) {
|
|
1012
|
+
const market = this.driftClient.getSpotMarketAccount(targetMarketIndex);
|
|
1013
|
+
currentQuoteAssetValue = this.getSpotMarketAssetValue(numericConstants_1.QUOTE_SPOT_MARKET_INDEX);
|
|
1014
|
+
currentSpotMarketNetValue =
|
|
1015
|
+
currentSpotMarketNetValue !== null && currentSpotMarketNetValue !== void 0 ? currentSpotMarketNetValue : this.getSpotPositionValue(targetMarketIndex);
|
|
1016
|
+
let freeCollateral = this.getFreeCollateral();
|
|
1017
|
+
const marginRatio = _1.calculateSpotMarketMarginRatio(market, 'Initial', numericConstants_1.ZERO, types_1.isVariant(direction, 'long')
|
|
1018
|
+
? _1.SpotBalanceType.DEPOSIT
|
|
1019
|
+
: _1.SpotBalanceType.BORROW);
|
|
1020
|
+
let tradeAmount = numericConstants_1.ZERO;
|
|
1021
|
+
if (this.getUserAccount().isMarginTradingEnabled) {
|
|
1022
|
+
// if the user is buying/selling and already short/long, need to account for closing out short/long
|
|
1023
|
+
if (types_1.isVariant(direction, 'long') && currentSpotMarketNetValue.lt(numericConstants_1.ZERO)) {
|
|
1024
|
+
tradeAmount = currentSpotMarketNetValue.abs();
|
|
1025
|
+
const marginRatio = _1.calculateSpotMarketMarginRatio(market, 'Initial', this.getSpotTokenAmount(targetMarketIndex), _1.SpotBalanceType.BORROW);
|
|
1026
|
+
freeCollateral = freeCollateral.add(tradeAmount.mul(new _1.BN(marginRatio)).div(numericConstants_1.MARGIN_PRECISION));
|
|
1027
|
+
}
|
|
1028
|
+
else if (types_1.isVariant(direction, 'short') &&
|
|
1029
|
+
currentSpotMarketNetValue.gt(numericConstants_1.ZERO)) {
|
|
1030
|
+
tradeAmount = currentSpotMarketNetValue;
|
|
1031
|
+
const marginRatio = _1.calculateSpotMarketMarginRatio(market, 'Initial', this.getSpotTokenAmount(targetMarketIndex), _1.SpotBalanceType.DEPOSIT);
|
|
1032
|
+
freeCollateral = freeCollateral.add(tradeAmount.mul(new _1.BN(marginRatio)).div(numericConstants_1.MARGIN_PRECISION));
|
|
1033
|
+
}
|
|
1034
|
+
tradeAmount = tradeAmount.add(freeCollateral.mul(numericConstants_1.MARGIN_PRECISION).div(new _1.BN(marginRatio)));
|
|
1035
|
+
}
|
|
1036
|
+
else if (types_1.isVariant(direction, 'long')) {
|
|
1037
|
+
tradeAmount = _1.BN.min(currentQuoteAssetValue, freeCollateral.mul(numericConstants_1.MARGIN_PRECISION).div(new _1.BN(marginRatio)));
|
|
1038
|
+
}
|
|
1039
|
+
else {
|
|
1040
|
+
tradeAmount = _1.BN.max(numericConstants_1.ZERO, currentSpotMarketNetValue);
|
|
1041
|
+
}
|
|
1042
|
+
return tradeAmount;
|
|
1043
|
+
}
|
|
952
1044
|
// TODO - should this take the price impact of the trade into account for strict accuracy?
|
|
953
1045
|
/**
|
|
954
1046
|
* Returns the leverage ratio for the account after adding (or subtracting) the given quote size to the given position
|
|
955
1047
|
* @param targetMarketIndex
|
|
956
|
-
* @param
|
|
1048
|
+
* @param: targetMarketType
|
|
957
1049
|
* @param tradeQuoteAmount
|
|
1050
|
+
* @param tradeSide
|
|
1051
|
+
* @param includeOpenOrders
|
|
958
1052
|
* @returns leverageRatio : Precision TEN_THOUSAND
|
|
959
1053
|
*/
|
|
960
|
-
accountLeverageRatioAfterTrade(targetMarketIndex, tradeQuoteAmount, tradeSide, includeOpenOrders = true) {
|
|
1054
|
+
accountLeverageRatioAfterTrade(targetMarketIndex, targetMarketType, tradeQuoteAmount, tradeSide, includeOpenOrders = true) {
|
|
1055
|
+
const tradeIsPerp = types_1.isVariant(targetMarketType, 'perp');
|
|
1056
|
+
if (!tradeIsPerp) {
|
|
1057
|
+
// calculate new asset/liability values for base and quote market to find new account leverage
|
|
1058
|
+
const totalLiabilityValue = this.getTotalLiabilityValue();
|
|
1059
|
+
const totalAssetValue = this.getTotalAssetValue();
|
|
1060
|
+
const spotLiabilityValue = this.getSpotMarketLiabilityValue(undefined, undefined, undefined, includeOpenOrders);
|
|
1061
|
+
const currentQuoteAssetValue = this.getSpotMarketAssetValue(numericConstants_1.QUOTE_SPOT_MARKET_INDEX, undefined, includeOpenOrders);
|
|
1062
|
+
const currentQuoteLiabilityValue = this.getSpotMarketLiabilityValue(numericConstants_1.QUOTE_SPOT_MARKET_INDEX, undefined, undefined, includeOpenOrders);
|
|
1063
|
+
const currentQuoteValue = currentQuoteAssetValue.sub(currentQuoteLiabilityValue);
|
|
1064
|
+
const currentSpotMarketAssetValue = this.getSpotMarketAssetValue(targetMarketIndex, undefined, includeOpenOrders);
|
|
1065
|
+
const currentSpotMarketLiabilityValue = this.getSpotMarketLiabilityValue(targetMarketIndex, undefined, undefined, includeOpenOrders);
|
|
1066
|
+
const currentSpotMarketNetValue = currentSpotMarketAssetValue.sub(currentSpotMarketLiabilityValue);
|
|
1067
|
+
let assetValueToAdd = numericConstants_1.ZERO;
|
|
1068
|
+
let liabilityValueToAdd = numericConstants_1.ZERO;
|
|
1069
|
+
const newQuoteNetValue = tradeSide == _1.PositionDirection.SHORT
|
|
1070
|
+
? currentQuoteValue.add(tradeQuoteAmount)
|
|
1071
|
+
: currentQuoteValue.sub(tradeQuoteAmount);
|
|
1072
|
+
const newQuoteAssetValue = _1.BN.max(newQuoteNetValue, numericConstants_1.ZERO);
|
|
1073
|
+
const newQuoteLiabilityValue = _1.BN.min(newQuoteNetValue, numericConstants_1.ZERO).abs();
|
|
1074
|
+
assetValueToAdd = assetValueToAdd.add(newQuoteAssetValue.sub(currentQuoteAssetValue));
|
|
1075
|
+
liabilityValueToAdd = liabilityValueToAdd.add(newQuoteLiabilityValue.sub(currentQuoteLiabilityValue));
|
|
1076
|
+
const newSpotMarketNetValue = tradeSide == _1.PositionDirection.LONG
|
|
1077
|
+
? currentSpotMarketNetValue.add(tradeQuoteAmount)
|
|
1078
|
+
: currentSpotMarketNetValue.sub(tradeQuoteAmount);
|
|
1079
|
+
const newSpotMarketAssetValue = _1.BN.max(newSpotMarketNetValue, numericConstants_1.ZERO);
|
|
1080
|
+
const newSpotMarketLiabilityValue = _1.BN.min(newSpotMarketNetValue, numericConstants_1.ZERO).abs();
|
|
1081
|
+
assetValueToAdd = assetValueToAdd.add(newSpotMarketAssetValue.sub(currentSpotMarketAssetValue));
|
|
1082
|
+
liabilityValueToAdd = liabilityValueToAdd.add(newSpotMarketLiabilityValue.sub(currentSpotMarketLiabilityValue));
|
|
1083
|
+
const totalAssetValueAfterTrade = totalAssetValue.add(assetValueToAdd);
|
|
1084
|
+
const totalSpotLiabilityValueAfterTrade = spotLiabilityValue.add(liabilityValueToAdd);
|
|
1085
|
+
const totalLiabilityValueAfterTrade = totalLiabilityValue.add(liabilityValueToAdd);
|
|
1086
|
+
const netAssetValueAfterTrade = totalAssetValueAfterTrade.sub(totalSpotLiabilityValueAfterTrade);
|
|
1087
|
+
if (netAssetValueAfterTrade.eq(numericConstants_1.ZERO)) {
|
|
1088
|
+
return numericConstants_1.ZERO;
|
|
1089
|
+
}
|
|
1090
|
+
const newLeverage = totalLiabilityValueAfterTrade
|
|
1091
|
+
.mul(numericConstants_1.TEN_THOUSAND)
|
|
1092
|
+
.div(netAssetValueAfterTrade);
|
|
1093
|
+
return newLeverage;
|
|
1094
|
+
}
|
|
961
1095
|
const currentPosition = this.getPerpPosition(targetMarketIndex) ||
|
|
962
1096
|
this.getEmptyPosition(targetMarketIndex);
|
|
963
1097
|
const oracleData = this.getOracleDataForPerpMarket(targetMarketIndex);
|
|
@@ -1063,7 +1197,7 @@ class User {
|
|
|
1063
1197
|
depositAmount: numericConstants_1.ZERO,
|
|
1064
1198
|
};
|
|
1065
1199
|
}
|
|
1066
|
-
const depositAmount = spotBalance_1.getTokenAmount(position.scaledBalance, spotMarket,
|
|
1200
|
+
const depositAmount = spotBalance_1.getTokenAmount(position.scaledBalance, spotMarket, _1.SpotBalanceType.DEPOSIT);
|
|
1067
1201
|
if (netDeposits.lt(numericConstants_1.ZERO)) {
|
|
1068
1202
|
return {
|
|
1069
1203
|
canBypass: false,
|
package/package.json
CHANGED
|
@@ -87,6 +87,16 @@ export const MainnetPerpMarkets: PerpMarketConfig[] = [
|
|
|
87
87
|
launchTs: 1670347281000,
|
|
88
88
|
oracleSource: OracleSource.PYTH,
|
|
89
89
|
},
|
|
90
|
+
{
|
|
91
|
+
fullName: 'Aptos',
|
|
92
|
+
category: ['L1', 'Infra'],
|
|
93
|
+
symbol: 'APT-PERP',
|
|
94
|
+
baseAssetSymbol: 'APT',
|
|
95
|
+
marketIndex: 3,
|
|
96
|
+
oracle: new PublicKey('FNNvb1AFDnDVPkocEri8mWbJ1952HQZtFLuwPiUjSJQ'),
|
|
97
|
+
launchTs: 1675802661000,
|
|
98
|
+
oracleSource: OracleSource.PYTH,
|
|
99
|
+
},
|
|
90
100
|
];
|
|
91
101
|
|
|
92
102
|
export const PerpMarkets: { [key in DriftEnv]: PerpMarketConfig[] } = {
|
package/src/events/fetchLogs.ts
CHANGED
|
@@ -61,15 +61,15 @@ export async function fetchLogs(
|
|
|
61
61
|
|
|
62
62
|
const chunkedSignatures = chunk(filteredSignatures, 100);
|
|
63
63
|
|
|
64
|
+
const config = { commitment: finality, maxSupportedTransactionVersion: 0 };
|
|
65
|
+
|
|
64
66
|
const transactionLogs = (
|
|
65
67
|
await Promise.all(
|
|
66
68
|
chunkedSignatures.map(async (chunk) => {
|
|
67
69
|
const transactions = await connection.getTransactions(
|
|
68
70
|
chunk.map((confirmedSignature) => confirmedSignature.signature),
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
maxSupportedTransactionVersion: 0,
|
|
72
|
-
}
|
|
71
|
+
//@ts-ignore
|
|
72
|
+
config
|
|
73
73
|
);
|
|
74
74
|
|
|
75
75
|
return transactions.reduce((logs, transaction) => {
|
package/src/idl/drift.json
CHANGED
package/src/math/market.ts
CHANGED
|
@@ -25,9 +25,11 @@ import {
|
|
|
25
25
|
MARGIN_PRECISION,
|
|
26
26
|
PRICE_TO_QUOTE_PRECISION,
|
|
27
27
|
ZERO,
|
|
28
|
+
QUOTE_SPOT_MARKET_INDEX,
|
|
28
29
|
} from '../constants/numericConstants';
|
|
29
30
|
import { getTokenAmount } from './spotBalance';
|
|
30
31
|
import { DLOB } from '../dlob/DLOB';
|
|
32
|
+
import { assert } from '../assert/assert';
|
|
31
33
|
|
|
32
34
|
/**
|
|
33
35
|
* Calculates market mark price
|
|
@@ -131,7 +133,7 @@ export function calculateMarketMarginRatio(
|
|
|
131
133
|
): number {
|
|
132
134
|
let marginRatio;
|
|
133
135
|
switch (marginCategory) {
|
|
134
|
-
case 'Initial':
|
|
136
|
+
case 'Initial': {
|
|
135
137
|
marginRatio = calculateSizePremiumLiabilityWeight(
|
|
136
138
|
size,
|
|
137
139
|
new BN(market.imfFactor),
|
|
@@ -139,7 +141,8 @@ export function calculateMarketMarginRatio(
|
|
|
139
141
|
MARGIN_PRECISION
|
|
140
142
|
).toNumber();
|
|
141
143
|
break;
|
|
142
|
-
|
|
144
|
+
}
|
|
145
|
+
case 'Maintenance': {
|
|
143
146
|
marginRatio = calculateSizePremiumLiabilityWeight(
|
|
144
147
|
size,
|
|
145
148
|
new BN(market.imfFactor),
|
|
@@ -147,6 +150,7 @@ export function calculateMarketMarginRatio(
|
|
|
147
150
|
MARGIN_PRECISION
|
|
148
151
|
).toNumber();
|
|
149
152
|
break;
|
|
153
|
+
}
|
|
150
154
|
}
|
|
151
155
|
|
|
152
156
|
return marginRatio;
|
|
@@ -202,6 +206,25 @@ export function calculateMarketAvailablePNL(
|
|
|
202
206
|
);
|
|
203
207
|
}
|
|
204
208
|
|
|
209
|
+
export function calculateMarketMaxAvailableInsurance(
|
|
210
|
+
perpMarket: PerpMarketAccount,
|
|
211
|
+
spotMarket: SpotMarketAccount
|
|
212
|
+
): BN {
|
|
213
|
+
assert(spotMarket.marketIndex == QUOTE_SPOT_MARKET_INDEX);
|
|
214
|
+
|
|
215
|
+
// todo: insuranceFundAllocation technically not guaranteed to be in Insurance Fund
|
|
216
|
+
const insuranceFundAllocation =
|
|
217
|
+
perpMarket.insuranceClaim.quoteMaxInsurance.sub(
|
|
218
|
+
perpMarket.insuranceClaim.quoteSettledInsurance
|
|
219
|
+
);
|
|
220
|
+
const ammFeePool = getTokenAmount(
|
|
221
|
+
perpMarket.amm.feePool.scaledBalance,
|
|
222
|
+
spotMarket,
|
|
223
|
+
SpotBalanceType.DEPOSIT
|
|
224
|
+
);
|
|
225
|
+
return insuranceFundAllocation.add(ammFeePool);
|
|
226
|
+
}
|
|
227
|
+
|
|
205
228
|
export function calculateNetUserPnl(
|
|
206
229
|
perpMarket: PerpMarketAccount,
|
|
207
230
|
oraclePriceData: OraclePriceData
|
package/src/math/spotBalance.ts
CHANGED
|
@@ -146,27 +146,27 @@ export function calculateAssetWeight(
|
|
|
146
146
|
}
|
|
147
147
|
|
|
148
148
|
export function calculateLiabilityWeight(
|
|
149
|
-
|
|
149
|
+
size: BN,
|
|
150
150
|
spotMarket: SpotMarketAccount,
|
|
151
151
|
marginCategory: MarginCategory
|
|
152
152
|
): BN {
|
|
153
153
|
const sizePrecision = TEN.pow(new BN(spotMarket.decimals));
|
|
154
154
|
let sizeInAmmReservePrecision;
|
|
155
155
|
if (sizePrecision.gt(AMM_RESERVE_PRECISION)) {
|
|
156
|
-
sizeInAmmReservePrecision =
|
|
156
|
+
sizeInAmmReservePrecision = size.div(
|
|
157
157
|
sizePrecision.div(AMM_RESERVE_PRECISION)
|
|
158
158
|
);
|
|
159
159
|
} else {
|
|
160
|
-
sizeInAmmReservePrecision =
|
|
160
|
+
sizeInAmmReservePrecision = size
|
|
161
161
|
.mul(AMM_RESERVE_PRECISION)
|
|
162
162
|
.div(sizePrecision);
|
|
163
163
|
}
|
|
164
164
|
|
|
165
|
-
let
|
|
165
|
+
let liabilityWeight;
|
|
166
166
|
|
|
167
167
|
switch (marginCategory) {
|
|
168
168
|
case 'Initial':
|
|
169
|
-
|
|
169
|
+
liabilityWeight = calculateSizePremiumLiabilityWeight(
|
|
170
170
|
sizeInAmmReservePrecision,
|
|
171
171
|
new BN(spotMarket.imfFactor),
|
|
172
172
|
new BN(spotMarket.initialLiabilityWeight),
|
|
@@ -174,7 +174,7 @@ export function calculateLiabilityWeight(
|
|
|
174
174
|
);
|
|
175
175
|
break;
|
|
176
176
|
case 'Maintenance':
|
|
177
|
-
|
|
177
|
+
liabilityWeight = calculateSizePremiumLiabilityWeight(
|
|
178
178
|
sizeInAmmReservePrecision,
|
|
179
179
|
new BN(spotMarket.imfFactor),
|
|
180
180
|
new BN(spotMarket.maintenanceLiabilityWeight),
|
|
@@ -182,11 +182,11 @@ export function calculateLiabilityWeight(
|
|
|
182
182
|
);
|
|
183
183
|
break;
|
|
184
184
|
default:
|
|
185
|
-
|
|
185
|
+
liabilityWeight = spotMarket.initialLiabilityWeight;
|
|
186
186
|
break;
|
|
187
187
|
}
|
|
188
188
|
|
|
189
|
-
return
|
|
189
|
+
return liabilityWeight;
|
|
190
190
|
}
|
|
191
191
|
|
|
192
192
|
export function calculateUtilization(bank: SpotMarketAccount): BN {
|