@defisaver/positions-sdk 2.1.60 → 2.1.61-aave-v4-dev

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 (158) hide show
  1. package/cjs/aaveV3/index.d.ts +1 -0
  2. package/cjs/aaveV3/index.js +1 -0
  3. package/cjs/aaveV4/index.d.ts +7 -0
  4. package/cjs/aaveV4/index.js +174 -0
  5. package/cjs/compoundV2/index.d.ts +1 -0
  6. package/cjs/compoundV2/index.js +1 -0
  7. package/cjs/compoundV3/index.d.ts +1 -0
  8. package/cjs/compoundV3/index.js +1 -0
  9. package/cjs/config/contracts.d.ts +1277 -0
  10. package/cjs/config/contracts.js +9 -0
  11. package/cjs/contracts.d.ts +23120 -0
  12. package/cjs/contracts.js +2 -1
  13. package/cjs/eulerV2/index.d.ts +1 -0
  14. package/cjs/eulerV2/index.js +1 -0
  15. package/cjs/fluid/index.d.ts +3 -0
  16. package/cjs/helpers/aaveHelpers/index.js +1 -0
  17. package/cjs/helpers/aaveV4Helpers/index.d.ts +13 -0
  18. package/cjs/helpers/aaveV4Helpers/index.js +117 -0
  19. package/cjs/helpers/compoundHelpers/index.js +2 -0
  20. package/cjs/helpers/curveUsdHelpers/index.js +1 -0
  21. package/cjs/helpers/eulerHelpers/index.js +1 -0
  22. package/cjs/helpers/fluidHelpers/index.js +1 -0
  23. package/cjs/helpers/index.d.ts +1 -0
  24. package/cjs/helpers/index.js +2 -1
  25. package/cjs/helpers/liquityV2Helpers/index.js +1 -0
  26. package/cjs/helpers/llamaLendHelpers/index.js +1 -0
  27. package/cjs/helpers/morphoBlueHelpers/index.js +1 -0
  28. package/cjs/helpers/sparkHelpers/index.js +1 -0
  29. package/cjs/index.d.ts +2 -1
  30. package/cjs/index.js +3 -1
  31. package/cjs/liquity/index.js +2 -0
  32. package/cjs/maker/index.js +2 -0
  33. package/cjs/markets/aaveV4/index.d.ts +16 -0
  34. package/cjs/markets/aaveV4/index.js +59 -0
  35. package/cjs/markets/index.d.ts +1 -0
  36. package/cjs/markets/index.js +3 -1
  37. package/cjs/moneymarket/moneymarketCommonService.d.ts +1 -0
  38. package/cjs/moneymarket/moneymarketCommonService.js +8 -1
  39. package/cjs/portfolio/index.js +20 -0
  40. package/cjs/spark/index.d.ts +1 -0
  41. package/cjs/spark/index.js +1 -0
  42. package/cjs/types/aave.d.ts +1 -0
  43. package/cjs/types/aaveV4.d.ts +139 -0
  44. package/cjs/types/aaveV4.js +13 -0
  45. package/cjs/types/common.d.ts +1 -0
  46. package/cjs/types/compound.d.ts +1 -0
  47. package/cjs/types/curveUsd.d.ts +2 -0
  48. package/cjs/types/euler.d.ts +1 -0
  49. package/cjs/types/fluid.d.ts +1 -0
  50. package/cjs/types/index.d.ts +1 -0
  51. package/cjs/types/index.js +1 -0
  52. package/cjs/types/liquity.d.ts +1 -0
  53. package/cjs/types/liquityV2.d.ts +2 -0
  54. package/cjs/types/llamaLend.d.ts +2 -0
  55. package/cjs/types/maker.d.ts +1 -0
  56. package/cjs/types/morphoBlue.d.ts +2 -0
  57. package/cjs/types/portfolio.d.ts +4 -0
  58. package/cjs/types/spark.d.ts +1 -0
  59. package/esm/aaveV3/index.d.ts +1 -0
  60. package/esm/aaveV3/index.js +1 -0
  61. package/esm/aaveV4/index.d.ts +7 -0
  62. package/esm/aaveV4/index.js +165 -0
  63. package/esm/compoundV2/index.d.ts +1 -0
  64. package/esm/compoundV2/index.js +1 -0
  65. package/esm/compoundV3/index.d.ts +1 -0
  66. package/esm/compoundV3/index.js +1 -0
  67. package/esm/config/contracts.d.ts +1277 -0
  68. package/esm/config/contracts.js +8 -0
  69. package/esm/contracts.d.ts +23120 -0
  70. package/esm/contracts.js +1 -0
  71. package/esm/eulerV2/index.d.ts +1 -0
  72. package/esm/eulerV2/index.js +1 -0
  73. package/esm/fluid/index.d.ts +3 -0
  74. package/esm/helpers/aaveHelpers/index.js +2 -1
  75. package/esm/helpers/aaveV4Helpers/index.d.ts +13 -0
  76. package/esm/helpers/aaveV4Helpers/index.js +108 -0
  77. package/esm/helpers/compoundHelpers/index.js +3 -1
  78. package/esm/helpers/curveUsdHelpers/index.js +2 -1
  79. package/esm/helpers/eulerHelpers/index.js +2 -1
  80. package/esm/helpers/fluidHelpers/index.js +2 -1
  81. package/esm/helpers/index.d.ts +1 -0
  82. package/esm/helpers/index.js +1 -0
  83. package/esm/helpers/liquityV2Helpers/index.js +2 -1
  84. package/esm/helpers/llamaLendHelpers/index.js +2 -1
  85. package/esm/helpers/morphoBlueHelpers/index.js +2 -1
  86. package/esm/helpers/sparkHelpers/index.js +2 -1
  87. package/esm/index.d.ts +2 -1
  88. package/esm/index.js +2 -1
  89. package/esm/liquity/index.js +2 -0
  90. package/esm/maker/index.js +2 -0
  91. package/esm/markets/aaveV4/index.d.ts +16 -0
  92. package/esm/markets/aaveV4/index.js +47 -0
  93. package/esm/markets/index.d.ts +1 -0
  94. package/esm/markets/index.js +1 -0
  95. package/esm/moneymarket/moneymarketCommonService.d.ts +1 -0
  96. package/esm/moneymarket/moneymarketCommonService.js +6 -0
  97. package/esm/portfolio/index.js +21 -1
  98. package/esm/spark/index.d.ts +1 -0
  99. package/esm/spark/index.js +1 -0
  100. package/esm/types/aave.d.ts +1 -0
  101. package/esm/types/aaveV4.d.ts +139 -0
  102. package/esm/types/aaveV4.js +10 -0
  103. package/esm/types/common.d.ts +1 -0
  104. package/esm/types/compound.d.ts +1 -0
  105. package/esm/types/curveUsd.d.ts +2 -0
  106. package/esm/types/euler.d.ts +1 -0
  107. package/esm/types/fluid.d.ts +1 -0
  108. package/esm/types/index.d.ts +1 -0
  109. package/esm/types/index.js +1 -0
  110. package/esm/types/liquity.d.ts +1 -0
  111. package/esm/types/liquityV2.d.ts +2 -0
  112. package/esm/types/llamaLend.d.ts +2 -0
  113. package/esm/types/maker.d.ts +1 -0
  114. package/esm/types/morphoBlue.d.ts +2 -0
  115. package/esm/types/portfolio.d.ts +4 -0
  116. package/esm/types/spark.d.ts +1 -0
  117. package/package.json +1 -1
  118. package/src/aaveV3/index.ts +1 -0
  119. package/src/aaveV4/index.ts +176 -0
  120. package/src/compoundV2/index.ts +1 -0
  121. package/src/compoundV3/index.ts +1 -0
  122. package/src/config/contracts.ts +8 -0
  123. package/src/contracts.ts +3 -1
  124. package/src/eulerV2/index.ts +1 -0
  125. package/src/helpers/aaveHelpers/index.ts +2 -1
  126. package/src/helpers/aaveV4Helpers/index.ts +128 -0
  127. package/src/helpers/compoundHelpers/index.ts +3 -1
  128. package/src/helpers/curveUsdHelpers/index.ts +5 -1
  129. package/src/helpers/eulerHelpers/index.ts +2 -1
  130. package/src/helpers/fluidHelpers/index.ts +4 -1
  131. package/src/helpers/index.ts +1 -0
  132. package/src/helpers/liquityV2Helpers/index.ts +4 -1
  133. package/src/helpers/llamaLendHelpers/index.ts +4 -1
  134. package/src/helpers/morphoBlueHelpers/index.ts +2 -1
  135. package/src/helpers/sparkHelpers/index.ts +2 -1
  136. package/src/index.ts +2 -0
  137. package/src/liquity/index.ts +2 -0
  138. package/src/maker/index.ts +2 -0
  139. package/src/markets/aaveV4/index.ts +68 -0
  140. package/src/markets/index.ts +6 -1
  141. package/src/moneymarket/moneymarketCommonService.ts +6 -0
  142. package/src/portfolio/index.ts +20 -0
  143. package/src/spark/index.ts +1 -0
  144. package/src/types/aave.ts +1 -0
  145. package/src/types/aaveV4.ts +155 -0
  146. package/src/types/common.ts +1 -0
  147. package/src/types/compound.ts +1 -0
  148. package/src/types/curveUsd.ts +2 -0
  149. package/src/types/euler.ts +1 -0
  150. package/src/types/fluid.ts +2 -1
  151. package/src/types/index.ts +2 -1
  152. package/src/types/liquity.ts +1 -0
  153. package/src/types/liquityV2.ts +2 -0
  154. package/src/types/llamaLend.ts +2 -0
  155. package/src/types/maker.ts +1 -0
  156. package/src/types/morphoBlue.ts +2 -0
  157. package/src/types/portfolio.ts +4 -0
  158. package/src/types/spark.ts +1 -0
