@drift-labs/sdk 2.33.1-beta.2 → 2.33.1-beta.4
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/idl/drift.json +5 -2
- package/lib/math/oracles.js +2 -3
- package/lib/math/spotBalance.d.ts +4 -0
- package/lib/math/spotBalance.js +28 -3
- package/lib/types.d.ts +2 -2
- package/package.json +1 -1
- package/src/idl/drift.json +5 -2
- package/src/math/oracles.ts +7 -7
- package/src/math/spotBalance.ts +72 -4
- package/src/types.ts +2 -2
- package/tests/dlob/helpers.ts +2 -2
package/VERSION
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
2.33.1-beta.
|
|
1
|
+
2.33.1-beta.4
|
package/lib/idl/drift.json
CHANGED
|
@@ -6900,11 +6900,11 @@
|
|
|
6900
6900
|
"kind": "struct",
|
|
6901
6901
|
"fields": [
|
|
6902
6902
|
{
|
|
6903
|
-
"name": "
|
|
6903
|
+
"name": "markOraclePercentDivergence",
|
|
6904
6904
|
"type": "u64"
|
|
6905
6905
|
},
|
|
6906
6906
|
{
|
|
6907
|
-
"name": "
|
|
6907
|
+
"name": "oracleTwap5minPercentDivergence",
|
|
6908
6908
|
"type": "u64"
|
|
6909
6909
|
}
|
|
6910
6910
|
]
|
|
@@ -7637,6 +7637,9 @@
|
|
|
7637
7637
|
{
|
|
7638
7638
|
"name": "Initial"
|
|
7639
7639
|
},
|
|
7640
|
+
{
|
|
7641
|
+
"name": "Fill"
|
|
7642
|
+
},
|
|
7640
7643
|
{
|
|
7641
7644
|
"name": "Maintenance"
|
|
7642
7645
|
}
|
package/lib/math/oracles.js
CHANGED
|
@@ -45,9 +45,8 @@ function isOracleTooDivergent(amm, oraclePriceData, oracleGuardRails, now) {
|
|
|
45
45
|
.div(sinceStart.add(sinceLastUpdate));
|
|
46
46
|
const oracleSpread = oracleTwap5min.sub(oraclePriceData.price);
|
|
47
47
|
const oracleSpreadPct = oracleSpread.mul(numericConstants_1.PRICE_PRECISION).div(oracleTwap5min);
|
|
48
|
-
const
|
|
49
|
-
|
|
50
|
-
.gte(numericConstants_1.BID_ASK_SPREAD_PRECISION.mul(oracleGuardRails.priceDivergence.markOracleDivergenceNumerator).div(oracleGuardRails.priceDivergence.markOracleDivergenceDenominator));
|
|
48
|
+
const maxDivergence = index_1.BN.max(oracleGuardRails.priceDivergence.markOraclePercentDivergence, numericConstants_1.PERCENTAGE_PRECISION.div(new index_1.BN(10)));
|
|
49
|
+
const tooDivergent = oracleSpreadPct.abs().gte(maxDivergence);
|
|
51
50
|
return tooDivergent;
|
|
52
51
|
}
|
|
53
52
|
exports.isOracleTooDivergent = isOracleTooDivergent;
|
|
@@ -67,6 +67,10 @@ export declare function calculateInterestAccumulated(bank: SpotMarketAccount, no
|
|
|
67
67
|
borrowInterest: BN;
|
|
68
68
|
depositInterest: BN;
|
|
69
69
|
};
|
|
70
|
+
export declare function calculateTokenUtilizationLimits(depositTokenAmount: BN, borrowTokenAmount: BN, spotMarket: SpotMarketAccount): {
|
|
71
|
+
minDepositTokensForUtilization: BN;
|
|
72
|
+
maxBorrowTokensForUtilization: BN;
|
|
73
|
+
};
|
|
70
74
|
export declare function calculateWithdrawLimit(spotMarket: SpotMarketAccount, now: BN): {
|
|
71
75
|
borrowLimit: BN;
|
|
72
76
|
withdrawLimit: BN;
|
package/lib/math/spotBalance.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.calculateWithdrawLimit = exports.calculateInterestAccumulated = exports.calculateBorrowRate = exports.calculateDepositRate = exports.calculateInterestRate = exports.calculateSpotMarketBorrowCapacity = exports.calculateUtilization = exports.calculateLiabilityWeight = exports.calculateAssetWeight = exports.getTokenValue = exports.getStrictTokenValue = exports.getSignedTokenAmount = exports.getTokenAmount = exports.getBalance = void 0;
|
|
3
|
+
exports.calculateWithdrawLimit = exports.calculateTokenUtilizationLimits = exports.calculateInterestAccumulated = exports.calculateBorrowRate = exports.calculateDepositRate = exports.calculateInterestRate = exports.calculateSpotMarketBorrowCapacity = exports.calculateUtilization = exports.calculateLiabilityWeight = exports.calculateAssetWeight = exports.getTokenValue = exports.getStrictTokenValue = exports.getSignedTokenAmount = exports.getTokenAmount = exports.getBalance = void 0;
|
|
4
4
|
const types_1 = require("../types");
|
|
5
5
|
const anchor_1 = require("@coral-xyz/anchor");
|
|
6
6
|
const numericConstants_1 = require("../constants/numericConstants");
|
|
@@ -281,6 +281,27 @@ function calculateInterestAccumulated(bank, now) {
|
|
|
281
281
|
return { borrowInterest, depositInterest };
|
|
282
282
|
}
|
|
283
283
|
exports.calculateInterestAccumulated = calculateInterestAccumulated;
|
|
284
|
+
function calculateTokenUtilizationLimits(depositTokenAmount, borrowTokenAmount, spotMarket) {
|
|
285
|
+
// Calculates the allowable minimum deposit and maximum borrow amounts for immediate withdrawal based on market utilization.
|
|
286
|
+
// First, it determines a maximum withdrawal utilization from the market's target and historic utilization.
|
|
287
|
+
// Then, it deduces corresponding deposit/borrow amounts.
|
|
288
|
+
// Note: For deposit sizes below the guard threshold, withdrawals aren't blocked.
|
|
289
|
+
const maxWithdrawUtilization = anchor_1.BN.max(spotMarket.optimalUtilization, spotMarket.utilizationTwap.add(numericConstants_1.SPOT_MARKET_UTILIZATION_PRECISION.sub(spotMarket.utilizationTwap).div(new anchor_1.BN(2))));
|
|
290
|
+
let minDepositTokensForUtilization = borrowTokenAmount
|
|
291
|
+
.mul(numericConstants_1.SPOT_MARKET_UTILIZATION_PRECISION)
|
|
292
|
+
.div(maxWithdrawUtilization);
|
|
293
|
+
// don't block withdraws for deposit sizes below guard threshold
|
|
294
|
+
minDepositTokensForUtilization = anchor_1.BN.min(minDepositTokensForUtilization, depositTokenAmount.sub(spotMarket.withdrawGuardThreshold));
|
|
295
|
+
let maxBorrowTokensForUtilization = maxWithdrawUtilization
|
|
296
|
+
.mul(depositTokenAmount)
|
|
297
|
+
.div(numericConstants_1.SPOT_MARKET_UTILIZATION_PRECISION);
|
|
298
|
+
maxBorrowTokensForUtilization = anchor_1.BN.max(spotMarket.withdrawGuardThreshold, maxBorrowTokensForUtilization);
|
|
299
|
+
return {
|
|
300
|
+
minDepositTokensForUtilization,
|
|
301
|
+
maxBorrowTokensForUtilization,
|
|
302
|
+
};
|
|
303
|
+
}
|
|
304
|
+
exports.calculateTokenUtilizationLimits = calculateTokenUtilizationLimits;
|
|
284
305
|
function calculateWithdrawLimit(spotMarket, now) {
|
|
285
306
|
const marketDepositTokenAmount = getTokenAmount(spotMarket.depositBalance, spotMarket, types_1.SpotBalanceType.DEPOSIT);
|
|
286
307
|
const marketBorrowTokenAmount = getTokenAmount(spotMarket.borrowBalance, spotMarket, types_1.SpotBalanceType.BORROW);
|
|
@@ -295,8 +316,12 @@ function calculateWithdrawLimit(spotMarket, now) {
|
|
|
295
316
|
.mul(sinceStart)
|
|
296
317
|
.add(marketDepositTokenAmount.mul(sinceLast))
|
|
297
318
|
.div(sinceLast.add(sinceStart));
|
|
298
|
-
const
|
|
299
|
-
const
|
|
319
|
+
const lesserDepositAmount = anchor_1.BN.min(marketDepositTokenAmount, depositTokenTwapLive);
|
|
320
|
+
const maxBorrowTokensTwap = anchor_1.BN.max(spotMarket.withdrawGuardThreshold, anchor_1.BN.min(anchor_1.BN.max(marketDepositTokenAmount.div(new anchor_1.BN(6)), borrowTokenTwapLive.add(lesserDepositAmount.div(new anchor_1.BN(10)))), lesserDepositAmount.sub(lesserDepositAmount.div(new anchor_1.BN(5))))); // between ~15-80% utilization with friction on twap
|
|
321
|
+
const minDepositTokensTwap = depositTokenTwapLive.sub(anchor_1.BN.max(depositTokenTwapLive.div(new anchor_1.BN(4)), anchor_1.BN.min(spotMarket.withdrawGuardThreshold, depositTokenTwapLive)));
|
|
322
|
+
const { minDepositTokensForUtilization, maxBorrowTokensForUtilization } = calculateTokenUtilizationLimits(marketDepositTokenAmount, marketBorrowTokenAmount, spotMarket);
|
|
323
|
+
const minDepositTokens = anchor_1.BN.max(minDepositTokensForUtilization, minDepositTokensTwap);
|
|
324
|
+
const maxBorrowTokens = anchor_1.BN.min(maxBorrowTokensForUtilization, maxBorrowTokensTwap);
|
|
300
325
|
const withdrawLimit = anchor_1.BN.max(marketDepositTokenAmount.sub(minDepositTokens), numericConstants_1.ZERO);
|
|
301
326
|
let borrowLimit = maxBorrowTokens.sub(marketBorrowTokenAmount);
|
|
302
327
|
borrowLimit = anchor_1.BN.min(borrowLimit, marketDepositTokenAmount.sub(marketBorrowTokenAmount));
|
package/lib/types.d.ts
CHANGED
|
@@ -1035,8 +1035,8 @@ export type OrderFillerRewardStructure = {
|
|
|
1035
1035
|
};
|
|
1036
1036
|
export type OracleGuardRails = {
|
|
1037
1037
|
priceDivergence: {
|
|
1038
|
-
|
|
1039
|
-
|
|
1038
|
+
markOraclePercentDivergence: BN;
|
|
1039
|
+
oracleTwap5MinPercentDivergence: BN;
|
|
1040
1040
|
};
|
|
1041
1041
|
validity: {
|
|
1042
1042
|
slotsBeforeStaleForAmm: BN;
|
package/package.json
CHANGED
package/src/idl/drift.json
CHANGED
|
@@ -6900,11 +6900,11 @@
|
|
|
6900
6900
|
"kind": "struct",
|
|
6901
6901
|
"fields": [
|
|
6902
6902
|
{
|
|
6903
|
-
"name": "
|
|
6903
|
+
"name": "markOraclePercentDivergence",
|
|
6904
6904
|
"type": "u64"
|
|
6905
6905
|
},
|
|
6906
6906
|
{
|
|
6907
|
-
"name": "
|
|
6907
|
+
"name": "oracleTwap5minPercentDivergence",
|
|
6908
6908
|
"type": "u64"
|
|
6909
6909
|
}
|
|
6910
6910
|
]
|
|
@@ -7637,6 +7637,9 @@
|
|
|
7637
7637
|
{
|
|
7638
7638
|
"name": "Initial"
|
|
7639
7639
|
},
|
|
7640
|
+
{
|
|
7641
|
+
"name": "Fill"
|
|
7642
|
+
},
|
|
7640
7643
|
{
|
|
7641
7644
|
"name": "Maintenance"
|
|
7642
7645
|
}
|
package/src/math/oracles.ts
CHANGED
|
@@ -7,6 +7,7 @@ import {
|
|
|
7
7
|
ONE,
|
|
8
8
|
ZERO,
|
|
9
9
|
FIVE_MINUTE,
|
|
10
|
+
PERCENTAGE_PRECISION,
|
|
10
11
|
} from '../constants/numericConstants';
|
|
11
12
|
import { BN, HistoricalOracleData, PerpMarketAccount } from '../index';
|
|
12
13
|
import { assert } from '../assert/assert';
|
|
@@ -78,13 +79,12 @@ export function isOracleTooDivergent(
|
|
|
78
79
|
const oracleSpread = oracleTwap5min.sub(oraclePriceData.price);
|
|
79
80
|
const oracleSpreadPct = oracleSpread.mul(PRICE_PRECISION).div(oracleTwap5min);
|
|
80
81
|
|
|
81
|
-
const
|
|
82
|
-
.
|
|
83
|
-
.
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
);
|
|
82
|
+
const maxDivergence = BN.max(
|
|
83
|
+
oracleGuardRails.priceDivergence.markOraclePercentDivergence,
|
|
84
|
+
PERCENTAGE_PRECISION.div(new BN(10))
|
|
85
|
+
);
|
|
86
|
+
|
|
87
|
+
const tooDivergent = oracleSpreadPct.abs().gte(maxDivergence);
|
|
88
88
|
|
|
89
89
|
return tooDivergent;
|
|
90
90
|
}
|
package/src/math/spotBalance.ts
CHANGED
|
@@ -416,6 +416,53 @@ export function calculateInterestAccumulated(
|
|
|
416
416
|
return { borrowInterest, depositInterest };
|
|
417
417
|
}
|
|
418
418
|
|
|
419
|
+
export function calculateTokenUtilizationLimits(
|
|
420
|
+
depositTokenAmount: BN,
|
|
421
|
+
borrowTokenAmount: BN,
|
|
422
|
+
spotMarket: SpotMarketAccount
|
|
423
|
+
): {
|
|
424
|
+
minDepositTokensForUtilization: BN;
|
|
425
|
+
maxBorrowTokensForUtilization: BN;
|
|
426
|
+
} {
|
|
427
|
+
// Calculates the allowable minimum deposit and maximum borrow amounts for immediate withdrawal based on market utilization.
|
|
428
|
+
// First, it determines a maximum withdrawal utilization from the market's target and historic utilization.
|
|
429
|
+
// Then, it deduces corresponding deposit/borrow amounts.
|
|
430
|
+
// Note: For deposit sizes below the guard threshold, withdrawals aren't blocked.
|
|
431
|
+
|
|
432
|
+
const maxWithdrawUtilization = BN.max(
|
|
433
|
+
spotMarket.optimalUtilization,
|
|
434
|
+
spotMarket.utilizationTwap.add(
|
|
435
|
+
SPOT_MARKET_UTILIZATION_PRECISION.sub(spotMarket.utilizationTwap).div(
|
|
436
|
+
new BN(2)
|
|
437
|
+
)
|
|
438
|
+
)
|
|
439
|
+
);
|
|
440
|
+
|
|
441
|
+
let minDepositTokensForUtilization = borrowTokenAmount
|
|
442
|
+
.mul(SPOT_MARKET_UTILIZATION_PRECISION)
|
|
443
|
+
.div(maxWithdrawUtilization);
|
|
444
|
+
|
|
445
|
+
// don't block withdraws for deposit sizes below guard threshold
|
|
446
|
+
minDepositTokensForUtilization = BN.min(
|
|
447
|
+
minDepositTokensForUtilization,
|
|
448
|
+
depositTokenAmount.sub(spotMarket.withdrawGuardThreshold)
|
|
449
|
+
);
|
|
450
|
+
|
|
451
|
+
let maxBorrowTokensForUtilization = maxWithdrawUtilization
|
|
452
|
+
.mul(depositTokenAmount)
|
|
453
|
+
.div(SPOT_MARKET_UTILIZATION_PRECISION);
|
|
454
|
+
|
|
455
|
+
maxBorrowTokensForUtilization = BN.max(
|
|
456
|
+
spotMarket.withdrawGuardThreshold,
|
|
457
|
+
maxBorrowTokensForUtilization
|
|
458
|
+
);
|
|
459
|
+
|
|
460
|
+
return {
|
|
461
|
+
minDepositTokensForUtilization,
|
|
462
|
+
maxBorrowTokensForUtilization,
|
|
463
|
+
};
|
|
464
|
+
}
|
|
465
|
+
|
|
419
466
|
export function calculateWithdrawLimit(
|
|
420
467
|
spotMarket: SpotMarketAccount,
|
|
421
468
|
now: BN
|
|
@@ -451,24 +498,45 @@ export function calculateWithdrawLimit(
|
|
|
451
498
|
.add(marketDepositTokenAmount.mul(sinceLast))
|
|
452
499
|
.div(sinceLast.add(sinceStart));
|
|
453
500
|
|
|
454
|
-
const
|
|
501
|
+
const lesserDepositAmount = BN.min(
|
|
502
|
+
marketDepositTokenAmount,
|
|
503
|
+
depositTokenTwapLive
|
|
504
|
+
);
|
|
505
|
+
const maxBorrowTokensTwap = BN.max(
|
|
455
506
|
spotMarket.withdrawGuardThreshold,
|
|
456
507
|
BN.min(
|
|
457
508
|
BN.max(
|
|
458
509
|
marketDepositTokenAmount.div(new BN(6)),
|
|
459
|
-
borrowTokenTwapLive.add(
|
|
510
|
+
borrowTokenTwapLive.add(lesserDepositAmount.div(new BN(10)))
|
|
460
511
|
),
|
|
461
|
-
|
|
512
|
+
lesserDepositAmount.sub(lesserDepositAmount.div(new BN(5)))
|
|
462
513
|
)
|
|
463
514
|
); // between ~15-80% utilization with friction on twap
|
|
464
515
|
|
|
465
|
-
const
|
|
516
|
+
const minDepositTokensTwap = depositTokenTwapLive.sub(
|
|
466
517
|
BN.max(
|
|
467
518
|
depositTokenTwapLive.div(new BN(4)),
|
|
468
519
|
BN.min(spotMarket.withdrawGuardThreshold, depositTokenTwapLive)
|
|
469
520
|
)
|
|
470
521
|
);
|
|
471
522
|
|
|
523
|
+
const { minDepositTokensForUtilization, maxBorrowTokensForUtilization } =
|
|
524
|
+
calculateTokenUtilizationLimits(
|
|
525
|
+
marketDepositTokenAmount,
|
|
526
|
+
marketBorrowTokenAmount,
|
|
527
|
+
spotMarket
|
|
528
|
+
);
|
|
529
|
+
|
|
530
|
+
const minDepositTokens = BN.max(
|
|
531
|
+
minDepositTokensForUtilization,
|
|
532
|
+
minDepositTokensTwap
|
|
533
|
+
);
|
|
534
|
+
|
|
535
|
+
const maxBorrowTokens = BN.min(
|
|
536
|
+
maxBorrowTokensForUtilization,
|
|
537
|
+
maxBorrowTokensTwap
|
|
538
|
+
);
|
|
539
|
+
|
|
472
540
|
const withdrawLimit = BN.max(
|
|
473
541
|
marketDepositTokenAmount.sub(minDepositTokens),
|
|
474
542
|
ZERO
|
package/src/types.ts
CHANGED
|
@@ -1013,8 +1013,8 @@ export type OrderFillerRewardStructure = {
|
|
|
1013
1013
|
|
|
1014
1014
|
export type OracleGuardRails = {
|
|
1015
1015
|
priceDivergence: {
|
|
1016
|
-
|
|
1017
|
-
|
|
1016
|
+
markOraclePercentDivergence: BN;
|
|
1017
|
+
oracleTwap5MinPercentDivergence: BN;
|
|
1018
1018
|
};
|
|
1019
1019
|
validity: {
|
|
1020
1020
|
slotsBeforeStaleForAmm: BN;
|
package/tests/dlob/helpers.ts
CHANGED
|
@@ -511,8 +511,8 @@ export const mockStateAccount: StateAccount = {
|
|
|
511
511
|
liquidationDuration: 0,
|
|
512
512
|
oracleGuardRails: {
|
|
513
513
|
priceDivergence: {
|
|
514
|
-
|
|
515
|
-
|
|
514
|
+
markOraclePercentDivergence: new BN(0),
|
|
515
|
+
oracleTwap5MinPercentDivergence: new BN(0),
|
|
516
516
|
},
|
|
517
517
|
validity: {
|
|
518
518
|
slotsBeforeStaleForAmm: new BN(0),
|