@defisaver/positions-sdk 2.1.52 → 2.1.53-aave-v4

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