@gearbox-protocol/sdk 13.0.0-beta.4 → 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.
Files changed (65) hide show
  1. package/dist/cjs/common-utils/index.js +22 -0
  2. package/dist/cjs/common-utils/package.json +1 -0
  3. package/dist/cjs/{sdk → common-utils}/utils/assetsMath.js +78 -12
  4. package/dist/cjs/common-utils/utils/bigintMath.js +65 -0
  5. package/dist/cjs/common-utils/utils/creditAccount/calcHealthFactor.js +76 -0
  6. package/dist/cjs/common-utils/utils/creditAccount/calcOverallAPY.js +81 -0
  7. package/dist/cjs/{sdk/utils/priceMath.js → common-utils/utils/creditAccount/calcQuotaBorrowRate.js} +19 -12
  8. package/dist/cjs/{sdk/utils/bigintMath.js → common-utils/utils/creditAccount/calcRelativeBaseBorrowRate.js} +11 -10
  9. package/dist/cjs/common-utils/utils/creditAccount/debt.js +64 -0
  10. package/dist/cjs/common-utils/utils/creditAccount/getTimeToLiquidation.js +38 -0
  11. package/dist/cjs/common-utils/utils/creditAccount/index.js +38 -0
  12. package/dist/cjs/common-utils/utils/creditAccount/liquidationPrice.js +47 -0
  13. package/dist/cjs/common-utils/utils/creditAccount/quotaUtils.js +149 -0
  14. package/dist/cjs/common-utils/utils/creditAccount/sort.js +95 -0
  15. package/dist/cjs/common-utils/utils/creditAccount/types.js +16 -0
  16. package/dist/cjs/{sdk → common-utils}/utils/endpoints.js +11 -17
  17. package/dist/cjs/common-utils/utils/index.js +30 -0
  18. package/dist/cjs/common-utils/utils/priceMath.js +66 -0
  19. package/dist/cjs/sdk/utils/index.js +0 -10
  20. package/dist/esm/common-utils/index.js +1 -0
  21. package/dist/esm/common-utils/package.json +1 -0
  22. package/dist/esm/{sdk → common-utils}/utils/assetsMath.js +78 -12
  23. package/dist/esm/common-utils/utils/bigintMath.js +41 -0
  24. package/dist/esm/common-utils/utils/creditAccount/calcHealthFactor.js +55 -0
  25. package/dist/esm/common-utils/utils/creditAccount/calcOverallAPY.js +60 -0
  26. package/dist/esm/common-utils/utils/creditAccount/calcQuotaBorrowRate.js +18 -0
  27. package/dist/esm/common-utils/utils/creditAccount/calcRelativeBaseBorrowRate.js +10 -0
  28. package/dist/esm/common-utils/utils/creditAccount/debt.js +43 -0
  29. package/dist/esm/common-utils/utils/creditAccount/getTimeToLiquidation.js +18 -0
  30. package/dist/esm/common-utils/utils/creditAccount/index.js +9 -0
  31. package/dist/esm/common-utils/utils/creditAccount/liquidationPrice.js +23 -0
  32. package/dist/esm/common-utils/utils/creditAccount/quotaUtils.js +125 -0
  33. package/dist/esm/common-utils/utils/creditAccount/sort.js +67 -0
  34. package/dist/esm/common-utils/utils/creditAccount/types.js +0 -0
  35. package/dist/esm/{sdk → common-utils}/utils/endpoints.js +9 -14
  36. package/dist/esm/common-utils/utils/index.js +5 -0
  37. package/dist/esm/common-utils/utils/priceMath.js +42 -0
  38. package/dist/esm/sdk/utils/index.js +0 -5
  39. package/dist/types/common-utils/index.d.ts +1 -0
  40. package/dist/types/common-utils/utils/assetsMath.d.ts +114 -0
  41. package/dist/types/common-utils/utils/bigintMath.d.ts +43 -0
  42. package/dist/types/common-utils/utils/creditAccount/calcHealthFactor.d.ts +25 -0
  43. package/dist/types/common-utils/utils/creditAccount/calcOverallAPY.d.ts +37 -0
  44. package/dist/types/common-utils/utils/creditAccount/calcQuotaBorrowRate.d.ts +18 -0
  45. package/dist/types/common-utils/utils/creditAccount/calcRelativeBaseBorrowRate.d.ts +15 -0
  46. package/dist/types/common-utils/utils/creditAccount/debt.d.ts +35 -0
  47. package/dist/types/common-utils/utils/creditAccount/getTimeToLiquidation.d.ts +16 -0
  48. package/dist/types/common-utils/utils/creditAccount/index.d.ts +9 -0
  49. package/dist/types/common-utils/utils/creditAccount/liquidationPrice.d.ts +25 -0
  50. package/dist/types/common-utils/utils/creditAccount/quotaUtils.d.ts +81 -0
  51. package/dist/types/common-utils/utils/creditAccount/sort.d.ts +55 -0
  52. package/dist/types/common-utils/utils/creditAccount/types.d.ts +18 -0
  53. package/dist/types/{sdk → common-utils}/utils/endpoints.d.ts +13 -5
  54. package/dist/types/common-utils/utils/index.d.ts +5 -0
  55. package/dist/types/common-utils/utils/priceMath.d.ts +47 -0
  56. package/dist/types/sdk/utils/index.d.ts +0 -5
  57. package/package.json +6 -1
  58. package/dist/cjs/sdk/utils/creditAccount.js +0 -411
  59. package/dist/esm/sdk/utils/bigintMath.js +0 -9
  60. package/dist/esm/sdk/utils/creditAccount.js +0 -396
  61. package/dist/esm/sdk/utils/priceMath.js +0 -11
  62. package/dist/types/sdk/utils/assetsMath.d.ts +0 -42
  63. package/dist/types/sdk/utils/bigintMath.d.ts +0 -6
  64. package/dist/types/sdk/utils/creditAccount.d.ts +0 -128
  65. package/dist/types/sdk/utils/priceMath.d.ts +0 -9
