@defisaver/positions-sdk 2.1.71 → 2.1.72-aave-v4-3-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 (78) hide show
  1. package/cjs/aaveV4/index.d.ts +7 -0
  2. package/cjs/aaveV4/index.js +293 -0
  3. package/cjs/aaveV4/lend.d.ts +45 -0
  4. package/cjs/aaveV4/lend.js +141 -0
  5. package/cjs/config/contracts.d.ts +1551 -0
  6. package/cjs/config/contracts.js +9 -0
  7. package/cjs/contracts.d.ts +32741 -0
  8. package/cjs/contracts.js +2 -1
  9. package/cjs/helpers/aaveV4Helpers/index.d.ts +12 -0
  10. package/cjs/helpers/aaveV4Helpers/index.js +117 -0
  11. package/cjs/helpers/index.d.ts +1 -0
  12. package/cjs/helpers/index.js +2 -1
  13. package/cjs/index.d.ts +2 -1
  14. package/cjs/index.js +3 -1
  15. package/cjs/markets/aave/marketAssets.js +1 -1
  16. package/cjs/markets/aaveV4/index.d.ts +28 -0
  17. package/cjs/markets/aaveV4/index.js +140 -0
  18. package/cjs/markets/index.d.ts +1 -0
  19. package/cjs/markets/index.js +3 -1
  20. package/cjs/portfolio/index.js +20 -0
  21. package/cjs/staking/eligibility.d.ts +6 -0
  22. package/cjs/staking/eligibility.js +37 -19
  23. package/cjs/staking/staking.js +4 -2
  24. package/cjs/types/aaveV4.d.ts +153 -0
  25. package/cjs/types/aaveV4.js +19 -0
  26. package/cjs/types/common.d.ts +2 -1
  27. package/cjs/types/common.js +1 -0
  28. package/cjs/types/index.d.ts +1 -0
  29. package/cjs/types/index.js +1 -0
  30. package/cjs/types/portfolio.d.ts +4 -0
  31. package/esm/aaveV4/index.d.ts +7 -0
  32. package/esm/aaveV4/index.js +250 -0
  33. package/esm/aaveV4/lend.d.ts +45 -0
  34. package/esm/aaveV4/lend.js +134 -0
  35. package/esm/config/contracts.d.ts +1551 -0
  36. package/esm/config/contracts.js +8 -0
  37. package/esm/contracts.d.ts +32741 -0
  38. package/esm/contracts.js +1 -0
  39. package/esm/helpers/aaveV4Helpers/index.d.ts +12 -0
  40. package/esm/helpers/aaveV4Helpers/index.js +108 -0
  41. package/esm/helpers/index.d.ts +1 -0
  42. package/esm/helpers/index.js +1 -0
  43. package/esm/index.d.ts +2 -1
  44. package/esm/index.js +2 -1
  45. package/esm/markets/aave/marketAssets.js +1 -1
  46. package/esm/markets/aaveV4/index.d.ts +28 -0
  47. package/esm/markets/aaveV4/index.js +122 -0
  48. package/esm/markets/index.d.ts +1 -0
  49. package/esm/markets/index.js +1 -0
  50. package/esm/portfolio/index.js +21 -1
  51. package/esm/staking/eligibility.d.ts +6 -0
  52. package/esm/staking/eligibility.js +35 -18
  53. package/esm/staking/staking.js +4 -2
  54. package/esm/types/aaveV4.d.ts +153 -0
  55. package/esm/types/aaveV4.js +16 -0
  56. package/esm/types/common.d.ts +2 -1
  57. package/esm/types/common.js +1 -0
  58. package/esm/types/index.d.ts +1 -0
  59. package/esm/types/index.js +1 -0
  60. package/esm/types/portfolio.d.ts +4 -0
  61. package/package.json +2 -2
  62. package/src/aaveV4/index.ts +286 -0
  63. package/src/aaveV4/lend.ts +180 -0
  64. package/src/config/contracts.ts +9 -1
  65. package/src/contracts.ts +3 -1
  66. package/src/helpers/aaveV4Helpers/index.ts +133 -0
  67. package/src/helpers/index.ts +1 -0
  68. package/src/index.ts +2 -0
  69. package/src/markets/aave/marketAssets.ts +1 -1
  70. package/src/markets/aaveV4/index.ts +149 -0
  71. package/src/markets/index.ts +6 -1
  72. package/src/portfolio/index.ts +20 -0
  73. package/src/staking/eligibility.ts +67 -15
  74. package/src/staking/staking.ts +3 -2
  75. package/src/types/aaveV4.ts +169 -0
  76. package/src/types/common.ts +1 -0
  77. package/src/types/index.ts +2 -1
  78. package/src/types/portfolio.ts +4 -0
