@defisaver/positions-sdk 2.1.49-aave-v4-dev-1-dev → 2.1.49-aave-v4-dev-2

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 (116) hide show
  1. package/.mocharc.json +4 -4
  2. package/.nvmrc +1 -1
  3. package/README.md +64 -64
  4. package/cjs/helpers/aaveV4Helpers/index.d.ts +4 -0
  5. package/cjs/helpers/aaveV4Helpers/index.js +54 -2
  6. package/cjs/helpers/morphoBlueHelpers/index.js +66 -66
  7. package/cjs/savings/morphoVaults/index.js +17 -17
  8. package/esm/helpers/aaveV4Helpers/index.d.ts +4 -0
  9. package/esm/helpers/aaveV4Helpers/index.js +53 -2
  10. package/esm/helpers/morphoBlueHelpers/index.js +66 -66
  11. package/esm/savings/morphoVaults/index.js +17 -17
  12. package/package.json +48 -48
  13. package/src/aaveV2/index.ts +240 -240
  14. package/src/aaveV3/index.ts +635 -635
  15. package/src/aaveV3/merit.ts +97 -97
  16. package/src/aaveV3/merkl.ts +74 -74
  17. package/src/aaveV4/index.ts +168 -168
  18. package/src/claiming/aaveV3.ts +154 -154
  19. package/src/claiming/compV3.ts +22 -22
  20. package/src/claiming/ethena.ts +61 -61
  21. package/src/claiming/index.ts +12 -12
  22. package/src/claiming/king.ts +66 -66
  23. package/src/claiming/morphoBlue.ts +118 -118
  24. package/src/claiming/spark.ts +225 -225
  25. package/src/compoundV2/index.ts +244 -244
  26. package/src/compoundV3/index.ts +274 -274
  27. package/src/config/contracts.ts +1328 -1328
  28. package/src/constants/index.ts +10 -10
  29. package/src/contracts.ts +173 -173
  30. package/src/curveUsd/index.ts +254 -254
  31. package/src/eulerV2/index.ts +324 -324
  32. package/src/exchange/index.ts +25 -25
  33. package/src/fluid/index.ts +1800 -1800
  34. package/src/helpers/aaveHelpers/index.ts +191 -191
  35. package/src/helpers/aaveV4Helpers/index.ts +120 -68
  36. package/src/helpers/compoundHelpers/index.ts +283 -283
  37. package/src/helpers/curveUsdHelpers/index.ts +40 -40
  38. package/src/helpers/eulerHelpers/index.ts +222 -222
  39. package/src/helpers/fluidHelpers/index.ts +326 -326
  40. package/src/helpers/index.ts +11 -11
  41. package/src/helpers/liquityV2Helpers/index.ts +82 -82
  42. package/src/helpers/llamaLendHelpers/index.ts +53 -53
  43. package/src/helpers/makerHelpers/index.ts +52 -52
  44. package/src/helpers/morphoBlueHelpers/index.ts +396 -396
  45. package/src/helpers/sparkHelpers/index.ts +158 -158
  46. package/src/index.ts +51 -51
  47. package/src/liquity/index.ts +159 -159
  48. package/src/liquityV2/index.ts +703 -703
  49. package/src/llamaLend/index.ts +305 -305
  50. package/src/maker/index.ts +223 -223
  51. package/src/markets/aave/index.ts +118 -118
  52. package/src/markets/aave/marketAssets.ts +54 -54
  53. package/src/markets/aaveV4/index.ts +18 -18
  54. package/src/markets/compound/index.ts +243 -243
  55. package/src/markets/compound/marketsAssets.ts +97 -97
  56. package/src/markets/curveUsd/index.ts +69 -69
  57. package/src/markets/euler/index.ts +26 -26
  58. package/src/markets/fluid/index.ts +2900 -2900
  59. package/src/markets/index.ts +25 -25
  60. package/src/markets/liquityV2/index.ts +102 -102
  61. package/src/markets/llamaLend/contractAddresses.ts +141 -141
  62. package/src/markets/llamaLend/index.ts +235 -235
  63. package/src/markets/morphoBlue/index.ts +971 -971
  64. package/src/markets/spark/index.ts +29 -29
  65. package/src/markets/spark/marketAssets.ts +12 -12
  66. package/src/moneymarket/moneymarketCommonService.ts +85 -85
  67. package/src/morphoBlue/index.ts +274 -274
  68. package/src/portfolio/index.ts +618 -618
  69. package/src/savings/index.ts +95 -95
  70. package/src/savings/makerDsr/index.ts +53 -53
  71. package/src/savings/makerDsr/options.ts +9 -9
  72. package/src/savings/morphoVaults/index.ts +80 -80
  73. package/src/savings/morphoVaults/options.ts +193 -193
  74. package/src/savings/skyOptions/index.ts +95 -95
  75. package/src/savings/skyOptions/options.ts +10 -10
  76. package/src/savings/sparkSavingsVaults/index.ts +60 -60
  77. package/src/savings/sparkSavingsVaults/options.ts +35 -35
  78. package/src/savings/yearnV3Vaults/index.ts +61 -61
  79. package/src/savings/yearnV3Vaults/options.ts +55 -55
  80. package/src/savings/yearnVaults/index.ts +73 -73
  81. package/src/savings/yearnVaults/options.ts +32 -32
  82. package/src/services/priceService.ts +278 -278
  83. package/src/services/utils.ts +115 -115
  84. package/src/services/viem.ts +34 -34
  85. package/src/setup.ts +8 -8
  86. package/src/spark/index.ts +459 -459
  87. package/src/staking/eligibility.ts +53 -53
  88. package/src/staking/index.ts +1 -1
  89. package/src/staking/staking.ts +192 -192
  90. package/src/types/aave.ts +198 -198
  91. package/src/types/aaveV4.ts +142 -142
  92. package/src/types/claiming.ts +114 -114
  93. package/src/types/common.ts +107 -107
  94. package/src/types/compound.ts +144 -144
  95. package/src/types/curveUsd.ts +123 -123
  96. package/src/types/euler.ts +175 -175
  97. package/src/types/fluid.ts +483 -483
  98. package/src/types/index.ts +15 -15
  99. package/src/types/liquity.ts +30 -30
  100. package/src/types/liquityV2.ts +126 -126
  101. package/src/types/llamaLend.ts +159 -159
  102. package/src/types/maker.ts +63 -63
  103. package/src/types/merit.ts +1 -1
  104. package/src/types/merkl.ts +70 -70
  105. package/src/types/morphoBlue.ts +200 -200
  106. package/src/types/portfolio.ts +64 -64
  107. package/src/types/savings/index.ts +23 -23
  108. package/src/types/savings/makerDsr.ts +13 -13
  109. package/src/types/savings/morphoVaults.ts +32 -32
  110. package/src/types/savings/sky.ts +14 -14
  111. package/src/types/savings/sparkSavingsVaults.ts +15 -15
  112. package/src/types/savings/yearnV3Vaults.ts +17 -17
  113. package/src/types/savings/yearnVaults.ts +14 -14
  114. package/src/types/spark.ts +134 -134
  115. package/src/umbrella/index.ts +69 -69
  116. package/src/umbrella/umbrellaUtils.ts +29 -29