@@ -0,0 +1,55 @@
1
+ import {
2
+ PERCENTAGE_FACTOR,
3
+ PRICE_DECIMALS
4
+ } from "../../../sdk/index.js";
5
+ import { BigIntMath } from "../bigintMath.js";
6
+ import { PriceUtils } from "../priceMath.js";
7
+ const MAX_UINT16 = 65535;
8
+ function calcHealthFactor({
9
+ assets,
10
+ quotas,
11
+ quotasInfo,
12
+ liquidationThresholds,
13
+ underlyingToken,
14
+ debt,
15
+ prices,
16
+ tokensList
17
+ }) {
18
+ if (debt === 0n) return MAX_UINT16;
19
+ const underlyingDecimals = tokensList[underlyingToken]?.decimals || 18;
20
+ const underlyingPrice = prices[underlyingToken] || 0n;
21
+ const assetMoney = assets.reduce(
22
+ (acc, { token: tokenAddress, balance: amount }) => {
23
+ const tokenDecimals = tokensList[tokenAddress]?.decimals || 18;
24
+ const lt = liquidationThresholds[tokenAddress] || 0n;
25
+ const price = prices[tokenAddress] || 0n;
26
+ const tokenMoney = PriceUtils.calcTotalPrice(
27
+ price,
28
+ amount,
29
+ tokenDecimals
30
+ );
31
+ const tokenLtMoney = tokenMoney * lt / PERCENTAGE_FACTOR;
32
+ const { isActive = false } = quotasInfo?.[tokenAddress] || {};
33
+ const quota = quotas[tokenAddress];
34
+ const quotaBalance = isActive ? quota?.balance || 0n : 0n;
35
+ const quotaMoney = PriceUtils.calcTotalPrice(
36
+ underlyingPrice,
37
+ quotaBalance,
38
+ underlyingDecimals
39
+ );
40
+ const money = quota ? BigIntMath.min(quotaMoney, tokenLtMoney) : tokenLtMoney;
41
+ return acc + money;
42
+ },
43
+ 0n
44
+ );
45
+ const borrowedMoney = PriceUtils.calcTotalPrice(
46
+ underlyingPrice || PRICE_DECIMALS,
47
+ debt,
48
+ underlyingDecimals
49
+ );
50
+ const hfInPercent = borrowedMoney > 0n ? assetMoney * PERCENTAGE_FACTOR / borrowedMoney : 0n;
51
+ return Number(hfInPercent);
52
+ }
53
+ export {
54
+ calcHealthFactor
55
+ };
@@ -0,0 +1,60 @@
1
+ import {
2
+ PERCENTAGE_FACTOR,
3
+ PRICE_DECIMALS
4
+ } from "../../../sdk/index.js";
5
+ import { PriceUtils } from "../priceMath.js";
6
+ function calcOverallAPY({
7
+ caAssets,
8
+ lpAPY,
9
+ prices,
10
+ quotas,
11
+ quotaRates,
12
+ feeInterest,
13
+ totalValue,
14
+ debt,
15
+ baseRateWithFee,
16
+ underlyingToken,
17
+ tokensList
18
+ }) {
19
+ if (!lpAPY || !totalValue || totalValue <= 0n || !debt || totalValue <= debt)
20
+ return void 0;
21
+ const underlyingTokenDecimals = tokensList[underlyingToken]?.decimals || 18;
22
+ const underlyingPrice = prices[underlyingToken];
23
+ const assetAPYMoney = caAssets.reduce(
24
+ (acc, { token: tokenAddress, balance: amount }) => {
25
+ const apy = lpAPY[tokenAddress] || 0;
26
+ const tokenDecimals = tokensList[tokenAddress]?.decimals || 18;
27
+ const price = prices[tokenAddress] || 0n;
28
+ const money = PriceUtils.calcTotalPrice(price, amount, tokenDecimals);
29
+ const apyMoney = money * BigInt(apy);
30
+ const { rate: quotaAPY = 0n, isActive = false } = quotaRates?.[tokenAddress] || {};
31
+ const { balance: quotaBalance = 0n } = quotas[tokenAddress] || {};
32
+ const quotaAmount = isActive ? quotaBalance : 0n;
33
+ const quotaMoney = PriceUtils.calcTotalPrice(
34
+ underlyingPrice || 0n,
35
+ quotaAmount,
36
+ underlyingTokenDecimals
37
+ );
38
+ const quotaRate = quotaAPY * (BigInt(feeInterest) + PERCENTAGE_FACTOR) / PERCENTAGE_FACTOR;
39
+ const quotaAPYMoney = quotaMoney * quotaRate;
40
+ return acc + apyMoney - quotaAPYMoney;
41
+ },
42
+ 0n
43
+ );
44
+ const debtMoney = PriceUtils.calcTotalPrice(
45
+ underlyingPrice || 0n,
46
+ debt,
47
+ underlyingTokenDecimals
48
+ );
49
+ const debtAPYMoney = debtMoney * BigInt(baseRateWithFee);
50
+ const yourAssetsMoney = PriceUtils.calcTotalPrice(
51
+ underlyingPrice || PRICE_DECIMALS,
52
+ totalValue - debt,
53
+ underlyingTokenDecimals
54
+ );
55
+ const apyInPercent = (assetAPYMoney - debtAPYMoney) / yourAssetsMoney;
56
+ return apyInPercent;
57
+ }
58
+ export {
59
+ calcOverallAPY
60
+ };
@@ -0,0 +1,18 @@
1
+ function calcQuotaBorrowRate({
2
+ quotas,
3
+ quotaRates
4
+ }) {
5
+ const totalRateBalance = Object.values(quotas).reduce(
6
+ (acc, { token, balance }) => {
7
+ const { rate = 0, isActive = false } = quotaRates?.[token] || {};
8
+ const quotaBalance = isActive ? balance : 0n;
9
+ const rateBalance = quotaBalance * BigInt(rate);
10
+ return acc + rateBalance;
11
+ },
12
+ 0n
13
+ );
14
+ return totalRateBalance;
15
+ }
16
+ export {
17
+ calcQuotaBorrowRate
18
+ };
@@ -0,0 +1,10 @@
1
+ function calcRelativeBaseBorrowRate({
2
+ debt,
3
+ baseRateWithFee,
4
+ assetAmountInUnderlying
5
+ }) {
6
+ return debt * BigInt(baseRateWithFee) * assetAmountInUnderlying;
7
+ }
8
+ export {
9
+ calcRelativeBaseBorrowRate
10
+ };
@@ -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
+ };
@@ -1,4 +1,4 @@
1
- import { isSupportedNetwork } from "../chain/chains.js";
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 = URLApi.getRelativeUrl(
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 = () => URLApi.getRelativeUrl(
30
+ static apyAllRewards = () => getRelativeUrl(
31
31
  "https://state-cache.gearbox.foundation/apy-server/latest.json"
32
32
  );
33
33
  }
34
- class URLApi {
35
- constructor() {
36
- }
37
- static getRelativeUrl = (url, options) => {
38
- const { params = {} } = options || {};
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,5 @@
1
+ export * from "./assetsMath.js";
2
+ export * from "./bigintMath.js";
3
+ export * from "./creditAccount/index.js";
4
+ export * from "./endpoints.js";
5
+ export * from "./priceMath.js";
@@ -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
+ };
@@ -1,13 +1,9 @@
1
1
  export * from "./AddressMap.js";
2
2
  export * from "./AddressSet.js";
3
3
  export * from "./abi-decode.js";
4
- export * from "./assetsMath.js";
5
- export * from "./bigintMath.js";
6
4
  export * from "./bytes32ToString.js";
7
5
  export * from "./childLogger.js";
8
6
  export * from "./createRawTx.js";
9
- export * from "./creditAccount.js";
10
- export * from "./endpoints.js";
11
7
  export * from "./etherscan.js";
12
8
  export * from "./filterDust.js";
13
9
  export * from "./formatter.js";
@@ -15,7 +11,6 @@ export * from "./hex.js";
15
11
  export * from "./isDust.js";
16
12
  export * from "./json.js";
17
13
  export * from "./mappers.js";
18
- export * from "./priceMath.js";
19
14
  export * from "./retry.js";
20
15
  export * from "./toAddress.js";
21
16
  export * from "./type-utils.js";
@@ -0,0 +1 @@
1
+ export * from "./utils/index.js";
@@ -0,0 +1,114 @@
1
+ import type { Address } from "viem";
2
+ import type { Asset } from "../../sdk/index.js";
3
+ interface TokenDataSlice {
4
+ symbol: string;
5
+ decimals: number;
6
+ }
7
+ export interface AssetWithView extends Asset {
8
+ balanceView: string;
9
+ }
10
+ export interface AssetWithAmountInTarget extends Asset {
11
+ amountInTarget: bigint;
12
+ }
13
+ interface NextAssetProps<T extends Asset> {
14
+ allowedTokens: Array<Address>;
15
+ selectedAssets: Array<T>;
16
+ balances: Record<Address, bigint>;
17
+ tokensList: Record<Address, TokenDataSlice>;
18
+ prices?: Record<Address, bigint>;
19
+ }
20
+ export type WrapResult = [Array<Asset>, bigint, bigint];
21
+ /**
22
+ * Static helper namespace for asset-list transformations and math.
23
+ *
24
+ * The constructor is intentionally private to prevent instantiation.
25
+ */
26
+ export declare class AssetUtils {
27
+ private constructor();
28
+ /**
29
+ * Selects the next candidate token to add to a selected-asset list.
30
+ *
31
+ * Flow:
32
+ * 1) Removes tokens already present in `selectedAssets`
33
+ * 2) Builds balances for the remaining allowed tokens
34
+ * 3) Sorts the balances using `CreditAccountDataUtils.sortBalances`
35
+ * 4) Returns the highest-priority token address, if any
36
+ *
37
+ * Addresses are normalized to lowercase for matching.
38
+ *
39
+ * @returns The next token address to select, or `undefined` if no candidates remain.
40
+ */
41
+ static nextAsset<T extends Asset>({ allowedTokens, selectedAssets, balances, tokensList, prices, }: NextAssetProps<T>): Address | undefined;
42
+ /**
43
+ * Builds a normalized balance record for a specific token subset.
44
+ *
45
+ * Missing balances are defaulted to `0n`.
46
+ *
47
+ * @param allowedTokens Tokens to include in the output record.
48
+ * @param externalBalances Source balances keyed by lowercase address.
49
+ * @returns A record that contains only `allowedTokens`.
50
+ */
51
+ private static getBalances;
52
+ /**
53
+ * Converts an asset array into a token-address keyed record.
54
+ *
55
+ * If duplicate token addresses are present, the last occurrence wins.
56
+ *
57
+ * @param a Source asset list.
58
+ * @returns Record keyed by `asset.token`.
59
+ */
60
+ static constructAssetRecord<A extends Asset>(a: Array<A>): Record<`0x${string}`, A>;
61
+ /**
62
+ * Creates a reusable wrapper function that merges "unwrapped" and "wrapped"
63
+ * token balances into the wrapped token representation.
64
+ *
65
+ * The returned function:
66
+ * - converts non-negative unwrapped balance into wrapped units by price
67
+ * - adds the converted amount to the wrapped token balance
68
+ * - removes the unwrapped token from the result list
69
+ * - leaves input untouched when no unwrapped token is present
70
+ *
71
+ * @returns A function producing `[assets, convertedUnwrapped, originalWrapped]`.
72
+ */
73
+ static memoWrap: (unwrappedAddress: Address, wrappedAddress: Address, prices: Record<Address, bigint>, tokensList: Record<Address, TokenDataSlice>) => (assets: Array<Asset>) => WrapResult;
74
+ /**
75
+ * Adds balances from the second asset list into the first list.
76
+ *
77
+ * Behavior:
78
+ * - balances are clamped to non-negative before summation
79
+ * - tokens found only in `b` are created in the output
80
+ * - existing asset metadata is preserved from `a` when possible
81
+ *
82
+ * @param a Base asset list.
83
+ * @param b Asset deltas to add.
84
+ * @returns A merged list containing assets from both inputs.
85
+ */
86
+ static sumAssets<A extends Asset, B extends Asset>(a: Array<A>, b: Array<B>): Array<A | B>;
87
+ /**
88
+ * Adds balances from the second list to matching assets in the first list.
89
+ *
90
+ * Behavior:
91
+ * - balances are clamped to non-negative before summation
92
+ * - only assets already present in `a` are returned
93
+ * - no new token entries are created
94
+ *
95
+ * @param a Base asset list.
96
+ * @param b Asset deltas keyed by token.
97
+ * @returns Updated version of `a` with adjusted balances.
98
+ */
99
+ static addBalances<A extends Asset, B extends Asset>(a: Array<A>, b: Array<B>): Array<A | B>;
100
+ /**
101
+ * Subtracts balances in the second list from matching assets in the first list.
102
+ *
103
+ * Behavior:
104
+ * - both operands are clamped to non-negative before subtraction
105
+ * - output balances are clamped to non-negative after subtraction
106
+ * - only assets already present in `a` are returned
107
+ *
108
+ * @param a Base asset list.
109
+ * @param b Asset amounts to subtract by token.
110
+ * @returns Updated `a` list with non-negative post-subtraction balances.
111
+ */
112
+ static subAssets<A extends Asset, B extends Asset>(a: Array<A>, b: Array<B>): Array<A>;
113
+ }
114
+ export {};