@@ -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
+ };
@@ -8,7 +8,7 @@ import {
8
8
  } from '../../services/utils';
9
9
  import { BLOCKS_IN_A_YEAR, borrowOperations, SECONDS_PER_YEAR } from '../../constants';
10
10
  import {
11
- aprToApy, calcLeverageLiqPrice, calculateBorrowingAssetLimit, getAssetsTotal, isLeveragedPos,
11
+ aprToApy, calcLeverageLiqPrice, calculateBorrowingAssetLimit, getAssetsTotal, getExposure, isLeveragedPos,
12
12
  } from '../../moneymarket';
13
13
  import { calculateNetApy, getStakingApy, STAKING_ASSETS } from '../../staking';
14
14
  import {
@@ -158,6 +158,7 @@ export const getCompoundV2AggregatedData = ({
158
158
  const assetPrice = assetsData[handleWbtcLegacy(leveragedAsset)].price;
159
159
  payload.liquidationPrice = calcLeverageLiqPrice(leveragedType, assetPrice, payload.borrowedUsd, payload.liquidationLimitUsd);
160
160
  }
161
+ payload.exposure = getExposure(payload.borrowedUsd, payload.suppliedUsd);
161
162
 
162
163
  return payload;
163
164
  };
@@ -207,6 +208,7 @@ export const getCompoundV3AggregatedData = ({
207
208
  }
208
209
  payload.minCollRatio = new Dec(payload.suppliedCollateralUsd).div(payload.borrowLimitUsd).mul(100).toString();
209
210
  payload.collLiquidationRatio = new Dec(payload.suppliedCollateralUsd).div(payload.liquidationLimitUsd).mul(100).toString();
211
+ payload.exposure = getExposure(payload.borrowedUsd, payload.suppliedUsd);
210
212
 
211
213
  return payload;
212
214
  };
@@ -1,7 +1,9 @@
1
1
  import Dec from 'decimal.js';
2
2
  import { CrvUSDAggregatedPositionData, CrvUSDMarketData, CrvUSDUsedAssets } from '../../types';
3
3
  import { MMUsedAssets, NetworkNumber } from '../../types/common';
4
- import { calcLeverageLiqPrice, getAssetsTotal, isLeveragedPos } from '../../moneymarket';
4
+ import {
5
+ calcLeverageLiqPrice, getAssetsTotal, getExposure, isLeveragedPos,
6
+ } from '../../moneymarket';
5
7
  import { mapRange } from '../../services/utils';
6
8
 
7
9
  export const getCrvUsdAggregatedData = ({
@@ -37,5 +39,7 @@ export const getCrvUsdAggregatedData = ({
37
39
  payload.liquidationPrice = calcLeverageLiqPrice(leveragedType, usedAssets[selectedMarket.collAsset].price, payload.borrowedUsd, payload.borrowLimitUsd);
38
40
  }
39
41
 
42
+ payload.exposure = getExposure(payload.borrowedUsd, payload.suppliedUsd);
43
+
40
44
  return payload;
41
45
  };
@@ -4,7 +4,7 @@ import {
4
4
  EthAddress, EthereumProvider, LeverageType, MMAssetsData, NetworkNumber,
5
5
  } from '../../types/common';
6
6
  import {
7
- calcLeverageLiqPrice, getAssetsTotal, STABLE_ASSETS,
7
+ calcLeverageLiqPrice, getAssetsTotal, getExposure, STABLE_ASSETS,
8
8
  } from '../../moneymarket';
9
9
  import { calculateNetApy } from '../../staking';
10
10
  import {
@@ -117,6 +117,7 @@ export const getEulerV2AggregatedData = ({
117
117
  }
118
118
  payload.minCollRatio = new Dec(payload.suppliedCollateralUsd).div(payload.borrowLimitUsd).mul(100).toString();
119
119
  payload.collLiquidationRatio = new Dec(payload.suppliedCollateralUsd).div(payload.liquidationLimitUsd).mul(100).toString();
120
+ payload.exposure = getExposure(payload.borrowedUsd, payload.suppliedUsd);
120
121
  return payload;
121
122
  };
122
123
 
@@ -7,7 +7,9 @@ import {
7
7
  FluidVaultType,
8
8
  InnerFluidMarketData,
9
9
  } from '../../types';
10
- import { calcLeverageLiqPrice, getAssetsTotal, isLeveragedPos } from '../../moneymarket';
10
+ import {
11
+ calcLeverageLiqPrice, getAssetsTotal, getExposure, isLeveragedPos,
12
+ } from '../../moneymarket';
11
13
  import { calculateNetApy } from '../../staking';
12
14
  import { LeverageType, MMAssetsData } from '../../types/common';
13
15
  import { getEthAmountForDecimals } from '../../services/utils';
@@ -103,6 +105,7 @@ borrowShares?: string,
103
105
 
104
106
  payload.minCollRatio = new Dec(payload.suppliedUsd).div(payload.borrowLimitUsd).mul(100).toString();
105
107
  payload.collLiquidationRatio = new Dec(payload.suppliedUsd).div(payload.liquidationLimitUsd).mul(100).toString();
108
+ payload.exposure = getExposure(payload.borrowedUsd, payload.suppliedUsd);
106
109
 
107
110
  return payload;
108
111
  };
@@ -8,3 +8,4 @@ export * as llamaLendHelpers from './llamaLendHelpers';
8
8
  export * as liquityV2Helpers from './liquityV2Helpers';
9
9
  export * as eulerV2Helpers from './eulerHelpers';
10
10
  export * as fluidHelpers from './fluidHelpers';
11
+ export * as aaveV4Helpers from './aaveV4Helpers';
@@ -1,5 +1,7 @@
1
1
  import Dec from 'decimal.js';
2
- import { calcLeverageLiqPrice, getAssetsTotal, isLeveragedPos } from '../../moneymarket';
2
+ import {
3
+ calcLeverageLiqPrice, getAssetsTotal, getExposure, isLeveragedPos,
4
+ } from '../../moneymarket';
3
5
  import {
4
6
  LiquityV2AggregatedTroveData, LiquityV2AssetsData, LiquityV2UsedAsset, LiquityV2UsedAssets,
5
7
  } from '../../types';
@@ -77,6 +79,7 @@ export const getLiquityV2AggregatedPositionData = ({
77
79
  const assetPrice = assetsData[leveragedAsset].price;
78
80
  payload.liquidationPrice = calcLeverageLiqPrice(leveragedType, assetPrice, payload.borrowedUsd, payload.borrowLimitUsd);
79
81
  }
82
+ payload.exposure = getExposure(payload.borrowedUsd, payload.suppliedUsd);
80
83
 
81
84
  return payload;
82
85
  };
@@ -3,7 +3,9 @@ import {
3
3
  LlamaLendAggregatedPositionData, LlamaLendAssetsData, LlamaLendMarketData, LlamaLendUsedAssets,
4
4
  } from '../../types';
5
5
  import { MMAssetsData, MMUsedAssets, NetworkNumber } from '../../types/common';
6
- import { calcLeverageLiqPrice, getAssetsTotal, isLeveragedPos } from '../../moneymarket';
6
+ import {
7
+ calcLeverageLiqPrice, getAssetsTotal, getExposure, isLeveragedPos,
8
+ } from '../../moneymarket';
7
9
  import { mapRange } from '../../services/utils';
8
10
  import { calculateNetApy } from '../../staking';
9
11
 
@@ -49,5 +51,6 @@ export const getLlamaLendAggregatedData = ({
49
51
  payload.liquidationPrice = calcLeverageLiqPrice(leveragedType, usedAssets[collAsset].price, payload.borrowedUsd, payload.borrowLimitUsd);
50
52
  }
51
53
 
54
+ payload.exposure = getExposure(payload.borrowedUsd, payload.suppliedUsd);
52
55
  return payload;
53
56
  };
@@ -1,7 +1,7 @@
1
1
  import Dec from 'decimal.js';
2
2
  import { assetAmountInWei, getAssetInfo, getAssetInfoByAddress } from '@defisaver/tokens';
3
3
  import {
4
- aprToApy, calcLeverageLiqPrice, getAssetsTotal, isLeveragedPos,
4
+ aprToApy, calcLeverageLiqPrice, getAssetsTotal, getExposure, isLeveragedPos,
5
5
  } from '../../moneymarket';
6
6
  import { calculateNetApy } from '../../staking';
7
7
  import {
@@ -76,6 +76,7 @@ export const getMorphoBlueAggregatedPositionData = ({ usedAssets, assetsData, ma
76
76
  }
77
77
  payload.minCollRatio = new Dec(payload.suppliedCollateralUsd).div(payload.borrowLimitUsd).mul(100).toString();
78
78
  payload.collLiquidationRatio = new Dec(payload.suppliedCollateralUsd).div(payload.liquidationLimitUsd).mul(100).toString();
79
+ payload.exposure = getExposure(payload.borrowedUsd, payload.suppliedUsd);
79
80
 
80
81
  return payload;
81
82
  };
@@ -1,7 +1,7 @@
1
1
  import Dec from 'decimal.js';
2
2
  import { assetAmountInWei, getAssetInfo, getAssetInfoByAddress } from '@defisaver/tokens';
3
3
  import {
4
- aprToApy, calcLeverageLiqPrice, getAssetsTotal, isLeveragedPos,
4
+ aprToApy, calcLeverageLiqPrice, getAssetsTotal, getExposure, isLeveragedPos,
5
5
  } from '../../moneymarket';
6
6
  import {
7
7
  SparkAggregatedPositionData,
@@ -127,6 +127,7 @@ export const sparkGetAggregatedPositionData = ({
127
127
  payload.collLiquidationRatio = new Dec(payload.suppliedCollateralUsd).div(payload.liquidationLimitUsd).mul(100).toString();
128
128
  payload.healthRatio = new Dec(payload.liquidationLimitUsd).div(payload.borrowedUsd).toDP(4).toString();
129
129
  payload.minHealthRatio = new Dec(payload.liquidationLimitUsd).div(payload.borrowLimitUsd).toDP(4).toString();
130
+ payload.exposure = getExposure(payload.borrowedUsd, payload.suppliedUsd);
130
131
  return payload;
131
132
  };
132
133
 
package/src/index.ts CHANGED
@@ -1,6 +1,7 @@
1
1
  import './setup';
2
2
 
3
3
  import * as fluid from './fluid';
4
+ import * as aaveV4 from './aaveV4';
4
5
  import * as aaveV3 from './aaveV3';
5
6
  import * as aaveV2 from './aaveV2';
6
7
  import * as compoundV3 from './compoundV3';
@@ -27,6 +28,7 @@ export * from './types';
27
28
  export {
28
29
  aaveV2,
29
30
  aaveV3,
31
+ aaveV4,
30
32
  compoundV2,
31
33
  compoundV3,
32
34
  spark,
@@ -17,6 +17,7 @@ import { LIQUITY_TROVE_STATUS_ENUM, LiquityTroveInfo } from '../types';
17
17
  import { ZERO_ADDRESS } from '../constants';
18
18
  import { getViemProvider, setViemBlockNumber } from '../services/viem';
19
19
  import { getEthAmountForDecimals } from '../services/utils';
20
+ import { getExposure } from '../moneymarket';
20
21
 
21
22
  export const LIQUITY_NORMAL_MODE_RATIO = 110; // MCR
22
23
  export const LIQUITY_RECOVERY_MODE_RATIO = 150; // CCR
@@ -104,6 +105,7 @@ export const _getLiquityTroveInfo = async (provider: Client, network: NetworkNum
104
105
  minCollateralRatio: recoveryMode ? LIQUITY_RECOVERY_MODE_RATIO : LIQUITY_NORMAL_MODE_RATIO,
105
106
  priceForRecovery: new Dec(recoveryMode ? LIQUITY_RECOVERY_MODE_RATIO : LIQUITY_NORMAL_MODE_RATIO).mul(totalLUSD).div(totalETH).div(100)
106
107
  .toString(),
108
+ exposure: getExposure(assetAmountInEth(troveInfo[2].toString()), new Dec(assetAmountInEth(troveInfo[1].toString())).mul(assetPrice).toString()),
107
109
  };
108
110
 
109
111
  return payload;
@@ -13,6 +13,7 @@ import { CdpData, CdpInfo, CdpType } from '../types';
13
13
  import { wethToEth } from '../services/utils';
14
14
  import { parseCollateralInfo } from '../helpers/makerHelpers';
15
15
  import { getViemProvider, setViemBlockNumber } from '../services/viem';
16
+ import { getExposure } from '../moneymarket';
16
17
 
17
18
  export const _getMakerAccountBalances = async (provider: PublicClient, network: NetworkNumber, block: Blockish, addressMapping: boolean, cdpId: string, _managerAddress?: EthAddress): Promise<PositionBalances> => {
18
19
  let balances: PositionBalances = {
@@ -214,6 +215,7 @@ export const _getMakerCdpData = async (provider: Client, network: NetworkNumber,
214
215
  globalDebtCurrent: collInfo.globalDebtCurrent,
215
216
  liquidationFee: collInfo.liquidationFee,
216
217
  lastUpdated: Date.now(),
218
+ exposure: getExposure(assetAmountInEth(debt, 'DAI'), collateralUsd),
217
219
  };
218
220
  };
219
221
 
@@ -0,0 +1,68 @@
1
+ import {
2
+ AaveV4HubInfo,
3
+ AaveV4HubsType,
4
+ AaveV4SpokeInfo,
5
+ AaveV4SpokesType,
6
+ NetworkNumber,
7
+ } from '../../types';
8
+
9
+ // HUBS
10
+
11
+ export const AAVE_V4_CORE_HUB = (networkId: NetworkNumber): AaveV4HubInfo => ({
12
+ chainIds: [NetworkNumber.Eth],
13
+ label: 'Core Hub',
14
+ value: AaveV4HubsType.AaveV4CoreHub,
15
+ address: '0xaD905aD5EA5B98cD50AE40Cfe368344686a21366',
16
+ });
17
+
18
+ export const AAVE_V4_YIELD_SEEKING_HUB = (networkId: NetworkNumber): AaveV4HubInfo => ({
19
+ chainIds: [NetworkNumber.Eth],
20
+ label: 'Yield Seeking Hub',
21
+ value: AaveV4HubsType.AaveV4YieldSeekingHub,
22
+ address: '0x86F37ba3b480c5fE22A7eb1ba2B2D49c94089FBB',
23
+ });
24
+
25
+ export const AaveV4Hubs = (networkId: NetworkNumber) => ({
26
+ [AaveV4HubsType.AaveV4CoreHub]: AAVE_V4_CORE_HUB(networkId),
27
+ [AaveV4HubsType.AaveV4YieldSeekingHub]: AAVE_V4_YIELD_SEEKING_HUB(networkId),
28
+ }) as const;
29
+
30
+ export const getAaveV4HubTypeInfo = (type: AaveV4HubsType, network?: NetworkNumber) => ({ ...AaveV4Hubs(network ?? NetworkNumber.Eth) }[type]);
31
+
32
+ export const getAaveV4HubByAddress = (networkId: NetworkNumber, address: string): AaveV4HubInfo | undefined => Object.values(AaveV4Hubs(networkId)).find(
33
+ hub => hub.address.toLowerCase() === address.toLowerCase(),
34
+ );
35
+
36
+ // SPOKES
37
+
38
+ export const AAVE_V4_CORE_SPOKE = (networkId: NetworkNumber): AaveV4SpokeInfo => ({
39
+ chainIds: [NetworkNumber.Eth],
40
+ label: 'Core Spoke',
41
+ value: AaveV4SpokesType.AaveV4CoreSpoke,
42
+ url: 'core',
43
+ address: '0xBa97c5E52cd5BC3D7950Ae70779F8FfE92d40CdC',
44
+ hubs: [
45
+ AAVE_V4_CORE_HUB(NetworkNumber.Eth).address,
46
+ ],
47
+ });
48
+
49
+ export const AAVE_V4_YIELD_SEEKING_SPOKE = (networkId: NetworkNumber): AaveV4SpokeInfo => ({
50
+ chainIds: [NetworkNumber.Eth],
51
+ label: 'Yield Seeking Spoke',
52
+ value: AaveV4SpokesType.AaveV4YieldSeekingSpoke,
53
+ url: 'yield-seeking',
54
+ address: '0x2559e4e04f2ca7180e5f20c2872d22ec89601b56',
55
+ hubs: [
56
+ AAVE_V4_CORE_HUB(NetworkNumber.Eth).address,
57
+ AAVE_V4_YIELD_SEEKING_HUB(NetworkNumber.Eth).address,
58
+ ],
59
+ });
60
+
61
+ export const AaveV4Spokes = (networkId: NetworkNumber) => ({
62
+ [AaveV4SpokesType.AaveV4CoreSpoke]: AAVE_V4_CORE_SPOKE(networkId),
63
+ [AaveV4SpokesType.AaveV4YieldSeekingSpoke]: AAVE_V4_YIELD_SEEKING_SPOKE(networkId),
64
+ }) as const;
65
+
66
+ export const getAaveV4SpokeTypeInfo = (type: AaveV4SpokesType, network?: NetworkNumber) => ({ ...AaveV4Spokes(network ?? NetworkNumber.Eth) }[type]);
67
+
68
+
@@ -21,5 +21,10 @@ export { LlamaLendMarkets } from './llamaLend';
21
21
  export { LiquityV2Markets, findLiquityV2MarketByAddress } from './liquityV2';
22
22
  export { EulerV2Markets } from './euler';
23
23
  export {
24
- FluidMarkets, getFluidVersionsDataForNetwork, getFluidMarketInfoById, getFTokenAddress, getFluidMarketInfoByAddress,
24
+ FluidMarkets,
25
+ getFluidVersionsDataForNetwork,
26
+ getFluidMarketInfoById,
27
+ getFTokenAddress,
28
+ getFluidMarketInfoByAddress,
25
29
  } from './fluid';
30
+ export { AaveV4Spokes } from './aaveV4';
@@ -82,3 +82,9 @@ export const aprToApy = (interest:string | number, frequency = BLOCKS_IN_A_YEAR)
82
82
  .minus(1)
83
83
  .times(100)
84
84
  .toString();
85
+
86
+ export const getExposure = (borrowedUsd: string, suppliedUsd: string) => {
87
+ if (borrowedUsd === '0' || suppliedUsd === '0') return 'N/A';
88
+ const balanceUsd = new Dec(suppliedUsd).sub(borrowedUsd).toString();
89
+ return new Dec(suppliedUsd).div(balanceUsd).toDecimalPlaces(2).toString();
90
+ };
@@ -2,6 +2,7 @@ import Dec from 'decimal.js';
2
2
  import { EthAddress, EthereumProvider, NetworkNumber } from '../types/common';
3
3
  import {
4
4
  AaveMarkets,
5
+ AaveV4Spokes,
5
6
  CompoundMarkets,
6
7
  CrvUsdMarkets,
7
8
  EulerV2Markets,
@@ -14,6 +15,7 @@ import { _getMorphoBlueAccountData, _getMorphoBlueMarketData, getMorphoEarn } fr
14
15
  import {
15
16
  AaveV2MarketData,
16
17
  AaveV3MarketData,
18
+ AaveV4SpokeData,
17
19
  AaveVersions,
18
20
  CdpInfo,
19
21
  CompoundV2MarketsData,
@@ -49,6 +51,7 @@ import { fetchSparkAirdropRewards, fetchSparkRewards } from '../claiming/spark';
49
51
  import { fetchMorphoBlueRewards } from '../claiming/morphoBlue';
50
52
  import { getKingRewards } from '../claiming/king';
51
53
  import { fetchEthenaAirdropRewards } from '../claiming/ethena';
54
+ import { _getAaveV4AccountData, _getAaveV4SpokeData } from '../aaveV4';
52
55
 
53
56
  export async function getPortfolioData(provider: EthereumProvider, network: NetworkNumber, defaultProvider: EthereumProvider, addresses: EthAddress[], isSim = false): Promise<{
54
57
  positions: PortfolioPositionsData;
@@ -71,6 +74,7 @@ export async function getPortfolioData(provider: EthereumProvider, network: Netw
71
74
  const llamaLendMarkets = [NetworkNumber.Eth, NetworkNumber.Arb].includes(network) ? Object.values(LlamaLendMarkets(network)).filter((market) => market.chainIds.includes(network)) : [];
72
75
  const liquityV2Markets = [NetworkNumber.Eth].includes(network) ? Object.values(LiquityV2Markets(network)) : [];
73
76
  const liquityV2MarketsStaking = [NetworkNumber.Eth].includes(network) ? Object.values(LiquityV2Markets(network)).filter(market => !market.isLegacy) : [];
77
+ const aaveV4Spokes = Object.values(AaveV4Spokes(network)).filter((market) => market.chainIds.includes(network));
74
78
 
75
79
  const args: [NetworkNumber, any?] = [network, { batch: { multicall: { batchSize: isSim ? 500_000 : 2_500_000 } } }];
76
80
  const client = getViemProvider(provider, ...args);
@@ -87,6 +91,7 @@ export async function getPortfolioData(provider: EthereumProvider, network: Netw
87
91
  const crvUsdMarketsData: Record<string, CrvUSDGlobalMarketData> = {};
88
92
  const llamaLendMarketsData: Record<string, LlamaLendGlobalMarketData> = {};
89
93
  const liquityV2MarketsData: Record<string, LiquityV2MarketData> = {};
94
+ const aaveV4SpokesData: Record<string, AaveV4SpokeData> = {};
90
95
 
91
96
  const markets = {
92
97
  morphoMarketsData,
@@ -99,6 +104,7 @@ export async function getPortfolioData(provider: EthereumProvider, network: Netw
99
104
  crvUsdMarketsData,
100
105
  llamaLendMarketsData,
101
106
  liquityV2MarketsData,
107
+ aaveV4SpokesData,
102
108
  };
103
109
 
104
110
  const positions: PortfolioPositionsData = {};
@@ -109,6 +115,7 @@ export async function getPortfolioData(provider: EthereumProvider, network: Netw
109
115
  for (const address of allAddresses) {
110
116
  positions[address.toLowerCase() as EthAddress] = {
111
117
  aaveV3: {},
118
+ aaveV4: {},
112
119
  morphoBlue: {},
113
120
  compoundV3: {},
114
121
  spark: {},
@@ -177,6 +184,10 @@ export async function getPortfolioData(provider: EthereumProvider, network: Netw
177
184
  const marketData = await _getAaveV3MarketData(client, network, market);
178
185
  aaveV3MarketsData[market.value] = marketData;
179
186
  }),
187
+ ...aaveV4Spokes.map(async (spoke) => {
188
+ const spokeData = await _getAaveV4SpokeData(client, network, spoke);
189
+ aaveV4SpokesData[spoke.value] = spokeData;
190
+ }),
180
191
  ...aaveV2Markets.map(async (market) => {
181
192
  const marketData = await _getAaveV2MarketsData(client, network, market);
182
193
  aaveV2MarketsData[market.value] = marketData;
@@ -429,6 +440,15 @@ export async function getPortfolioData(provider: EthereumProvider, network: Netw
429
440
  positions[address.toLowerCase() as EthAddress].aaveV3[market.value] = { error: `Error fetching AaveV3 account data for address ${address} on market ${market.value}`, data: null };
430
441
  }
431
442
  })).flat(),
443
+ ...aaveV4Spokes.map((spoke) => allAddresses.map(async (address) => {
444
+ try {
445
+ const accData = await _getAaveV4AccountData(client, network, aaveV4SpokesData[spoke.value], address);
446
+ if (new Dec(accData.suppliedUsd).gt(0)) positions[address.toLowerCase() as EthAddress].aaveV4[spoke.value] = { error: '', data: accData };
447
+ } catch (error) {
448
+ console.error(`Error fetching AaveV4 account data for address ${address} on spoke ${spoke.value}:`, error);
449
+ positions[address.toLowerCase() as EthAddress].aaveV4[spoke.value] = { error: `Error fetching AaveV4 account data for address ${address} on spoke ${spoke.value}`, data: null };
450
+ }
451
+ })).flat(),
432
452
  ...morphoMarkets.map((market) => addresses.map(async (address) => {
433
453
  try {
434
454
  const [accDataPromise, earnDataPromise] = await Promise.allSettled([
@@ -264,6 +264,7 @@ export const EMPTY_SPARK_DATA = {
264
264
  suppliedCollateralUsd: '0',
265
265
  totalSupplied: '0',
266
266
  eModeCategories: [],
267
+ exposure: 'N/A',
267
268
  };
268
269
 
269
270
  export const _getSparkAccountBalances = async (provider: Client, network: NetworkNumber, block: Blockish, addressMapping: boolean, address: EthAddress): Promise<PositionBalances> => {
package/src/types/aave.ts CHANGED
@@ -179,6 +179,7 @@ export interface AaveV3AggregatedPositionData {
179
179
  liqRatio: string,
180
180
  liqPercent: string,
181
181
  leveragedType: LeverageType,
182
+ exposure: string,
182
183
  leveragedAsset?: string,
183
184
  liquidationPrice?: string,
184
185
  minCollRatio?: string,