@defisaver/positions-sdk 2.1.79-aave-v4-6-dev → 2.1.79-aave-v4-8-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.
@@ -17,38 +17,37 @@ const viem_1 = require("../services/viem");
17
17
  const utils_1 = require("../services/utils");
18
18
  const common_1 = require("../types/common");
19
19
  exports.AAVE_V4_TOKENIZED_SPOKES = {
20
- AAVE_CORE: '0x08309234884cF7E015b07Bf22569017Aa035cdeF',
21
- EURC_CORE: '0x73596dED4B2Eb0aC85e477b3c8dB56FC427E6774',
22
- GHO_CORE: '0xf7E1f1b43922527e5054bD77E7f863Cf182b194D',
23
- GHO_PRIME: '0xeF1cAd5c6a2C9cb83c952b4B96bbD35b3F61F18f',
24
- LBTC_CORE: '0x8f4D423590F22833131e3493bf67A27213398f8e',
25
- LINK_CORE: '0xBE1197750b423e30137E97d9183065d33E903BE6',
26
- PT_USDe_PLUS: '0x8cA27Ab284F2aA2BcF33D9129e11c101aD2d16de',
27
- PT_sUSDe_PLUS: '0xb8A464EC56071a98c854f30fE19CfeCc41FA6233',
28
- PYUSD_CORE: '0x203FB463087005698d50768FcA837047f738632d',
29
- RLUSD_CORE: '0xa9afdd0c54fb153CaE39cE86E49626B5e9d15513',
30
- USDC_CORE: '0xa2e476f4cbB06C7bFA8Ad51bCcbF198cd32CfD35',
31
- USDC_PLUS: '0x320Bec4fB7a25e64c003A007D0AeF7AB3D6C30d7',
32
- USDC_PRIME: '0x0A0507F7A1129892b5cf74b8B4e911442c466b87',
33
- USDG_CORE: '0x87c224256f09a014C1BC3e9FbB094C3AdD8fBaCC',
34
- USDT_CORE: '0x3f12BD5999b9172550893FF52691c980676f9E73',
35
- USDT_PLUS: '0xa4E74a78bED2d3ab8971e8AB26fb39f26DD8eEd9',
36
- USDT_PRIME: '0xF565fB55bc96d65561887898bfeb25C1dE7e06d2',
37
- USDe_PLUS: '0xA0d346ab2699B689AC67aba5174164A84206BB73',
38
- WBTC_CORE: '0x837Ab872A665e0CF467d41cF56a054031b4A38bc',
39
- WBTC_PRIME: '0xeae98b8a1798738182B2123DF1eB93d97BD29F34',
40
- WETH_CORE: '0x3961a75099E986F59a1a31c6f945061641dFD2b2',
41
- WETH_PRIME: '0xa411826a6ef5d289c0FAa7d5B45FE8aAB52257F6',
42
- XAUt_CORE: '0x470341bC0e2B833C54D0120642713BdF762A494F',
43
- cbBTC_CORE: '0xe8D5E595d5b6b5EFf84B7064765fd0e8DfD214C9',
44
- cbBTC_PRIME: '0x0E986545150DcDDe46Ea9df355D0fD2af33bd75D',
45
- frxUSD_CORE: '0x00C8A6a42947Cc4E7B6f27963Cab0143ccaaD2B5',
46
- frxUSD_PLUS: '0xCAB288d37CAb5a9db7b503F086455276Dcde61F1',
47
- rsETH_CORE: '0x6eEce89caE2163584bA7Ff9743861B9633c245E0',
48
- sUSDe_PLUS: '0xdf47fc43c88B06edC47753b7d647ff18037D2F3d',
49
- weETH_CORE: '0xB67F20bFF413C8E5d633B54BD28899c4c9e33ed0',
50
- wstETH_CORE: '0x474602394d0B02F43AC3D7C8c5cFc0814b03fd40',
51
- wstETH_PRIME: '0xAcCdAb49ECB9A801CfF62a92fc80D52339b33770',
20
+ AAVE_CORE: '0x0A65197b16C5969F92672051c9C9C0C75B369135',
21
+ EURC_CORE: '0x6D9e2Cdd61CaF69af99b275704B6e272C41c6718',
22
+ GHO_CORE: '0x58C14a5E061c9bC6926c5b853445290F296C2F7B',
23
+ LBTC_CORE: '0x7961F140B570490849DB878AE222570ea838799d',
24
+ LINK_CORE: '0xE69C2045095C8Ab3E2a7d77de2328faE5baF797c',
25
+ RLUSD_CORE: '0xC8a125AE4275a78AADc53B46Ca10566Bc9B249E0',
26
+ USDC_CORE: '0x531E90a2376902DE8915789Fcc1075e3B0c153E7',
27
+ USDG_CORE: '0xAC2435E3C25e8246870D33ce0a26988A46d5DB68',
28
+ USDT_CORE: '0x5eC44a70F309854fe04d495cFE1B5dA63DD1cc73',
29
+ WBTC_CORE: '0x82A9CC4656784E55Ef2E78F704028B5E1Bfc1732',
30
+ WETH_CORE: '0x7320CF22Ac095bA2a2e0a652F77efB836c2E751b',
31
+ XAUt_CORE: '0x4E712562fcb5337011398B6C630f55b60641cd5e',
32
+ cbBTC_CORE: '0x33B41B74366F55327d959FfF6D6b6fBc2853dbB1',
33
+ frxUSD_CORE: '0x2226749630775ee20230Ad65214fB339087eF30D',
34
+ rsETH_CORE: '0x45a04Ca1A5cbEeA4B44356c75EDd29b33eB2527a',
35
+ weETH_CORE: '0x559cEc2C840D9DBB18936Afc5E5341D78bfC7Cbe',
36
+ wstETH_CORE: '0xcb0E7dA9c635628f6d4827355AeCa75aB8d3560f',
37
+ GHO_PLUS: '0xA54382db40EC602c0a173A08f9E86Ed40F9D4D10',
38
+ PT_USDe_7MAY2026_PLUS: '0xdd2Eb78BF9e6aC5068B95aD2d451e8c9Af10ac81',
39
+ PT_sUSDE_7MAY2026_PLUS: '0x90774889c22D2F2Adf44da1f04C7c95542590df4',
40
+ USDC_PLUS: '0xc94bdd83D2c7655C280655D60954e79E88D4F949',
41
+ USDT_PLUS: '0x80835EB50694EE0e519743f67e5401e6FD300006',
42
+ USDe_PLUS: '0x502Cd81da6a8F1785eb2eEE72713B7388E16A854',
43
+ sUSDe_PLUS: '0x24f8c062e1E0451736C1D6E023510DA262a41df4',
44
+ GHO_PRIME: '0x900fD46d565d1ac8995928c0179052ec02a6D0E1',
45
+ USDC_PRIME: '0x486415fb1F8b062c89ED548f871cf64304AACb31',
46
+ USDT_PRIME: '0x46c588DD8453aC259c1f6a54b4C9A93C2aC3762D',
47
+ WBTC_PRIME: '0x5AE3d87De89CA6Ce501e8317887F71EABED69E18',
48
+ WETH_PRIME: '0x2087513383330B961A3753B47627Bbf149F31c70',
49
+ cbBTC_PRIME: '0xD38098faf52D8E915EdED84fBF30F81C17906938',
50
+ wstETH_PRIME: '0xFCD3D3C69cd032DE0cc78fE529B7447D2fe7F666',
52
51
  };