@@ -0,0 +1,180 @@
1
+ import { assetAmountInEth, getAssetInfoByAddress } from '@defisaver/tokens';
2
+ import { AaveV4ViewContractViem } from '../contracts';
3
+ import { getViemProvider } from '../services/viem';
4
+ import { wethToEth } from '../services/utils';
5
+ import {
6
+ EthAddress,
7
+ EthereumProvider,
8
+ NetworkNumber,
9
+ } from '../types/common';
10
+
11
+ export interface AaveV4TokenizationSpokeData {
12
+ underlyingAsset: EthAddress;
13
+ assetId: string;
14
+ decimals: number;
15
+ spoke: EthAddress;
16
+ spokeActive: boolean;
17
+ spokeHalted: boolean;
18
+ spokeDepositCap: string;
19
+ spokeTotalAssets: string;
20
+ spokeTotalShares: string;
21
+ hub: EthAddress;
22
+ hubLiquidity: string;
23
+ hubDrawnRate: string;
24
+ convertToShares: string;
25
+ convertToAssets: string;
26
+ user: EthAddress;
27
+ userSuppliedAssets: string;
28
+ userSuppliedShares: string;
29
+ }
30
+
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',
64
+ };
65
+
66
+ export const AAVE_V4_TOKENIZED_SPOKE_ADDRESSES: Partial<Record<NetworkNumber, EthAddress[]>> = {
67
+ [NetworkNumber.Eth]: Object.values(AAVE_V4_TOKENIZED_SPOKES),
68
+ };
69
+
70
+ export type AaveV4TokenizedHubKey = 'CORE' | 'PLUS' | 'PRIME';
71
+
72
+ export const aaveV4GetTokenizedHubKey = (hubNameOrKey?: string | null): AaveV4TokenizedHubKey | null => {
73
+ if (!hubNameOrKey) return null;
74
+ const normalized = hubNameOrKey.trim().toUpperCase();
75
+
76
+ // TODO AaveV4 Maybe turn into constants
77
+ if (normalized === 'CORE' || normalized === 'CORE HUB') return 'CORE';
78
+ if (normalized === 'PLUS' || normalized === 'PLUS HUB') return 'PLUS';
79
+ if (normalized === 'PRIME' || normalized === 'PRIME HUB') return 'PRIME';
80
+
81
+ if (normalized.includes('CORE')) return 'CORE';
82
+ if (normalized.includes('PLUS')) return 'PLUS';
83
+ if (normalized.includes('PRIME')) return 'PRIME';
84
+
85
+ return null;
86
+ };
87
+
88
+ export const aaveV4GetTokenizedVaultKey = (
89
+ symbol: string,
90
+ hubNameOrKey?: string | null,
91
+ ): string | null => {
92
+ if (!symbol) return null;
93
+ const hubKey = aaveV4GetTokenizedHubKey(hubNameOrKey);
94
+ if (!hubKey) return null;
95
+
96
+ const normalizedSymbol = symbol.trim().replace(/-/g, '_');
97
+
98
+ return `${normalizedSymbol}_${hubKey}`;
99
+ };
100
+
101
+ export const aaveV4GetTokenizedVaultAddress = (
102
+ network: NetworkNumber,
103
+ symbol: string,
104
+ hubNameOrKey?: string | null,
105
+ ): EthAddress | undefined => {
106
+ if (network !== NetworkNumber.Eth) return undefined;
107
+ const key = aaveV4GetTokenizedVaultKey(symbol, hubNameOrKey);
108
+ if (!key) return undefined;
109
+ return AAVE_V4_TOKENIZED_SPOKES[key];
110
+ };
111
+
112
+ /** Parsed tokenization spoke data with human-readable supplied amounts for display */
113
+ export interface AaveV4TokenizationSpokeDataParsed {
114
+ vaultAddress: EthAddress;
115
+ key: string | null;
116
+ symbol: string;
117
+ hubKey: string;
118
+ userSuppliedAssetsEth: string;
119
+ userSuppliedSharesEth: string;
120
+ userSuppliedAssets: string;
121
+ userSuppliedShares: string;
122
+ underlyingAsset: EthAddress;
123
+ spoke: EthAddress;
124
+ decimals: number;
125
+ }
126
+
127
+ const AAVE_V4_TOKENIZED_SPOKE_ADDRESS_TO_KEY: Record<string, string> = Object.entries(
128
+ AAVE_V4_TOKENIZED_SPOKES,
129
+ ).reduce((acc, [k, v]) => {
130
+ acc[v.toLowerCase()] = k;
131
+ return acc;
132
+ }, {} as Record<string, string>);
133
+
134
+ /**
135
+ * Fetches tokenization vault data for the given user via getTokenizationSpokesData.
136
+ * Returns parsed data including userSuppliedAssets in human-readable form for each vault.
137
+ */
138
+ export async function getAaveV4TokenizationSpokesData(
139
+ provider: EthereumProvider,
140
+ network: NetworkNumber,
141
+ userAddress: EthAddress,
142
+ ): Promise<AaveV4TokenizationSpokeDataParsed[]> {
143
+ const spokes = AAVE_V4_TOKENIZED_SPOKE_ADDRESSES[network] ?? [];
144
+ if (spokes.length === 0) return [];
145
+
146
+ const client = getViemProvider(provider, network);
147
+ const viewContract = AaveV4ViewContractViem(client, network);
148
+ const raw = await viewContract.read.getTokenizationSpokesData([spokes, userAddress]);
149
+
150
+ return raw.map((r: any, i: number) => {
151
+ const vaultAddress = spokes[i];
152
+ const key = AAVE_V4_TOKENIZED_SPOKE_ADDRESS_TO_KEY[vaultAddress.toLowerCase()] ?? null;
153
+ const symbol = wethToEth(getAssetInfoByAddress(r.underlyingAsset, network).symbol);
154
+ if (symbol === '?') { // unsupported asset
155
+ return null;
156
+ }
157
+ const hubKey = key ? key.split('_').pop() ?? '' : '';
158
+ const decimals = Number(r.decimals ?? 18);
159
+ const userSuppliedAssetsRaw = r.userSuppliedAssets ?? 0;
160
+ const userSuppliedSharesRaw = r.userSuppliedShares ?? 0;
161
+
162
+ const userSuppliedAssetsEth = assetAmountInEth(userSuppliedAssetsRaw.toString(), symbol);
163
+ const userSuppliedSharesEth = assetAmountInEth(userSuppliedSharesRaw.toString(), symbol);
164
+ return {
165
+ vaultAddress,
166
+ key,
167
+ symbol,
168
+ hubKey,
169
+ userSuppliedAssetsEth,
170
+ userSuppliedSharesEth,
171
+ userSuppliedAssets: userSuppliedAssetsRaw.toString(),
172
+ userSuppliedShares: userSuppliedSharesRaw.toString(),
173
+ underlyingAsset: r.underlyingAsset,
174
+ spoke: r.spoke,
175
+ decimals,
176
+ };
177
+ }).filter(item => item != null);
178
+ }
179
+
180
+
@@ -620,7 +620,7 @@ export const AaveLoanInfoV2 = {
620
620
  "address": "0xEDf1087544a01596b70Da746F861B878F245B08f"
621
621
  },
622
622
  }
623
- },
623
+ },
624
624
  }
625
625
  } as const;
