@gearbox-protocol/sdk 13.0.0-beta.3 → 13.0.0-beta.5
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/dist/cjs/abi/iPriceFeed.js +84 -0
- package/dist/cjs/common-utils/index.js +22 -0
- package/dist/cjs/common-utils/package.json +1 -0
- package/dist/cjs/{sdk → common-utils}/utils/assetsMath.js +88 -21
- package/dist/cjs/common-utils/utils/bigintMath.js +65 -0
- package/dist/cjs/common-utils/utils/creditAccount/calcHealthFactor.js +76 -0
- package/dist/cjs/common-utils/utils/creditAccount/calcOverallAPY.js +81 -0
- package/dist/cjs/{sdk/utils/priceMath.js → common-utils/utils/creditAccount/calcQuotaBorrowRate.js} +19 -12
- package/dist/cjs/{sdk/utils/bigintMath.js → common-utils/utils/creditAccount/calcRelativeBaseBorrowRate.js} +11 -10
- package/dist/cjs/common-utils/utils/creditAccount/debt.js +64 -0
- package/dist/cjs/common-utils/utils/creditAccount/getTimeToLiquidation.js +38 -0
- package/dist/cjs/common-utils/utils/creditAccount/index.js +38 -0
- package/dist/cjs/common-utils/utils/creditAccount/liquidationPrice.js +47 -0
- package/dist/cjs/common-utils/utils/creditAccount/quotaUtils.js +149 -0
- package/dist/cjs/common-utils/utils/creditAccount/sort.js +95 -0
- package/dist/cjs/common-utils/utils/creditAccount/types.js +16 -0
- package/dist/cjs/{sdk → common-utils}/utils/endpoints.js +11 -17
- package/dist/cjs/common-utils/utils/index.js +30 -0
- package/dist/cjs/common-utils/utils/priceMath.js +66 -0
- package/dist/cjs/permissionless/bindings/cross-chain-multisig.js +3 -3
- package/dist/cjs/permissionless/bindings/instance-manager.js +2 -2
- package/dist/cjs/plugins/adapters/contracts/MellowDepositQueueAdapterContract.js +0 -6
- package/dist/cjs/plugins/adapters/contracts/MellowRedeemQueueAdapterContract.js +0 -6
- package/dist/cjs/sdk/GearboxSDK.js +0 -2
- package/dist/cjs/sdk/base/BaseContract.js +5 -2
- package/dist/cjs/sdk/base/ChainContractsRegister.js +2 -10
- package/dist/cjs/sdk/base/Construct.js +25 -19
- package/dist/cjs/sdk/base/SDKConstruct.js +1 -1
- package/dist/cjs/sdk/market/adapters/PlaceholderAdapterContracts.js +16 -0
- package/dist/cjs/sdk/market/pricefeeds/updates/PriceUpdatesCache.js +0 -17
- package/dist/cjs/sdk/market/pricefeeds/updates/PythUpdater.js +1 -1
- package/dist/cjs/sdk/market/pricefeeds/updates/RedstoneUpdater.js +1 -1
- package/dist/cjs/sdk/market/pricefeeds/updates/fetchPythPayloads.js +2 -2
- package/dist/cjs/sdk/utils/formatter.js +3 -3
- package/dist/cjs/sdk/utils/index.js +0 -10
- package/dist/esm/abi/iPriceFeed.js +60 -0
- package/dist/esm/common-utils/index.js +1 -0
- package/dist/esm/common-utils/package.json +1 -0
- package/dist/esm/{sdk → common-utils}/utils/assetsMath.js +80 -13
- package/dist/esm/common-utils/utils/bigintMath.js +41 -0
- package/dist/esm/common-utils/utils/creditAccount/calcHealthFactor.js +55 -0
- package/dist/esm/common-utils/utils/creditAccount/calcOverallAPY.js +60 -0
- package/dist/esm/common-utils/utils/creditAccount/calcQuotaBorrowRate.js +18 -0
- package/dist/esm/common-utils/utils/creditAccount/calcRelativeBaseBorrowRate.js +10 -0
- package/dist/esm/common-utils/utils/creditAccount/debt.js +43 -0
- package/dist/esm/common-utils/utils/creditAccount/getTimeToLiquidation.js +18 -0
- package/dist/esm/common-utils/utils/creditAccount/index.js +9 -0
- package/dist/esm/common-utils/utils/creditAccount/liquidationPrice.js +23 -0
- package/dist/esm/common-utils/utils/creditAccount/quotaUtils.js +125 -0
- package/dist/esm/common-utils/utils/creditAccount/sort.js +67 -0
- package/dist/esm/common-utils/utils/creditAccount/types.js +0 -0
- package/dist/esm/{sdk → common-utils}/utils/endpoints.js +9 -14
- package/dist/esm/common-utils/utils/index.js +5 -0
- package/dist/esm/common-utils/utils/priceMath.js +42 -0
- package/dist/esm/permissionless/bindings/cross-chain-multisig.js +3 -3
- package/dist/esm/permissionless/bindings/instance-manager.js +2 -2
- package/dist/esm/plugins/adapters/contracts/MellowDepositQueueAdapterContract.js +0 -6
- package/dist/esm/plugins/adapters/contracts/MellowRedeemQueueAdapterContract.js +0 -6
- package/dist/esm/sdk/GearboxSDK.js +0 -2
- package/dist/esm/sdk/base/BaseContract.js +5 -2
- package/dist/esm/sdk/base/ChainContractsRegister.js +2 -10
- package/dist/esm/sdk/base/Construct.js +25 -19
- package/dist/esm/sdk/base/SDKConstruct.js +1 -1
- package/dist/esm/sdk/market/adapters/PlaceholderAdapterContracts.js +16 -0
- package/dist/esm/sdk/market/pricefeeds/updates/PriceUpdatesCache.js +0 -17
- package/dist/esm/sdk/market/pricefeeds/updates/PythUpdater.js +1 -1
- package/dist/esm/sdk/market/pricefeeds/updates/RedstoneUpdater.js +1 -1
- package/dist/esm/sdk/market/pricefeeds/updates/fetchPythPayloads.js +2 -2
- package/dist/esm/sdk/utils/formatter.js +1 -1
- package/dist/esm/sdk/utils/index.js +0 -5
- package/dist/types/abi/iPriceFeed.d.ts +87 -0
- package/dist/types/common-utils/index.d.ts +1 -0
- package/dist/types/common-utils/utils/assetsMath.d.ts +114 -0
- package/dist/types/common-utils/utils/bigintMath.d.ts +43 -0
- package/dist/types/common-utils/utils/creditAccount/calcHealthFactor.d.ts +25 -0
- package/dist/types/common-utils/utils/creditAccount/calcOverallAPY.d.ts +37 -0
- package/dist/types/common-utils/utils/creditAccount/calcQuotaBorrowRate.d.ts +18 -0
- package/dist/types/common-utils/utils/creditAccount/calcRelativeBaseBorrowRate.d.ts +15 -0
- package/dist/types/common-utils/utils/creditAccount/debt.d.ts +35 -0
- package/dist/types/common-utils/utils/creditAccount/getTimeToLiquidation.d.ts +16 -0
- package/dist/types/common-utils/utils/creditAccount/index.d.ts +9 -0
- package/dist/types/common-utils/utils/creditAccount/liquidationPrice.d.ts +25 -0
- package/dist/types/common-utils/utils/creditAccount/quotaUtils.d.ts +81 -0
- package/dist/types/common-utils/utils/creditAccount/sort.d.ts +55 -0
- package/dist/types/common-utils/utils/creditAccount/types.d.ts +18 -0
- package/dist/types/{sdk → common-utils}/utils/endpoints.d.ts +13 -5
- package/dist/types/common-utils/utils/index.d.ts +5 -0
- package/dist/types/common-utils/utils/priceMath.d.ts +47 -0
- package/dist/types/permissionless/bindings/cross-chain-multisig.d.ts +3 -3
- package/dist/types/permissionless/bindings/instance-manager.d.ts +3 -3
- package/dist/types/plugins/adapters/contracts/MellowDepositQueueAdapterContract.d.ts +1 -4
- package/dist/types/plugins/adapters/contracts/MellowRedeemQueueAdapterContract.d.ts +1 -4
- package/dist/types/sdk/base/ChainContractsRegister.d.ts +0 -2
- package/dist/types/sdk/base/Construct.d.ts +7 -10
- package/dist/types/sdk/market/adapters/PlaceholderAdapterContracts.d.ts +2 -1
- package/dist/types/sdk/market/pricefeeds/updates/PriceUpdatesCache.d.ts +1 -8
- package/dist/types/sdk/utils/index.d.ts +0 -5
- package/package.json +11 -2
- package/dist/cjs/sdk/utils/creditAccount.js +0 -409
- package/dist/esm/sdk/utils/bigintMath.js +0 -9
- package/dist/esm/sdk/utils/creditAccount.js +0 -396
- package/dist/esm/sdk/utils/priceMath.js +0 -11
- package/dist/types/sdk/utils/assetsMath.d.ts +0 -42
- package/dist/types/sdk/utils/bigintMath.d.ts +0 -6
- package/dist/types/sdk/utils/creditAccount.d.ts +0 -128
- package/dist/types/sdk/utils/priceMath.d.ts +0 -9
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
import {
|
|
2
|
+
PERCENTAGE_FACTOR,
|
|
3
|
+
PRICE_DECIMALS_POW,
|
|
4
|
+
WAD_DECIMALS_POW
|
|
5
|
+
} from "../../../sdk/index.js";
|
|
6
|
+
import { BigIntMath } from "../bigintMath.js";
|
|
7
|
+
import { PriceUtils } from "../priceMath.js";
|
|
8
|
+
function calcMaxDebtIncrease(healthFactor, debt, underlyingLT, minHf = Number(PERCENTAGE_FACTOR)) {
|
|
9
|
+
const result = debt * BigInt(healthFactor - minHf) / BigInt(minHf - underlyingLT);
|
|
10
|
+
return BigIntMath.max(0n, result);
|
|
11
|
+
}
|
|
12
|
+
function calcMaxLendingDebt({
|
|
13
|
+
assets,
|
|
14
|
+
liquidationThresholds,
|
|
15
|
+
underlyingToken,
|
|
16
|
+
prices,
|
|
17
|
+
tokensList,
|
|
18
|
+
targetHF = PERCENTAGE_FACTOR
|
|
19
|
+
}) {
|
|
20
|
+
const assetsLTMoney = assets.reduce(
|
|
21
|
+
(acc, { token: tokenAddress, balance: amount }) => {
|
|
22
|
+
const tokenDecimals = tokensList[tokenAddress]?.decimals || 18;
|
|
23
|
+
const lt = liquidationThresholds[tokenAddress] || 0n;
|
|
24
|
+
const price = prices[tokenAddress] || 0n;
|
|
25
|
+
const tokenMoney = PriceUtils.calcTotalPrice(
|
|
26
|
+
price,
|
|
27
|
+
amount,
|
|
28
|
+
tokenDecimals
|
|
29
|
+
);
|
|
30
|
+
const tokenLtMoney = tokenMoney * lt;
|
|
31
|
+
return acc + tokenLtMoney;
|
|
32
|
+
},
|
|
33
|
+
0n
|
|
34
|
+
);
|
|
35
|
+
const underlyingPrice = prices[underlyingToken] || 0n;
|
|
36
|
+
const underlyingDecimals = tokensList[underlyingToken]?.decimals || 18;
|
|
37
|
+
const max = underlyingPrice > 0 ? assetsLTMoney * 10n ** BigInt(underlyingDecimals) / underlyingPrice / targetHF / 10n ** BigInt(WAD_DECIMALS_POW - PRICE_DECIMALS_POW) : 0n;
|
|
38
|
+
return max;
|
|
39
|
+
}
|
|
40
|
+
export {
|
|
41
|
+
calcMaxDebtIncrease,
|
|
42
|
+
calcMaxLendingDebt
|
|
43
|
+
};
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import {
|
|
2
|
+
PERCENTAGE_DECIMALS,
|
|
3
|
+
PERCENTAGE_FACTOR,
|
|
4
|
+
SECONDS_PER_YEAR
|
|
5
|
+
} from "../../../sdk/index.js";
|
|
6
|
+
function getTimeToLiquidation({
|
|
7
|
+
healthFactor,
|
|
8
|
+
totalBorrowRate_debt
|
|
9
|
+
}) {
|
|
10
|
+
if (healthFactor <= PERCENTAGE_FACTOR || totalBorrowRate_debt === 0n)
|
|
11
|
+
return null;
|
|
12
|
+
const HF_1 = BigInt(healthFactor) - PERCENTAGE_FACTOR;
|
|
13
|
+
const brPerYear = BigInt(SECONDS_PER_YEAR) * PERCENTAGE_FACTOR * PERCENTAGE_DECIMALS / totalBorrowRate_debt;
|
|
14
|
+
return HF_1 * brPerYear * 1000n / PERCENTAGE_FACTOR;
|
|
15
|
+
}
|
|
16
|
+
export {
|
|
17
|
+
getTimeToLiquidation
|
|
18
|
+
};
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
export * from "./calcHealthFactor.js";
|
|
2
|
+
export * from "./calcQuotaBorrowRate.js";
|
|
3
|
+
export * from "./calcQuotaBorrowRate.js";
|
|
4
|
+
export * from "./calcRelativeBaseBorrowRate.js";
|
|
5
|
+
export * from "./debt.js";
|
|
6
|
+
export * from "./getTimeToLiquidation.js";
|
|
7
|
+
export * from "./liquidationPrice.js";
|
|
8
|
+
export * from "./quotaUtils.js";
|
|
9
|
+
export * from "./sort.js";
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
import { PERCENTAGE_FACTOR, PRICE_DECIMALS, WAD } from "../../../sdk/index.js";
|
|
2
|
+
function liquidationPrice({
|
|
3
|
+
liquidationThresholds,
|
|
4
|
+
debt,
|
|
5
|
+
underlyingToken,
|
|
6
|
+
targetToken,
|
|
7
|
+
assets,
|
|
8
|
+
tokensList
|
|
9
|
+
}) {
|
|
10
|
+
const underlyingDecimals = tokensList[underlyingToken]?.decimals || 18;
|
|
11
|
+
const { balance: underlyingBalance = 0n } = assets[underlyingToken] || {};
|
|
12
|
+
const ltUnderlying = liquidationThresholds[underlyingToken] || 0n;
|
|
13
|
+
const effectiveDebt = (debt - underlyingBalance * ltUnderlying / PERCENTAGE_FACTOR) * WAD / 10n ** BigInt(underlyingDecimals);
|
|
14
|
+
const targetDecimals = tokensList[targetToken]?.decimals || 18;
|
|
15
|
+
const { balance: targetBalance = 0n } = assets[targetToken] || {};
|
|
16
|
+
const effectiveTargetBalance = targetBalance * WAD / 10n ** BigInt(targetDecimals);
|
|
17
|
+
const lpLT = liquidationThresholds[targetToken] || 0n;
|
|
18
|
+
if (targetBalance <= 0n || lpLT <= 0n) return 0n;
|
|
19
|
+
return effectiveDebt * PRICE_DECIMALS * PERCENTAGE_FACTOR / (effectiveTargetBalance * lpLT);
|
|
20
|
+
}
|
|
21
|
+
export {
|
|
22
|
+
liquidationPrice
|
|
23
|
+
};
|
|
@@ -0,0 +1,125 @@
|
|
|
1
|
+
import {
|
|
2
|
+
MIN_INT96,
|
|
3
|
+
PERCENTAGE_FACTOR
|
|
4
|
+
} from "../../../sdk/index.js";
|
|
5
|
+
import { BigIntMath } from "../bigintMath.js";
|
|
6
|
+
function roundUpQuota(quotaChange) {
|
|
7
|
+
return quotaChange !== MIN_INT96 ? quotaChange / PERCENTAGE_FACTOR * PERCENTAGE_FACTOR : quotaChange;
|
|
8
|
+
}
|
|
9
|
+
function calcRecommendedQuota({
|
|
10
|
+
amount,
|
|
11
|
+
debt,
|
|
12
|
+
lt,
|
|
13
|
+
quotaReserve
|
|
14
|
+
}) {
|
|
15
|
+
const recommendedBaseQuota = BigIntMath.min(
|
|
16
|
+
debt,
|
|
17
|
+
amount * lt / PERCENTAGE_FACTOR
|
|
18
|
+
);
|
|
19
|
+
const recommendedQuota = recommendedBaseQuota * (PERCENTAGE_FACTOR + quotaReserve) / PERCENTAGE_FACTOR;
|
|
20
|
+
return roundUpQuota(recommendedQuota);
|
|
21
|
+
}
|
|
22
|
+
function calcDefaultQuota({
|
|
23
|
+
amount,
|
|
24
|
+
lt,
|
|
25
|
+
quotaReserve
|
|
26
|
+
}) {
|
|
27
|
+
const recommendedBaseQuota = amount * lt / PERCENTAGE_FACTOR;
|
|
28
|
+
const recommendedQuota = recommendedBaseQuota * (PERCENTAGE_FACTOR + quotaReserve) / PERCENTAGE_FACTOR;
|
|
29
|
+
return roundUpQuota(recommendedQuota);
|
|
30
|
+
}
|
|
31
|
+
function calcQuotaUpdate(props) {
|
|
32
|
+
const { quotas, initialQuotas, maxDebt, allowedToSpend, allowedToObtain } = props;
|
|
33
|
+
const quotaDecrease = Object.keys(allowedToSpend).reduce((acc, token) => {
|
|
34
|
+
const ch = getSingleQuotaChange(token, 0n, props);
|
|
35
|
+
if (ch && ch.balance < 0) acc[ch.token] = ch;
|
|
36
|
+
return acc;
|
|
37
|
+
}, {});
|
|
38
|
+
const quotaCap = roundUpQuota(maxDebt * 2n);
|
|
39
|
+
const quotaBought = Object.values(initialQuotas).reduce(
|
|
40
|
+
(sum, q) => sum + roundUpQuota(q?.quota || 0n),
|
|
41
|
+
0n
|
|
42
|
+
);
|
|
43
|
+
const quotaReduced = Object.values(quotaDecrease).reduce((sum, q) => {
|
|
44
|
+
const quotaBalance = q.balance || 0n;
|
|
45
|
+
const safeBalance = quotaBalance === MIN_INT96 ? BigIntMath.neg(roundUpQuota(initialQuotas[q.token]?.quota || 0n)) : quotaBalance;
|
|
46
|
+
return sum + safeBalance;
|
|
47
|
+
}, 0n);
|
|
48
|
+
const maxQuotaIncrease = roundUpQuota(
|
|
49
|
+
BigIntMath.max(quotaCap - (quotaBought + quotaReduced), 0n)
|
|
50
|
+
);
|
|
51
|
+
const quotaIncrease = Object.keys(allowedToObtain).reduce((acc, token) => {
|
|
52
|
+
const ch = getSingleQuotaChange(token, maxQuotaIncrease, props);
|
|
53
|
+
if (ch && ch.balance > 0) acc[ch.token] = ch;
|
|
54
|
+
return acc;
|
|
55
|
+
}, {});
|
|
56
|
+
const quotaChange = {
|
|
57
|
+
...quotaDecrease,
|
|
58
|
+
...quotaIncrease
|
|
59
|
+
};
|
|
60
|
+
const desiredQuota = Object.values(quotas).reduce(
|
|
61
|
+
(acc, cmQuota) => {
|
|
62
|
+
const { token, isActive } = cmQuota;
|
|
63
|
+
const { quota: initialQuota = 0n } = initialQuotas[token] || {};
|
|
64
|
+
if (!isActive) {
|
|
65
|
+
acc[token] = {
|
|
66
|
+
balance: initialQuota,
|
|
67
|
+
token
|
|
68
|
+
};
|
|
69
|
+
} else {
|
|
70
|
+
const change = quotaChange[token]?.balance || 0n;
|
|
71
|
+
const quotaAfter = change === MIN_INT96 ? 0n : initialQuota + change;
|
|
72
|
+
acc[token] = {
|
|
73
|
+
balance: quotaAfter,
|
|
74
|
+
token
|
|
75
|
+
};
|
|
76
|
+
}
|
|
77
|
+
return acc;
|
|
78
|
+
},
|
|
79
|
+
{}
|
|
80
|
+
);
|
|
81
|
+
return {
|
|
82
|
+
desiredQuota,
|
|
83
|
+
quotaDecrease: Object.values(quotaDecrease),
|
|
84
|
+
quotaIncrease: Object.values(quotaIncrease)
|
|
85
|
+
};
|
|
86
|
+
}
|
|
87
|
+
function getSingleQuotaChange(token, unsafeMaxQuotaIncrease, props) {
|
|
88
|
+
const { isActive = false } = props.quotas[token] || {};
|
|
89
|
+
const { quota: unsafeInitialQuota = 0n } = props.initialQuotas[token] || {};
|
|
90
|
+
if (!isActive) {
|
|
91
|
+
return void 0;
|
|
92
|
+
}
|
|
93
|
+
const assetAfter = props.assetsAfterUpdate[token];
|
|
94
|
+
const { amountInTarget = 0n } = assetAfter || {};
|
|
95
|
+
const lt = props.liquidationThresholds[token] || 0n;
|
|
96
|
+
const maxQuotaIncrease = roundUpQuota(unsafeMaxQuotaIncrease);
|
|
97
|
+
const initialQuota = roundUpQuota(unsafeInitialQuota);
|
|
98
|
+
const defaultQuota = props.calcModification?.type === "recommendedQuota" && props.calcModification.debt > 0 ? calcRecommendedQuota({
|
|
99
|
+
lt,
|
|
100
|
+
quotaReserve: props.quotaReserve,
|
|
101
|
+
amount: amountInTarget,
|
|
102
|
+
debt: props.calcModification.debt
|
|
103
|
+
}) : calcDefaultQuota({
|
|
104
|
+
lt,
|
|
105
|
+
quotaReserve: props.quotaReserve,
|
|
106
|
+
amount: amountInTarget
|
|
107
|
+
});
|
|
108
|
+
const unsafeQuotaChange = roundUpQuota(defaultQuota - initialQuota);
|
|
109
|
+
const quotaChange = unsafeQuotaChange > 0 ? BigIntMath.min(maxQuotaIncrease, unsafeQuotaChange) : unsafeQuotaChange < 0 && BigIntMath.abs(unsafeQuotaChange) >= initialQuota ? MIN_INT96 : unsafeQuotaChange;
|
|
110
|
+
const correctIncrease = assetAfter && props.allowedToObtain[token] && quotaChange > 0;
|
|
111
|
+
const correctDecrease = assetAfter && props.allowedToSpend[token] && quotaChange < 0;
|
|
112
|
+
if (correctIncrease || correctDecrease) {
|
|
113
|
+
return {
|
|
114
|
+
balance: quotaChange,
|
|
115
|
+
token
|
|
116
|
+
};
|
|
117
|
+
}
|
|
118
|
+
return void 0;
|
|
119
|
+
}
|
|
120
|
+
export {
|
|
121
|
+
calcDefaultQuota,
|
|
122
|
+
calcQuotaUpdate,
|
|
123
|
+
calcRecommendedQuota,
|
|
124
|
+
roundUpQuota
|
|
125
|
+
};
|
|
@@ -0,0 +1,67 @@
|
|
|
1
|
+
import { PRICE_DECIMALS } from "../../../sdk/index.js";
|
|
2
|
+
import { PriceUtils } from "../priceMath.js";
|
|
3
|
+
function sortBalances(balances, prices, tokens) {
|
|
4
|
+
return Object.entries(balances).sort(
|
|
5
|
+
([addr1, amount1], [addr2, amount2]) => {
|
|
6
|
+
return assetComparator(
|
|
7
|
+
{
|
|
8
|
+
token: addr1,
|
|
9
|
+
balance: amount1
|
|
10
|
+
},
|
|
11
|
+
{
|
|
12
|
+
token: addr2,
|
|
13
|
+
balance: amount2
|
|
14
|
+
},
|
|
15
|
+
prices,
|
|
16
|
+
prices,
|
|
17
|
+
tokens,
|
|
18
|
+
tokens
|
|
19
|
+
);
|
|
20
|
+
}
|
|
21
|
+
);
|
|
22
|
+
}
|
|
23
|
+
function sortAssets(balances, prices, tokens) {
|
|
24
|
+
return [...balances].sort(
|
|
25
|
+
(t1, t2) => assetComparator(t1, t2, prices, prices, tokens, tokens)
|
|
26
|
+
);
|
|
27
|
+
}
|
|
28
|
+
function assetComparator(t1, t2, prices1, prices2, tokens1, tokens2) {
|
|
29
|
+
const addr1Lc = t1.token.toLowerCase();
|
|
30
|
+
const addr2Lc = t2.token.toLowerCase();
|
|
31
|
+
const token1 = tokens1?.[addr1Lc];
|
|
32
|
+
const token2 = tokens2?.[addr2Lc];
|
|
33
|
+
const price1 = prices1?.[addr1Lc] || PRICE_DECIMALS;
|
|
34
|
+
const price2 = prices2?.[addr2Lc] || PRICE_DECIMALS;
|
|
35
|
+
const totalPrice1 = PriceUtils.calcTotalPrice(
|
|
36
|
+
price1,
|
|
37
|
+
t1.balance,
|
|
38
|
+
token1?.decimals
|
|
39
|
+
);
|
|
40
|
+
const totalPrice2 = PriceUtils.calcTotalPrice(
|
|
41
|
+
price2,
|
|
42
|
+
t2.balance,
|
|
43
|
+
token2?.decimals
|
|
44
|
+
);
|
|
45
|
+
if (totalPrice1 === totalPrice2) {
|
|
46
|
+
return t1.balance === t2.balance ? tokensAbcComparator(token1, token2) : amountAbcComparator(t1.balance, t2.balance);
|
|
47
|
+
}
|
|
48
|
+
return amountAbcComparator(totalPrice1, totalPrice2);
|
|
49
|
+
}
|
|
50
|
+
function tokensAbcComparator(t1, t2) {
|
|
51
|
+
const { symbol: symbol1 = "" } = t1 || {};
|
|
52
|
+
const { symbol: symbol2 = "" } = t2 || {};
|
|
53
|
+
const symbol1LC = symbol1.toLowerCase();
|
|
54
|
+
const symbol2LC = symbol2.toLowerCase();
|
|
55
|
+
if (symbol1LC === symbol2LC) return 0;
|
|
56
|
+
return symbol1LC > symbol2LC ? 1 : -1;
|
|
57
|
+
}
|
|
58
|
+
function amountAbcComparator(t1, t2) {
|
|
59
|
+
return t1 > t2 ? -1 : 1;
|
|
60
|
+
}
|
|
61
|
+
export {
|
|
62
|
+
amountAbcComparator,
|
|
63
|
+
assetComparator,
|
|
64
|
+
sortAssets,
|
|
65
|
+
sortBalances,
|
|
66
|
+
tokensAbcComparator
|
|
67
|
+
};
|
|
File without changes
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { isSupportedNetwork } from "
|
|
1
|
+
import { isSupportedNetwork } from "../../sdk/index.js";
|
|
2
2
|
const CHARTS_BACKEND_ADDRESS = "https://charts-server.fly.dev";
|
|
3
3
|
const STATIC_TOKEN = "https://static.gearbox.finance/tokens/";
|
|
4
4
|
class GearboxBackendApi {
|
|
@@ -8,7 +8,7 @@ class GearboxBackendApi {
|
|
|
8
8
|
const domain = CHARTS_BACKEND_ADDRESS;
|
|
9
9
|
const priceSourceArr = priceSource ? [priceSource] : [];
|
|
10
10
|
const isMain = isSupportedNetwork(chainId);
|
|
11
|
-
const relativePath =
|
|
11
|
+
const relativePath = getRelativeUrl(
|
|
12
12
|
url,
|
|
13
13
|
isMain ? {
|
|
14
14
|
...options,
|
|
@@ -27,20 +27,15 @@ class GearboxBackendApi {
|
|
|
27
27
|
const url = `https://dm.gearbox.finance/${network.toLowerCase()}_${root}.json`;
|
|
28
28
|
return url;
|
|
29
29
|
};
|
|
30
|
-
static apyAllRewards = () =>
|
|
30
|
+
static apyAllRewards = () => getRelativeUrl(
|
|
31
31
|
"https://state-cache.gearbox.foundation/apy-server/latest.json"
|
|
32
32
|
);
|
|
33
33
|
}
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
}
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
const paramsString = Object.entries(params).map(([key, value]) => `${key}=${value}`).join("&");
|
|
40
|
-
return [url, ...paramsString ? [paramsString] : []].join("?");
|
|
41
|
-
};
|
|
42
|
-
}
|
|
34
|
+
const getRelativeUrl = (url, options) => {
|
|
35
|
+
const { params = {} } = options || {};
|
|
36
|
+
const paramsString = Object.entries(params).map(([key, value]) => `${key}=${value}`).join("&");
|
|
37
|
+
return [url, ...paramsString ? [paramsString] : []].join("?");
|
|
38
|
+
};
|
|
43
39
|
export {
|
|
44
|
-
GearboxBackendApi
|
|
45
|
-
URLApi
|
|
40
|
+
GearboxBackendApi
|
|
46
41
|
};
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
import { PRICE_DECIMALS, WAD } from "../../sdk/index.js";
|
|
2
|
+
class PriceUtils {
|
|
3
|
+
/**
|
|
4
|
+
* This class is intentionally non-instantiable.
|
|
5
|
+
*/
|
|
6
|
+
constructor() {
|
|
7
|
+
}
|
|
8
|
+
/**
|
|
9
|
+
* Calculates normalized total value for a token amount at a given price.
|
|
10
|
+
*
|
|
11
|
+
* Formula:
|
|
12
|
+
* `(amount * WAD * price) / 10^decimals / PRICE_DECIMALS`
|
|
13
|
+
*
|
|
14
|
+
* @param price Token unit price in `PRICE_DECIMALS` precision.
|
|
15
|
+
* @param amount Token amount in raw token units.
|
|
16
|
+
* @param decimals Token decimals used to normalize `amount` (defaults to `18`).
|
|
17
|
+
* @returns Total value in WAD-normalized units.
|
|
18
|
+
*/
|
|
19
|
+
static calcTotalPrice = (price, amount, decimals = 18) => amount * WAD * price / 10n ** BigInt(decimals) / PRICE_DECIMALS;
|
|
20
|
+
/**
|
|
21
|
+
* Converts a normalized monetary value into target token amount by price.
|
|
22
|
+
*
|
|
23
|
+
* Formula:
|
|
24
|
+
* `(totalMoney * 10^targetDecimals * PRICE_DECIMALS) / targetPrice / WAD`
|
|
25
|
+
*
|
|
26
|
+
* Safety behavior:
|
|
27
|
+
* - returns `0n` when `targetPrice <= 0n` to avoid invalid division
|
|
28
|
+
*
|
|
29
|
+
* @param totalMoney Value to convert, expected in WAD-normalized units.
|
|
30
|
+
* @param target Conversion target configuration:
|
|
31
|
+
* - `price`: target token unit price in `PRICE_DECIMALS` precision
|
|
32
|
+
* - `decimals`: target token decimals (defaults to `18`)
|
|
33
|
+
* @returns Target token amount in raw token units.
|
|
34
|
+
*/
|
|
35
|
+
static convertByPrice(totalMoney, { price: targetPrice, decimals: targetDecimals = 18 }) {
|
|
36
|
+
if (targetPrice <= 0n) return 0n;
|
|
37
|
+
return totalMoney * 10n ** BigInt(targetDecimals) * PRICE_DECIMALS / targetPrice / WAD;
|
|
38
|
+
}
|
|
39
|
+
}
|
|
40
|
+
export {
|
|
41
|
+
PriceUtils
|
|
42
|
+
};
|
|
@@ -16,8 +16,8 @@ import { InstanceManagerContract } from "./instance-manager.js";
|
|
|
16
16
|
import { MarketConfiguratorFactoryContract } from "./market-configurator-factory.js";
|
|
17
17
|
const abi = crossChainMultisigAbi;
|
|
18
18
|
class CrossChainMultisigContract extends BaseContract {
|
|
19
|
-
constructor(addr,
|
|
20
|
-
super({
|
|
19
|
+
constructor(addr, register) {
|
|
20
|
+
super({ register }, { abi, addr, name: "CrossChainMultisig" });
|
|
21
21
|
}
|
|
22
22
|
async getExecutedBatches(fromBlock, toBlock) {
|
|
23
23
|
const events = await this.getEvents("ExecuteBatch", fromBlock, toBlock);
|
|
@@ -170,7 +170,7 @@ class CrossChainMultisigContract extends BaseContract {
|
|
|
170
170
|
case Addresses.INSTANCE_MANAGER.toLowerCase(): {
|
|
171
171
|
const instanceManager = new InstanceManagerContract(
|
|
172
172
|
target,
|
|
173
|
-
this.
|
|
173
|
+
this.register
|
|
174
174
|
);
|
|
175
175
|
return instanceManager.parseFunctionData(calldata);
|
|
176
176
|
}
|
|
@@ -22,8 +22,8 @@ import { RoutingManagerContract } from "./router/index.js";
|
|
|
22
22
|
import { TreasurySplitterContract } from "./treasury-splitter.js";
|
|
23
23
|
const abi = instanceManagerAbi;
|
|
24
24
|
class InstanceManagerContract extends BaseContract {
|
|
25
|
-
constructor(addr,
|
|
26
|
-
super({
|
|
25
|
+
constructor(addr, register) {
|
|
26
|
+
super({ register }, { abi, addr, name: "InstanceManager" });
|
|
27
27
|
}
|
|
28
28
|
// TODO:
|
|
29
29
|
#decodeFunctionData(target, calldata) {
|
|
@@ -48,12 +48,6 @@ class MellowDepositQueueAdapterContract extends AbstractAdapterContract {
|
|
|
48
48
|
referral: this.#referral ? this.labelAddress(this.#referral) : void 0
|
|
49
49
|
};
|
|
50
50
|
}
|
|
51
|
-
/** Legacy adapter not present in integrations-v3. */
|
|
52
|
-
classifyLegacyOperation(_parsed, _transfers) {
|
|
53
|
-
throw new Error(
|
|
54
|
-
`classifyLegacyOperation is not supported for legacy adapter: ${this.contractType}`
|
|
55
|
-
);
|
|
56
|
-
}
|
|
57
51
|
}
|
|
58
52
|
export {
|
|
59
53
|
MellowDepositQueueAdapterContract
|
|
@@ -40,12 +40,6 @@ class MellowRedeemQueueAdapterContract extends AbstractAdapterContract {
|
|
|
40
40
|
phantomToken: this.#phantomToken ? this.labelAddress(this.#phantomToken) : void 0
|
|
41
41
|
};
|
|
42
42
|
}
|
|
43
|
-
/** Legacy adapter not present in integrations-v3. */
|
|
44
|
-
classifyLegacyOperation(_parsed, _transfers) {
|
|
45
|
-
throw new Error(
|
|
46
|
-
`classifyLegacyOperation is not supported for legacy adapter: ${this.contractType}`
|
|
47
|
-
);
|
|
48
|
-
}
|
|
49
43
|
}
|
|
50
44
|
export {
|
|
51
45
|
MellowRedeemQueueAdapterContract
|
|
@@ -144,8 +144,6 @@ class GearboxSDK extends ChainContractsRegister {
|
|
|
144
144
|
if (options.gasLimit !== null) {
|
|
145
145
|
this.gasLimit = options.gasLimit || 550000000n;
|
|
146
146
|
}
|
|
147
|
-
Object.assign(this, ChainContractsRegister.for(this.client, this.logger));
|
|
148
|
-
this.resetContracts();
|
|
149
147
|
}
|
|
150
148
|
async #attach(opts) {
|
|
151
149
|
const {
|
|
@@ -57,8 +57,11 @@ class BaseContract extends Construct {
|
|
|
57
57
|
this.contractType = bytes32ToString(this.contractType);
|
|
58
58
|
}
|
|
59
59
|
this.name = args.name || this.contractType || this.address || this.constructor.name;
|
|
60
|
-
this.
|
|
61
|
-
|
|
60
|
+
const register = this.safeGetRegister();
|
|
61
|
+
if (register) {
|
|
62
|
+
register.setContract(this.address, this);
|
|
63
|
+
register.setAddressLabel(this.address, this.name);
|
|
64
|
+
}
|
|
62
65
|
}
|
|
63
66
|
stateHuman(_ = true) {
|
|
64
67
|
return {
|
|
@@ -2,16 +2,6 @@ import { NOT_DEPLOYED } from "../constants/addresses.js";
|
|
|
2
2
|
import { AddressMap } from "../utils/AddressMap.js";
|
|
3
3
|
import { TokensMeta } from "./TokensMeta.js";
|
|
4
4
|
class ChainContractsRegister {
|
|
5
|
-
static #chains = /* @__PURE__ */ new Map();
|
|
6
|
-
static for(client, logger) {
|
|
7
|
-
const chainId = client.chain.id;
|
|
8
|
-
let result = ChainContractsRegister.#chains.get(chainId);
|
|
9
|
-
if (!result) {
|
|
10
|
-
result = new ChainContractsRegister(client, logger);
|
|
11
|
-
ChainContractsRegister.#chains.set(chainId, result);
|
|
12
|
-
}
|
|
13
|
-
return result;
|
|
14
|
-
}
|
|
15
5
|
contracts = new AddressMap(
|
|
16
6
|
[],
|
|
17
7
|
"contracts"
|
|
@@ -32,7 +22,9 @@ class ChainContractsRegister {
|
|
|
32
22
|
this.logger?.debug(
|
|
33
23
|
`resetting contacts register with ${this.contracts.size} contracts`
|
|
34
24
|
);
|
|
25
|
+
this.labels.clear();
|
|
35
26
|
this.contracts.clear();
|
|
27
|
+
this.tokensMeta.reset();
|
|
36
28
|
}
|
|
37
29
|
getContract(address) {
|
|
38
30
|
return this.contracts.get(address);
|
|
@@ -3,27 +3,41 @@ import { ChainContractsRegister } from "./ChainContractsRegister.js";
|
|
|
3
3
|
class Construct {
|
|
4
4
|
logger;
|
|
5
5
|
client;
|
|
6
|
-
register;
|
|
6
|
+
#register;
|
|
7
7
|
/**
|
|
8
8
|
* Indicates that contract state needs to be updated
|
|
9
9
|
*/
|
|
10
10
|
#dirty = false;
|
|
11
11
|
constructor(options) {
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
this
|
|
12
|
+
if (options instanceof ChainContractsRegister) {
|
|
13
|
+
this.#register = options;
|
|
14
|
+
this.client = options.client;
|
|
15
|
+
} else if ("register" in options) {
|
|
16
|
+
this.#register = options.register;
|
|
17
|
+
this.client = options.register.client;
|
|
17
18
|
} else {
|
|
18
|
-
|
|
19
|
-
this.register = register;
|
|
20
|
-
this.client = register.client;
|
|
19
|
+
this.client = options.client;
|
|
21
20
|
}
|
|
22
21
|
this.logger = childLogger(
|
|
23
22
|
this.constructor.name,
|
|
24
|
-
this
|
|
23
|
+
this.#register?.logger ?? options.logger
|
|
25
24
|
);
|
|
26
25
|
}
|
|
26
|
+
/**
|
|
27
|
+
* Throws if register was not provided in constructor options
|
|
28
|
+
* Ephemeral contracts that do not need to access other contracts may not need it
|
|
29
|
+
*/
|
|
30
|
+
get register() {
|
|
31
|
+
if (!this.#register) {
|
|
32
|
+
throw new Error(
|
|
33
|
+
"contracts register not available, it must be provided if contract needs to access other contracts"
|
|
34
|
+
);
|
|
35
|
+
}
|
|
36
|
+
return this.#register;
|
|
37
|
+
}
|
|
38
|
+
safeGetRegister() {
|
|
39
|
+
return this.#register;
|
|
40
|
+
}
|
|
27
41
|
get chain() {
|
|
28
42
|
return this.client.chain;
|
|
29
43
|
}
|
|
@@ -45,19 +59,11 @@ class Construct {
|
|
|
45
59
|
set dirty(value) {
|
|
46
60
|
this.#dirty = value;
|
|
47
61
|
}
|
|
48
|
-
/**
|
|
49
|
-
* Syntax sugar for rgister.tokensMeta
|
|
50
|
-
*/
|
|
51
62
|
get tokensMeta() {
|
|
52
63
|
return this.register.tokensMeta;
|
|
53
64
|
}
|
|
54
|
-
/**
|
|
55
|
-
* Syntax suggar for getting contract labels
|
|
56
|
-
* @param address
|
|
57
|
-
* @returns
|
|
58
|
-
*/
|
|
59
65
|
labelAddress(address, omitAddress) {
|
|
60
|
-
return this
|
|
66
|
+
return this.#register?.labelAddress(address, omitAddress) ?? address;
|
|
61
67
|
}
|
|
62
68
|
/**
|
|
63
69
|
* Returns list of addresses that should be watched for events to sync state
|
|
@@ -1,11 +1,21 @@
|
|
|
1
|
+
import { decodeAbiParameters } from "viem";
|
|
1
2
|
import {
|
|
2
3
|
MissingSerializedParamsError,
|
|
3
4
|
PlaceholderContract
|
|
4
5
|
} from "../../base/index.js";
|
|
5
6
|
class PlaceholderAdapterContract extends PlaceholderContract {
|
|
6
7
|
#targetContract;
|
|
8
|
+
#creditManager;
|
|
7
9
|
constructor(options, args) {
|
|
8
10
|
super(options, args.baseParams);
|
|
11
|
+
if (args.baseParams.serializedParams) {
|
|
12
|
+
const [cm, tc] = decodeAbiParameters(
|
|
13
|
+
[{ type: "address" }, { type: "address" }],
|
|
14
|
+
args.baseParams.serializedParams
|
|
15
|
+
);
|
|
16
|
+
this.#creditManager = cm;
|
|
17
|
+
this.#targetContract = tc;
|
|
18
|
+
}
|
|
9
19
|
}
|
|
10
20
|
get targetContract() {
|
|
11
21
|
if (!this.#targetContract) {
|
|
@@ -13,6 +23,12 @@ class PlaceholderAdapterContract extends PlaceholderContract {
|
|
|
13
23
|
}
|
|
14
24
|
return this.#targetContract;
|
|
15
25
|
}
|
|
26
|
+
get creditManager() {
|
|
27
|
+
if (!this.#creditManager) {
|
|
28
|
+
throw new MissingSerializedParamsError("creditManager");
|
|
29
|
+
}
|
|
30
|
+
return this.#creditManager;
|
|
31
|
+
}
|
|
16
32
|
}
|
|
17
33
|
export {
|
|
18
34
|
PlaceholderAdapterContract
|
|
@@ -1,21 +1,4 @@
|
|
|
1
1
|
class PriceUpdatesCache {
|
|
2
|
-
static #caches = /* @__PURE__ */ new Map();
|
|
3
|
-
/**
|
|
4
|
-
* Price update caches can be shared across networks
|
|
5
|
-
* @param id - unique key to identify the cache
|
|
6
|
-
* @param opts
|
|
7
|
-
* @returns
|
|
8
|
-
*/
|
|
9
|
-
static get(id, opts) {
|
|
10
|
-
const key = `${id}:${opts.historical ? "historical" : "latest"}:${opts.ttl}`;
|
|
11
|
-
const cache = PriceUpdatesCache.#caches.get(key);
|
|
12
|
-
if (cache) {
|
|
13
|
-
return cache;
|
|
14
|
-
}
|
|
15
|
-
const newCache = new PriceUpdatesCache(opts);
|
|
16
|
-
PriceUpdatesCache.#caches.set(key, newCache);
|
|
17
|
-
return newCache;
|
|
18
|
-
}
|
|
19
2
|
#cache = /* @__PURE__ */ new Map();
|
|
20
3
|
#ttlMs;
|
|
21
4
|
#historical;
|
|
@@ -44,7 +44,7 @@ class PythUpdater extends SDKConstruct {
|
|
|
44
44
|
`using historical timestamp ${this.#historicalTimestamp}`
|
|
45
45
|
);
|
|
46
46
|
}
|
|
47
|
-
this.#cache = PriceUpdatesCache
|
|
47
|
+
this.#cache = new PriceUpdatesCache({
|
|
48
48
|
// currently staleness period is 240 seconds on all networks, add some buffer
|
|
49
49
|
// this period of 4 minutes is selected based on time that is required for user to sign transaction with wallet
|
|
50
50
|
// so it's unlikely to decrease
|
|
@@ -52,7 +52,7 @@ class RedstoneUpdater extends SDKConstruct {
|
|
|
52
52
|
`using historical timestamp ${this.#historicalTimestampMs}`
|
|
53
53
|
);
|
|
54
54
|
}
|
|
55
|
-
this.#cache = PriceUpdatesCache
|
|
55
|
+
this.#cache = new PriceUpdatesCache({
|
|
56
56
|
// currently staleness period is 240 seconds on all networks, add some buffer
|
|
57
57
|
// this period of 4 minutes is selected based on time that is required for user to sign transaction with wallet
|
|
58
58
|
// so it's unlikely to decrease
|