53
52
  exports.AAVE_V4_TOKENIZED_SPOKE_ADDRESSES = {
54
53
  [common_1.NetworkNumber.Eth]: Object.values(exports.AAVE_V4_TOKENIZED_SPOKES),
@@ -4,6 +4,14 @@ export declare const getApyAfterValuesEstimation: (usedAssets: AaveV4UsedReserve
4
4
  borrowRate: string;
5
5
  supplyRate: string;
6
6
  }>;
7
+ export declare const calculateNetApyAaveV4: ({ usedAssets, assetsData, }: {
8
+ usedAssets: AaveV4UsedReserveAssets;
9
+ assetsData: AaveV4AssetsData;
10
+ }) => {
11
+ netApy: string;
12
+ totalInterestUsd: string;
13
+ incentiveUsd: string;
14
+ };
7
15
  export declare const aaveV4GetCollateralFactor: (assetData: AaveV4ReserveAssetData, usedAssetData: AaveV4UsedReserveAsset, useUserCollateralFactor?: boolean) => number;
8
16
  export declare const isLeveragedPosAaveV4: (usedAssets: AaveV4UsedReserveAssets, dustLimit?: number) => {
9
17
  leveragedType: LeverageType;
@@ -3,9 +3,10 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
3
3
  return (mod && mod.__esModule) ? mod : { "default": mod };
4
4
  };
5
5
  Object.defineProperty(exports, "__esModule", { value: true });
6
- exports.aaveV4GetAggregatedPositionData = exports.isLeveragedPosAaveV4 = exports.aaveV4GetCollateralFactor = exports.getApyAfterValuesEstimation = exports.calcUserRiskPremiumBps = void 0;
6
+ exports.aaveV4GetAggregatedPositionData = exports.isLeveragedPosAaveV4 = exports.aaveV4GetCollateralFactor = exports.calculateNetApyAaveV4 = exports.getApyAfterValuesEstimation = exports.calcUserRiskPremiumBps = void 0;
7
7
  const decimal_js_1 = __importDefault(require("decimal.js"));
8
8
  const moneymarket_1 = require("../../moneymarket");
9
+ const staking_1 = require("../../staking");
9
10
  const types_1 = require("../../types");
10
11
  const calcUserRiskPremiumBps = (usedAssets, assetsData) => {
11
12
  const collaterals = [];
@@ -78,6 +79,54 @@ const getApyAfterValuesEstimation = (usedAssets, assetsData) => {
78
79
  return result;
79
80
  };
80
81
  exports.getApyAfterValuesEstimation = getApyAfterValuesEstimation;
82
+ const calculateNetApyAaveV4 = ({ usedAssets, assetsData, }) => {
83
+ const riskPremiumBps = (0, exports.calcUserRiskPremiumBps)(usedAssets, assetsData);
84
+ const riskPremiumFraction = new decimal_js_1.default(riskPremiumBps).div(10000);
85
+ const sumValues = Object.entries(usedAssets).reduce((_acc, [identifier, usedAsset]) => {
86
+ const acc = Object.assign({}, _acc);
87
+ const assetData = assetsData[identifier];
88
+ if (!assetData)
89
+ return acc;
90
+ if (usedAsset.isSupplied) {
91
+ const amount = usedAsset.suppliedUsd;
92
+ acc.suppliedUsd = new decimal_js_1.default(acc.suppliedUsd).add(amount).toString();
93
+ const supplyInterest = (0, staking_1.calculateInterestEarned)(amount, assetData.supplyRate, 'year', true);
94
+ acc.supplyInterest = new decimal_js_1.default(acc.supplyInterest).add(supplyInterest.toString()).toString();
95
+ if (assetData.supplyIncentives) {
96
+ for (const supplyIncentive of assetData.supplyIncentives) {
97
+ const incentiveInterest = (0, staking_1.calculateInterestEarned)(amount, supplyIncentive.apy, 'year', true);
98
+ acc.incentiveUsd = new decimal_js_1.default(acc.incentiveUsd).add(incentiveInterest).toString();
99
+ }
100
+ }
101
+ }
102
+ if (usedAsset.isBorrowed) {
103
+ const amount = usedAsset.borrowedUsd;
104
+ acc.borrowedUsd = new decimal_js_1.default(acc.borrowedUsd).add(amount).toString();
105
+ // User borrow rate = baseRate * (1 + riskPremiumFraction)
106
+ const drawnRate = new decimal_js_1.default(assetData.drawnRate);
107
+ const baseBorrowApr = drawnRate.mul(100);
108
+ const userBorrowApr = baseBorrowApr.mul(new decimal_js_1.default(1).add(riskPremiumFraction));
109
+ const userBorrowRate = (0, moneymarket_1.aprToApy)(userBorrowApr.toString());
110
+ const borrowInterest = (0, staking_1.calculateInterestEarned)(amount, userBorrowRate, 'year', true);
111
+ acc.borrowInterest = new decimal_js_1.default(acc.borrowInterest).sub(borrowInterest.toString()).toString();
112
+ if (assetData.borrowIncentives) {
113
+ for (const borrowIncentive of assetData.borrowIncentives) {
114
+ const incentiveInterest = (0, staking_1.calculateInterestEarned)(amount, borrowIncentive.apy, 'year', true);
115
+ acc.incentiveUsd = new decimal_js_1.default(acc.incentiveUsd).add(incentiveInterest).toString();
116
+ }
117
+ }
118
+ }
119
+ return acc;
120
+ }, {
121
+ borrowInterest: '0', supplyInterest: '0', incentiveUsd: '0', borrowedUsd: '0', suppliedUsd: '0',
122
+ });
123
+ const { borrowedUsd, suppliedUsd, borrowInterest, supplyInterest, incentiveUsd, } = sumValues;
124
+ const totalInterestUsd = new decimal_js_1.default(borrowInterest).add(supplyInterest).add(incentiveUsd).toString();
125
+ const balance = new decimal_js_1.default(suppliedUsd).sub(borrowedUsd);
126
+ const netApy = balance.isZero() ? '0' : new decimal_js_1.default(totalInterestUsd).div(balance).times(100).toString();
127
+ return { netApy, totalInterestUsd, incentiveUsd };
128
+ };
129
+ exports.calculateNetApyAaveV4 = calculateNetApyAaveV4;
81
130
  const aaveV4GetCollateralFactor = (assetData, usedAssetData, useUserCollateralFactor = false) => (useUserCollateralFactor ? usedAssetData.collateralFactor : assetData.collateralFactor);
82
131
  exports.aaveV4GetCollateralFactor = aaveV4GetCollateralFactor;
83
132
  const isLeveragedPosAaveV4 = (usedAssets, dustLimit = 5) => {
@@ -174,15 +223,10 @@ const aaveV4GetAggregatedPositionData = ({ usedAssets, assetsData, network, useU
174
223
  payload.collLiquidationRatio = new decimal_js_1.default(payload.suppliedCollateralUsd).div(payload.liquidationLimitUsd).mul(100).toString();
175
224
  // payload.healthRatio = new Dec(payload.liquidationLimitUsd).div(payload.borrowedUsd).toDP(4).toString();
176
225
  payload.minHealthRatio = new decimal_js_1.default(payload.liquidationLimitUsd).div(payload.borrowLimitUsd).toDP(4).toString();
177
- // TODO: Re-implement netApy calculation
178
- // const { netApy, incentiveUsd, totalInterestUsd } = calculateNetApy({
179
- // usedAssets,
180
- // assetsData,
181
- // optionalData: { healthRatio: payload.healthRatio },
182
- // });
183
- payload.netApy = '0';
184
- payload.incentiveUsd = '0';
185
- payload.totalInterestUsd = '0';
226
+ const { netApy, incentiveUsd, totalInterestUsd } = (0, exports.calculateNetApyAaveV4)({ usedAssets, assetsData });
227
+ payload.netApy = netApy;
228
+ payload.incentiveUsd = incentiveUsd;
229
+ payload.totalInterestUsd = totalInterestUsd;
186
230
  return payload;
187
231
  };
188
232
  exports.aaveV4GetAggregatedPositionData = aaveV4GetAggregatedPositionData;
@@ -13,38 +13,37 @@ import { getViemProvider } from '../services/viem';
13
13
  import { wethToEth } from '../services/utils';
14
14
  import { NetworkNumber, } from '../types/common';
15
15
  export const AAVE_V4_TOKENIZED_SPOKES = {
16
- AAVE_CORE: '0x08309234884cF7E015b07Bf22569017Aa035cdeF',
17
- EURC_CORE: '0x73596dED4B2Eb0aC85e477b3c8dB56FC427E6774',
18
- GHO_CORE: '0xf7E1f1b43922527e5054bD77E7f863Cf182b194D',
19
- GHO_PRIME: '0xeF1cAd5c6a2C9cb83c952b4B96bbD35b3F61F18f',
20
- LBTC_CORE: '0x8f4D423590F22833131e3493bf67A27213398f8e',
21
- LINK_CORE: '0xBE1197750b423e30137E97d9183065d33E903BE6',
22
- PT_USDe_PLUS: '0x8cA27Ab284F2aA2BcF33D9129e11c101aD2d16de',
23
- PT_sUSDe_PLUS: '0xb8A464EC56071a98c854f30fE19CfeCc41FA6233',
24
- PYUSD_CORE: '0x203FB463087005698d50768FcA837047f738632d',
25
- RLUSD_CORE: '0xa9afdd0c54fb153CaE39cE86E49626B5e9d15513',
26
- USDC_CORE: '0xa2e476f4cbB06C7bFA8Ad51bCcbF198cd32CfD35',
27
- USDC_PLUS: '0x320Bec4fB7a25e64c003A007D0AeF7AB3D6C30d7',
28
- USDC_PRIME: '0x0A0507F7A1129892b5cf74b8B4e911442c466b87',
29
- USDG_CORE: '0x87c224256f09a014C1BC3e9FbB094C3AdD8fBaCC',
30
- USDT_CORE: '0x3f12BD5999b9172550893FF52691c980676f9E73',
31
- USDT_PLUS: '0xa4E74a78bED2d3ab8971e8AB26fb39f26DD8eEd9',
32
- USDT_PRIME: '0xF565fB55bc96d65561887898bfeb25C1dE7e06d2',
33
- USDe_PLUS: '0xA0d346ab2699B689AC67aba5174164A84206BB73',
34
- WBTC_CORE: '0x837Ab872A665e0CF467d41cF56a054031b4A38bc',
35
- WBTC_PRIME: '0xeae98b8a1798738182B2123DF1eB93d97BD29F34',
36
- WETH_CORE: '0x3961a75099E986F59a1a31c6f945061641dFD2b2',
37
- WETH_PRIME: '0xa411826a6ef5d289c0FAa7d5B45FE8aAB52257F6',
38
- XAUt_CORE: '0x470341bC0e2B833C54D0120642713BdF762A494F',
39
- cbBTC_CORE: '0xe8D5E595d5b6b5EFf84B7064765fd0e8DfD214C9',
40
- cbBTC_PRIME: '0x0E986545150DcDDe46Ea9df355D0fD2af33bd75D',
41
- frxUSD_CORE: '0x00C8A6a42947Cc4E7B6f27963Cab0143ccaaD2B5',
42
- frxUSD_PLUS: '0xCAB288d37CAb5a9db7b503F086455276Dcde61F1',
43
- rsETH_CORE: '0x6eEce89caE2163584bA7Ff9743861B9633c245E0',
44
- sUSDe_PLUS: '0xdf47fc43c88B06edC47753b7d647ff18037D2F3d',
45
- weETH_CORE: '0xB67F20bFF413C8E5d633B54BD28899c4c9e33ed0',
46
- wstETH_CORE: '0x474602394d0B02F43AC3D7C8c5cFc0814b03fd40',
47
- wstETH_PRIME: '0xAcCdAb49ECB9A801CfF62a92fc80D52339b33770',
16
+ AAVE_CORE: '0x0A65197b16C5969F92672051c9C9C0C75B369135',
17
+ EURC_CORE: '0x6D9e2Cdd61CaF69af99b275704B6e272C41c6718',
18
+ GHO_CORE: '0x58C14a5E061c9bC6926c5b853445290F296C2F7B',
19
+ LBTC_CORE: '0x7961F140B570490849DB878AE222570ea838799d',
20
+ LINK_CORE: '0xE69C2045095C8Ab3E2a7d77de2328faE5baF797c',
21
+ RLUSD_CORE: '0xC8a125AE4275a78AADc53B46Ca10566Bc9B249E0',
22
+ USDC_CORE: '0x531E90a2376902DE8915789Fcc1075e3B0c153E7',
23
+ USDG_CORE: '0xAC2435E3C25e8246870D33ce0a26988A46d5DB68',
24
+ USDT_CORE: '0x5eC44a70F309854fe04d495cFE1B5dA63DD1cc73',
25
+ WBTC_CORE: '0x82A9CC4656784E55Ef2E78F704028B5E1Bfc1732',
26
+ WETH_CORE: '0x7320CF22Ac095bA2a2e0a652F77efB836c2E751b',
27
+ XAUt_CORE: '0x4E712562fcb5337011398B6C630f55b60641cd5e',
28
+ cbBTC_CORE: '0x33B41B74366F55327d959FfF6D6b6fBc2853dbB1',
29
+ frxUSD_CORE: '0x2226749630775ee20230Ad65214fB339087eF30D',
30
+ rsETH_CORE: '0x45a04Ca1A5cbEeA4B44356c75EDd29b33eB2527a',
31
+ weETH_CORE: '0x559cEc2C840D9DBB18936Afc5E5341D78bfC7Cbe',
32
+ wstETH_CORE: '0xcb0E7dA9c635628f6d4827355AeCa75aB8d3560f',
33
+ GHO_PLUS: '0xA54382db40EC602c0a173A08f9E86Ed40F9D4D10',
34
+ PT_USDe_7MAY2026_PLUS: '0xdd2Eb78BF9e6aC5068B95aD2d451e8c9Af10ac81',
35
+ PT_sUSDE_7MAY2026_PLUS: '0x90774889c22D2F2Adf44da1f04C7c95542590df4',
36
+ USDC_PLUS: '0xc94bdd83D2c7655C280655D60954e79E88D4F949',
37
+ USDT_PLUS: '0x80835EB50694EE0e519743f67e5401e6FD300006',
38
+ USDe_PLUS: '0x502Cd81da6a8F1785eb2eEE72713B7388E16A854',
39
+ sUSDe_PLUS: '0x24f8c062e1E0451736C1D6E023510DA262a41df4',
40
+ GHO_PRIME: '0x900fD46d565d1ac8995928c0179052ec02a6D0E1',
41
+ USDC_PRIME: '0x486415fb1F8b062c89ED548f871cf64304AACb31',
42
+ USDT_PRIME: '0x46c588DD8453aC259c1f6a54b4C9A93C2aC3762D',
43
+ WBTC_PRIME: '0x5AE3d87De89CA6Ce501e8317887F71EABED69E18',
44
+ WETH_PRIME: '0x2087513383330B961A3753B47627Bbf149F31c70',
45
+ cbBTC_PRIME: '0xD38098faf52D8E915EdED84fBF30F81C17906938',
46
+ wstETH_PRIME: '0xFCD3D3C69cd032DE0cc78fE529B7447D2fe7F666',
48
47
  };
49
48
  export const AAVE_V4_TOKENIZED_SPOKE_ADDRESSES = {
50
49
  [NetworkNumber.Eth]: Object.values(AAVE_V4_TOKENIZED_SPOKES),
@@ -4,6 +4,14 @@ export declare const getApyAfterValuesEstimation: (usedAssets: AaveV4UsedReserve
4
4
  borrowRate: string;
5
5
  supplyRate: string;
6
6
  }>;
7
+ export declare const calculateNetApyAaveV4: ({ usedAssets, assetsData, }: {
8
+ usedAssets: AaveV4UsedReserveAssets;
9
+ assetsData: AaveV4AssetsData;
10
+ }) => {
11
+ netApy: string;
12
+ totalInterestUsd: string;
13
+ incentiveUsd: string;
14
+ };
7
15
  export declare const aaveV4GetCollateralFactor: (assetData: AaveV4ReserveAssetData, usedAssetData: AaveV4UsedReserveAsset, useUserCollateralFactor?: boolean) => number;
8
16
  export declare const isLeveragedPosAaveV4: (usedAssets: AaveV4UsedReserveAssets, dustLimit?: number) => {
9
17
  leveragedType: LeverageType;
@@ -1,5 +1,6 @@
1
1
  import Dec from 'decimal.js';
2
2
  import { aprToApy, calcLeverageLiqPrice, getAssetsTotal, STABLE_ASSETS, } from '../../moneymarket';
3
+ import { calculateInterestEarned } from '../../staking';
3
4
  import { LeverageType, } from '../../types';
4
5
  export const calcUserRiskPremiumBps = (usedAssets, assetsData) => {
5
6
  const collaterals = [];
@@ -70,6 +71,53 @@ export const getApyAfterValuesEstimation = (usedAssets, assetsData) => {
70
71
  });
71
72
  return result;
72
73
  };
74
+ export const calculateNetApyAaveV4 = ({ usedAssets, assetsData, }) => {
75
+ const riskPremiumBps = calcUserRiskPremiumBps(usedAssets, assetsData);
76
+ const riskPremiumFraction = new Dec(riskPremiumBps).div(10000);
77
+ const sumValues = Object.entries(usedAssets).reduce((_acc, [identifier, usedAsset]) => {
78
+ const acc = Object.assign({}, _acc);
79
+ const assetData = assetsData[identifier];
80
+ if (!assetData)
81
+ return acc;
82
+ if (usedAsset.isSupplied) {
83
+ const amount = usedAsset.suppliedUsd;
84
+ acc.suppliedUsd = new Dec(acc.suppliedUsd).add(amount).toString();
85
+ const supplyInterest = calculateInterestEarned(amount, assetData.supplyRate, 'year', true);
86
+ acc.supplyInterest = new Dec(acc.supplyInterest).add(supplyInterest.toString()).toString();
87
+ if (assetData.supplyIncentives) {
88
+ for (const supplyIncentive of assetData.supplyIncentives) {
89
+ const incentiveInterest = calculateInterestEarned(amount, supplyIncentive.apy, 'year', true);
90
+ acc.incentiveUsd = new Dec(acc.incentiveUsd).add(incentiveInterest).toString();
91
+ }
92
+ }
93
+ }
94
+ if (usedAsset.isBorrowed) {
95
+ const amount = usedAsset.borrowedUsd;
96
+ acc.borrowedUsd = new Dec(acc.borrowedUsd).add(amount).toString();
97
+ // User borrow rate = baseRate * (1 + riskPremiumFraction)
98
+ const drawnRate = new Dec(assetData.drawnRate);
99
+ const baseBorrowApr = drawnRate.mul(100);
100
+ const userBorrowApr = baseBorrowApr.mul(new Dec(1).add(riskPremiumFraction));
101
+ const userBorrowRate = aprToApy(userBorrowApr.toString());
102
+ const borrowInterest = calculateInterestEarned(amount, userBorrowRate, 'year', true);
103
+ acc.borrowInterest = new Dec(acc.borrowInterest).sub(borrowInterest.toString()).toString();
104
+ if (assetData.borrowIncentives) {
105
+ for (const borrowIncentive of assetData.borrowIncentives) {
106
+ const incentiveInterest = calculateInterestEarned(amount, borrowIncentive.apy, 'year', true);
107
+ acc.incentiveUsd = new Dec(acc.incentiveUsd).add(incentiveInterest).toString();
108
+ }
109
+ }
110
+ }
111
+ return acc;
112
+ }, {
113
+ borrowInterest: '0', supplyInterest: '0', incentiveUsd: '0', borrowedUsd: '0', suppliedUsd: '0',
114
+ });
115
+ const { borrowedUsd, suppliedUsd, borrowInterest, supplyInterest, incentiveUsd, } = sumValues;
116
+ const totalInterestUsd = new Dec(borrowInterest).add(supplyInterest).add(incentiveUsd).toString();
117
+ const balance = new Dec(suppliedUsd).sub(borrowedUsd);
118
+ const netApy = balance.isZero() ? '0' : new Dec(totalInterestUsd).div(balance).times(100).toString();
119
+ return { netApy, totalInterestUsd, incentiveUsd };
120
+ };
73
121
  export const aaveV4GetCollateralFactor = (assetData, usedAssetData, useUserCollateralFactor = false) => (useUserCollateralFactor ? usedAssetData.collateralFactor : assetData.collateralFactor);
74
122
  export const isLeveragedPosAaveV4 = (usedAssets, dustLimit = 5) => {
75
123
  let borrowUnstable = 0;
@@ -164,14 +212,9 @@ export const aaveV4GetAggregatedPositionData = ({ usedAssets, assetsData, networ
164
212
  payload.collLiquidationRatio = new Dec(payload.suppliedCollateralUsd).div(payload.liquidationLimitUsd).mul(100).toString();
165
213
  // payload.healthRatio = new Dec(payload.liquidationLimitUsd).div(payload.borrowedUsd).toDP(4).toString();
166
214
  payload.minHealthRatio = new Dec(payload.liquidationLimitUsd).div(payload.borrowLimitUsd).toDP(4).toString();
167
- // TODO: Re-implement netApy calculation
168
- // const { netApy, incentiveUsd, totalInterestUsd } = calculateNetApy({
169
- // usedAssets,
170
- // assetsData,
171
- // optionalData: { healthRatio: payload.healthRatio },
172
- // });
173
- payload.netApy = '0';
174
- payload.incentiveUsd = '0';
175
- payload.totalInterestUsd = '0';
215
+ const { netApy, incentiveUsd, totalInterestUsd } = calculateNetApyAaveV4({ usedAssets, assetsData });
216
+ payload.netApy = netApy;
217
+ payload.incentiveUsd = incentiveUsd;
218
+ payload.totalInterestUsd = totalInterestUsd;
176
219
  return payload;
177
220
  };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@defisaver/positions-sdk",
3
- "version": "2.1.79-aave-v4-6-dev",
3
+ "version": "2.1.79-aave-v4-8-dev",
4
4
  "description": "",
5
5
  "main": "./cjs/index.js",
6
6
  "module": "./esm/index.js",
@@ -29,38 +29,39 @@ export interface AaveV4TokenizationSpokeData {
29
29
  }
30
30
 
31
31
  export const AAVE_V4_TOKENIZED_SPOKES: Record<string, EthAddress> = {
32
- AAVE_CORE: '0x08309234884cF7E015b07Bf22569017Aa035cdeF',
33
- EURC_CORE: '0x73596dED4B2Eb0aC85e477b3c8dB56FC427E6774',
34
- GHO_CORE: '0xf7E1f1b43922527e5054bD77E7f863Cf182b194D',
35
- GHO_PRIME: '0xeF1cAd5c6a2C9cb83c952b4B96bbD35b3F61F18f',
36
- LBTC_CORE: '0x8f4D423590F22833131e3493bf67A27213398f8e',
37
- LINK_CORE: '0xBE1197750b423e30137E97d9183065d33E903BE6',
38
- PT_USDe_PLUS: '0x8cA27Ab284F2aA2BcF33D9129e11c101aD2d16de',
39
- PT_sUSDe_PLUS: '0xb8A464EC56071a98c854f30fE19CfeCc41FA6233',
40
- PYUSD_CORE: '0x203FB463087005698d50768FcA837047f738632d',
41
- RLUSD_CORE: '0xa9afdd0c54fb153CaE39cE86E49626B5e9d15513',
42
- USDC_CORE: '0xa2e476f4cbB06C7bFA8Ad51bCcbF198cd32CfD35',
43
- USDC_PLUS: '0x320Bec4fB7a25e64c003A007D0AeF7AB3D6C30d7',
44
- USDC_PRIME: '0x0A0507F7A1129892b5cf74b8B4e911442c466b87',
45
- USDG_CORE: '0x87c224256f09a014C1BC3e9FbB094C3AdD8fBaCC',
46
- USDT_CORE: '0x3f12BD5999b9172550893FF52691c980676f9E73',
47
- USDT_PLUS: '0xa4E74a78bED2d3ab8971e8AB26fb39f26DD8eEd9',
48
- USDT_PRIME: '0xF565fB55bc96d65561887898bfeb25C1dE7e06d2',
49
- USDe_PLUS: '0xA0d346ab2699B689AC67aba5174164A84206BB73',
50
- WBTC_CORE: '0x837Ab872A665e0CF467d41cF56a054031b4A38bc',
51
- WBTC_PRIME: '0xeae98b8a1798738182B2123DF1eB93d97BD29F34',
52
- WETH_CORE: '0x3961a75099E986F59a1a31c6f945061641dFD2b2',
53
- WETH_PRIME: '0xa411826a6ef5d289c0FAa7d5B45FE8aAB52257F6',
54
- XAUt_CORE: '0x470341bC0e2B833C54D0120642713BdF762A494F',
55
- cbBTC_CORE: '0xe8D5E595d5b6b5EFf84B7064765fd0e8DfD214C9',
56
- cbBTC_PRIME: '0x0E986545150DcDDe46Ea9df355D0fD2af33bd75D',
57
- frxUSD_CORE: '0x00C8A6a42947Cc4E7B6f27963Cab0143ccaaD2B5',
58
- frxUSD_PLUS: '0xCAB288d37CAb5a9db7b503F086455276Dcde61F1',
59
- rsETH_CORE: '0x6eEce89caE2163584bA7Ff9743861B9633c245E0',
60
- sUSDe_PLUS: '0xdf47fc43c88B06edC47753b7d647ff18037D2F3d',
61
- weETH_CORE: '0xB67F20bFF413C8E5d633B54BD28899c4c9e33ed0',
62
- wstETH_CORE: '0x474602394d0B02F43AC3D7C8c5cFc0814b03fd40',
63
- wstETH_PRIME: '0xAcCdAb49ECB9A801CfF62a92fc80D52339b33770',
32
+ AAVE_CORE: '0x0A65197b16C5969F92672051c9C9C0C75B369135',
33
+ EURC_CORE: '0x6D9e2Cdd61CaF69af99b275704B6e272C41c6718',
34
+ GHO_CORE: '0x58C14a5E061c9bC6926c5b853445290F296C2F7B',
35
+ LBTC_CORE: '0x7961F140B570490849DB878AE222570ea838799d',
36
+ LINK_CORE: '0xE69C2045095C8Ab3E2a7d77de2328faE5baF797c',
37
+ RLUSD_CORE: '0xC8a125AE4275a78AADc53B46Ca10566Bc9B249E0',
38
+ USDC_CORE: '0x531E90a2376902DE8915789Fcc1075e3B0c153E7',
39
+ USDG_CORE: '0xAC2435E3C25e8246870D33ce0a26988A46d5DB68',
40
+ USDT_CORE: '0x5eC44a70F309854fe04d495cFE1B5dA63DD1cc73',
41
+ WBTC_CORE: '0x82A9CC4656784E55Ef2E78F704028B5E1Bfc1732',
42
+ WETH_CORE: '0x7320CF22Ac095bA2a2e0a652F77efB836c2E751b',
43
+ XAUt_CORE: '0x4E712562fcb5337011398B6C630f55b60641cd5e',
44
+ cbBTC_CORE: '0x33B41B74366F55327d959FfF6D6b6fBc2853dbB1',
45
+ frxUSD_CORE: '0x2226749630775ee20230Ad65214fB339087eF30D',
46
+ rsETH_CORE: '0x45a04Ca1A5cbEeA4B44356c75EDd29b33eB2527a',
47
+ weETH_CORE: '0x559cEc2C840D9DBB18936Afc5E5341D78bfC7Cbe',
48
+ wstETH_CORE: '0xcb0E7dA9c635628f6d4827355AeCa75aB8d3560f',
49
+
50
+ GHO_PLUS: '0xA54382db40EC602c0a173A08f9E86Ed40F9D4D10',
51
+ PT_USDe_7MAY2026_PLUS: '0xdd2Eb78BF9e6aC5068B95aD2d451e8c9Af10ac81',
52
+ PT_sUSDE_7MAY2026_PLUS: '0x90774889c22D2F2Adf44da1f04C7c95542590df4',
53
+ USDC_PLUS: '0xc94bdd83D2c7655C280655D60954e79E88D4F949',
54
+ USDT_PLUS: '0x80835EB50694EE0e519743f67e5401e6FD300006',
55
+ USDe_PLUS: '0x502Cd81da6a8F1785eb2eEE72713B7388E16A854',
56
+ sUSDe_PLUS: '0x24f8c062e1E0451736C1D6E023510DA262a41df4',
57
+
58
+ GHO_PRIME: '0x900fD46d565d1ac8995928c0179052ec02a6D0E1',
59
+ USDC_PRIME: '0x486415fb1F8b062c89ED548f871cf64304AACb31',
60
+ USDT_PRIME: '0x46c588DD8453aC259c1f6a54b4C9A93C2aC3762D',
61
+ WBTC_PRIME: '0x5AE3d87De89CA6Ce501e8317887F71EABED69E18',
62
+ WETH_PRIME: '0x2087513383330B961A3753B47627Bbf149F31c70',
63
+ cbBTC_PRIME: '0xD38098faf52D8E915EdED84fBF30F81C17906938',
64
+ wstETH_PRIME: '0xFCD3D3C69cd032DE0cc78fE529B7447D2fe7F666',
64
65
  };
65
66
 
66
67
  export const AAVE_V4_TOKENIZED_SPOKE_ADDRESSES: Partial<Record<NetworkNumber, EthAddress[]>> = {
@@ -5,6 +5,7 @@ import {
5
5
  getAssetsTotal,
6
6
  STABLE_ASSETS,
7
7
  } from '../../moneymarket';
8
+ import { calculateInterestEarned } from '../../staking';
8
9
  import {
9
10
  AaveV4AggregatedPositionData,
10
11
  AaveV4AssetsData,
@@ -107,6 +108,70 @@ export const getApyAfterValuesEstimation = (
107
108
  return result;
108
109
  };
109
110
 
111
+ export const calculateNetApyAaveV4 = ({
112
+ usedAssets,
113
+ assetsData,
114
+ }: {
115
+ usedAssets: AaveV4UsedReserveAssets,
116
+ assetsData: AaveV4AssetsData,
117
+ }) => {
118
+ const riskPremiumBps = calcUserRiskPremiumBps(usedAssets, assetsData);
119
+ const riskPremiumFraction = new Dec(riskPremiumBps).div(10000);
120
+
121
+ const sumValues = Object.entries(usedAssets).reduce((_acc, [identifier, usedAsset]) => {
122
+ const acc = { ..._acc };
123
+ const assetData = assetsData[identifier];
124
+ if (!assetData) return acc;
125
+
126
+ if (usedAsset.isSupplied) {
127
+ const amount = usedAsset.suppliedUsd;
128
+ acc.suppliedUsd = new Dec(acc.suppliedUsd).add(amount).toString();
129
+ const supplyInterest = calculateInterestEarned(amount, assetData.supplyRate, 'year', true);
130
+ acc.supplyInterest = new Dec(acc.supplyInterest).add(supplyInterest.toString()).toString();
131
+
132
+ if (assetData.supplyIncentives) {
133
+ for (const supplyIncentive of assetData.supplyIncentives) {
134
+ const incentiveInterest = calculateInterestEarned(amount, supplyIncentive.apy, 'year', true);
135
+ acc.incentiveUsd = new Dec(acc.incentiveUsd).add(incentiveInterest).toString();
136
+ }
137
+ }
138
+ }
139
+
140
+ if (usedAsset.isBorrowed) {
141
+ const amount = usedAsset.borrowedUsd;
142
+ acc.borrowedUsd = new Dec(acc.borrowedUsd).add(amount).toString();
143
+ // User borrow rate = baseRate * (1 + riskPremiumFraction)
144
+ const drawnRate = new Dec(assetData.drawnRate);
145
+ const baseBorrowApr = drawnRate.mul(100);
146
+ const userBorrowApr = baseBorrowApr.mul(new Dec(1).add(riskPremiumFraction));
147
+ const userBorrowRate = aprToApy(userBorrowApr.toString());
148
+ const borrowInterest = calculateInterestEarned(amount, userBorrowRate, 'year', true);
149
+ acc.borrowInterest = new Dec(acc.borrowInterest).sub(borrowInterest.toString()).toString();
150
+
151
+ if (assetData.borrowIncentives) {
152
+ for (const borrowIncentive of assetData.borrowIncentives) {
153
+ const incentiveInterest = calculateInterestEarned(amount, borrowIncentive.apy, 'year', true);
154
+ acc.incentiveUsd = new Dec(acc.incentiveUsd).add(incentiveInterest).toString();
155
+ }
156
+ }
157
+ }
158
+
159
+ return acc;
160
+ }, {
161
+ borrowInterest: '0', supplyInterest: '0', incentiveUsd: '0', borrowedUsd: '0', suppliedUsd: '0',
162
+ });
163
+
164
+ const {
165
+ borrowedUsd, suppliedUsd, borrowInterest, supplyInterest, incentiveUsd,
166
+ } = sumValues;
167
+
168
+ const totalInterestUsd = new Dec(borrowInterest).add(supplyInterest).add(incentiveUsd).toString();
169
+ const balance = new Dec(suppliedUsd).sub(borrowedUsd);
170
+ const netApy = balance.isZero() ? '0' : new Dec(totalInterestUsd).div(balance).times(100).toString();
171
+
172
+ return { netApy, totalInterestUsd, incentiveUsd };
173
+ };
174
+
110
175
  export const aaveV4GetCollateralFactor = (assetData: AaveV4ReserveAssetData, usedAssetData: AaveV4UsedReserveAsset, useUserCollateralFactor: boolean = false): number => (useUserCollateralFactor ? usedAssetData.collateralFactor : assetData.collateralFactor);
111
176
 
112
177
  export const isLeveragedPosAaveV4 = (usedAssets: AaveV4UsedReserveAssets, dustLimit = 5) => {
@@ -217,14 +282,9 @@ export const aaveV4GetAggregatedPositionData = ({
217
282
  // payload.healthRatio = new Dec(payload.liquidationLimitUsd).div(payload.borrowedUsd).toDP(4).toString();
218
283
  payload.minHealthRatio = new Dec(payload.liquidationLimitUsd).div(payload.borrowLimitUsd).toDP(4).toString();
219
284
 
220
- // TODO: Re-implement netApy calculation
221
- // const { netApy, incentiveUsd, totalInterestUsd } = calculateNetApy({
222
- // usedAssets,
223
- // assetsData,
224
- // optionalData: { healthRatio: payload.healthRatio },
225
- // });
226
- payload.netApy = '0';
227
- payload.incentiveUsd = '0';
228
- payload.totalInterestUsd = '0';
285
+ const { netApy, incentiveUsd, totalInterestUsd } = calculateNetApyAaveV4({ usedAssets, assetsData });
286
+ payload.netApy = netApy;
287
+ payload.incentiveUsd = incentiveUsd;
288
+ payload.totalInterestUsd = totalInterestUsd;
229
289
  return payload;
230
290
  };