626
626
  export const LendingPoolAddressesProvider = {
@@ -1322,4 +1322,12 @@ export const SkySavings = {
1322
1322
  } as const;
1323
1323
  export const YearnV3Vault = {
1324
1324
  "abi": [{"stateMutability":"view","type":"function","name":"balanceOf","inputs":[{"name":"addr","type":"address"}],"outputs":[{"name":"","type":"uint256"}]},{"stateMutability":"view","type":"function","name":"totalAssets","inputs":[],"outputs":[{"name":"","type":"uint256"}]},{"stateMutability":"view","type":"function","name":"totalDebt","inputs":[],"outputs":[{"name":"","type":"uint256"}]},{"stateMutability":"view","type":"function","name":"totalSupply","inputs":[],"outputs":[{"name":"","type":"uint256"}]}]
1325
+ } as const;
1326
+ export const AaveV4View = {
1327
+ "abi": [{"inputs":[{"internalType":"address","name":"_eoa","type":"address"},{"internalType":"address","name":"_proxy","type":"address"},{"internalType":"address","name":"_spoke","type":"address"}],"name":"getEOAApprovalsAndBalances","outputs":[{"components":[{"internalType":"address","name":"eoa","type":"address"},{"internalType":"address","name":"proxy","type":"address"},{"internalType":"address","name":"spoke","type":"address"},{"internalType":"bool","name":"giverPositionManagerEnabled","type":"bool"},{"internalType":"bool","name":"takerPositionManagerEnabled","type":"bool"},{"internalType":"bool","name":"configPositionManagerEnabled","type":"bool"},{"internalType":"bool","name":"canSetUsingAsCollateral","type":"bool"},{"internalType":"bool","name":"canUpdateUserRiskPremium","type":"bool"},{"internalType":"bool","name":"canUpdateUserDynamicConfig","type":"bool"},{"components":[{"internalType":"uint256","name":"reserveId","type":"uint256"},{"internalType":"address","name":"underlying","type":"address"},{"internalType":"uint256","name":"delegateeBorrowApproval","type":"uint256"},{"internalType":"uint256","name":"delegateeWithdrawApproval","type":"uint256"},{"internalType":"uint256","name":"eoaReserveBalance","type":"uint256"}],"internalType":"struct AaveV4View.EOAReserveApprovalData[]","name":"reserveApprovals","type":"tuple[]"}],"internalType":"struct AaveV4View.EOAApprovalData","name":"data","type":"tuple"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_spoke","type":"address"},{"internalType":"address","name":"_user","type":"address"}],"name":"getHealthFactor","outputs":[{"internalType":"uint256","name":"healthFactor","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_hub","type":"address"}],"name":"getHubAllAssetsData","outputs":[{"components":[{"internalType":"uint16","name":"assetId","type":"uint16"},{"internalType":"uint8","name":"decimals","type":"uint8"},{"internalType":"address","name":"underlying","type":"address"},{"internalType":"uint256","name":"liquidity","type":"uint256"},{"internalType":"uint256","name":"totalSupplied","type":"uint256"},{"internalType":"uint256","name":"totalDrawn","type":"uint256"},{"internalType":"uint256","name":"totalPremium","type":"uint256"},{"internalType":"uint256","name":"totalDebt","type":"uint256"},{"internalType":"uint256","name":"totalDrawnShares","type":"uint256"},{"internalType":"uint256","name":"totalPremiumShares","type":"uint256"},{"internalType":"uint256","name":"swept","type":"uint256"},{"internalType":"uint16","name":"liquidityFee","type":"uint16"},{"internalType":"uint120","name":"drawnIndex","type":"uint120"},{"internalType":"uint96","name":"drawnRate","type":"uint96"},{"internalType":"uint40","name":"lastUpdateTimestamp","type":"uint40"},{"internalType":"address","name":"irStrategy","type":"address"},{"internalType":"address","name":"reinvestmentController","type":"address"},{"internalType":"address","name":"feeReceiver","type":"address"},{"internalType":"uint256","name":"deficitRay","type":"uint256"}],"internalType":"struct AaveV4View.HubAssetData[]","name":"hubAssetData","type":"tuple[]"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_hub","type":"address"},{"internalType":"uint256","name":"_assetId","type":"uint256"}],"name":"getHubAssetData","outputs":[{"components":[{"internalType":"uint16","name":"assetId","type":"uint16"},{"internalType":"uint8","name":"decimals","type":"uint8"},{"internalType":"address","name":"underlying","type":"address"},{"internalType":"uint256","name":"liquidity","type":"uint256"},{"internalType":"uint256","name":"totalSupplied","type":"uint256"},{"internalType":"uint256","name":"totalDrawn","type":"uint256"},{"internalType":"uint256","name":"totalPremium","type":"uint256"},{"internalType":"uint256","name":"totalDebt","type":"uint256"},{"internalType":"uint256","name":"totalDrawnShares","type":"uint256"},{"internalType":"uint256","name":"totalPremiumShares","type":"uint256"},{"internalType":"uint256","name":"swept","type":"uint256"},{"internalType":"uint16","name":"liquidityFee","type":"uint16"},{"internalType":"uint120","name":"drawnIndex","type":"uint120"},{"internalType":"uint96","name":"drawnRate","type":"uint96"},{"internalType":"uint40","name":"lastUpdateTimestamp","type":"uint40"},{"internalType":"address","name":"irStrategy","type":"address"},{"internalType":"address","name":"reinvestmentController","type":"address"},{"internalType":"address","name":"feeReceiver","type":"address"},{"internalType":"uint256","name":"deficitRay","type":"uint256"}],"internalType":"struct AaveV4View.HubAssetData","name":"hubAssetData","type":"tuple"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_spoke","type":"address"},{"internalType":"address","name":"_user","type":"address"}],"name":"getLoanData","outputs":[{"components":[{"internalType":"address","name":"user","type":"address"},{"internalType":"uint256","name":"riskPremium","type":"uint256"},{"internalType":"uint256","name":"avgCollateralFactor","type":"uint256"},{"internalType":"uint256","name":"healthFactor","type":"uint256"},{"internalType":"uint256","name":"totalCollateralInUsd","type":"uint256"},{"internalType":"uint256","name":"totalDebtInUsdRay","type":"uint256"},{"internalType":"uint256","name":"activeCollateralCount","type":"uint256"},{"internalType":"uint256","name":"borrowCount","type":"uint256"},{"components":[{"internalType":"uint256","name":"reserveId","type":"uint256"},{"internalType":"uint16","name":"assetId","type":"uint16"},{"internalType":"address","name":"underlying","type":"address"},{"internalType":"uint256","name":"supplied","type":"uint256"},{"internalType":"uint256","name":"drawn","type":"uint256"},{"internalType":"uint256","name":"premium","type":"uint256"},{"internalType":"uint256","name":"totalDebt","type":"uint256"},{"internalType":"uint16","name":"collateralFactor","type":"uint16"},{"internalType":"uint32","name":"maxLiquidationBonus","type":"uint32"},{"internalType":"uint16","name":"liquidationFee","type":"uint16"},{"internalType":"bool","name":"isUsingAsCollateral","type":"bool"},{"internalType":"bool","name":"isBorrowing","type":"bool"}],"internalType":"struct AaveV4View.UserReserveData[]","name":"reserves","type":"tuple[]"}],"internalType":"struct AaveV4View.LoanData","name":"loanData","type":"tuple"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_user","type":"address"},{"internalType":"address[]","name":"_spokes","type":"address[]"}],"name":"getLoanDataForMultipleSpokes","outputs":[{"components":[{"internalType":"address","name":"user","type":"address"},{"internalType":"uint256","name":"riskPremium","type":"uint256"},{"internalType":"uint256","name":"avgCollateralFactor","type":"uint256"},{"internalType":"uint256","name":"healthFactor","type":"uint256"},{"internalType":"uint256","name":"totalCollateralInUsd","type":"uint256"},{"internalType":"uint256","name":"totalDebtInUsdRay","type":"uint256"},{"internalType":"uint256","name":"activeCollateralCount","type":"uint256"},{"internalType":"uint256","name":"borrowCount","type":"uint256"},{"components":[{"internalType":"uint256","name":"reserveId","type":"uint256"},{"internalType":"uint16","name":"assetId","type":"uint16"},{"internalType":"address","name":"underlying","type":"address"},{"internalType":"uint256","name":"supplied","type":"uint256"},{"internalType":"uint256","name":"drawn","type":"uint256"},{"internalType":"uint256","name":"premium","type":"uint256"},{"internalType":"uint256","name":"totalDebt","type":"uint256"},{"internalType":"uint16","name":"collateralFactor","type":"uint16"},{"internalType":"uint32","name":"maxLiquidationBonus","type":"uint32"},{"internalType":"uint16","name":"liquidationFee","type":"uint16"},{"internalType":"bool","name":"isUsingAsCollateral","type":"bool"},{"internalType":"bool","name":"isBorrowing","type":"bool"}],"internalType":"struct AaveV4View.UserReserveData[]","name":"reserves","type":"tuple[]"}],"internalType":"struct AaveV4View.LoanData[]","name":"loans","type":"tuple[]"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_spoke","type":"address"},{"internalType":"address[]","name":"_users","type":"address[]"}],"name":"getLoanDataForMultipleUsers","outputs":[{"components":[{"internalType":"address","name":"user","type":"address"},{"internalType":"uint256","name":"riskPremium","type":"uint256"},{"internalType":"uint256","name":"avgCollateralFactor","type":"uint256"},{"internalType":"uint256","name":"healthFactor","type":"uint256"},{"internalType":"uint256","name":"totalCollateralInUsd","type":"uint256"},{"internalType":"uint256","name":"totalDebtInUsdRay","type":"uint256"},{"internalType":"uint256","name":"activeCollateralCount","type":"uint256"},{"internalType":"uint256","name":"borrowCount","type":"uint256"},{"components":[{"internalType":"uint256","name":"reserveId","type":"uint256"},{"internalType":"uint16","name":"assetId","type":"uint16"},{"internalType":"address","name":"underlying","type":"address"},{"internalType":"uint256","name":"supplied","type":"uint256"},{"internalType":"uint256","name":"drawn","type":"uint256"},{"internalType":"uint256","name":"premium","type":"uint256"},{"internalType":"uint256","name":"totalDebt","type":"uint256"},{"internalType":"uint16","name":"collateralFactor","type":"uint16"},{"internalType":"uint32","name":"maxLiquidationBonus","type":"uint32"},{"internalType":"uint16","name":"liquidationFee","type":"uint16"},{"internalType":"bool","name":"isUsingAsCollateral","type":"bool"},{"internalType":"bool","name":"isBorrowing","type":"bool"}],"internalType":"struct AaveV4View.UserReserveData[]","name":"reserves","type":"tuple[]"}],"internalType":"struct AaveV4View.LoanData[]","name":"loans","type":"tuple[]"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_spoke","type":"address"},{"internalType":"address","name":"_user","type":"address"}],"name":"getLoanDataFull","outputs":[{"components":[{"internalType":"address","name":"user","type":"address"},{"internalType":"uint256","name":"riskPremium","type":"uint256"},{"internalType":"uint256","name":"avgCollateralFactor","type":"uint256"},{"internalType":"uint256","name":"healthFactor","type":"uint256"},{"internalType":"uint256","name":"totalCollateralInUsd","type":"uint256"},{"internalType":"uint256","name":"totalDebtInUsdRay","type":"uint256"},{"internalType":"uint256","name":"activeCollateralCount","type":"uint256"},{"internalType":"uint256","name":"borrowCount","type":"uint256"},{"components":[{"internalType":"uint256","name":"reserveId","type":"uint256"},{"internalType":"address","name":"underlying","type":"address"},{"internalType":"uint256","name":"price","type":"uint256"},{"internalType":"uint8","name":"decimals","type":"uint8"},{"internalType":"bool","name":"isUsingAsCollateral","type":"bool"},{"internalType":"bool","name":"isBorrowing","type":"bool"},{"internalType":"bool","name":"reservePaused","type":"bool"},{"internalType":"bool","name":"reserveFrozen","type":"bool"},{"internalType":"bool","name":"borrowable","type":"bool"},{"internalType":"bool","name":"spokeActive","type":"bool"},{"internalType":"bool","name":"spokeHalted","type":"bool"},{"internalType":"uint256","name":"userSupplied","type":"uint256"},{"internalType":"uint256","name":"userDrawn","type":"uint256"},{"internalType":"uint256","name":"userPremium","type":"uint256"},{"internalType":"uint256","name":"userTotalDebt","type":"uint256"},{"internalType":"uint24","name":"collateralRisk","type":"uint24"},{"internalType":"uint16","name":"userCollateralFactor","type":"uint16"},{"internalType":"uint32","name":"userMaxLiquidationBonus","type":"uint32"},{"internalType":"uint16","name":"userLiquidationFee","type":"uint16"},{"internalType":"uint16","name":"latestCollateralFactor","type":"uint16"},{"internalType":"uint32","name":"latestMaxLiquidationBonus","type":"uint32"},{"internalType":"uint16","name":"latestLiquidationFee","type":"uint16"},{"internalType":"address","name":"hub","type":"address"},{"internalType":"uint16","name":"hubAssetId","type":"uint16"},{"internalType":"uint256","name":"hubLiquidity","type":"uint256"},{"internalType":"uint96","name":"drawnRate","type":"uint96"},{"internalType":"uint120","name":"drawnIndex","type":"uint120"},{"internalType":"uint256","name":"spokeTotalSupplied","type":"uint256"},{"internalType":"uint256","name":"spokeTotalDrawn","type":"uint256"},{"internalType":"uint256","name":"spokeTotalPremium","type":"uint256"},{"internalType":"uint256","name":"spokeTotalDebt","type":"uint256"},{"internalType":"uint256","name":"spokeSupplyCap","type":"uint256"},{"internalType":"uint256","name":"spokeBorrowCap","type":"uint256"},{"internalType":"uint256","name":"spokeDeficitRay","type":"uint256"}],"internalType":"struct AaveV4View.UserReserveDataFull[]","name":"reserves","type":"tuple[]"}],"internalType":"struct AaveV4View.LoanDataWithFullReserves","name":"loanData","type":"tuple"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_spoke","type":"address"},{"internalType":"uint256","name":"_reserveId","type":"uint256"}],"name":"getReserveData","outputs":[{"components":[{"internalType":"address","name":"underlying","type":"address"},{"internalType":"uint16","name":"collateralFactor","type":"uint16"},{"internalType":"uint256","name":"price","type":"uint256"}],"internalType":"struct AaveV4View.ReserveData","name":"reserveData","type":"tuple"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_spoke","type":"address"},{"internalType":"uint256","name":"_reserveId","type":"uint256"}],"name":"getReserveDataFull","outputs":[{"components":[{"internalType":"address","name":"underlying","type":"address"},{"internalType":"address","name":"hub","type":"address"},{"internalType":"uint16","name":"assetId","type":"uint16"},{"internalType":"uint8","name":"decimals","type":"uint8"},{"internalType":"bool","name":"paused","type":"bool"},{"internalType":"bool","name":"frozen","type":"bool"},{"internalType":"bool","name":"borrowable","type":"bool"},{"internalType":"uint24","name":"collateralRisk","type":"uint24"},{"internalType":"uint16","name":"collateralFactor","type":"uint16"},{"internalType":"uint32","name":"maxLiquidationBonus","type":"uint32"},{"internalType":"uint16","name":"liquidationFee","type":"uint16"},{"internalType":"uint256","name":"price","type":"uint256"},{"internalType":"uint256","name":"totalSupplied","type":"uint256"},{"internalType":"uint256","name":"totalDrawn","type":"uint256"},{"internalType":"uint256","name":"totalPremium","type":"uint256"},{"internalType":"uint256","name":"totalDebt","type":"uint256"},{"internalType":"uint256","name":"supplyCap","type":"uint256"},{"internalType":"uint256","name":"borrowCap","type":"uint256"},{"internalType":"uint256","name":"deficitRay","type":"uint256"},{"internalType":"bool","name":"spokeActive","type":"bool"},{"internalType":"bool","name":"spokeHalted","type":"bool"}],"internalType":"struct AaveV4View.ReserveDataFull","name":"reserveData","type":"tuple"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_spoke","type":"address"},{"internalType":"uint256","name":"_reserveId","type":"uint256"}],"name":"getReservePrice","outputs":[{"internalType":"uint256","name":"price","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_spoke","type":"address"},{"internalType":"uint256[]","name":"_reserveIds","type":"uint256[]"}],"name":"getReservePrices","outputs":[{"internalType":"uint256[]","name":"prices","type":"uint256[]"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_spoke","type":"address"},{"internalType":"uint256[]","name":"_reserveIds","type":"uint256[]"}],"name":"getReservesData","outputs":[{"components":[{"internalType":"address","name":"underlying","type":"address"},{"internalType":"uint16","name":"collateralFactor","type":"uint16"},{"internalType":"uint256","name":"price","type":"uint256"}],"internalType":"struct AaveV4View.ReserveData[]","name":"reserveData","type":"tuple[]"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_spoke","type":"address"},{"internalType":"uint256[]","name":"_reserveIds","type":"uint256[]"}],"name":"getReservesDataFull","outputs":[{"components":[{"internalType":"address","name":"underlying","type":"address"},{"internalType":"address","name":"hub","type":"address"},{"internalType":"uint16","name":"assetId","type":"uint16"},{"internalType":"uint8","name":"decimals","type":"uint8"},{"internalType":"bool","name":"paused","type":"bool"},{"internalType":"bool","name":"frozen","type":"bool"},{"internalType":"bool","name":"borrowable","type":"bool"},{"internalType":"uint24","name":"collateralRisk","type":"uint24"},{"internalType":"uint16","name":"collateralFactor","type":"uint16"},{"internalType":"uint32","name":"maxLiquidationBonus","type":"uint32"},{"internalType":"uint16","name":"liquidationFee","type":"uint16"},{"internalType":"uint256","name":"price","type":"uint256"},{"internalType":"uint256","name":"totalSupplied","type":"uint256"},{"internalType":"uint256","name":"totalDrawn","type":"uint256"},{"internalType":"uint256","name":"totalPremium","type":"uint256"},{"internalType":"uint256","name":"totalDebt","type":"uint256"},{"internalType":"uint256","name":"supplyCap","type":"uint256"},{"internalType":"uint256","name":"borrowCap","type":"uint256"},{"internalType":"uint256","name":"deficitRay","type":"uint256"},{"internalType":"bool","name":"spokeActive","type":"bool"},{"internalType":"bool","name":"spokeHalted","type":"bool"}],"internalType":"struct AaveV4View.ReserveDataFull[]","name":"reserveData","type":"tuple[]"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_spoke","type":"address"}],"name":"getSpokeData","outputs":[{"components":[{"internalType":"uint128","name":"targetHealthFactor","type":"uint128"},{"internalType":"uint64","name":"healthFactorForMaxBonus","type":"uint64"},{"internalType":"uint16","name":"liquidationBonusFactor","type":"uint16"},{"internalType":"address","name":"oracle","type":"address"},{"internalType":"uint256","name":"oracleDecimals","type":"uint256"},{"internalType":"uint256","name":"reserveCount","type":"uint256"}],"internalType":"struct AaveV4View.SpokeData","name":"spokeData","type":"tuple"},{"components":[{"internalType":"address","name":"underlying","type":"address"},{"internalType":"uint16","name":"collateralFactor","type":"uint16"},{"internalType":"uint256","name":"price","type":"uint256"}],"internalType":"struct AaveV4View.ReserveData[]","name":"reserves","type":"tuple[]"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_spoke","type":"address"}],"name":"getSpokeDataFull","outputs":[{"components":[{"internalType":"uint128","name":"targetHealthFactor","type":"uint128"},{"internalType":"uint64","name":"healthFactorForMaxBonus","type":"uint64"},{"internalType":"uint16","name":"liquidationBonusFactor","type":"uint16"},{"internalType":"address","name":"oracle","type":"address"},{"internalType":"uint256","name":"oracleDecimals","type":"uint256"},{"internalType":"uint256","name":"reserveCount","type":"uint256"}],"internalType":"struct AaveV4View.SpokeData","name":"spokeData","type":"tuple"},{"components":[{"internalType":"address","name":"underlying","type":"address"},{"internalType":"address","name":"hub","type":"address"},{"internalType":"uint16","name":"assetId","type":"uint16"},{"internalType":"uint8","name":"decimals","type":"uint8"},{"internalType":"bool","name":"paused","type":"bool"},{"internalType":"bool","name":"frozen","type":"bool"},{"internalType":"bool","name":"borrowable","type":"bool"},{"internalType":"uint24","name":"collateralRisk","type":"uint24"},{"internalType":"uint16","name":"collateralFactor","type":"uint16"},{"internalType":"uint32","name":"maxLiquidationBonus","type":"uint32"},{"internalType":"uint16","name":"liquidationFee","type":"uint16"},{"internalType":"uint256","name":"price","type":"uint256"},{"internalType":"uint256","name":"totalSupplied","type":"uint256"},{"internalType":"uint256","name":"totalDrawn","type":"uint256"},{"internalType":"uint256","name":"totalPremium","type":"uint256"},{"internalType":"uint256","name":"totalDebt","type":"uint256"},{"internalType":"uint256","name":"supplyCap","type":"uint256"},{"internalType":"uint256","name":"borrowCap","type":"uint256"},{"internalType":"uint256","name":"deficitRay","type":"uint256"},{"internalType":"bool","name":"spokeActive","type":"bool"},{"internalType":"bool","name":"spokeHalted","type":"bool"}],"internalType":"struct AaveV4View.ReserveDataFull[]","name":"reserves","type":"tuple[]"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_hub","type":"address"},{"internalType":"uint256","name":"_assetId","type":"uint256"}],"name":"getSpokesForAsset","outputs":[{"internalType":"address[]","name":"spokes","type":"address[]"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_spoke","type":"address"},{"internalType":"address","name":"_user","type":"address"}],"name":"getTokenizationSpokeData","outputs":[{"components":[{"internalType":"address","name":"underlyingAsset","type":"address"},{"internalType":"uint256","name":"assetId","type":"uint256"},{"internalType":"uint8","name":"decimals","type":"uint8"},{"internalType":"address","name":"spoke","type":"address"},{"internalType":"bool","name":"spokeActive","type":"bool"},{"internalType":"bool","name":"spokeHalted","type":"bool"},{"internalType":"uint256","name":"spokeDepositCap","type":"uint256"},{"internalType":"uint256","name":"spokeTotalAssets","type":"uint256"},{"internalType":"uint256","name":"spokeTotalShares","type":"uint256"},{"internalType":"address","name":"hub","type":"address"},{"internalType":"uint256","name":"hubLiquidity","type":"uint256"},{"internalType":"uint96","name":"hubDrawnRate","type":"uint96"},{"internalType":"uint256","name":"convertToShares","type":"uint256"},{"internalType":"uint256","name":"convertToAssets","type":"uint256"},{"internalType":"address","name":"user","type":"address"},{"internalType":"uint256","name":"userSuppliedAssets","type":"uint256"},{"internalType":"uint256","name":"userSuppliedShares","type":"uint256"}],"internalType":"struct AaveV4View.TokenizationSpokeData","name":"spokeData","type":"tuple"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address[]","name":"_spokes","type":"address[]"},{"internalType":"address","name":"_user","type":"address"}],"name":"getTokenizationSpokesData","outputs":[{"components":[{"internalType":"address","name":"underlyingAsset","type":"address"},{"internalType":"uint256","name":"assetId","type":"uint256"},{"internalType":"uint8","name":"decimals","type":"uint8"},{"internalType":"address","name":"spoke","type":"address"},{"internalType":"bool","name":"spokeActive","type":"bool"},{"internalType":"bool","name":"spokeHalted","type":"bool"},{"internalType":"uint256","name":"spokeDepositCap","type":"uint256"},{"internalType":"uint256","name":"spokeTotalAssets","type":"uint256"},{"internalType":"uint256","name":"spokeTotalShares","type":"uint256"},{"internalType":"address","name":"hub","type":"address"},{"internalType":"uint256","name":"hubLiquidity","type":"uint256"},{"internalType":"uint96","name":"hubDrawnRate","type":"uint96"},{"internalType":"uint256","name":"convertToShares","type":"uint256"},{"internalType":"uint256","name":"convertToAssets","type":"uint256"},{"internalType":"address","name":"user","type":"address"},{"internalType":"uint256","name":"userSuppliedAssets","type":"uint256"},{"internalType":"uint256","name":"userSuppliedShares","type":"uint256"}],"internalType":"struct AaveV4View.TokenizationSpokeData[]","name":"spokeData","type":"tuple[]"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_spoke","type":"address"},{"internalType":"address","name":"_user","type":"address"},{"internalType":"uint256[]","name":"_reserveIds","type":"uint256[]"}],"name":"getUserReserveData","outputs":[{"components":[{"internalType":"uint256","name":"reserveId","type":"uint256"},{"internalType":"uint16","name":"assetId","type":"uint16"},{"internalType":"address","name":"underlying","type":"address"},{"internalType":"uint256","name":"supplied","type":"uint256"},{"internalType":"uint256","name":"drawn","type":"uint256"},{"internalType":"uint256","name":"premium","type":"uint256"},{"internalType":"uint256","name":"totalDebt","type":"uint256"},{"internalType":"uint16","name":"collateralFactor","type":"uint16"},{"internalType":"uint32","name":"maxLiquidationBonus","type":"uint32"},{"internalType":"uint16","name":"liquidationFee","type":"uint16"},{"internalType":"bool","name":"isUsingAsCollateral","type":"bool"},{"internalType":"bool","name":"isBorrowing","type":"bool"}],"internalType":"struct AaveV4View.UserReserveData[]","name":"_userReserves","type":"tuple[]"}],"stateMutability":"view","type":"function"}],
1328
+ "networks": {
1329
+ "1": {
1330
+ "address": "0x34b6B5A3e8fB9135EbB47ACE4242b47E51064f5D",
1331
+ }
1332
+ }
1325
1333
  } as const;
package/src/contracts.ts CHANGED
@@ -169,4 +169,6 @@ export const YearnViewContractViem = createViemContractFromConfigFunc('YearnView
169
169
 
170
170
  export const MakerDsrContractViem = createViemContractFromConfigFunc('MakerDsr');
171
171
 
172
- export const SkySavingsContractView = createViemContractFromConfigFunc('SkySavings');
172
+ export const SkySavingsContractView = createViemContractFromConfigFunc('SkySavings');
173
+
174
+ export const AaveV4ViewContractViem = createViemContractFromConfigFunc('AaveV4View');
@@ -0,0 +1,133 @@
1
+ import Dec from 'decimal.js';
2
+ import { calcLeverageLiqPrice, getAssetsTotal, STABLE_ASSETS } from '../../moneymarket';
3
+ import {
4
+ AaveV4AggregatedPositionData,
5
+ AaveV4AssetsData,
6
+ AaveV4ReserveAssetData,
7
+ AaveV4UsedReserveAsset,
8
+ AaveV4UsedReserveAssets,
9
+ LeverageType,
10
+ NetworkNumber,
11
+ } from '../../types';
12
+
13
+ export const aaveV4GetCollateralFactor = (assetData: AaveV4ReserveAssetData, usedAssetData: AaveV4UsedReserveAsset, useUserCollateralFactor: boolean = false): number => (useUserCollateralFactor ? usedAssetData.collateralFactor : assetData.collateralFactor);
14
+
15
+ export const isLeveragedPosAaveV4 = (usedAssets: AaveV4UsedReserveAssets, dustLimit = 5) => {
16
+ let borrowUnstable = 0;
17
+ let supplyStable = 0;
18
+ let borrowStable = 0;
19
+ let supplyUnstable = 0;
20
+ let longAsset = '';
21
+ let shortAsset = '';
22
+ Object.values(usedAssets).forEach(({
23
+ symbol, suppliedUsd, borrowedUsd, collateral, reserveId,
24
+ }) => {
25
+ const spokeAsset = `${symbol}-${reserveId}`;
26
+ const isSupplied = (+suppliedUsd) > dustLimit; // ignore dust like <limit leftover supply
27
+ const isBorrowed = (+borrowedUsd) > dustLimit; // ignore dust like <limit leftover supply
28
+ if (isSupplied && STABLE_ASSETS.includes(symbol) && collateral) supplyStable += 1;
29
+ if (isBorrowed && STABLE_ASSETS.includes(symbol)) borrowStable += 1;
30
+ if (isBorrowed && !STABLE_ASSETS.includes(symbol)) {
31
+ borrowUnstable += 1;
32
+ shortAsset = spokeAsset;
33
+ }
34
+ if (isSupplied && !STABLE_ASSETS.includes(symbol) && collateral) {
35
+ supplyUnstable += 1;
36
+ longAsset = spokeAsset;
37
+ }
38
+ });
39
+ const isLong = borrowStable > 0 && borrowUnstable === 0 && supplyUnstable === 1 && supplyStable === 0;
40
+ const isShort = supplyStable > 0 && supplyUnstable === 0 && borrowUnstable === 1 && borrowStable === 0;
41
+ const isVolatilePair = supplyUnstable === 1 && borrowUnstable === 1 && supplyStable === 0 && borrowStable === 0;
42
+ if (isLong) {
43
+ return {
44
+ leveragedType: LeverageType.Long,
45
+ leveragedAsset: longAsset,
46
+ };
47
+ }
48
+ if (isShort) {
49
+ return {
50
+ leveragedType: LeverageType.Short,
51
+ leveragedAsset: shortAsset,
52
+ };
53
+ }
54
+ if (isVolatilePair) {
55
+ return {
56
+ leveragedType: LeverageType.VolatilePair,
57
+ leveragedAsset: longAsset,
58
+ };
59
+ }
60
+ return {
61
+ leveragedType: LeverageType.None,
62
+ leveragedAsset: '',
63
+ };
64
+ };
65
+
66
+ export const aaveV4GetAggregatedPositionData = ({
67
+ usedAssets,
68
+ assetsData,
69
+ network,
70
+ useUserCollateralFactor = false,
71
+ }: {
72
+ usedAssets: AaveV4UsedReserveAssets,
73
+ assetsData: AaveV4AssetsData,
74
+ network: NetworkNumber,
75
+ useUserCollateralFactor?: boolean,
76
+ }): AaveV4AggregatedPositionData => {
77
+ const payload = {} as AaveV4AggregatedPositionData;
78
+ payload.suppliedUsd = getAssetsTotal(usedAssets, ({ isSupplied }: { isSupplied: boolean }) => isSupplied, ({ suppliedUsd }: { suppliedUsd: string }) => suppliedUsd);
79
+ payload.suppliedCollateralUsd = getAssetsTotal(usedAssets, ({ isSupplied, collateral }: { isSupplied: boolean, collateral: string }) => isSupplied && collateral, ({ suppliedUsd }: { suppliedUsd: string }) => suppliedUsd);
80
+ payload.borrowLimitUsd = getAssetsTotal(
81
+ usedAssets,
82
+ ({ isSupplied, collateral }: { isSupplied: boolean, collateral: string }) => isSupplied && collateral,
83
+ ({ symbol, suppliedUsd, reserveId }: { symbol: string, suppliedUsd: string, reserveId: number }) => new Dec(suppliedUsd).mul(aaveV4GetCollateralFactor(assetsData[`${symbol}-${reserveId}`], usedAssets[`${symbol}-${reserveId}`], useUserCollateralFactor)),
84
+ );
85
+ payload.liquidationLimitUsd = payload.borrowLimitUsd;
86
+ payload.borrowedUsd = getAssetsTotal(usedAssets, ({ isBorrowed }: { isBorrowed: boolean }) => isBorrowed, ({ borrowedUsd }: { borrowedUsd: string }) => borrowedUsd);
87
+ payload.drawnUsd = getAssetsTotal(usedAssets, ({ isBorrowed }: { isBorrowed: boolean }) => isBorrowed, ({ drawnUsd }: { drawnUsd: string }) => drawnUsd);
88
+ payload.premiumUsd = getAssetsTotal(usedAssets, ({ isBorrowed }: { isBorrowed: boolean }) => isBorrowed, ({ premiumUsd }: { premiumUsd: string }) => premiumUsd);
89
+ const leftToBorrowUsd = new Dec(payload.borrowLimitUsd).sub(payload.borrowedUsd);
90
+ payload.leftToBorrowUsd = leftToBorrowUsd.lte('0') ? '0' : leftToBorrowUsd.toString();
91
+ payload.ratio = +payload.suppliedUsd ? new Dec(payload.borrowLimitUsd).div(payload.borrowedUsd).mul(100).toString() : '0';
92
+ payload.collRatio = +payload.suppliedUsd ? new Dec(payload.suppliedCollateralUsd).div(payload.borrowedUsd).mul(100).toString() : '0';
93
+ payload.liqRatio = new Dec(payload.borrowLimitUsd).div(payload.liquidationLimitUsd).toString();
94
+ payload.liqPercent = new Dec(payload.borrowLimitUsd).div(payload.liquidationLimitUsd).mul(100).toString();
95
+ const { leveragedType, leveragedAsset } = isLeveragedPosAaveV4(usedAssets);
96
+ payload.leveragedType = leveragedType;
97
+ payload.leveragedAsset = leveragedAsset;
98
+ payload.liquidationPrice = '';
99
+ if (leveragedType !== '') {
100
+ const leveragedAssetData = assetsData[leveragedAsset];
101
+ let assetPrice = leveragedAssetData?.price || '0';
102
+ if (leveragedType === LeverageType.VolatilePair) {
103
+ const borrowedAsset = (Object.values(usedAssets) as AaveV4UsedReserveAsset[]).find(({ borrowedUsd }: { borrowedUsd: string }) => +borrowedUsd > 0);
104
+ const borrowedAssetPrice = assetsData[`${borrowedAsset!.symbol}-${borrowedAsset!.reserveId}`].price;
105
+ const leveragedAssetPrice = assetsData[leveragedAsset].price;
106
+ const isReverse = new Dec(leveragedAssetPrice).lt(borrowedAssetPrice);
107
+ if (isReverse) {
108
+ payload.leveragedType = LeverageType.VolatilePairReverse;
109
+ payload.currentVolatilePairRatio = new Dec(borrowedAssetPrice).div(leveragedAssetPrice).toDP(18).toString();
110
+ assetPrice = new Dec(borrowedAssetPrice).div(assetPrice).toString();
111
+ } else {
112
+ assetPrice = new Dec(assetPrice).div(borrowedAssetPrice).toString();
113
+ payload.currentVolatilePairRatio = new Dec(leveragedAssetPrice).div(borrowedAssetPrice).toDP(18).toString();
114
+ }
115
+ }
116
+ payload.liquidationPrice = calcLeverageLiqPrice(payload.leveragedType, assetPrice, payload.borrowedUsd, payload.liquidationLimitUsd);
117
+ }
118
+ payload.minCollRatio = new Dec(payload.suppliedCollateralUsd).div(payload.borrowLimitUsd).mul(100).toString();
119
+ payload.collLiquidationRatio = new Dec(payload.suppliedCollateralUsd).div(payload.liquidationLimitUsd).mul(100).toString();
120
+ // payload.healthRatio = new Dec(payload.liquidationLimitUsd).div(payload.borrowedUsd).toDP(4).toString();
121
+ payload.minHealthRatio = new Dec(payload.liquidationLimitUsd).div(payload.borrowLimitUsd).toDP(4).toString();
122
+
123
+ // TODO: Re-implement netApy calculation
124
+ // const { netApy, incentiveUsd, totalInterestUsd } = calculateNetApy({
125
+ // usedAssets,
126
+ // assetsData,
127
+ // optionalData: { healthRatio: payload.healthRatio },
128
+ // });
129
+ payload.netApy = '0';
130
+ payload.incentiveUsd = '0';
131
+ payload.totalInterestUsd = '0';
132
+ return payload;
133
+ };
@@ -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';
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,
@@ -20,7 +20,7 @@ export const aaveV3AssetsDefaultMarketBase = ['ETH', 'cbETH', 'USDbC', 'wstETH',
20
20
 
21
21
  export const aaveV3AssetsDefaultMarketLinea = ['ETH', 'USDC', 'weETH', 'ezETH', 'USDT', 'wstETH', 'wrsETH', 'WBTC', 'mUSD'];
22
22
 
23
- export const aaveV3AssetsDefaultMarketPlasma = ['ETH', 'USDT', 'sUSDe', 'USDe', 'weETH', 'XAUt', 'PT USDe Jan', 'PT sUSDe Jan', 'wrsETH', 'wstETH', 'syrupUSDT', 'XPL', 'PT USDe Apr', 'PT sUSDe Apr'];
23
+ export const aaveV3AssetsDefaultMarketPlasma = ['ETH', 'USDT', 'sUSDe', 'USDe', 'weETH', 'XAUt', 'PT USDe Jan', 'PT sUSDe Jan', 'wrsETH', 'wstETH', 'syrupUSDT', 'XPL', 'PT USDe Apr', 'PT sUSDe Apr', 'GHO'];
24
24
 
25
25
  // @dev Keep assets in array, do not assign directly, so we can parse it and edit it programmatically with `scripts/updateMarkets`
26
26
  export const aaveV3AssetsDefaultMarket = {
@@ -0,0 +1,149 @@
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: '0x3Ed2C9829FBCab6015E331a0352F8ae148217D70',
16
+ });
17
+
18
+ export const AAVE_V4_PLUS_HUB = (networkId: NetworkNumber): AaveV4HubInfo => ({
19
+ chainIds: [NetworkNumber.Eth],
20
+ label: 'Plus Hub',
21
+ value: AaveV4HubsType.AaveV4PlusHub,
22
+ address: '0xcb8C80026248f92c6DE735264c23c8e22922C562',
23
+ });
24
+
25
+ export const AAVE_V4_PRIME_HUB = (networkId: NetworkNumber): AaveV4HubInfo => ({
26
+ chainIds: [NetworkNumber.Eth],
27
+ label: 'Prime Hub',
28
+ value: AaveV4HubsType.AaveV4PrimeHub,
29
+ address: '0xea40581231Ca775e6A3d7c129cF231D292B85f20',
30
+ });
31
+
32
+ export const AaveV4Hubs = (networkId: NetworkNumber) => ({
33
+ [AaveV4HubsType.AaveV4CoreHub]: AAVE_V4_CORE_HUB(networkId),
34
+ [AaveV4HubsType.AaveV4PlusHub]: AAVE_V4_PLUS_HUB(networkId),
35
+ [AaveV4HubsType.AaveV4PrimeHub]: AAVE_V4_PRIME_HUB(networkId),
36
+ }) as const;
37
+
38
+ export const getAaveV4HubTypeInfo = (type: AaveV4HubsType, network?: NetworkNumber) => ({ ...AaveV4Hubs(network ?? NetworkNumber.Eth) }[type]);
39
+
40
+ export const getAaveV4HubByAddress = (networkId: NetworkNumber, address: string): AaveV4HubInfo | undefined => Object.values(AaveV4Hubs(networkId)).find(
41
+ hub => hub.address.toLowerCase() === address.toLowerCase(),
42
+ );
43
+
44
+ // SPOKES
45
+
46
+ export const AAVE_V4_BLUECHIP_SPOKE = (networkId: NetworkNumber): AaveV4SpokeInfo => ({
47
+ chainIds: [NetworkNumber.Eth],
48
+ label: 'Bluechip Spoke',
49
+ value: AaveV4SpokesType.AaveV4BluechipSpoke,
50
+ url: 'bluechip',
51
+ address: '0x637F9E189332a2821e5B046E2d7EEFae2405d6c5',
52
+ hubs: [
53
+ AAVE_V4_CORE_HUB(NetworkNumber.Eth).address,
54
+ AAVE_V4_PLUS_HUB(NetworkNumber.Eth).address,
55
+ AAVE_V4_PRIME_HUB(NetworkNumber.Eth).address,
56
+ ],
57
+ });
58
+
59
+ export const AAVE_V4_ETHENA_SPOKE = (networkId: NetworkNumber): AaveV4SpokeInfo => ({
60
+ chainIds: [NetworkNumber.Eth],
61
+ label: 'Ethena Spoke',
62
+ value: AaveV4SpokesType.AaveV4EthenaSpoke,
63
+ url: 'ethena',
64
+ address: '0x4054a9EbfcdB692599a8dF61eb0b3484F2d279D4',
65
+ hubs: [
66
+ AAVE_V4_CORE_HUB(NetworkNumber.Eth).address,
67
+ AAVE_V4_PLUS_HUB(NetworkNumber.Eth).address,
68
+ AAVE_V4_PRIME_HUB(NetworkNumber.Eth).address,
69
+ ],
70
+ });
71
+
72
+ export const AAVE_V4_ETHERFI_SPOKE = (networkId: NetworkNumber): AaveV4SpokeInfo => ({
73
+ chainIds: [NetworkNumber.Eth],
74
+ label: 'Etherfi Spoke',
75
+ value: AaveV4SpokesType.AaveV4EtherfiSpoke,
76
+ url: 'etherfi',
77
+ address: '0x4054a9EbfcdB692599a8dF61eb0b3484F2d279D4',
78
+ hubs: [
79
+ AAVE_V4_CORE_HUB(NetworkNumber.Eth).address,
80
+ AAVE_V4_PLUS_HUB(NetworkNumber.Eth).address,
81
+ AAVE_V4_PRIME_HUB(NetworkNumber.Eth).address,
82
+ ],
83
+ });
84
+
85
+ export const AAVE_V4_GOLD_SPOKE = (networkId: NetworkNumber): AaveV4SpokeInfo => ({
86
+ chainIds: [NetworkNumber.Eth],
87
+ label: 'Gold Spoke',
88
+ value: AaveV4SpokesType.AaveV4GoldSpoke,
89
+ url: 'gold',
90
+ address: '0x0DC7ccE912Afab8B49031A0A95DB74531741C2c4',
91
+ hubs: [
92
+ AAVE_V4_CORE_HUB(NetworkNumber.Eth).address,
93
+ AAVE_V4_PLUS_HUB(NetworkNumber.Eth).address,
94
+ AAVE_V4_PRIME_HUB(NetworkNumber.Eth).address,
95
+ ],
96
+ });
97
+
98
+ export const AAVE_V4_KELP_SPOKE = (networkId: NetworkNumber): AaveV4SpokeInfo => ({
99
+ chainIds: [NetworkNumber.Eth],
100
+ label: 'Kelp Spoke',
101
+ value: AaveV4SpokesType.AaveV4KelpSpoke,
102
+ url: 'kelp',
103
+ address: '0x8aC76d950a3D03F9E1d857b5AAFFdA3f86C1e9AA',
104
+ hubs: [
105
+ AAVE_V4_CORE_HUB(NetworkNumber.Eth).address,
106
+ AAVE_V4_PLUS_HUB(NetworkNumber.Eth).address,
107
+ AAVE_V4_PRIME_HUB(NetworkNumber.Eth).address,
108
+ ],
109
+ });
110
+
111
+ export const AAVE_V4_LIDO_SPOKE = (networkId: NetworkNumber): AaveV4SpokeInfo => ({
112
+ chainIds: [NetworkNumber.Eth],
113
+ label: 'Lido Spoke',
114
+ value: AaveV4SpokesType.AaveV4LidoSpoke,
115
+ url: 'lido',
116
+ address: '0x4D4a7b3Ce709b4362D7095a4A0105bDFDb5dA2a7',
117
+ hubs: [
118
+ AAVE_V4_CORE_HUB(NetworkNumber.Eth).address,
119
+ AAVE_V4_PLUS_HUB(NetworkNumber.Eth).address,
120
+ AAVE_V4_PRIME_HUB(NetworkNumber.Eth).address,
121
+ ],
122
+ });
123
+
124
+ export const AAVE_V4_MAIN_SPOKE = (networkId: NetworkNumber): AaveV4SpokeInfo => ({
125
+ chainIds: [NetworkNumber.Eth],
126
+ label: 'Main Spoke',
127
+ value: AaveV4SpokesType.AaveV4MainSpoke,
128
+ url: 'main',
129
+ address: '0x46539e9123A18c427e6b4DFF114c28CF405Cb023',
130
+ hubs: [
131
+ AAVE_V4_CORE_HUB(NetworkNumber.Eth).address,
132
+ AAVE_V4_PLUS_HUB(NetworkNumber.Eth).address,
133
+ AAVE_V4_PRIME_HUB(NetworkNumber.Eth).address,
134
+ ],
135
+ });
136
+
137
+ export const AaveV4Spokes = (networkId: NetworkNumber) => ({
138
+ [AaveV4SpokesType.AaveV4BluechipSpoke]: AAVE_V4_BLUECHIP_SPOKE(networkId),
139
+ [AaveV4SpokesType.AaveV4EthenaSpoke]: AAVE_V4_ETHENA_SPOKE(networkId),
140
+ [AaveV4SpokesType.AaveV4EtherfiSpoke]: AAVE_V4_ETHERFI_SPOKE(networkId),
141
+ [AaveV4SpokesType.AaveV4GoldSpoke]: AAVE_V4_GOLD_SPOKE(networkId),
142
+ [AaveV4SpokesType.AaveV4KelpSpoke]: AAVE_V4_KELP_SPOKE(networkId),
143
+ [AaveV4SpokesType.AaveV4LidoSpoke]: AAVE_V4_LIDO_SPOKE(networkId),
144
+ [AaveV4SpokesType.AaveV4MainSpoke]: AAVE_V4_MAIN_SPOKE(networkId),
145
+ }) as const;
146
+
147
+ export const getAaveV4SpokeTypeInfo = (type: AaveV4SpokesType, network?: NetworkNumber) => ({ ...AaveV4Spokes(network ?? NetworkNumber.Eth) }[type]);
148
+
149
+
@@ -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';