@@ -1,192 +1,192 @@
1
- import Dec from 'decimal.js';
2
- import { assetAmountInWei, getAssetInfo, getAssetInfoByAddress } from '@defisaver/tokens';
3
- import { Client } from 'viem';
4
- import {
5
- AaveAssetData, AaveHelperCommon, AaveMarketInfo, AaveV3AggregatedPositionData, AaveV3AssetsData, AaveV3UsedAssets, AaveVersions,
6
- } from '../../types';
7
- import { getNativeAssetFromWrapped, getWrappedNativeAssetFromUnwrapped } from '../../services/utils';
8
- import {
9
- aprToApy, calcLeverageLiqPrice, getAssetsTotal, isLeveragedPos,
10
- } from '../../moneymarket';
11
- import { calculateNetApy } from '../../staking';
12
- import { borrowOperations } from '../../constants';
13
- import { EthAddress, EthereumProvider, NetworkNumber } from '../../types/common';
14
- import { AaveLoanInfoV2ContractViem, AaveV3ViewContractViem } from '../../contracts';
15
- import { getViemProvider } from '../../services/viem';
16
-
17
- export const AAVE_V3_MARKETS = [AaveVersions.AaveV3, AaveVersions.AaveV3Lido, AaveVersions.AaveV3Etherfi];
18
-
19
- export const isAaveV2 = ({ selectedMarket }: { selectedMarket: Partial<AaveMarketInfo> }) => selectedMarket.value === AaveVersions.AaveV2;
20
- export const isAaveV3 = ({ selectedMarket }: { selectedMarket: Partial<AaveMarketInfo> }) => AAVE_V3_MARKETS.includes(selectedMarket.value as AaveVersions);
21
-
22
- export const aaveV3IsInIsolationMode = ({ usedAssets, assetsData }: { usedAssets: AaveV3UsedAssets, assetsData: AaveV3AssetsData }) => Object.values(usedAssets).some(({ symbol, collateral }) => collateral && assetsData[symbol].isIsolated);
23
- export const aaveV3IsInSiloedMode = ({ usedAssets, assetsData }: { usedAssets: AaveV3UsedAssets, assetsData: AaveV3AssetsData }) => Object.values(usedAssets).some(({ symbol, debt }) => debt && assetsData[symbol].isSiloed);
24
-
25
- export const aaveAnyGetCollSuppliedAssets = ({ usedAssets }: { usedAssets: AaveV3UsedAssets }) => Object.values(usedAssets)
26
- .filter(({ isSupplied, collateral }: { isSupplied: boolean, collateral: boolean }) => isSupplied && collateral);
27
-
28
- export const aaveAnyGetSuppliableAssets = ({
29
- usedAssets, eModeCategory, assetsData, selectedMarket, network, ...rest
30
- }: AaveHelperCommon) => {
31
- const data = {
32
- usedAssets, eModeCategory, assetsData, selectedMarket, network, ...rest,
33
- };
34
-
35
- const collAccountAssets = aaveAnyGetCollSuppliedAssets(data);
36
- const marketAssets = Object.values(assetsData) as AaveAssetData[];
37
-
38
- if (collAccountAssets.length === 0 || !isAaveV3(data)) return marketAssets.filter(({ canBeSupplied }) => canBeSupplied).map(({ symbol }) => ({ symbol, canBeCollateral: true }));
39
-
40
- if (aaveV3IsInIsolationMode(data)) {
41
- const collAsset = collAccountAssets[0].symbol;
42
- return marketAssets.filter(d => d.canBeSupplied).map(({ symbol }) => ({ symbol, canBeCollateral: symbol === collAsset }));
43
- }
44
-
45
- return marketAssets.filter(d => d.canBeSupplied).map(({ symbol, isIsolated }) => ({ symbol, canBeCollateral: !isIsolated }));
46
- };
47
-
48
- export const aaveAnyGetSuppliableAsCollAssets = ({
49
- usedAssets, eModeCategory, assetsData, selectedMarket, network, ...rest
50
- }: AaveHelperCommon) => aaveAnyGetSuppliableAssets({
51
- usedAssets, eModeCategory, assetsData, selectedMarket, network, ...rest,
52
- }).filter(({ canBeCollateral }) => canBeCollateral);
53
-
54
- export const aaveAnyGetEmodeMutableProps = (
55
- {
56
- eModeCategory,
57
- eModeCategoriesData,
58
- assetsData,
59
- }: AaveHelperCommon, _asset: string) => {
60
- const asset = getNativeAssetFromWrapped(_asset);
61
-
62
- const assetData = assetsData[asset];
63
- const eModeCategoryData: { collateralAssets: string[], collateralFactor: string, liquidationRatio: string, ltvZeroAssets: string[] } = eModeCategoriesData?.[eModeCategory] || {
64
- collateralAssets: [], ltvZeroAssets: [], collateralFactor: '0', liquidationRatio: '0',
65
- };
66
-
67
- if (
68
- eModeCategory === 0
69
- || !eModeCategoryData.collateralAssets.includes(asset)
70
- || new Dec(eModeCategoryData.collateralFactor || 0).eq(0)
71
- ) {
72
- const { liquidationRatio, collateralFactor } = assetData;
73
- return ({ liquidationRatio, collateralFactor });
74
- }
75
- if (eModeCategoryData.ltvZeroAssets.includes(asset)) return ({ liquidationRatio: '0', collateralFactor: '0' });
76
-
77
- const { liquidationRatio, collateralFactor } = eModeCategoryData;
78
- return ({ liquidationRatio, collateralFactor });
79
- };
80
-
81
- export const aaveAnyGetAggregatedPositionData = ({
82
- usedAssets,
83
- eModeCategory,
84
- assetsData,
85
- selectedMarket,
86
- network,
87
- ...rest
88
- }: AaveHelperCommon): AaveV3AggregatedPositionData => {
89
- const data = {
90
- usedAssets, eModeCategory, assetsData, selectedMarket, network, ...rest,
91
- };
92
- const payload = {} as AaveV3AggregatedPositionData;
93
- payload.suppliedUsd = getAssetsTotal(usedAssets, ({ isSupplied }: { isSupplied: boolean }) => isSupplied, ({ suppliedUsd }: { suppliedUsd: string }) => suppliedUsd);
94
- payload.suppliedCollateralUsd = getAssetsTotal(usedAssets, ({ isSupplied, collateral }: { isSupplied: boolean, collateral: string }) => isSupplied && collateral, ({ suppliedUsd }: { suppliedUsd: string }) => suppliedUsd);
95
- payload.borrowLimitUsd = getAssetsTotal(
96
- usedAssets,
97
- ({ isSupplied, collateral }: { isSupplied: boolean, collateral: string }) => isSupplied && collateral,
98
- ({ symbol, suppliedUsd }: { symbol: string, suppliedUsd: string }) => new Dec(suppliedUsd).mul(aaveAnyGetEmodeMutableProps(data, symbol).collateralFactor),
99
- );
100
- payload.liquidationLimitUsd = getAssetsTotal(
101
- usedAssets,
102
- ({ isSupplied, collateral }: { isSupplied: boolean, collateral: string }) => isSupplied && collateral,
103
- ({ symbol, suppliedUsd }: { symbol: string, suppliedUsd: string }) => new Dec(suppliedUsd).mul(aaveAnyGetEmodeMutableProps(data, symbol).liquidationRatio),
104
- );
105
- payload.borrowedUsd = getAssetsTotal(usedAssets, ({ isBorrowed }: { isBorrowed: boolean }) => isBorrowed, ({ borrowedUsd }: { borrowedUsd: string }) => borrowedUsd);
106
- const leftToBorrowUsd = new Dec(payload.borrowLimitUsd).sub(payload.borrowedUsd);
107
- payload.leftToBorrowUsd = leftToBorrowUsd.lte('0') ? '0' : leftToBorrowUsd.toString();
108
- payload.ratio = +payload.suppliedUsd ? new Dec(payload.borrowLimitUsd).div(payload.borrowedUsd).mul(100).toString() : '0';
109
- payload.collRatio = +payload.suppliedUsd ? new Dec(payload.suppliedCollateralUsd).div(payload.borrowedUsd).mul(100).toString() : '0';
110
- payload.liqRatio = new Dec(payload.borrowLimitUsd).div(payload.liquidationLimitUsd).toString();
111
- payload.liqPercent = new Dec(payload.borrowLimitUsd).div(payload.liquidationLimitUsd).mul(100).toString();
112
- const { leveragedType, leveragedAsset } = isLeveragedPos(usedAssets);
113
- payload.leveragedType = leveragedType;
114
- payload.leveragedAsset = leveragedAsset;
115
- payload.liquidationPrice = '';
116
- if (leveragedType !== '') {
117
- let assetPrice = data.assetsData[leveragedAsset].price;
118
- if (leveragedType === 'lsd-leverage') {
119
- // Treat ETH like a stablecoin in a long stETH position
120
- payload.leveragedLsdAssetRatio = new Dec(assetsData[leveragedAsset].price).div(assetsData.ETH.price).toDP(18).toString();
121
- assetPrice = new Dec(assetPrice).div(assetsData.ETH.price).toString();
122
- }
123
- payload.liquidationPrice = calcLeverageLiqPrice(leveragedType, assetPrice, payload.borrowedUsd, payload.liquidationLimitUsd);
124
- }
125
- payload.minCollRatio = new Dec(payload.suppliedCollateralUsd).div(payload.borrowLimitUsd).mul(100).toString();
126
- payload.collLiquidationRatio = new Dec(payload.suppliedCollateralUsd).div(payload.liquidationLimitUsd).mul(100).toString();
127
- payload.healthRatio = new Dec(payload.liquidationLimitUsd).div(payload.borrowedUsd).toDP(4).toString();
128
- payload.minHealthRatio = new Dec(payload.liquidationLimitUsd).div(payload.borrowLimitUsd).toDP(4).toString();
129
-
130
- const { netApy, incentiveUsd, totalInterestUsd } = calculateNetApy({
131
- usedAssets,
132
- assetsData,
133
- optionalData: { healthRatio: payload.healthRatio },
134
- });
135
- payload.netApy = netApy;
136
- payload.incentiveUsd = incentiveUsd;
137
- payload.totalInterestUsd = totalInterestUsd;
138
- return payload;
139
- };
140
-
141
- const getApyAfterValuesEstimationInner = async (selectedMarket: AaveMarketInfo, actions: [{ action: string, amount: string, asset: string }], client: Client, network: NetworkNumber) => {
142
- const params = actions.map(({ action, asset, amount }) => {
143
- const isDebtAsset = borrowOperations.includes(action);
144
- const amountInWei = assetAmountInWei(amount, asset);
145
- const assetInfo = getAssetInfo(getWrappedNativeAssetFromUnwrapped(asset), network);
146
- let liquidityAdded;
147
- let liquidityTaken;
148
- if (isDebtAsset) {
149
- liquidityAdded = action === 'payback' ? amountInWei : '0';
150
- liquidityTaken = action === 'borrow' ? amountInWei : '0';
151
- } else {
152
- liquidityAdded = action === 'collateral' ? amountInWei : '0';
153
- liquidityTaken = action === 'withdraw' ? amountInWei : '0';
154
- }
155
- return {
156
- reserveAddress: assetInfo.address as EthAddress,
157
- liquidityAdded: BigInt(liquidityAdded),
158
- liquidityTaken: BigInt(liquidityTaken),
159
- isDebtAsset,
160
- };
161
- });
162
- const viewContract = isAaveV2({ selectedMarket }) ? AaveLoanInfoV2ContractViem(client, network) : AaveV3ViewContractViem(client, network);
163
- const data = await viewContract.read.getApyAfterValuesEstimation([selectedMarket.providerAddress, params]);
164
- const rates: { [key: string]: { supplyRate: string, borrowRate: string } } = {};
165
- data.forEach((d: { reserveAddress: EthAddress, supplyRate: BigInt, variableBorrowRate: BigInt }) => {
166
- const asset = getNativeAssetFromWrapped(getAssetInfoByAddress(d.reserveAddress, network).symbol);
167
- rates[asset] = {
168
- supplyRate: aprToApy(new Dec(d.supplyRate.toString()).div(1e25).toString()),
169
- borrowRate: aprToApy(new Dec(d.variableBorrowRate.toString()).div(1e25).toString()),
170
- };
171
- });
172
- return rates;
173
- };
174
-
175
- export const getApyAfterValuesEstimation = async (selectedMarket: AaveMarketInfo, actions: [{ action: string, amount: string, asset: string }], provider: EthereumProvider, network: NetworkNumber) => getApyAfterValuesEstimationInner(selectedMarket, actions, getViemProvider(provider, network), network);
176
-
177
- /**
178
- * won't cover all cases
179
- */
180
- export const getAaveUnderlyingSymbol = (_symbol = '') => {
181
- let symbol = _symbol
182
- .replace(/^aEthLido/, '')
183
- .replace(/^aEthEtherFi/, '')
184
- .replace(/^aEth/, '')
185
- .replace(/^aArb/, '')
186
- .replace(/^aOpt/, '')
187
- .replace(/^aLin/, '')
188
- .replace(/^aPla/, '')
189
- .replace(/^aBas/, '');
190
- if (symbol.startsWith('a')) symbol = symbol.slice(1);
191
- return getNativeAssetFromWrapped(symbol);
1
+ import Dec from 'decimal.js';
2
+ import { assetAmountInWei, getAssetInfo, getAssetInfoByAddress } from '@defisaver/tokens';
3
+ import { Client } from 'viem';
4
+ import {
5
+ AaveAssetData, AaveHelperCommon, AaveMarketInfo, AaveV3AggregatedPositionData, AaveV3AssetsData, AaveV3UsedAssets, AaveVersions,
6
+ } from '../../types';
7
+ import { getNativeAssetFromWrapped, getWrappedNativeAssetFromUnwrapped } from '../../services/utils';
8
+ import {
9
+ aprToApy, calcLeverageLiqPrice, getAssetsTotal, isLeveragedPos,
10
+ } from '../../moneymarket';
11
+ import { calculateNetApy } from '../../staking';
12
+ import { borrowOperations } from '../../constants';
13
+ import { EthAddress, EthereumProvider, NetworkNumber } from '../../types/common';
14
+ import { AaveLoanInfoV2ContractViem, AaveV3ViewContractViem } from '../../contracts';
15
+ import { getViemProvider } from '../../services/viem';
16
+
17
+ export const AAVE_V3_MARKETS = [AaveVersions.AaveV3, AaveVersions.AaveV3Lido, AaveVersions.AaveV3Etherfi];
18
+
19
+ export const isAaveV2 = ({ selectedMarket }: { selectedMarket: Partial<AaveMarketInfo> }) => selectedMarket.value === AaveVersions.AaveV2;
20
+ export const isAaveV3 = ({ selectedMarket }: { selectedMarket: Partial<AaveMarketInfo> }) => AAVE_V3_MARKETS.includes(selectedMarket.value as AaveVersions);
21
+
22
+ export const aaveV3IsInIsolationMode = ({ usedAssets, assetsData }: { usedAssets: AaveV3UsedAssets, assetsData: AaveV3AssetsData }) => Object.values(usedAssets).some(({ symbol, collateral }) => collateral && assetsData[symbol].isIsolated);
23
+ export const aaveV3IsInSiloedMode = ({ usedAssets, assetsData }: { usedAssets: AaveV3UsedAssets, assetsData: AaveV3AssetsData }) => Object.values(usedAssets).some(({ symbol, debt }) => debt && assetsData[symbol].isSiloed);
24
+
25
+ export const aaveAnyGetCollSuppliedAssets = ({ usedAssets }: { usedAssets: AaveV3UsedAssets }) => Object.values(usedAssets)
26
+ .filter(({ isSupplied, collateral }: { isSupplied: boolean, collateral: boolean }) => isSupplied && collateral);
27
+
28
+ export const aaveAnyGetSuppliableAssets = ({
29
+ usedAssets, eModeCategory, assetsData, selectedMarket, network, ...rest
30
+ }: AaveHelperCommon) => {
31
+ const data = {
32
+ usedAssets, eModeCategory, assetsData, selectedMarket, network, ...rest,
33
+ };
34
+
35
+ const collAccountAssets = aaveAnyGetCollSuppliedAssets(data);
36
+ const marketAssets = Object.values(assetsData) as AaveAssetData[];
37
+
38
+ if (collAccountAssets.length === 0 || !isAaveV3(data)) return marketAssets.filter(({ canBeSupplied }) => canBeSupplied).map(({ symbol }) => ({ symbol, canBeCollateral: true }));
39
+
40
+ if (aaveV3IsInIsolationMode(data)) {
41
+ const collAsset = collAccountAssets[0].symbol;
42
+ return marketAssets.filter(d => d.canBeSupplied).map(({ symbol }) => ({ symbol, canBeCollateral: symbol === collAsset }));
43
+ }
44
+
45
+ return marketAssets.filter(d => d.canBeSupplied).map(({ symbol, isIsolated }) => ({ symbol, canBeCollateral: !isIsolated }));
46
+ };
47
+
48
+ export const aaveAnyGetSuppliableAsCollAssets = ({
49
+ usedAssets, eModeCategory, assetsData, selectedMarket, network, ...rest
50
+ }: AaveHelperCommon) => aaveAnyGetSuppliableAssets({
51
+ usedAssets, eModeCategory, assetsData, selectedMarket, network, ...rest,
52
+ }).filter(({ canBeCollateral }) => canBeCollateral);
53
+
54
+ export const aaveAnyGetEmodeMutableProps = (
55
+ {
56
+ eModeCategory,
57
+ eModeCategoriesData,
58
+ assetsData,
59
+ }: AaveHelperCommon, _asset: string) => {
60
+ const asset = getNativeAssetFromWrapped(_asset);
61
+
62
+ const assetData = assetsData[asset];
63
+ const eModeCategoryData: { collateralAssets: string[], collateralFactor: string, liquidationRatio: string, ltvZeroAssets: string[] } = eModeCategoriesData?.[eModeCategory] || {
64
+ collateralAssets: [], ltvZeroAssets: [], collateralFactor: '0', liquidationRatio: '0',
65
+ };
66
+
67
+ if (
68
+ eModeCategory === 0
69
+ || !eModeCategoryData.collateralAssets.includes(asset)
70
+ || new Dec(eModeCategoryData.collateralFactor || 0).eq(0)
71
+ ) {
72
+ const { liquidationRatio, collateralFactor } = assetData;
73
+ return ({ liquidationRatio, collateralFactor });
74
+ }
75
+ if (eModeCategoryData.ltvZeroAssets.includes(asset)) return ({ liquidationRatio: '0', collateralFactor: '0' });
76
+
77
+ const { liquidationRatio, collateralFactor } = eModeCategoryData;
78
+ return ({ liquidationRatio, collateralFactor });
79
+ };
80
+
81
+ export const aaveAnyGetAggregatedPositionData = ({
82
+ usedAssets,
83
+ eModeCategory,
84
+ assetsData,
85
+ selectedMarket,
86
+ network,
87
+ ...rest
88
+ }: AaveHelperCommon): AaveV3AggregatedPositionData => {
89
+ const data = {
90
+ usedAssets, eModeCategory, assetsData, selectedMarket, network, ...rest,
91
+ };
92
+ const payload = {} as AaveV3AggregatedPositionData;
93
+ payload.suppliedUsd = getAssetsTotal(usedAssets, ({ isSupplied }: { isSupplied: boolean }) => isSupplied, ({ suppliedUsd }: { suppliedUsd: string }) => suppliedUsd);
94
+ payload.suppliedCollateralUsd = getAssetsTotal(usedAssets, ({ isSupplied, collateral }: { isSupplied: boolean, collateral: string }) => isSupplied && collateral, ({ suppliedUsd }: { suppliedUsd: string }) => suppliedUsd);
95
+ payload.borrowLimitUsd = getAssetsTotal(
96
+ usedAssets,
97
+ ({ isSupplied, collateral }: { isSupplied: boolean, collateral: string }) => isSupplied && collateral,
98
+ ({ symbol, suppliedUsd }: { symbol: string, suppliedUsd: string }) => new Dec(suppliedUsd).mul(aaveAnyGetEmodeMutableProps(data, symbol).collateralFactor),
99
+ );
100
+ payload.liquidationLimitUsd = getAssetsTotal(
101
+ usedAssets,
102
+ ({ isSupplied, collateral }: { isSupplied: boolean, collateral: string }) => isSupplied && collateral,
103
+ ({ symbol, suppliedUsd }: { symbol: string, suppliedUsd: string }) => new Dec(suppliedUsd).mul(aaveAnyGetEmodeMutableProps(data, symbol).liquidationRatio),
104
+ );
105
+ payload.borrowedUsd = getAssetsTotal(usedAssets, ({ isBorrowed }: { isBorrowed: boolean }) => isBorrowed, ({ borrowedUsd }: { borrowedUsd: string }) => borrowedUsd);
106
+ const leftToBorrowUsd = new Dec(payload.borrowLimitUsd).sub(payload.borrowedUsd);
107
+ payload.leftToBorrowUsd = leftToBorrowUsd.lte('0') ? '0' : leftToBorrowUsd.toString();
108
+ payload.ratio = +payload.suppliedUsd ? new Dec(payload.borrowLimitUsd).div(payload.borrowedUsd).mul(100).toString() : '0';
109
+ payload.collRatio = +payload.suppliedUsd ? new Dec(payload.suppliedCollateralUsd).div(payload.borrowedUsd).mul(100).toString() : '0';
110
+ payload.liqRatio = new Dec(payload.borrowLimitUsd).div(payload.liquidationLimitUsd).toString();
111
+ payload.liqPercent = new Dec(payload.borrowLimitUsd).div(payload.liquidationLimitUsd).mul(100).toString();
112
+ const { leveragedType, leveragedAsset } = isLeveragedPos(usedAssets);
113
+ payload.leveragedType = leveragedType;
114
+ payload.leveragedAsset = leveragedAsset;
115
+ payload.liquidationPrice = '';
116
+ if (leveragedType !== '') {
117
+ let assetPrice = data.assetsData[leveragedAsset].price;
118
+ if (leveragedType === 'lsd-leverage') {
119
+ // Treat ETH like a stablecoin in a long stETH position
120
+ payload.leveragedLsdAssetRatio = new Dec(assetsData[leveragedAsset].price).div(assetsData.ETH.price).toDP(18).toString();
121
+ assetPrice = new Dec(assetPrice).div(assetsData.ETH.price).toString();
122
+ }
123
+ payload.liquidationPrice = calcLeverageLiqPrice(leveragedType, assetPrice, payload.borrowedUsd, payload.liquidationLimitUsd);
124
+ }
125
+ payload.minCollRatio = new Dec(payload.suppliedCollateralUsd).div(payload.borrowLimitUsd).mul(100).toString();
126
+ payload.collLiquidationRatio = new Dec(payload.suppliedCollateralUsd).div(payload.liquidationLimitUsd).mul(100).toString();
127
+ payload.healthRatio = new Dec(payload.liquidationLimitUsd).div(payload.borrowedUsd).toDP(4).toString();
128
+ payload.minHealthRatio = new Dec(payload.liquidationLimitUsd).div(payload.borrowLimitUsd).toDP(4).toString();
129
+
130
+ const { netApy, incentiveUsd, totalInterestUsd } = calculateNetApy({
131
+ usedAssets,
132
+ assetsData,
133
+ optionalData: { healthRatio: payload.healthRatio },
134
+ });
135
+ payload.netApy = netApy;
136
+ payload.incentiveUsd = incentiveUsd;
137
+ payload.totalInterestUsd = totalInterestUsd;
138
+ return payload;
139
+ };
140
+
141
+ const getApyAfterValuesEstimationInner = async (selectedMarket: AaveMarketInfo, actions: [{ action: string, amount: string, asset: string }], client: Client, network: NetworkNumber) => {
142
+ const params = actions.map(({ action, asset, amount }) => {
143
+ const isDebtAsset = borrowOperations.includes(action);
144
+ const amountInWei = assetAmountInWei(amount, asset);
145
+ const assetInfo = getAssetInfo(getWrappedNativeAssetFromUnwrapped(asset), network);
146
+ let liquidityAdded;
147
+ let liquidityTaken;
148
+ if (isDebtAsset) {
149
+ liquidityAdded = action === 'payback' ? amountInWei : '0';
150
+ liquidityTaken = action === 'borrow' ? amountInWei : '0';
151
+ } else {
152
+ liquidityAdded = action === 'collateral' ? amountInWei : '0';
153
+ liquidityTaken = action === 'withdraw' ? amountInWei : '0';
154
+ }
155
+ return {
156
+ reserveAddress: assetInfo.address as EthAddress,
157
+ liquidityAdded: BigInt(liquidityAdded),
158
+ liquidityTaken: BigInt(liquidityTaken),
159
+ isDebtAsset,
160
+ };
161
+ });
162
+ const viewContract = isAaveV2({ selectedMarket }) ? AaveLoanInfoV2ContractViem(client, network) : AaveV3ViewContractViem(client, network);
163
+ const data = await viewContract.read.getApyAfterValuesEstimation([selectedMarket.providerAddress, params]);
164
+ const rates: { [key: string]: { supplyRate: string, borrowRate: string } } = {};
165
+ data.forEach((d: { reserveAddress: EthAddress, supplyRate: BigInt, variableBorrowRate: BigInt }) => {
166
+ const asset = getNativeAssetFromWrapped(getAssetInfoByAddress(d.reserveAddress, network).symbol);
167
+ rates[asset] = {
168
+ supplyRate: aprToApy(new Dec(d.supplyRate.toString()).div(1e25).toString()),
169
+ borrowRate: aprToApy(new Dec(d.variableBorrowRate.toString()).div(1e25).toString()),
170
+ };
171
+ });
172
+ return rates;
173
+ };
174
+
175
+ export const getApyAfterValuesEstimation = async (selectedMarket: AaveMarketInfo, actions: [{ action: string, amount: string, asset: string }], provider: EthereumProvider, network: NetworkNumber) => getApyAfterValuesEstimationInner(selectedMarket, actions, getViemProvider(provider, network), network);
176
+
177
+ /**
178
+ * won't cover all cases
179
+ */
180
+ export const getAaveUnderlyingSymbol = (_symbol = '') => {
181
+ let symbol = _symbol
182
+ .replace(/^aEthLido/, '')
183
+ .replace(/^aEthEtherFi/, '')
184
+ .replace(/^aEth/, '')
185
+ .replace(/^aArb/, '')
186
+ .replace(/^aOpt/, '')
187
+ .replace(/^aLin/, '')
188
+ .replace(/^aPla/, '')
189
+ .replace(/^aBas/, '');
190
+ if (symbol.startsWith('a')) symbol = symbol.slice(1);
191
+ return getNativeAssetFromWrapped(symbol);
192
192
  };
@@ -1,69 +1,121 @@
1
- import Dec from 'decimal.js';
2
- import { calcLeverageLiqPrice, getAssetsTotal, isLeveragedPos } from '../../moneymarket';
3
- import {
4
- AaveV4AggregatedPositionData, AaveV4AssetsData, AaveV4ReserveAssetData, AaveV4UsedReserveAsset, AaveV4UsedReserveAssets,
5
- } from '../../types';
6
- import { NetworkNumber } from '../../types/common';
7
-
8
- export const aaveV4GetCollateralFactor = (assetData: AaveV4ReserveAssetData, usedAssetData: AaveV4UsedReserveAsset, useUserCollateralFactor: boolean = false): number => (useUserCollateralFactor ? usedAssetData.collateralFactor : assetData.collateralFactor);
9
-
10
- export const aaveV4GetAggregatedPositionData = ({
11
- usedAssets,
12
- assetsData,
13
- network,
14
- useUserCollateralFactor = false,
15
- }: {
16
- usedAssets: AaveV4UsedReserveAssets,
17
- assetsData: AaveV4AssetsData,
18
- network: NetworkNumber,
19
- useUserCollateralFactor?: boolean,
20
- }): AaveV4AggregatedPositionData => {
21
- const payload = {} as AaveV4AggregatedPositionData;
22
- payload.suppliedUsd = getAssetsTotal(usedAssets, ({ isSupplied }: { isSupplied: boolean }) => isSupplied, ({ suppliedUsd }: { suppliedUsd: string }) => suppliedUsd);
23
- payload.suppliedCollateralUsd = getAssetsTotal(usedAssets, ({ isSupplied, collateral }: { isSupplied: boolean, collateral: string }) => isSupplied && collateral, ({ suppliedUsd }: { suppliedUsd: string }) => suppliedUsd);
24
- payload.borrowLimitUsd = getAssetsTotal(
25
- usedAssets,
26
- ({ isSupplied, collateral }: { isSupplied: boolean, collateral: string }) => isSupplied && collateral,
27
- ({ symbol, suppliedUsd, reserveId }: { symbol: string, suppliedUsd: string, reserveId: number }) => new Dec(suppliedUsd).mul(aaveV4GetCollateralFactor(assetsData[`${symbol}-${reserveId}`], usedAssets[`${symbol}-${reserveId}`], useUserCollateralFactor)),
28
- );
29
- payload.liquidationLimitUsd = payload.borrowLimitUsd;
30
- payload.borrowedUsd = getAssetsTotal(usedAssets, ({ isBorrowed }: { isBorrowed: boolean }) => isBorrowed, ({ borrowedUsd }: { borrowedUsd: string }) => borrowedUsd);
31
- payload.drawnUsd = getAssetsTotal(usedAssets, ({ isBorrowed }: { isBorrowed: boolean }) => isBorrowed, ({ drawnUsd }: { drawnUsd: string }) => drawnUsd);
32
- payload.premiumUsd = getAssetsTotal(usedAssets, ({ isBorrowed }: { isBorrowed: boolean }) => isBorrowed, ({ premiumUsd }: { premiumUsd: string }) => premiumUsd);
33
- const leftToBorrowUsd = new Dec(payload.borrowLimitUsd).sub(payload.borrowedUsd);
34
- payload.leftToBorrowUsd = leftToBorrowUsd.lte('0') ? '0' : leftToBorrowUsd.toString();
35
- payload.ratio = +payload.suppliedUsd ? new Dec(payload.borrowLimitUsd).div(payload.borrowedUsd).mul(100).toString() : '0';
36
- payload.collRatio = +payload.suppliedUsd ? new Dec(payload.suppliedCollateralUsd).div(payload.borrowedUsd).mul(100).toString() : '0';
37
- payload.liqRatio = new Dec(payload.borrowLimitUsd).div(payload.liquidationLimitUsd).toString();
38
- payload.liqPercent = new Dec(payload.borrowLimitUsd).div(payload.liquidationLimitUsd).mul(100).toString();
39
- const { leveragedType, leveragedAsset } = isLeveragedPos(usedAssets);
40
- payload.leveragedType = leveragedType;
41
- payload.leveragedAsset = leveragedAsset;
42
- payload.liquidationPrice = '';
43
- if (leveragedType !== '') {
44
- const leveragedAssetData = Object.values(assetsData).find((asset) => asset.symbol === leveragedAsset);
45
- let assetPrice = leveragedAssetData?.price || '0';
46
- if (leveragedType === 'lsd-leverage') {
47
- // Treat ETH like a stablecoin in a long stETH position
48
- const ethPrice = Object.values(assetsData).find((asset) => asset.symbol === 'ETH')?.price || '0';
49
- payload.leveragedLsdAssetRatio = new Dec(leveragedAssetData?.price || '0').div(ethPrice).toDP(18).toString();
50
- assetPrice = new Dec(assetPrice).div(ethPrice).toString();
51
- }
52
- payload.liquidationPrice = calcLeverageLiqPrice(leveragedType, assetPrice, payload.borrowedUsd, payload.liquidationLimitUsd);
53
- }
54
- payload.minCollRatio = new Dec(payload.suppliedCollateralUsd).div(payload.borrowLimitUsd).mul(100).toString();
55
- payload.collLiquidationRatio = new Dec(payload.suppliedCollateralUsd).div(payload.liquidationLimitUsd).mul(100).toString();
56
- // payload.healthRatio = new Dec(payload.liquidationLimitUsd).div(payload.borrowedUsd).toDP(4).toString();
57
- payload.minHealthRatio = new Dec(payload.liquidationLimitUsd).div(payload.borrowLimitUsd).toDP(4).toString();
58
-
59
- // TODO: Re-implement netApy calculation
60
- // const { netApy, incentiveUsd, totalInterestUsd } = calculateNetApy({
61
- // usedAssets,
62
- // assetsData,
63
- // optionalData: { healthRatio: payload.healthRatio },
64
- // });
65
- payload.netApy = '0';
66
- payload.incentiveUsd = '0';
67
- payload.totalInterestUsd = '0';
68
- return payload;
1
+ import Dec from 'decimal.js';
2
+ import { calcLeverageLiqPrice, getAssetsTotal, STABLE_ASSETS } from '../../moneymarket';
3
+ import {
4
+ AaveV4AggregatedPositionData, AaveV4AssetsData, AaveV4ReserveAssetData, AaveV4UsedReserveAsset, AaveV4UsedReserveAssets,
5
+ } from '../../types';
6
+ import { NetworkNumber } from '../../types/common';
7
+
8
+ export const aaveV4GetCollateralFactor = (assetData: AaveV4ReserveAssetData, usedAssetData: AaveV4UsedReserveAsset, useUserCollateralFactor: boolean = false): number => (useUserCollateralFactor ? usedAssetData.collateralFactor : assetData.collateralFactor);
9
+
10
+ export const isLeveragedPosAaveV4 = (usedAssets: AaveV4UsedReserveAssets, dustLimit = 5) => {
11
+ let borrowUnstable = 0;
12
+ let supplyStable = 0;
13
+ let borrowStable = 0;
14
+ let supplyUnstable = 0;
15
+ let longAsset = '';
16
+ let shortAsset = '';
17
+ Object.values(usedAssets).forEach(({
18
+ symbol, suppliedUsd, borrowedUsd, collateral, reserveId,
19
+ }) => {
20
+ const spokeAsset = `${symbol}-${reserveId}`;
21
+ const isSupplied = (+suppliedUsd) > dustLimit; // ignore dust like <limit leftover supply
22
+ const isBorrowed = (+borrowedUsd) > dustLimit; // ignore dust like <limit leftover supply
23
+ if (isSupplied && STABLE_ASSETS.includes(symbol) && collateral) supplyStable += 1;
24
+ if (isBorrowed && STABLE_ASSETS.includes(symbol)) borrowStable += 1;
25
+ if (isBorrowed && !STABLE_ASSETS.includes(symbol)) {
26
+ borrowUnstable += 1;
27
+ shortAsset = spokeAsset;
28
+ }
29
+ if (isSupplied && !STABLE_ASSETS.includes(symbol) && collateral) {
30
+ supplyUnstable += 1;
31
+ longAsset = spokeAsset;
32
+ }
33
+ });
34
+ const isLong = borrowStable > 0 && borrowUnstable === 0 && supplyUnstable === 1 && supplyStable === 0;
35
+ const isShort = supplyStable > 0 && supplyUnstable === 0 && borrowUnstable === 1 && borrowStable === 0;
36
+ // lsd -> liquid staking derivative
37
+ const isLsdLeveraged = supplyUnstable === 1 && borrowUnstable === 1 && shortAsset === 'ETH' && ['stETH', 'wstETH', 'cbETH', 'rETH', 'ezETH', 'weETH'].includes(longAsset);
38
+ if (isLong) {
39
+ return {
40
+ leveragedType: 'long',
41
+ leveragedAsset: longAsset,
42
+ };
43
+ }
44
+ if (isShort) {
45
+ return {
46
+ leveragedType: 'short',
47
+ leveragedAsset: shortAsset,
48
+ };
49
+ }
50
+ if (isLsdLeveraged) {
51
+ return {
52
+ leveragedType: 'lsd-leverage',
53
+ leveragedAsset: longAsset,
54
+ };
55
+ }
56
+ return {
57
+ leveragedType: '',
58
+ leveragedAsset: '',
59
+ };
60
+ };
61
+
62
+ export const aaveV4GetAggregatedPositionData = ({
63
+ usedAssets,
64
+ assetsData,
65
+ network,
66
+ useUserCollateralFactor = false,
67
+ }: {
68
+ usedAssets: AaveV4UsedReserveAssets,
69
+ assetsData: AaveV4AssetsData,
70
+ network: NetworkNumber,
71
+ useUserCollateralFactor?: boolean,
72
+ }): AaveV4AggregatedPositionData => {
73
+ const payload = {} as AaveV4AggregatedPositionData;
74
+ payload.suppliedUsd = getAssetsTotal(usedAssets, ({ isSupplied }: { isSupplied: boolean }) => isSupplied, ({ suppliedUsd }: { suppliedUsd: string }) => suppliedUsd);
75
+ payload.suppliedCollateralUsd = getAssetsTotal(usedAssets, ({ isSupplied, collateral }: { isSupplied: boolean, collateral: string }) => isSupplied && collateral, ({ suppliedUsd }: { suppliedUsd: string }) => suppliedUsd);
76
+ payload.borrowLimitUsd = getAssetsTotal(
77
+ usedAssets,
78
+ ({ isSupplied, collateral }: { isSupplied: boolean, collateral: string }) => isSupplied && collateral,
79
+ ({ symbol, suppliedUsd, reserveId }: { symbol: string, suppliedUsd: string, reserveId: number }) => new Dec(suppliedUsd).mul(aaveV4GetCollateralFactor(assetsData[`${symbol}-${reserveId}`], usedAssets[`${symbol}-${reserveId}`], useUserCollateralFactor)),
80
+ );
81
+ payload.liquidationLimitUsd = payload.borrowLimitUsd;
82
+ payload.borrowedUsd = getAssetsTotal(usedAssets, ({ isBorrowed }: { isBorrowed: boolean }) => isBorrowed, ({ borrowedUsd }: { borrowedUsd: string }) => borrowedUsd);
83
+ payload.drawnUsd = getAssetsTotal(usedAssets, ({ isBorrowed }: { isBorrowed: boolean }) => isBorrowed, ({ drawnUsd }: { drawnUsd: string }) => drawnUsd);
84
+ payload.premiumUsd = getAssetsTotal(usedAssets, ({ isBorrowed }: { isBorrowed: boolean }) => isBorrowed, ({ premiumUsd }: { premiumUsd: string }) => premiumUsd);
85
+ const leftToBorrowUsd = new Dec(payload.borrowLimitUsd).sub(payload.borrowedUsd);
86
+ payload.leftToBorrowUsd = leftToBorrowUsd.lte('0') ? '0' : leftToBorrowUsd.toString();
87
+ payload.ratio = +payload.suppliedUsd ? new Dec(payload.borrowLimitUsd).div(payload.borrowedUsd).mul(100).toString() : '0';
88
+ payload.collRatio = +payload.suppliedUsd ? new Dec(payload.suppliedCollateralUsd).div(payload.borrowedUsd).mul(100).toString() : '0';
89
+ payload.liqRatio = new Dec(payload.borrowLimitUsd).div(payload.liquidationLimitUsd).toString();
90
+ payload.liqPercent = new Dec(payload.borrowLimitUsd).div(payload.liquidationLimitUsd).mul(100).toString();
91
+ const { leveragedType, leveragedAsset } = isLeveragedPosAaveV4(usedAssets);
92
+ payload.leveragedType = leveragedType;
93
+ payload.leveragedAsset = leveragedAsset;
94
+ payload.liquidationPrice = '';
95
+ if (leveragedType !== '') {
96
+ const leveragedAssetData = Object.values(assetsData).find((asset) => asset.symbol === leveragedAsset);
97
+ let assetPrice = leveragedAssetData?.price || '0';
98
+ if (leveragedType === 'lsd-leverage') {
99
+ // Treat ETH like a stablecoin in a long stETH position
100
+ const ethPrice = Object.values(assetsData).find((asset) => asset.symbol === 'ETH')?.price || '0';
101
+ payload.leveragedLsdAssetRatio = new Dec(leveragedAssetData?.price || '0').div(ethPrice).toDP(18).toString();
102
+ assetPrice = new Dec(assetPrice).div(ethPrice).toString();
103
+ }
104
+ payload.liquidationPrice = calcLeverageLiqPrice(leveragedType, assetPrice, payload.borrowedUsd, payload.liquidationLimitUsd);
105
+ }
106
+ payload.minCollRatio = new Dec(payload.suppliedCollateralUsd).div(payload.borrowLimitUsd).mul(100).toString();
107
+ payload.collLiquidationRatio = new Dec(payload.suppliedCollateralUsd).div(payload.liquidationLimitUsd).mul(100).toString();
108
+ // payload.healthRatio = new Dec(payload.liquidationLimitUsd).div(payload.borrowedUsd).toDP(4).toString();
109
+ payload.minHealthRatio = new Dec(payload.liquidationLimitUsd).div(payload.borrowLimitUsd).toDP(4).toString();
110
+
111
+ // TODO: Re-implement netApy calculation
112
+ // const { netApy, incentiveUsd, totalInterestUsd } = calculateNetApy({
113
+ // usedAssets,
114
+ // assetsData,
115
+ // optionalData: { healthRatio: payload.healthRatio },
116
+ // });
117
+ payload.netApy = '0';
118
+ payload.incentiveUsd = '0';
119
+ payload.totalInterestUsd = '0';
120
+ return payload;
69
121
  };