From 80704defacbea8899c9e3e9a8db6864ff1a4c2df Mon Sep 17 00:00:00 2001 From: Samarendra Gouda Date: Wed, 9 Oct 2024 03:51:15 +0530 Subject: [PATCH 1/8] fix: arbitrum resolver --- .../protocols/arbitrum/aave_v3/helpers.sol | 237 ++++++++++-------- .../protocols/arbitrum/aave_v3/interfaces.sol | 132 +++++----- contracts/protocols/arbitrum/aave_v3/main.sol | 38 ++- 3 files changed, 212 insertions(+), 195 deletions(-) diff --git a/contracts/protocols/arbitrum/aave_v3/helpers.sol b/contracts/protocols/arbitrum/aave_v3/helpers.sol index ca3abb81..6241e585 100644 --- a/contracts/protocols/arbitrum/aave_v3/helpers.sol +++ b/contracts/protocols/arbitrum/aave_v3/helpers.sol @@ -4,8 +4,6 @@ import "./interfaces.sol"; import { DSMath } from "../../../utils/dsmath.sol"; contract AaveV3Helper is DSMath { - // ----------------------- USING LATEST ADDRESSES ----------------------------- - /** *@dev Returns ethereum address */ @@ -21,21 +19,7 @@ contract AaveV3Helper is DSMath { } function getUiDataProvider() internal pure returns (address) { - return 0x3f960bB91e85Ae2dB561BDd01B515C5A5c65802b; //Arbitrum UiPoolDataProvider Address - } - - /** - *@dev Returns Pool AddressProvider Address - */ - function getPoolAddressProvider() internal pure returns (address) { - return 0xa97684ead0e402dC232d5A977953DF7ECBaB3CDb; //Arbitrum PoolAddressesProvider address - } - - /** - *@dev Returns Pool DataProvider Address - */ - function getPoolDataProvider() internal pure returns (address) { - return 0x69FA688f1Dc47d4B5d8029D5a35FB7a548310654; //Arbitrum PoolDataProvider address + return 0xE92cd6164CE7DC68e740765BC1f2a091B6CBc3e4; //Arbitrum UiPoolDataProvider Address } /** @@ -56,22 +40,15 @@ contract AaveV3Helper is DSMath { return 0xb56c2F0B653B2e0b10C9b928C8580Ac5Df02C7C7; //Arbitrum address } - function getUiIncetivesProvider() internal view returns (address) { + function getUiIncetivesProvider() internal pure returns (address) { return 0xEFdd7374551897B11a23Ec7b5694C713DFDa76f1; } - /** - *@dev Returns StableDebtToken Address - */ - function getStableDebtToken() internal pure returns (address) { - return 0x52A1CeB68Ee6b7B5D13E0376A1E0E4423A8cE26e; //Arbitrum address - } - function getChainLinkFeed() internal pure returns (address) { return 0x639Fe6ab55C921f74e7fac1ee960C0B6293ba612; } - function getRewardsController() internal view returns (address) { + function getRewardsController() internal pure returns (address) { return 0x929EC64c34a17401F460460D4B9390518E5B473e; } @@ -153,7 +130,6 @@ contract AaveV3Helper is DSMath { struct AaveV3Token { uint256 supplyCap; uint256 borrowCap; - uint256 eModeCategory; uint256 debtCeiling; uint256 debtCeilingDecimals; uint256 liquidationFee; @@ -194,10 +170,13 @@ contract AaveV3Helper is DSMath { uint256 priceInUsd; } - IPoolAddressesProvider internal provider = IPoolAddressesProvider(getPoolAddressProvider()); + struct PoolSpecificInfo { + IPoolAddressesProvider provider; + IPool pool; + IAaveProtocolDataProvider aaveData; + } + IAaveOracle internal aaveOracle = IAaveOracle(getAaveOracle()); - IAaveProtocolDataProvider internal aaveData = IAaveProtocolDataProvider(provider.getPoolDataProvider()); - IPool internal pool = IPool(provider.getPool()); IUiIncentiveDataProviderV3 internal uiIncentives = IUiIncentiveDataProviderV3(getUiIncetivesProvider()); IRewardsController internal rewardsCntr = IRewardsController(getRewardsController()); @@ -212,8 +191,15 @@ contract AaveV3Helper is DSMath { } } - function getIncentivesInfo(address user) internal view returns (ReserveIncentiveData[] memory incentives) { - AggregatedReserveIncentiveData[] memory _aggregateIncentive = uiIncentives.getReservesIncentivesData(provider); + function getIncentivesInfo( + address user, + address poolAddressProvider + ) internal view returns (ReserveIncentiveData[] memory incentives) { + PoolSpecificInfo memory poolInfo = getPoolSpecificInfo(poolAddressProvider); + + AggregatedReserveIncentiveData[] memory _aggregateIncentive = uiIncentives.getReservesIncentivesData( + poolInfo.provider + ); incentives = new ReserveIncentiveData[](_aggregateIncentive.length); for (uint256 i = 0; i < _aggregateIncentive.length; i++) { address[] memory rToken = new address[](1); @@ -248,7 +234,7 @@ contract AaveV3Helper is DSMath { } } - function getRewardInfo(RewardInfo[] memory rewards) internal view returns (RewardsInfo[] memory rewardData) { + function getRewardInfo(RewardInfo[] memory rewards) internal pure returns (RewardsInfo[] memory rewardData) { rewardData = new RewardsInfo[](rewards.length); for (uint256 i = 0; i < rewards.length; i++) { rewardData[i] = RewardsInfo( @@ -261,28 +247,26 @@ contract AaveV3Helper is DSMath { } } - function getTokensPrices(uint256 basePriceInUSD, address[] memory tokens) - internal - view - returns (TokenPrice[] memory tokenPrices, uint256 ethPrice) - { + function getTokensPrices( + uint256 basePriceInUSD, + address[] memory tokens + ) internal view returns (TokenPrice[] memory tokenPrices, uint256 ethPrice) { uint256[] memory _tokenPrices = aaveOracle.getAssetsPrices(tokens); tokenPrices = new TokenPrice[](_tokenPrices.length); ethPrice = uint256(AggregatorV3Interface(getChainLinkFeed()).latestAnswer()); for (uint256 i = 0; i < _tokenPrices.length; i++) { tokenPrices[i] = TokenPrice( - (_tokenPrices[i] * basePriceInUSD * 10**10) / ethPrice, - wmul(_tokenPrices[i] * 10**10, basePriceInUSD * 10**10) + (_tokenPrices[i] * basePriceInUSD * 10 ** 10) / ethPrice, + wmul(_tokenPrices[i] * 10 ** 10, basePriceInUSD * 10 ** 10) ); } } - function getEmodePrices(address priceOracleAddr, address[] memory tokens) - internal - view - returns (uint256[] memory tokenPrices) - { + function getEmodePrices( + address priceOracleAddr, + address[] memory tokens + ) internal view returns (uint256[] memory tokenPrices) { tokenPrices = IPriceOracle(priceOracleAddr).getAssetsPrices(tokens); // tokenPrices = new uint256[](tokens.length); // for (uint256 i = 0; i < tokens.length; i++) { @@ -290,20 +274,34 @@ contract AaveV3Helper is DSMath { // } } - function getPendingRewards(address user, address[] memory _tokens) internal view returns (uint256 rewards) { + function getPendingRewards( + address user, + address[] memory _tokens, + address poolAddressProvider + ) internal view returns (uint256 rewards) { + PoolSpecificInfo memory poolInfo = getPoolSpecificInfo(poolAddressProvider); + uint256 arrLength = 2 * _tokens.length; address[] memory _atokens = new address[](arrLength); for (uint256 i = 0; i < _tokens.length; i++) { - (_atokens[2 * i], , _atokens[2 * i + 1]) = aaveData.getReserveTokensAddresses(_tokens[i]); + (_atokens[2 * i], , _atokens[2 * i + 1]) = poolInfo.aaveData.getReserveTokensAddresses(_tokens[i]); } rewards = IAaveIncentivesController(getAaveIncentivesAddress()).getRewardsBalance(_atokens, user); } - function getIsolationDebt(address token) internal view returns (uint256 isolationDebt) { - isolationDebt = uint256(pool.getReserveData(token).isolationModeTotalDebt); + function getIsolationDebt( + address token, + address poolAddressProvider + ) internal view returns (uint256 isolationDebt) { + PoolSpecificInfo memory poolInfo = getPoolSpecificInfo(poolAddressProvider); + isolationDebt = uint256(poolInfo.pool.getReserveData(token).isolationModeTotalDebt); } - function getUserData(address user) internal view returns (AaveV3UserData memory userData) { + function getUserData( + address user, + address poolAddressProvider + ) internal view returns (AaveV3UserData memory userData) { + PoolSpecificInfo memory poolInfo = getPoolSpecificInfo(poolAddressProvider); ( userData.totalCollateralBase, userData.totalBorrowsBase, @@ -311,14 +309,14 @@ contract AaveV3Helper is DSMath { userData.currentLiquidationThreshold, userData.ltv, userData.healthFactor - ) = pool.getUserAccountData(user); + ) = poolInfo.pool.getUserAccountData(user); userData.base = getBaseCurrencyDetails(); - userData.eModeId = pool.getUserEMode(user); + userData.eModeId = poolInfo.pool.getUserEMode(user); // userData.pendingRewards = getPendingRewards(tokens, user); } - function getFlags(address token) internal view returns (Flags memory flag) { + function getFlags(address token, IAaveProtocolDataProvider aaveData) internal view returns (Flags memory flag) { ( , , @@ -333,86 +331,96 @@ contract AaveV3Helper is DSMath { ) = aaveData.getReserveConfigurationData(token); } - function getIsolationBorrowStatus(address token) internal view returns (bool iBorrowStatus) { + function getIsolationBorrowStatus(address token, IPool pool) internal view returns (bool iBorrowStatus) { ReserveConfigurationMap memory self = (pool.getReserveData(token)).configuration; uint256 BORROWABLE_IN_ISOLATION_MASK = 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDFFFFFFFFFFFFFFF; return (self.data & ~BORROWABLE_IN_ISOLATION_MASK) != 0; } - function getV3Token(address token) internal view returns (AaveV3Token memory tokenData) { + function getV3Token( + address token, + IPool pool, + IAaveProtocolDataProvider aaveData + ) internal view returns (AaveV3Token memory tokenData) { ( (tokenData.borrowCap, tokenData.supplyCap), - tokenData.eModeCategory, tokenData.debtCeiling, tokenData.debtCeilingDecimals, tokenData.liquidationFee, tokenData.isPaused ) = ( aaveData.getReserveCaps(token), - aaveData.getReserveEModeCategory(token), aaveData.getDebtCeiling(token), aaveData.getDebtCeilingDecimals(), aaveData.getLiquidationProtocolFee(token), aaveData.getPaused(token) ); { - (tokenData.isolationBorrowEnabled) = getIsolationBorrowStatus(token); + (tokenData.isolationBorrowEnabled) = getIsolationBorrowStatus(token, pool); } // (tokenData.isolationModeTotalDebt) = getIsolationDebt(token); } - function getEmodeCategoryData(uint8 id, address[] memory tokens) - external - view - returns (EmodeData memory eModeData) - { - EModeCategory memory data_ = pool.getEModeCategoryData(id); + function getEmodeCategoryData( + uint8 id, + address poolAddressProvider + ) external view returns (EmodeData memory eModeData) { + PoolSpecificInfo memory poolInfo = getPoolSpecificInfo(poolAddressProvider); + EModeCollateralConfig memory config_ = poolInfo.pool.getEModeCategoryCollateralConfig(id); + string memory label = poolInfo.pool.getEModeCategoryLabel(id); + uint128 isCollateralBitmap = poolInfo.pool.getEModeCategoryCollateralBitmap(id); + uint128 isBorrowableBitmap = poolInfo.pool.getEModeCategoryBorrowableBitmap(id); + + EModeCategory memory data_ = EModeCategory( + config_.ltv, + config_.liquidationThreshold, + config_.liquidationBonus, + label, + isCollateralBitmap, + isBorrowableBitmap + ); { eModeData.data = data_; // eModeData.price = getEmodePrices(data_.priceSource, tokens); } } - function reserveConfig(address token) - internal - view - returns ( - uint256 decimals, - uint256 ltv, - uint256 threshold, - uint256 reserveFactor - ) - { + function reserveConfig( + address token, + IAaveProtocolDataProvider aaveData + ) internal view returns (uint256 decimals, uint256 ltv, uint256 threshold, uint256 reserveFactor) { (decimals, ltv, threshold, , reserveFactor, , , , , ) = aaveData.getReserveConfigurationData(token); } - function resData(address token) - internal - view - returns ( - uint256 availableLiquidity, - uint256 totalStableDebt, - uint256 totalVariableDebt - ) - { + function resData( + address token, + IAaveProtocolDataProvider aaveData + ) internal view returns (uint256 availableLiquidity, uint256 totalStableDebt, uint256 totalVariableDebt) { (, , availableLiquidity, totalStableDebt, totalVariableDebt, , , , , , , ) = aaveData.getReserveData(token); } - function getAaveTokensData(address token) internal view returns (ReserveAddresses memory reserve) { + function getAaveTokensData( + address token, + address poolAddressProvider + ) internal view returns (ReserveAddresses memory reserve) { + PoolSpecificInfo memory poolInfo = getPoolSpecificInfo(poolAddressProvider); ( reserve.aToken.tokenAddress, reserve.stableDebtToken.tokenAddress, reserve.variableDebtToken.tokenAddress - ) = aaveData.getReserveTokensAddresses(token); + ) = poolInfo.aaveData.getReserveTokensAddresses(token); reserve.aToken.symbol = IERC20Detailed(reserve.aToken.tokenAddress).symbol(); - reserve.stableDebtToken.symbol = IERC20Detailed(reserve.stableDebtToken.tokenAddress).symbol(); reserve.variableDebtToken.symbol = IERC20Detailed(reserve.variableDebtToken.tokenAddress).symbol(); reserve.aToken.decimals = IERC20Detailed(reserve.aToken.tokenAddress).decimals(); - reserve.stableDebtToken.decimals = IERC20Detailed(reserve.stableDebtToken.tokenAddress).decimals(); reserve.variableDebtToken.decimals = IERC20Detailed(reserve.variableDebtToken.tokenAddress).decimals(); } - function userCollateralData(address token) internal view returns (AaveV3TokenData memory aaveTokenData) { + function userCollateralData( + address token, + address poolAddressProvider + ) internal view returns (AaveV3TokenData memory aaveTokenData) { + PoolSpecificInfo memory poolInfo = getPoolSpecificInfo(poolAddressProvider); + aaveTokenData.asset = token; aaveTokenData.symbol = IERC20Detailed(token).symbol(); ( @@ -420,20 +428,20 @@ contract AaveV3Helper is DSMath { aaveTokenData.ltv, aaveTokenData.threshold, aaveTokenData.reserveFactor - ) = reserveConfig(token); + ) = reserveConfig(token, poolInfo.aaveData); { ( aaveTokenData.availableLiquidity, aaveTokenData.totalStableDebt, aaveTokenData.totalVariableDebt - ) = resData(token); + ) = resData(token, poolInfo.aaveData); } - aaveTokenData.token = getV3Token(token); + aaveTokenData.token = getV3Token(token, poolInfo.pool, poolInfo.aaveData); // aaveTokenData.tokenPrice = assetPrice; - aaveTokenData.reserves = getAaveTokensData(token); + aaveTokenData.reserves = getAaveTokensData(token, poolAddressProvider); //-------------INCENTIVE DETAILS--------------- @@ -448,13 +456,13 @@ contract AaveV3Helper is DSMath { // ); } - function getUserTokenData(address user, address token) - internal - view - returns (AaveV3UserTokenData memory tokenData) - { - uint256 basePrice = IPriceOracle(IPoolAddressesProvider(getPoolAddressProvider()).getPriceOracle()) - .getAssetPrice(token); + function getUserTokenData( + address user, + address token, + address poolAddressProvider + ) internal view returns (AaveV3UserTokenData memory tokenData) { + PoolSpecificInfo memory poolInfo = getPoolSpecificInfo(poolAddressProvider); + uint256 basePrice = IPriceOracle(poolInfo.provider.getPriceOracle()).getAssetPrice(token); tokenData.price = basePrice; ( tokenData.supplyBalance, @@ -466,13 +474,13 @@ contract AaveV3Helper is DSMath { tokenData.supplyRate, , tokenData.isCollateral - ) = aaveData.getUserReserveData(token, user); + ) = poolInfo.aaveData.getUserReserveData(token, user); { - tokenData.flag = getFlags(token); - (, , , , , , tokenData.variableBorrowRate, tokenData.stableBorrowRate, , , , ) = aaveData.getReserveData( - token - ); + tokenData.flag = getFlags(token, poolInfo.aaveData); + (, , , , , , tokenData.variableBorrowRate, tokenData.stableBorrowRate, , , , ) = poolInfo + .aaveData + .getReserveData(token); } } @@ -480,7 +488,7 @@ contract AaveV3Helper is DSMath { ethPrice = uint256(AggregatorV3Interface(getChainLinkFeed()).latestAnswer()); } - function getPrices(bytes memory data) internal view returns (uint256) { + function getPrices(bytes memory data) internal pure returns (uint256) { (, BaseCurrencyInfo memory baseCurrency) = abi.decode(data, (AggregatedReserveData[], BaseCurrencyInfo)); return uint256(baseCurrency.marketReferenceCurrencyPriceInUsd); } @@ -503,8 +511,9 @@ contract AaveV3Helper is DSMath { // } } - function getList() public view returns (address[] memory data) { - data = pool.getReservesList(); + function getList(address poolAddressProvider) public view returns (address[] memory data) { + PoolSpecificInfo memory poolInfo = getPoolSpecificInfo(poolAddressProvider); + data = poolInfo.pool.getReservesList(); } function isUsingAsCollateralOrBorrowing(uint256 self, uint256 reserveIndex) public pure returns (bool) { @@ -522,7 +531,17 @@ contract AaveV3Helper is DSMath { return (self >> (reserveIndex * 2)) & 1 != 0; } - function getConfig(address user) public view returns (UserConfigurationMap memory data) { - data = pool.getUserConfiguration(user); + function getConfig( + address user, + address poolAddressProvider + ) public view returns (UserConfigurationMap memory data) { + PoolSpecificInfo memory poolInfo = getPoolSpecificInfo(poolAddressProvider); + data = poolInfo.pool.getUserConfiguration(user); + } + + function getPoolSpecificInfo(address poolAddressProvider) internal view returns (PoolSpecificInfo memory poolInfo) { + poolInfo.provider = IPoolAddressesProvider(poolAddressProvider); + poolInfo.pool = IPool(poolInfo.provider.getPool()); + poolInfo.aaveData = IAaveProtocolDataProvider(poolInfo.provider.getPoolDataProvider()); } } diff --git a/contracts/protocols/arbitrum/aave_v3/interfaces.sol b/contracts/protocols/arbitrum/aave_v3/interfaces.sol index 03a838a5..2fd2562d 100644 --- a/contracts/protocols/arbitrum/aave_v3/interfaces.sol +++ b/contracts/protocols/arbitrum/aave_v3/interfaces.sol @@ -28,8 +28,15 @@ struct EModeCategory { uint16 liquidationThreshold; uint16 liquidationBonus; // each eMode category may or may not have a custom oracle to override the individual assets price oracles - address priceSource; string label; + uint128 isCollateralBitmap; + uint128 isBorrowableBitmap; +} + +struct EModeCollateralConfig { + uint16 ltv; + uint16 liquidationThreshold; + uint16 liquidationBonus; } struct ReserveConfigurationMap { @@ -146,13 +153,16 @@ struct AggregatedReserveData { uint16 eModeLtv; uint16 eModeLiquidationThreshold; uint16 eModeLiquidationBonus; - address eModePriceSource; + uint128 isCollateralBitmap; + uint128 isBorrowableBitmap; string eModeLabel; bool borrowableInIsolation; } interface IPool { - function getUserAccountData(address user) + function getUserAccountData( + address user + ) external view returns ( @@ -164,12 +174,17 @@ interface IPool { uint256 healthFactor ); - function getEModeCategoryData(uint8 id) external view returns (EModeCategory memory); + // 3.2 Updated Interface for eMode + function getEModeCategoryCollateralConfig(uint8 id) external view returns (EModeCollateralConfig memory); + function getEModeCategoryLabel(uint8 id) external view returns (string memory); + function getEModeCategoryCollateralBitmap(uint8 id) external view returns (uint128); + function getEModeCategoryBorrowableBitmap(uint8 id) external view returns (uint128); + //@return emode id of the user function getUserEMode(address user) external view returns (uint256); - function getReservesList() external view virtual returns (address[] memory); + function getReservesList() external view returns (address[] memory); function getUserConfiguration(address user) external view returns (UserConfigurationMap memory); @@ -201,14 +216,7 @@ interface IAaveIncentivesController { // @dev Returns the configuration of the distribution for a certain asset // @return The asset index, the emission per second and the last updated timestamp - function assets(address asset) - external - view - returns ( - uint128, - uint128, - uint256 - ); + function assets(address asset) external view returns (uint128, uint128, uint256); } interface IAaveOracle is IPriceOracleGetter { @@ -235,7 +243,9 @@ interface IPoolAddressesProvider { interface IPoolDataProvider { // @notice Returns the reserve data - function getReserveData(address asset) + function getReserveData( + address asset + ) external view returns ( @@ -267,7 +277,9 @@ interface IStableDebtToken { } interface IAaveProtocolDataProvider is IPoolDataProvider { - function getReserveConfigurationData(address asset) + function getReserveConfigurationData( + address asset + ) external view returns ( @@ -287,8 +299,6 @@ interface IAaveProtocolDataProvider is IPoolDataProvider { function getLiquidationProtocolFee(address asset) external view returns (uint256); - function getReserveEModeCategory(address asset) external view returns (uint256); - function getReserveCaps(address asset) external view returns (uint256 borrowCap, uint256 supplyCap); // @notice Returns the debt ceiling of the reserve @@ -299,7 +309,9 @@ interface IAaveProtocolDataProvider is IPoolDataProvider { function getATokenTotalSupply(address asset) external view returns (uint256); - function getReserveData(address asset) + function getReserveData( + address asset + ) external view override @@ -318,7 +330,10 @@ interface IAaveProtocolDataProvider is IPoolDataProvider { uint40 lastUpdateTimestamp ); - function getUserReserveData(address asset, address user) + function getUserReserveData( + address asset, + address user + ) external view returns ( @@ -333,14 +348,9 @@ interface IAaveProtocolDataProvider is IPoolDataProvider { bool usageAsCollateralEnabled ); - function getReserveTokensAddresses(address asset) - external - view - returns ( - address aTokenAddress, - address stableDebtTokenAddress, - address variableDebtTokenAddress - ); + function getReserveTokensAddresses( + address asset + ) external view returns (address aTokenAddress, address stableDebtTokenAddress, address variableDebtTokenAddress); } //chainlink price feed @@ -350,13 +360,7 @@ interface AggregatorV3Interface { function latestRoundData() external view - returns ( - uint80 roundId, - int256 answer, - uint256 startedAt, - uint256 updatedAt, - uint80 answeredInRound - ); + returns (uint80 roundId, int256 answer, uint256 startedAt, uint256 updatedAt, uint80 answeredInRound); function latestAnswer() external view returns (int256); } @@ -368,29 +372,24 @@ interface IERC20Detailed { } interface IUiIncentiveDataProviderV3 { - function getReservesIncentivesData(IPoolAddressesProvider provider) - external - view - returns (AggregatedReserveIncentiveData[] memory); + function getReservesIncentivesData( + IPoolAddressesProvider provider + ) external view returns (AggregatedReserveIncentiveData[] memory); - function getUserReservesIncentivesData(IPoolAddressesProvider provider, address user) - external - view - returns (UserReserveIncentiveData[] memory); + function getUserReservesIncentivesData( + IPoolAddressesProvider provider, + address user + ) external view returns (UserReserveIncentiveData[] memory); // generic method with full data - function getFullReservesIncentiveData(IPoolAddressesProvider provider, address user) - external - view - returns (AggregatedReserveIncentiveData[] memory, UserReserveIncentiveData[] memory); + function getFullReservesIncentiveData( + IPoolAddressesProvider provider, + address user + ) external view returns (AggregatedReserveIncentiveData[] memory, UserReserveIncentiveData[] memory); } interface IRewardsDistributor { - function getUserAssetData( - address user, - address asset, - address reward - ) external view returns (uint256); + function getUserAssetData(address user, address asset, address reward) external view returns (uint256); /** * @dev Returns the configuration of the distribution for a certain asset @@ -398,15 +397,7 @@ interface IRewardsDistributor { * @param reward The reward token of the incentivized asset * @return The asset index, the emission per second, the last updated timestamp and the distribution end timestamp **/ - function getRewardsData(address asset, address reward) - external - view - returns ( - uint256, - uint256, - uint256, - uint256 - ); + function getRewardsData(address asset, address reward) external view returns (uint256, uint256, uint256, uint256); /** * @dev Returns the list of available reward token addresses of an incentivized asset @@ -436,11 +427,7 @@ interface IRewardsDistributor { * @param reward The address of the reward token * @return The rewards amount **/ - function getUserRewards( - address[] calldata assets, - address user, - address reward - ) external view returns (uint256); + function getUserRewards(address[] calldata assets, address user, address reward) external view returns (uint256); /** * @dev Returns a list all rewards of an user, including already accrued and unrealized claimable rewards @@ -448,10 +435,10 @@ interface IRewardsDistributor { * @param user The address of the user * @return The function returns a Tuple of rewards list and the unclaimed rewards list **/ - function getAllUserRewards(address[] calldata assets, address user) - external - view - returns (address[] memory, uint256[] memory); + function getAllUserRewards( + address[] calldata assets, + address user + ) external view returns (address[] memory, uint256[] memory); /** * @dev Returns the decimals of an asset to calculate the distribution delta @@ -473,8 +460,7 @@ interface IRewardsController is IRewardsDistributor { } interface IUiPoolDataProviderV3 { - function getReservesData(IPoolAddressesProvider provider) - external - view - returns (AggregatedReserveData[] memory, BaseCurrencyInfo memory); + function getReservesData( + IPoolAddressesProvider provider + ) external view returns (AggregatedReserveData[] memory, BaseCurrencyInfo memory); } diff --git a/contracts/protocols/arbitrum/aave_v3/main.sol b/contracts/protocols/arbitrum/aave_v3/main.sol index 52e5a2eb..a50aa8ba 100644 --- a/contracts/protocols/arbitrum/aave_v3/main.sol +++ b/contracts/protocols/arbitrum/aave_v3/main.sol @@ -13,12 +13,17 @@ contract AaveV3Resolver is AaveV3Helper { *@notice get position of user, including details of user's overall position, rewards and assets owned for the tokens passed. *@param user The address of the user whose details are needed. *@param tokens Array of token addresses corresponding to which user details are needed. + *@return AaveV3UserData user's overall position (e.g. total collateral, total borrows, e-mode id etc.). *@return AaveV3UserTokenData details of user's tokens for the tokens passed (e.g. supplied amount, borrowed amount, supply rate etc.). *@return AaveV3TokenData details of tokens (e.g. symbol, decimals, ltv etc.). *@return ReserveIncentiveData details of user's rewards corresponding to the tokens passed. */ - function getPosition(address user, address[] memory tokens) + function getPosition( + address user, + address[] memory tokens, + address poolAddressProvider + ) public view returns ( @@ -35,18 +40,18 @@ contract AaveV3Resolver is AaveV3Helper { _tokens[i] = tokens[i] == getEthAddr() ? getWethAddr() : tokens[i]; } - AaveV3UserData memory userDetails = getUserData(user); + AaveV3UserData memory userDetails = getUserData(user, poolAddressProvider); // (TokenPrice[] memory tokenPrices, ) = getTokensPrices(userDetails.base.baseInUSD, _tokens); AaveV3UserTokenData[] memory tokensData = new AaveV3UserTokenData[](length); AaveV3TokenData[] memory collData = new AaveV3TokenData[](length); for (uint256 i = 0; i < length; i++) { - tokensData[i] = getUserTokenData(user, _tokens[i]); - collData[i] = userCollateralData(_tokens[i]); + tokensData[i] = getUserTokenData(user, _tokens[i], poolAddressProvider); + collData[i] = userCollateralData(_tokens[i], poolAddressProvider); } - return (userDetails, tokensData, collData, getIncentivesInfo(user)); + return (userDetails, tokensData, collData, getIncentivesInfo(user, poolAddressProvider)); } /** @@ -58,7 +63,10 @@ contract AaveV3Resolver is AaveV3Helper { *@return AaveV3TokenData details of tokens (e.g. symbol, decimals, ltv etc.). *@return ReserveIncentiveData details of user's rewards corresponding to the tokens in the market. */ - function getPositionAll(address user) + function getPositionAll( + address user, + address poolAddressProvider + ) public view returns ( @@ -68,7 +76,8 @@ contract AaveV3Resolver is AaveV3Helper { ReserveIncentiveData[] memory ) { - return getPosition(user, getList()); + address[] memory tokens = getList(poolAddressProvider); + return getPosition(user, tokens, poolAddressProvider); } /** @@ -78,9 +87,12 @@ contract AaveV3Resolver is AaveV3Helper { *@return collateral array with an element as true if the corresponding token is used as collateral by the user, false otherwise. *@return borrowed array with an element as true if the corresponding token is borrowed by the user, false otherwise. */ - function getConfiguration(address user) public view returns (bool[] memory collateral, bool[] memory borrowed) { - uint256 data = getConfig(user).data; - address[] memory reserveIndex = getList(); + function getConfiguration( + address user, + address poolAddressProvider + ) public view returns (bool[] memory collateral, bool[] memory borrowed) { + uint256 data = getConfig(user, poolAddressProvider).data; + address[] memory reserveIndex = getList(poolAddressProvider); collateral = new bool[](reserveIndex.length); borrowed = new bool[](reserveIndex.length); @@ -98,11 +110,11 @@ contract AaveV3Resolver is AaveV3Helper { *@notice get list of all tokens available in the market. *@return data array of token addresses available in the market. */ - function getReservesList() public view returns (address[] memory data) { - data = getList(); + function getReservesList(address poolAddressProvider) public view returns (address[] memory data) { + data = getList(poolAddressProvider); } } contract InstaAaveV3ResolverArbitrum is AaveV3Resolver { - string public constant name = "AaveV3-Resolver-v1.0"; + string public constant name = "AaveV3-Resolver-v1.1"; } From fa948fadae2aae94cfe33e93fa7ccf2ed583c76e Mon Sep 17 00:00:00 2001 From: Samarendra Gouda Date: Wed, 9 Oct 2024 03:54:07 +0530 Subject: [PATCH 2/8] fix: address --- contracts/protocols/arbitrum/aave_v3/helpers.sol | 6 +----- contracts/protocols/arbitrum/aave_v3/main.sol | 1 - 2 files changed, 1 insertion(+), 6 deletions(-) diff --git a/contracts/protocols/arbitrum/aave_v3/helpers.sol b/contracts/protocols/arbitrum/aave_v3/helpers.sol index 6241e585..62401990 100644 --- a/contracts/protocols/arbitrum/aave_v3/helpers.sol +++ b/contracts/protocols/arbitrum/aave_v3/helpers.sol @@ -18,10 +18,6 @@ contract AaveV3Helper is DSMath { return 0x82aF49447D8a07e3bd95BD0d56f35241523fBab1; //Arbitrum WETH Address } - function getUiDataProvider() internal pure returns (address) { - return 0xE92cd6164CE7DC68e740765BC1f2a091B6CBc3e4; //Arbitrum UiPoolDataProvider Address - } - /** *@dev Returns Aave Data Provider Address */ @@ -41,7 +37,7 @@ contract AaveV3Helper is DSMath { } function getUiIncetivesProvider() internal pure returns (address) { - return 0xEFdd7374551897B11a23Ec7b5694C713DFDa76f1; + return 0xE92cd6164CE7DC68e740765BC1f2a091B6CBc3e4; } function getChainLinkFeed() internal pure returns (address) { diff --git a/contracts/protocols/arbitrum/aave_v3/main.sol b/contracts/protocols/arbitrum/aave_v3/main.sol index a50aa8ba..1e3a3a75 100644 --- a/contracts/protocols/arbitrum/aave_v3/main.sol +++ b/contracts/protocols/arbitrum/aave_v3/main.sol @@ -13,7 +13,6 @@ contract AaveV3Resolver is AaveV3Helper { *@notice get position of user, including details of user's overall position, rewards and assets owned for the tokens passed. *@param user The address of the user whose details are needed. *@param tokens Array of token addresses corresponding to which user details are needed. - *@return AaveV3UserData user's overall position (e.g. total collateral, total borrows, e-mode id etc.). *@return AaveV3UserTokenData details of user's tokens for the tokens passed (e.g. supplied amount, borrowed amount, supply rate etc.). *@return AaveV3TokenData details of tokens (e.g. symbol, decimals, ltv etc.). From 55f71a86fa27f941ad18dc75ab5ab4eb6825e733 Mon Sep 17 00:00:00 2001 From: Samarendra Gouda Date: Wed, 9 Oct 2024 04:19:03 +0530 Subject: [PATCH 3/8] fix: update test --- test/arbitrum/aave_v3.test.ts | 38 +++++++++++++++++++++++------------ 1 file changed, 25 insertions(+), 13 deletions(-) diff --git a/test/arbitrum/aave_v3.test.ts b/test/arbitrum/aave_v3.test.ts index d0d36cc0..9706d2e1 100644 --- a/test/arbitrum/aave_v3.test.ts +++ b/test/arbitrum/aave_v3.test.ts @@ -1,15 +1,15 @@ import { SignerWithAddress } from "@nomiclabs/hardhat-ethers/signers"; +import hre from "hardhat"; import { expect } from "chai"; import { formatUnits } from "ethers/lib/utils"; import { ethers } from "hardhat"; import { InstaAaveV3ResolverArbitrum, InstaAaveV3ResolverArbitrum__factory } from "../../typechain"; import { Tokens } from "../consts"; -import BigNumber from "bignumber.js"; describe("Aave", () => { + const POOL_ADDRESS_PROVIDER_ARBITRUM = '0xa97684ead0e402dC232d5A977953DF7ECBaB3CDb' let signer: SignerWithAddress; - // const account = "0xde33f4573bB315939a9D1E65522575E1a9fC3e74"; - const account = "0xF1229410497686300cca7Bf6CCa3ba582cF872f7"; + const account = "0x545358c58C1dE83b54759f1A64487c83Cb6fdf26"; before(async () => { [signer] = await ethers.getSigners(); @@ -18,14 +18,28 @@ describe("Aave", () => { describe("Aave V3 Resolver", () => { let resolver: InstaAaveV3ResolverArbitrum; before(async () => { + await hre.network.provider.request({ + method: "hardhat_reset", + params: [ + { + forking: { + // eslint-disable-next-line @typescript-eslint/ban-ts-comment + // @ts-ignore + jsonRpcUrl: hre.config.networks.arbitrum.url, + blockNumber: 261807484, + }, + }, + ], + }); + const deployer = new InstaAaveV3ResolverArbitrum__factory(signer); resolver = await deployer.deploy(); await resolver.deployed(); }); it("should get user configurations and reserves list", async () => { - const reservesList = await resolver.getReservesList(); - const reserves = await resolver.getConfiguration(account); + const reservesList = await resolver.getReservesList(POOL_ADDRESS_PROVIDER_ARBITRUM); + const reserves = await resolver.getConfiguration(account, POOL_ADDRESS_PROVIDER_ARBITRUM); console.log("Collateral Reserves Address"); console.log(reservesList); console.log(reserves); @@ -46,7 +60,7 @@ describe("Aave", () => { const results = await resolver.callStatic.getPosition(account, [ "0xDA10009cBd5D07dd0CeCc66161FC93D7c9000da1", "0xf97f4df75117a78c1A5a0DBb814Af92458539FB4", - ]); + ], POOL_ADDRESS_PROVIDER_ARBITRUM); const userTokenData = results[1]; const tokenData = results[2]; const userData = results[0]; @@ -74,7 +88,7 @@ describe("Aave", () => { }); it("Returns the user's positions on AaveV3 for all assets", async () => { - const results = await resolver.callStatic.getPositionAll(account); + const results = await resolver.callStatic.getPositionAll(account, POOL_ADDRESS_PROVIDER_ARBITRUM); const userTokenData = results[1]; const tokenData = results[2]; const userData = results[0]; @@ -189,7 +203,7 @@ describe("Aave", () => { } console.log(); - console.log(`E-Mode category: ${tokenData[i].token.eModeCategory}`); + // console.log(`E-Mode category: ${tokenData[i].token.eModeCategory}`); console.log( "Debt ceiling: ", formatUnits(tokenData[i].token.debtCeiling, tokenData[i].token.debtCeilingDecimals), @@ -202,10 +216,7 @@ describe("Aave", () => { }); it("Returns the e-mode category details of e-modeID", async () => { - const emodeData = await resolver.getEmodeCategoryData(1, [ - "0xDA10009cBd5D07dd0CeCc66161FC93D7c9000da1", - "0xf97f4df75117a78c1A5a0DBb814Af92458539FB4", - ]); + const emodeData = await resolver.getEmodeCategoryData(1, POOL_ADDRESS_PROVIDER_ARBITRUM); console.log(); console.log("*************************************************"); console.log("E-Mode category Data"); @@ -213,8 +224,9 @@ describe("Aave", () => { console.log(`e-mode LTV: ${emodeData.data.ltv}`); console.log(`e-mode liquidation threshold: ${emodeData.data.liquidationThreshold}`); console.log(`e-mode liquidation bonus: ${emodeData.data.liquidationBonus}`); - console.log(`e-mode price oracle: ${emodeData.data.priceSource}`); console.log(`e-mode label: ${emodeData.data.label}`); + console.log(`e-mode is colleteral bitmap: ${emodeData.data.isCollateralBitmap}`); + console.log(`e-mode is borrowable bitmap: ${emodeData.data.isBorrowableBitmap}`); }); it("Returns the ethPrice", async () => { From be4975d980532a659914ba95541961ed3f3fbd40 Mon Sep 17 00:00:00 2001 From: Samarendra Gouda Date: Wed, 9 Oct 2024 05:16:23 +0530 Subject: [PATCH 4/8] fix: update optimism resolver --- .../protocols/optimism/aave_v3/helpers.sol | 320 +++++++++--------- .../protocols/optimism/aave_v3/interfaces.sol | 132 ++++---- contracts/protocols/optimism/aave_v3/main.sol | 37 +- test/optimism/aave_v3.test.ts | 55 +-- 4 files changed, 283 insertions(+), 261 deletions(-) diff --git a/contracts/protocols/optimism/aave_v3/helpers.sol b/contracts/protocols/optimism/aave_v3/helpers.sol index a039f4e6..6009e6c0 100644 --- a/contracts/protocols/optimism/aave_v3/helpers.sol +++ b/contracts/protocols/optimism/aave_v3/helpers.sol @@ -4,8 +4,6 @@ import "./interfaces.sol"; import { DSMath } from "../../../utils/dsmath.sol"; contract AaveV3Helper is DSMath { - // ----------------------- USING LATEST ADDRESSES ----------------------------- - /** *@dev Returns ethereum address */ @@ -20,24 +18,6 @@ contract AaveV3Helper is DSMath { return 0x4200000000000000000000000000000000000006; //Optimism WETH Address } - function getUiDataProvider() internal pure returns (address) { - return 0x64f558d4BFC1c03a8c8B2ff84976fF04c762b51f; //Optimism UiPoolDataProvider Address - } - - /** - *@dev Returns Pool AddressProvider Address - */ - function getPoolAddressProvider() internal pure returns (address) { - return 0xa97684ead0e402dC232d5A977953DF7ECBaB3CDb; //Optimism PoolAddressesProvider address - } - - /** - *@dev Returns Pool DataProvider Address - */ - function getPoolDataProvider() internal pure returns (address) { - return 0x69FA688f1Dc47d4B5d8029D5a35FB7a548310654; //Optimism PoolDataProvider address - } - /** *@dev Returns Aave Data Provider Address */ @@ -56,31 +36,18 @@ contract AaveV3Helper is DSMath { return 0xD81eb3728a631871a7eBBaD631b5f424909f0c77; //Optimism address } - /** - *@dev Returns StableDebtToken Address - */ - function getStableDebtToken() internal pure returns (address) { - return 0x52A1CeB68Ee6b7B5D13E0376A1E0E4423A8cE26e; //Optimism address + function getUiIncetivesProvider() internal pure returns (address) { + return 0xc0179321f0825c3e0F59Fe7Ca4E40557b97797a3; } function getChainLinkFeed() internal pure returns (address) { return 0x13e3Ee699D1909E989722E753853AE30b17e08c5; } - function getUiIncetivesProvider() internal view returns (address) { - return 0x6dD4b295B457A26CC2646aAf2519436681afb5d4; - } - - function getRewardsController() internal view returns (address) { + function getRewardsController() internal pure returns (address) { return 0x929EC64c34a17401F460460D4B9390518E5B473e; } - struct Token { - address tokenAddress; - string symbol; - uint256 decimals; - } - struct BaseCurrency { uint256 baseUnit; address baseAddress; @@ -88,10 +55,10 @@ contract AaveV3Helper is DSMath { string symbol; } - struct ReserveAddresses { - Token aToken; - Token stableDebtToken; - Token variableDebtToken; + struct Token { + address tokenAddress; + string symbol; + uint256 decimals; } struct EmodeData { @@ -99,31 +66,10 @@ contract AaveV3Helper is DSMath { EModeCategory data; } - //Rewards details - struct ReserveIncentiveData { - address underlyingAsset; - IncentivesData aIncentiveData; - IncentivesData vIncentiveData; - IncentivesData sIncentiveData; - } - - struct IncentivesData { - address token; - RewardsInfo[] rewardsTokenInfo; - UserRewards userRewards; - } - - struct UserRewards { - address[] rewardsToken; - uint256[] unbalancedAmounts; - } - - struct RewardsInfo { - string rewardTokenSymbol; - address rewardTokenAddress; - uint256 emissionPerSecond; - uint256 rewardTokenDecimals; - uint256 precision; + struct ReserveAddresses { + Token aToken; + Token stableDebtToken; + Token variableDebtToken; } struct AaveV3UserTokenData { @@ -166,8 +112,7 @@ contract AaveV3Helper is DSMath { // TokenPrice tokenPrice; AaveV3Token token; // uint256 collateralEmission; - // uint256 stableDebtEmission; - // uint256 varDebtEmission; + // uint256 debtEmission; } struct Flags { @@ -181,7 +126,6 @@ contract AaveV3Helper is DSMath { struct AaveV3Token { uint256 supplyCap; uint256 borrowCap; - uint256 eModeCategory; uint256 debtCeiling; uint256 debtCeilingDecimals; uint256 liquidationFee; @@ -190,15 +134,45 @@ contract AaveV3Helper is DSMath { bool isPaused; } + //Rewards details + struct ReserveIncentiveData { + address underlyingAsset; + IncentivesData aIncentiveData; + IncentivesData vIncentiveData; + IncentivesData sIncentiveData; + } + + struct IncentivesData { + address token; + RewardsInfo[] rewardsTokenInfo; + UserRewards userRewards; + } + + struct UserRewards { + address[] rewardsToken; + uint256[] unbalancedAmounts; + } + + struct RewardsInfo { + string rewardTokenSymbol; + address rewardTokenAddress; + uint256 emissionPerSecond; + uint256 rewardTokenDecimals; + uint256 precision; + } + struct TokenPrice { uint256 priceInEth; uint256 priceInUsd; } - IPoolAddressesProvider internal provider = IPoolAddressesProvider(getPoolAddressProvider()); + struct PoolSpecificInfo { + IPoolAddressesProvider provider; + IPool pool; + IAaveProtocolDataProvider aaveData; + } + IAaveOracle internal aaveOracle = IAaveOracle(getAaveOracle()); - IAaveProtocolDataProvider internal aaveData = IAaveProtocolDataProvider(provider.getPoolDataProvider()); - IPool internal pool = IPool(provider.getPool()); IUiIncentiveDataProviderV3 internal uiIncentives = IUiIncentiveDataProviderV3(getUiIncetivesProvider()); IRewardsController internal rewardsCntr = IRewardsController(getRewardsController()); @@ -213,8 +187,15 @@ contract AaveV3Helper is DSMath { } } - function getIncentivesInfo(address user) internal view returns (ReserveIncentiveData[] memory incentives) { - AggregatedReserveIncentiveData[] memory _aggregateIncentive = uiIncentives.getReservesIncentivesData(provider); + function getIncentivesInfo( + address user, + address poolAddressProvider + ) internal view returns (ReserveIncentiveData[] memory incentives) { + PoolSpecificInfo memory poolInfo = getPoolSpecificInfo(poolAddressProvider); + + AggregatedReserveIncentiveData[] memory _aggregateIncentive = uiIncentives.getReservesIncentivesData( + poolInfo.provider + ); incentives = new ReserveIncentiveData[](_aggregateIncentive.length); for (uint256 i = 0; i < _aggregateIncentive.length; i++) { address[] memory rToken = new address[](1); @@ -249,8 +230,7 @@ contract AaveV3Helper is DSMath { } } - function getRewardInfo(RewardInfo[] memory rewards) internal view returns (RewardsInfo[] memory rewardData) { - // console.log(rewards.length); + function getRewardInfo(RewardInfo[] memory rewards) internal pure returns (RewardsInfo[] memory rewardData) { rewardData = new RewardsInfo[](rewards.length); for (uint256 i = 0; i < rewards.length; i++) { rewardData[i] = RewardsInfo( @@ -263,28 +243,26 @@ contract AaveV3Helper is DSMath { } } - function getTokensPrices(uint256 basePriceInUSD, address[] memory tokens) - internal - view - returns (TokenPrice[] memory tokenPrices, uint256 ethPrice) - { + function getTokensPrices( + uint256 basePriceInUSD, + address[] memory tokens + ) internal view returns (TokenPrice[] memory tokenPrices, uint256 ethPrice) { uint256[] memory _tokenPrices = aaveOracle.getAssetsPrices(tokens); tokenPrices = new TokenPrice[](_tokenPrices.length); ethPrice = uint256(AggregatorV3Interface(getChainLinkFeed()).latestAnswer()); for (uint256 i = 0; i < _tokenPrices.length; i++) { tokenPrices[i] = TokenPrice( - (_tokenPrices[i] * basePriceInUSD * 10**10) / ethPrice, - wmul(_tokenPrices[i] * 10**10, basePriceInUSD * 10**10) + (_tokenPrices[i] * basePriceInUSD * 10 ** 10) / ethPrice, + wmul(_tokenPrices[i] * 10 ** 10, basePriceInUSD * 10 ** 10) ); } } - function getEmodePrices(address priceOracleAddr, address[] memory tokens) - internal - view - returns (uint256[] memory tokenPrices) - { + function getEmodePrices( + address priceOracleAddr, + address[] memory tokens + ) internal view returns (uint256[] memory tokenPrices) { tokenPrices = IPriceOracle(priceOracleAddr).getAssetsPrices(tokens); // tokenPrices = new uint256[](tokens.length); // for (uint256 i = 0; i < tokens.length; i++) { @@ -292,20 +270,34 @@ contract AaveV3Helper is DSMath { // } } - function getPendingRewards(address user, address[] memory _tokens) internal view returns (uint256 rewards) { + function getPendingRewards( + address user, + address[] memory _tokens, + address poolAddressProvider + ) internal view returns (uint256 rewards) { + PoolSpecificInfo memory poolInfo = getPoolSpecificInfo(poolAddressProvider); + uint256 arrLength = 2 * _tokens.length; address[] memory _atokens = new address[](arrLength); for (uint256 i = 0; i < _tokens.length; i++) { - (_atokens[2 * i], , _atokens[2 * i + 1]) = aaveData.getReserveTokensAddresses(_tokens[i]); + (_atokens[2 * i], , _atokens[2 * i + 1]) = poolInfo.aaveData.getReserveTokensAddresses(_tokens[i]); } rewards = IAaveIncentivesController(getAaveIncentivesAddress()).getRewardsBalance(_atokens, user); } - function getIsolationDebt(address token) internal view returns (uint256 isolationDebt) { - isolationDebt = uint256(pool.getReserveData(token).isolationModeTotalDebt); + function getIsolationDebt( + address token, + address poolAddressProvider + ) internal view returns (uint256 isolationDebt) { + PoolSpecificInfo memory poolInfo = getPoolSpecificInfo(poolAddressProvider); + isolationDebt = uint256(poolInfo.pool.getReserveData(token).isolationModeTotalDebt); } - function getUserData(address user) internal view returns (AaveV3UserData memory userData) { + function getUserData( + address user, + address poolAddressProvider + ) internal view returns (AaveV3UserData memory userData) { + PoolSpecificInfo memory poolInfo = getPoolSpecificInfo(poolAddressProvider); ( userData.totalCollateralBase, userData.totalBorrowsBase, @@ -313,14 +305,14 @@ contract AaveV3Helper is DSMath { userData.currentLiquidationThreshold, userData.ltv, userData.healthFactor - ) = pool.getUserAccountData(user); + ) = poolInfo.pool.getUserAccountData(user); userData.base = getBaseCurrencyDetails(); - userData.eModeId = pool.getUserEMode(user); + userData.eModeId = poolInfo.pool.getUserEMode(user); // userData.pendingRewards = getPendingRewards(tokens, user); } - function getFlags(address token) internal view returns (Flags memory flag) { + function getFlags(address token, IAaveProtocolDataProvider aaveData) internal view returns (Flags memory flag) { ( , , @@ -335,86 +327,96 @@ contract AaveV3Helper is DSMath { ) = aaveData.getReserveConfigurationData(token); } - function getIsolationBorrowStatus(address token) internal view returns (bool iBorrowStatus) { + function getIsolationBorrowStatus(address token, IPool pool) internal view returns (bool iBorrowStatus) { ReserveConfigurationMap memory self = (pool.getReserveData(token)).configuration; uint256 BORROWABLE_IN_ISOLATION_MASK = 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDFFFFFFFFFFFFFFF; return (self.data & ~BORROWABLE_IN_ISOLATION_MASK) != 0; } - function getV3Token(address token) internal view returns (AaveV3Token memory tokenData) { + function getV3Token( + address token, + IPool pool, + IAaveProtocolDataProvider aaveData + ) internal view returns (AaveV3Token memory tokenData) { ( (tokenData.borrowCap, tokenData.supplyCap), - tokenData.eModeCategory, tokenData.debtCeiling, tokenData.debtCeilingDecimals, tokenData.liquidationFee, tokenData.isPaused ) = ( aaveData.getReserveCaps(token), - aaveData.getReserveEModeCategory(token), aaveData.getDebtCeiling(token), aaveData.getDebtCeilingDecimals(), aaveData.getLiquidationProtocolFee(token), aaveData.getPaused(token) ); { - (tokenData.isolationBorrowEnabled) = getIsolationBorrowStatus(token); + (tokenData.isolationBorrowEnabled) = getIsolationBorrowStatus(token, pool); } // (tokenData.isolationModeTotalDebt) = getIsolationDebt(token); } - function getEmodeCategoryData(uint8 id, address[] memory tokens) - external - view - returns (EmodeData memory eModeData) - { - EModeCategory memory data_ = pool.getEModeCategoryData(id); + function getEmodeCategoryData( + uint8 id, + address poolAddressProvider + ) external view returns (EmodeData memory eModeData) { + PoolSpecificInfo memory poolInfo = getPoolSpecificInfo(poolAddressProvider); + EModeCollateralConfig memory config_ = poolInfo.pool.getEModeCategoryCollateralConfig(id); + string memory label = poolInfo.pool.getEModeCategoryLabel(id); + uint128 isCollateralBitmap = poolInfo.pool.getEModeCategoryCollateralBitmap(id); + uint128 isBorrowableBitmap = poolInfo.pool.getEModeCategoryBorrowableBitmap(id); + + EModeCategory memory data_ = EModeCategory( + config_.ltv, + config_.liquidationThreshold, + config_.liquidationBonus, + label, + isCollateralBitmap, + isBorrowableBitmap + ); { eModeData.data = data_; - // eModeData.price = getEmodePrices(data_.priceSource, tokens); //TODO + // eModeData.price = getEmodePrices(data_.priceSource, tokens); } } - function reserveConfig(address token) - internal - view - returns ( - uint256 decimals, - uint256 ltv, - uint256 threshold, - uint256 reserveFactor - ) - { + function reserveConfig( + address token, + IAaveProtocolDataProvider aaveData + ) internal view returns (uint256 decimals, uint256 ltv, uint256 threshold, uint256 reserveFactor) { (decimals, ltv, threshold, , reserveFactor, , , , , ) = aaveData.getReserveConfigurationData(token); } - function resData(address token) - internal - view - returns ( - uint256 availableLiquidity, - uint256 totalStableDebt, - uint256 totalVariableDebt - ) - { + function resData( + address token, + IAaveProtocolDataProvider aaveData + ) internal view returns (uint256 availableLiquidity, uint256 totalStableDebt, uint256 totalVariableDebt) { (, , availableLiquidity, totalStableDebt, totalVariableDebt, , , , , , , ) = aaveData.getReserveData(token); } - function getAaveTokensData(address token) internal view returns (ReserveAddresses memory reserve) { + function getAaveTokensData( + address token, + address poolAddressProvider + ) internal view returns (ReserveAddresses memory reserve) { + PoolSpecificInfo memory poolInfo = getPoolSpecificInfo(poolAddressProvider); ( reserve.aToken.tokenAddress, reserve.stableDebtToken.tokenAddress, reserve.variableDebtToken.tokenAddress - ) = aaveData.getReserveTokensAddresses(token); + ) = poolInfo.aaveData.getReserveTokensAddresses(token); reserve.aToken.symbol = IERC20Detailed(reserve.aToken.tokenAddress).symbol(); - reserve.stableDebtToken.symbol = IERC20Detailed(reserve.stableDebtToken.tokenAddress).symbol(); reserve.variableDebtToken.symbol = IERC20Detailed(reserve.variableDebtToken.tokenAddress).symbol(); reserve.aToken.decimals = IERC20Detailed(reserve.aToken.tokenAddress).decimals(); - reserve.stableDebtToken.decimals = IERC20Detailed(reserve.stableDebtToken.tokenAddress).decimals(); reserve.variableDebtToken.decimals = IERC20Detailed(reserve.variableDebtToken.tokenAddress).decimals(); } - function userCollateralData(address token) internal view returns (AaveV3TokenData memory aaveTokenData) { + function userCollateralData( + address token, + address poolAddressProvider + ) internal view returns (AaveV3TokenData memory aaveTokenData) { + PoolSpecificInfo memory poolInfo = getPoolSpecificInfo(poolAddressProvider); + aaveTokenData.asset = token; aaveTokenData.symbol = IERC20Detailed(token).symbol(); ( @@ -422,24 +424,25 @@ contract AaveV3Helper is DSMath { aaveTokenData.ltv, aaveTokenData.threshold, aaveTokenData.reserveFactor - ) = reserveConfig(token); + ) = reserveConfig(token, poolInfo.aaveData); { ( aaveTokenData.availableLiquidity, aaveTokenData.totalStableDebt, aaveTokenData.totalVariableDebt - ) = resData(token); + ) = resData(token, poolInfo.aaveData); } - aaveTokenData.token = getV3Token(token); + aaveTokenData.token = getV3Token(token, poolInfo.pool, poolInfo.aaveData); // aaveTokenData.tokenPrice = assetPrice; - aaveTokenData.reserves = getAaveTokensData(token); + + aaveTokenData.reserves = getAaveTokensData(token, poolAddressProvider); //-------------INCENTIVE DETAILS--------------- // (, aaveTokenData.collateralEmission, ) = IAaveIncentivesController(getAaveIncentivesAddress()).assets( - // aaveTokenData.reserves.aToken.tokenAddress + // aaveTokenData.reserves.aToken.tokenAddress // ); // (, aaveTokenData.varDebtEmission, ) = IAaveIncentivesController(getAaveIncentivesAddress()).assets( // aaveTokenData.reserves.variableDebtToken.tokenAddress @@ -449,13 +452,13 @@ contract AaveV3Helper is DSMath { // ); } - function getUserTokenData(address user, address token) - internal - view - returns (AaveV3UserTokenData memory tokenData) - { - uint256 basePrice = IPriceOracle(IPoolAddressesProvider(getPoolAddressProvider()).getPriceOracle()) - .getAssetPrice(token); + function getUserTokenData( + address user, + address token, + address poolAddressProvider + ) internal view returns (AaveV3UserTokenData memory tokenData) { + PoolSpecificInfo memory poolInfo = getPoolSpecificInfo(poolAddressProvider); + uint256 basePrice = IPriceOracle(poolInfo.provider.getPriceOracle()).getAssetPrice(token); tokenData.price = basePrice; ( tokenData.supplyBalance, @@ -467,13 +470,13 @@ contract AaveV3Helper is DSMath { tokenData.supplyRate, , tokenData.isCollateral - ) = aaveData.getUserReserveData(token, user); + ) = poolInfo.aaveData.getUserReserveData(token, user); { - tokenData.flag = getFlags(token); - (, , , , , , tokenData.variableBorrowRate, tokenData.stableBorrowRate, , , , ) = aaveData.getReserveData( - token - ); + tokenData.flag = getFlags(token, poolInfo.aaveData); + (, , , , , , tokenData.variableBorrowRate, tokenData.stableBorrowRate, , , , ) = poolInfo + .aaveData + .getReserveData(token); } } @@ -481,7 +484,7 @@ contract AaveV3Helper is DSMath { ethPrice = uint256(AggregatorV3Interface(getChainLinkFeed()).latestAnswer()); } - function getPrices(bytes memory data) internal view returns (uint256) { + function getPrices(bytes memory data) internal pure returns (uint256) { (, BaseCurrencyInfo memory baseCurrency) = abi.decode(data, (AggregatedReserveData[], BaseCurrencyInfo)); return uint256(baseCurrency.marketReferenceCurrencyPriceInUsd); } @@ -504,8 +507,9 @@ contract AaveV3Helper is DSMath { // } } - function getList() public view returns (address[] memory data) { - data = pool.getReservesList(); + function getList(address poolAddressProvider) public view returns (address[] memory data) { + PoolSpecificInfo memory poolInfo = getPoolSpecificInfo(poolAddressProvider); + data = poolInfo.pool.getReservesList(); } function isUsingAsCollateralOrBorrowing(uint256 self, uint256 reserveIndex) public pure returns (bool) { @@ -523,7 +527,17 @@ contract AaveV3Helper is DSMath { return (self >> (reserveIndex * 2)) & 1 != 0; } - function getConfig(address user) public view returns (UserConfigurationMap memory data) { - data = pool.getUserConfiguration(user); + function getConfig( + address user, + address poolAddressProvider + ) public view returns (UserConfigurationMap memory data) { + PoolSpecificInfo memory poolInfo = getPoolSpecificInfo(poolAddressProvider); + data = poolInfo.pool.getUserConfiguration(user); + } + + function getPoolSpecificInfo(address poolAddressProvider) internal view returns (PoolSpecificInfo memory poolInfo) { + poolInfo.provider = IPoolAddressesProvider(poolAddressProvider); + poolInfo.pool = IPool(poolInfo.provider.getPool()); + poolInfo.aaveData = IAaveProtocolDataProvider(poolInfo.provider.getPoolDataProvider()); } } diff --git a/contracts/protocols/optimism/aave_v3/interfaces.sol b/contracts/protocols/optimism/aave_v3/interfaces.sol index 03a838a5..2fd2562d 100644 --- a/contracts/protocols/optimism/aave_v3/interfaces.sol +++ b/contracts/protocols/optimism/aave_v3/interfaces.sol @@ -28,8 +28,15 @@ struct EModeCategory { uint16 liquidationThreshold; uint16 liquidationBonus; // each eMode category may or may not have a custom oracle to override the individual assets price oracles - address priceSource; string label; + uint128 isCollateralBitmap; + uint128 isBorrowableBitmap; +} + +struct EModeCollateralConfig { + uint16 ltv; + uint16 liquidationThreshold; + uint16 liquidationBonus; } struct ReserveConfigurationMap { @@ -146,13 +153,16 @@ struct AggregatedReserveData { uint16 eModeLtv; uint16 eModeLiquidationThreshold; uint16 eModeLiquidationBonus; - address eModePriceSource; + uint128 isCollateralBitmap; + uint128 isBorrowableBitmap; string eModeLabel; bool borrowableInIsolation; } interface IPool { - function getUserAccountData(address user) + function getUserAccountData( + address user + ) external view returns ( @@ -164,12 +174,17 @@ interface IPool { uint256 healthFactor ); - function getEModeCategoryData(uint8 id) external view returns (EModeCategory memory); + // 3.2 Updated Interface for eMode + function getEModeCategoryCollateralConfig(uint8 id) external view returns (EModeCollateralConfig memory); + function getEModeCategoryLabel(uint8 id) external view returns (string memory); + function getEModeCategoryCollateralBitmap(uint8 id) external view returns (uint128); + function getEModeCategoryBorrowableBitmap(uint8 id) external view returns (uint128); + //@return emode id of the user function getUserEMode(address user) external view returns (uint256); - function getReservesList() external view virtual returns (address[] memory); + function getReservesList() external view returns (address[] memory); function getUserConfiguration(address user) external view returns (UserConfigurationMap memory); @@ -201,14 +216,7 @@ interface IAaveIncentivesController { // @dev Returns the configuration of the distribution for a certain asset // @return The asset index, the emission per second and the last updated timestamp - function assets(address asset) - external - view - returns ( - uint128, - uint128, - uint256 - ); + function assets(address asset) external view returns (uint128, uint128, uint256); } interface IAaveOracle is IPriceOracleGetter { @@ -235,7 +243,9 @@ interface IPoolAddressesProvider { interface IPoolDataProvider { // @notice Returns the reserve data - function getReserveData(address asset) + function getReserveData( + address asset + ) external view returns ( @@ -267,7 +277,9 @@ interface IStableDebtToken { } interface IAaveProtocolDataProvider is IPoolDataProvider { - function getReserveConfigurationData(address asset) + function getReserveConfigurationData( + address asset + ) external view returns ( @@ -287,8 +299,6 @@ interface IAaveProtocolDataProvider is IPoolDataProvider { function getLiquidationProtocolFee(address asset) external view returns (uint256); - function getReserveEModeCategory(address asset) external view returns (uint256); - function getReserveCaps(address asset) external view returns (uint256 borrowCap, uint256 supplyCap); // @notice Returns the debt ceiling of the reserve @@ -299,7 +309,9 @@ interface IAaveProtocolDataProvider is IPoolDataProvider { function getATokenTotalSupply(address asset) external view returns (uint256); - function getReserveData(address asset) + function getReserveData( + address asset + ) external view override @@ -318,7 +330,10 @@ interface IAaveProtocolDataProvider is IPoolDataProvider { uint40 lastUpdateTimestamp ); - function getUserReserveData(address asset, address user) + function getUserReserveData( + address asset, + address user + ) external view returns ( @@ -333,14 +348,9 @@ interface IAaveProtocolDataProvider is IPoolDataProvider { bool usageAsCollateralEnabled ); - function getReserveTokensAddresses(address asset) - external - view - returns ( - address aTokenAddress, - address stableDebtTokenAddress, - address variableDebtTokenAddress - ); + function getReserveTokensAddresses( + address asset + ) external view returns (address aTokenAddress, address stableDebtTokenAddress, address variableDebtTokenAddress); } //chainlink price feed @@ -350,13 +360,7 @@ interface AggregatorV3Interface { function latestRoundData() external view - returns ( - uint80 roundId, - int256 answer, - uint256 startedAt, - uint256 updatedAt, - uint80 answeredInRound - ); + returns (uint80 roundId, int256 answer, uint256 startedAt, uint256 updatedAt, uint80 answeredInRound); function latestAnswer() external view returns (int256); } @@ -368,29 +372,24 @@ interface IERC20Detailed { } interface IUiIncentiveDataProviderV3 { - function getReservesIncentivesData(IPoolAddressesProvider provider) - external - view - returns (AggregatedReserveIncentiveData[] memory); + function getReservesIncentivesData( + IPoolAddressesProvider provider + ) external view returns (AggregatedReserveIncentiveData[] memory); - function getUserReservesIncentivesData(IPoolAddressesProvider provider, address user) - external - view - returns (UserReserveIncentiveData[] memory); + function getUserReservesIncentivesData( + IPoolAddressesProvider provider, + address user + ) external view returns (UserReserveIncentiveData[] memory); // generic method with full data - function getFullReservesIncentiveData(IPoolAddressesProvider provider, address user) - external - view - returns (AggregatedReserveIncentiveData[] memory, UserReserveIncentiveData[] memory); + function getFullReservesIncentiveData( + IPoolAddressesProvider provider, + address user + ) external view returns (AggregatedReserveIncentiveData[] memory, UserReserveIncentiveData[] memory); } interface IRewardsDistributor { - function getUserAssetData( - address user, - address asset, - address reward - ) external view returns (uint256); + function getUserAssetData(address user, address asset, address reward) external view returns (uint256); /** * @dev Returns the configuration of the distribution for a certain asset @@ -398,15 +397,7 @@ interface IRewardsDistributor { * @param reward The reward token of the incentivized asset * @return The asset index, the emission per second, the last updated timestamp and the distribution end timestamp **/ - function getRewardsData(address asset, address reward) - external - view - returns ( - uint256, - uint256, - uint256, - uint256 - ); + function getRewardsData(address asset, address reward) external view returns (uint256, uint256, uint256, uint256); /** * @dev Returns the list of available reward token addresses of an incentivized asset @@ -436,11 +427,7 @@ interface IRewardsDistributor { * @param reward The address of the reward token * @return The rewards amount **/ - function getUserRewards( - address[] calldata assets, - address user, - address reward - ) external view returns (uint256); + function getUserRewards(address[] calldata assets, address user, address reward) external view returns (uint256); /** * @dev Returns a list all rewards of an user, including already accrued and unrealized claimable rewards @@ -448,10 +435,10 @@ interface IRewardsDistributor { * @param user The address of the user * @return The function returns a Tuple of rewards list and the unclaimed rewards list **/ - function getAllUserRewards(address[] calldata assets, address user) - external - view - returns (address[] memory, uint256[] memory); + function getAllUserRewards( + address[] calldata assets, + address user + ) external view returns (address[] memory, uint256[] memory); /** * @dev Returns the decimals of an asset to calculate the distribution delta @@ -473,8 +460,7 @@ interface IRewardsController is IRewardsDistributor { } interface IUiPoolDataProviderV3 { - function getReservesData(IPoolAddressesProvider provider) - external - view - returns (AggregatedReserveData[] memory, BaseCurrencyInfo memory); + function getReservesData( + IPoolAddressesProvider provider + ) external view returns (AggregatedReserveData[] memory, BaseCurrencyInfo memory); } diff --git a/contracts/protocols/optimism/aave_v3/main.sol b/contracts/protocols/optimism/aave_v3/main.sol index 260a8055..59789522 100644 --- a/contracts/protocols/optimism/aave_v3/main.sol +++ b/contracts/protocols/optimism/aave_v3/main.sol @@ -18,7 +18,11 @@ contract AaveV3Resolver is AaveV3Helper { *@return AaveV3TokenData details of tokens (e.g. symbol, decimals, ltv etc.). *@return ReserveIncentiveData details of user's rewards corresponding to the tokens passed. */ - function getPosition(address user, address[] memory tokens) + function getPosition( + address user, + address[] memory tokens, + address poolAddressProvider + ) public view returns ( @@ -35,18 +39,18 @@ contract AaveV3Resolver is AaveV3Helper { _tokens[i] = tokens[i] == getEthAddr() ? getWethAddr() : tokens[i]; } - AaveV3UserData memory userDetails = getUserData(user); + AaveV3UserData memory userDetails = getUserData(user, poolAddressProvider); // (TokenPrice[] memory tokenPrices, ) = getTokensPrices(userDetails.base.baseInUSD, _tokens); AaveV3UserTokenData[] memory tokensData = new AaveV3UserTokenData[](length); AaveV3TokenData[] memory collData = new AaveV3TokenData[](length); for (uint256 i = 0; i < length; i++) { - tokensData[i] = getUserTokenData(user, _tokens[i]); - collData[i] = userCollateralData(_tokens[i]); + tokensData[i] = getUserTokenData(user, _tokens[i], poolAddressProvider); + collData[i] = userCollateralData(_tokens[i], poolAddressProvider); } - return (userDetails, tokensData, collData, getIncentivesInfo(user)); + return (userDetails, tokensData, collData, getIncentivesInfo(user, poolAddressProvider)); } /** @@ -58,7 +62,10 @@ contract AaveV3Resolver is AaveV3Helper { *@return AaveV3TokenData details of tokens (e.g. symbol, decimals, ltv etc.). *@return ReserveIncentiveData details of user's rewards corresponding to the tokens in the market. */ - function getPositionAll(address user) + function getPositionAll( + address user, + address poolAddressProvider + ) public view returns ( @@ -68,7 +75,8 @@ contract AaveV3Resolver is AaveV3Helper { ReserveIncentiveData[] memory ) { - return getPosition(user, getList()); + address[] memory tokens = getList(poolAddressProvider); + return getPosition(user, tokens, poolAddressProvider); } /** @@ -78,9 +86,12 @@ contract AaveV3Resolver is AaveV3Helper { *@return collateral array with an element as true if the corresponding token is used as collateral by the user, false otherwise. *@return borrowed array with an element as true if the corresponding token is borrowed by the user, false otherwise. */ - function getConfiguration(address user) public view returns (bool[] memory collateral, bool[] memory borrowed) { - uint256 data = getConfig(user).data; - address[] memory reserveIndex = getList(); + function getConfiguration( + address user, + address poolAddressProvider + ) public view returns (bool[] memory collateral, bool[] memory borrowed) { + uint256 data = getConfig(user, poolAddressProvider).data; + address[] memory reserveIndex = getList(poolAddressProvider); collateral = new bool[](reserveIndex.length); borrowed = new bool[](reserveIndex.length); @@ -98,11 +109,11 @@ contract AaveV3Resolver is AaveV3Helper { *@notice get list of all tokens available in the market. *@return data array of token addresses available in the market. */ - function getReservesList() public view returns (address[] memory data) { - data = getList(); + function getReservesList(address poolAddressProvider) public view returns (address[] memory data) { + data = getList(poolAddressProvider); } } contract InstaAaveV3ResolverOptimism is AaveV3Resolver { - string public constant name = "AaveV3-Resolver-v1.0"; + string public constant name = "AaveV3-Resolver-v1.1"; } diff --git a/test/optimism/aave_v3.test.ts b/test/optimism/aave_v3.test.ts index ee23baf1..0f10ae6e 100644 --- a/test/optimism/aave_v3.test.ts +++ b/test/optimism/aave_v3.test.ts @@ -1,31 +1,45 @@ import { SignerWithAddress } from "@nomiclabs/hardhat-ethers/signers"; +import hre from "hardhat"; import { expect } from "chai"; import { formatUnits } from "ethers/lib/utils"; import { ethers } from "hardhat"; -import { InstaAaveV3ResolverOptimism, InstaAaveV3ResolverOptimism__factory } from "../../typechain"; +import { InstaAaveV3ResolverArbitrum, InstaAaveV3ResolverArbitrum__factory } from "../../typechain"; import { Tokens } from "../consts"; -import BigNumber from "bignumber.js"; describe("Aave", () => { + const POOL_ADDRESS_PROVIDER_OPTIMISM = '0xa97684ead0e402dC232d5A977953DF7ECBaB3CDb' let signer: SignerWithAddress; - // const account = "0xde33f4573bB315939a9D1E65522575E1a9fC3e74"; - const account = "0xF1229410497686300cca7Bf6CCa3ba582cF872f7"; + const account = "0xf7CA1F0ff0995c84feF530F7c74C69fb80331E81"; before(async () => { [signer] = await ethers.getSigners(); }); describe("Aave V3 Resolver", () => { - let resolver: InstaAaveV3ResolverOptimism; + let resolver: InstaAaveV3ResolverArbitrum; before(async () => { - const deployer = new InstaAaveV3ResolverOptimism__factory(signer); + await hre.network.provider.request({ + method: "hardhat_reset", + params: [ + { + forking: { + // eslint-disable-next-line @typescript-eslint/ban-ts-comment + // @ts-ignore + jsonRpcUrl: hre.config.networks.optimism.url, + blockNumber: 126415487, + }, + }, + ], + }); + + const deployer = new InstaAaveV3ResolverArbitrum__factory(signer); resolver = await deployer.deploy(); await resolver.deployed(); }); it("should get user configurations and reserves list", async () => { - const reservesList = await resolver.getReservesList(); - const reserves = await resolver.getConfiguration(account); + const reservesList = await resolver.getReservesList(POOL_ADDRESS_PROVIDER_OPTIMISM); + const reserves = await resolver.getConfiguration(account, POOL_ADDRESS_PROVIDER_OPTIMISM); console.log("Collateral Reserves Address"); console.log(reservesList); console.log(reserves); @@ -44,9 +58,8 @@ describe("Aave", () => { it("Returns the positions on AaveV3", async () => { const results = await resolver.callStatic.getPosition(account, [ - "0xDA10009cBd5D07dd0CeCc66161FC93D7c9000da1", - "0x350a791Bfc2C21F9Ed5d10980Dad2e2638ffa7f6", - ]); + "0x4200000000000000000000000000000000000006", + ], POOL_ADDRESS_PROVIDER_OPTIMISM); const userTokenData = results[1]; const tokenData = results[2]; const userData = results[0]; @@ -74,7 +87,7 @@ describe("Aave", () => { }); it("Returns the user's positions on AaveV3 for all assets", async () => { - const results = await resolver.callStatic.getPositionAll(account); + const results = await resolver.callStatic.getPositionAll(account, POOL_ADDRESS_PROVIDER_OPTIMISM); const userTokenData = results[1]; const tokenData = results[2]; const userData = results[0]; @@ -146,7 +159,6 @@ describe("Aave", () => { console.log(`Reward token precision: ${rewards[i].aIncentiveData.rewardsTokenInfo[j].precision}`); console.log(`Emission rate per second: ${rewards[i].aIncentiveData.rewardsTokenInfo[j].emissionPerSecond}`); } - for (let j = 0; j < rewards[i].aIncentiveData.userRewards.rewardsToken.length; j++) { console.log( `Unclaimed Reward: ${rewards[i].aIncentiveData.userRewards.unbalancedAmounts[j]} for ${rewards[i].aIncentiveData.userRewards.rewardsToken[j]}`, @@ -165,9 +177,9 @@ describe("Aave", () => { console.log(`Reward token precision: ${rewards[i].sIncentiveData.rewardsTokenInfo[j].precision}`); console.log(`Emission rate per second: ${rewards[i].sIncentiveData.rewardsTokenInfo[j].emissionPerSecond}`); } - for (let j = 0; j < rewards[i].vIncentiveData.userRewards.rewardsToken.length; j++) { + for (let j = 0; j < rewards[i].sIncentiveData.userRewards.rewardsToken.length; j++) { console.log( - `Unclaimed Reward: ${rewards[i].vIncentiveData.userRewards.unbalancedAmounts[j]} for ${rewards[i].vIncentiveData.userRewards.rewardsToken[j]}`, + `Unclaimed Reward: ${rewards[i].sIncentiveData.userRewards.unbalancedAmounts[j]} for ${rewards[i].sIncentiveData.userRewards.rewardsToken[j]}`, ); } console.log("----------------------------------------------------"); @@ -185,11 +197,12 @@ describe("Aave", () => { } for (let j = 0; j < rewards[i].vIncentiveData.userRewards.rewardsToken.length; j++) { console.log( - `Unclaimed Reward: ${rewards[i].vIncentiveData.userRewards.unbalancedAmounts[j]} for ${rewards[i].sIncentiveData.userRewards.rewardsToken[j]}`, + `Unclaimed Reward: ${rewards[i].vIncentiveData.userRewards.unbalancedAmounts[j]} for ${rewards[i].vIncentiveData.userRewards.rewardsToken[j]}`, ); } console.log(); - console.log(`E-Mode category: ${tokenData[i].token.eModeCategory}`); + + // console.log(`E-Mode category: ${tokenData[i].token.eModeCategory}`); console.log( "Debt ceiling: ", formatUnits(tokenData[i].token.debtCeiling, tokenData[i].token.debtCeilingDecimals), @@ -202,10 +215,7 @@ describe("Aave", () => { }); it("Returns the e-mode category details of e-modeID", async () => { - const emodeData = await resolver.getEmodeCategoryData(1, [ - "0xDA10009cBd5D07dd0CeCc66161FC93D7c9000da1", - "0x350a791Bfc2C21F9Ed5d10980Dad2e2638ffa7f6", - ]); + const emodeData = await resolver.getEmodeCategoryData(1, POOL_ADDRESS_PROVIDER_OPTIMISM); console.log(); console.log("*************************************************"); console.log("E-Mode category Data"); @@ -213,8 +223,9 @@ describe("Aave", () => { console.log(`e-mode LTV: ${emodeData.data.ltv}`); console.log(`e-mode liquidation threshold: ${emodeData.data.liquidationThreshold}`); console.log(`e-mode liquidation bonus: ${emodeData.data.liquidationBonus}`); - console.log(`e-mode price oracle: ${emodeData.data.priceSource}`); console.log(`e-mode label: ${emodeData.data.label}`); + console.log(`e-mode is colleteral bitmap: ${emodeData.data.isCollateralBitmap}`); + console.log(`e-mode is borrowable bitmap: ${emodeData.data.isBorrowableBitmap}`); }); it("Returns the ethPrice", async () => { From c00d4ada6fd5ae94593aad950badf87f1f0b1ec6 Mon Sep 17 00:00:00 2001 From: Samarendra Gouda Date: Wed, 9 Oct 2024 06:23:22 +0530 Subject: [PATCH 5/8] fix: add polygon resolver --- .../protocols/polygon/aave_v3/helpers.sol | 285 ++++++++++-------- .../protocols/polygon/aave_v3/interfaces.sol | 132 ++++---- contracts/protocols/polygon/aave_v3/main.sol | 37 ++- 3 files changed, 234 insertions(+), 220 deletions(-) diff --git a/contracts/protocols/polygon/aave_v3/helpers.sol b/contracts/protocols/polygon/aave_v3/helpers.sol index 3677b943..7279b263 100644 --- a/contracts/protocols/polygon/aave_v3/helpers.sol +++ b/contracts/protocols/polygon/aave_v3/helpers.sol @@ -4,8 +4,6 @@ import "./interfaces.sol"; import { DSMath } from "../../../utils/dsmath.sol"; contract AaveV3Helper is DSMath { - // ----------------------- USING LATEST ADDRESSES ----------------------------- - /** *@dev Returns ethereum address */ @@ -20,24 +18,6 @@ contract AaveV3Helper is DSMath { return 0x0d500B1d8E8eF31E21C99d1Db9A6444d3ADf1270; //Polygon mainnet WMatic Address } - function getUiDataProvider() internal pure returns (address) { - return 0x8F1AD487C9413d7e81aB5B4E88B024Ae3b5637D0; //polygon UiPoolDataProvider Address - } - - /** - *@dev Returns Pool AddressProvider Address - */ - function getPoolAddressProvider() internal pure returns (address) { - return 0xa97684ead0e402dC232d5A977953DF7ECBaB3CDb; //Polygon Mainnet PoolAddressesProvider address - } - - /** - *@dev Returns Pool DataProvider Address - */ - function getPoolDataProvider() internal pure returns (address) { - return 0x69FA688f1Dc47d4B5d8029D5a35FB7a548310654; //Polygon Mainnet PoolDataProvider address - } - /** *@dev Returns Aave Data Provider Address */ @@ -56,29 +36,22 @@ contract AaveV3Helper is DSMath { return 0xb023e699F5a33916Ea823A16485e259257cA8Bd1; //Polygon address } - /** - *@dev Returns StableDebtToken Address - */ - function getStableDebtToken() internal pure returns (address) { - return 0x52A1CeB68Ee6b7B5D13E0376A1E0E4423A8cE26e; //Polygon address - } - function getChainLinkFeed() internal pure returns (address) { return 0xF9680D99D6C9589e2a93a78A04A279e509205945; } - function getUiIncetivesProvider() internal view returns (address) { - return 0x05E309C97317d8abc0f7e78185FC966FfbD2CEC0; + function getUiIncetivesProvider() internal pure returns (address) { + return 0x5c5228aC8BC1528482514aF3e27E692495148717; } - function getRewardsController() internal view returns (address) { + function getRewardsController() internal pure returns (address) { return 0x929EC64c34a17401F460460D4B9390518E5B473e; } struct BaseCurrency { uint256 baseUnit; address baseAddress; - // uint256 baseInUSD; //TODO + // uint256 baseInUSD; string symbol; } @@ -88,17 +61,17 @@ contract AaveV3Helper is DSMath { uint256 decimals; } + struct EmodeData { + // uint256[] price; + EModeCategory data; + } + struct ReserveAddresses { Token aToken; Token stableDebtToken; Token variableDebtToken; } - struct EmodeData { - // uint256[] price; - EModeCategory data; - } - struct AaveV3UserTokenData { uint256 supplyBalance; uint256 stableBorrowBalance; @@ -139,8 +112,7 @@ contract AaveV3Helper is DSMath { // TokenPrice tokenPrice; AaveV3Token token; // uint256 collateralEmission; - // uint256 stableDebtEmission; - // uint256 varDebtEmission; + // uint256 debtEmission; } struct Flags { @@ -154,7 +126,6 @@ contract AaveV3Helper is DSMath { struct AaveV3Token { uint256 supplyCap; uint256 borrowCap; - uint256 eModeCategory; uint256 debtCeiling; uint256 debtCeilingDecimals; uint256 liquidationFee; @@ -163,11 +134,6 @@ contract AaveV3Helper is DSMath { bool isPaused; } - struct TokenPrice { - uint256 priceInEth; - uint256 priceInUsd; - } - //Rewards details struct ReserveIncentiveData { address underlyingAsset; @@ -195,10 +161,18 @@ contract AaveV3Helper is DSMath { uint256 precision; } - IPoolAddressesProvider internal provider = IPoolAddressesProvider(getPoolAddressProvider()); + struct TokenPrice { + uint256 priceInEth; + uint256 priceInUsd; + } + + struct PoolSpecificInfo { + IPoolAddressesProvider provider; + IPool pool; + IAaveProtocolDataProvider aaveData; + } + IAaveOracle internal aaveOracle = IAaveOracle(getAaveOracle()); - IAaveProtocolDataProvider internal aaveData = IAaveProtocolDataProvider(provider.getPoolDataProvider()); - IPool internal pool = IPool(provider.getPool()); IUiIncentiveDataProviderV3 internal uiIncentives = IUiIncentiveDataProviderV3(getUiIncetivesProvider()); IRewardsController internal rewardsCntr = IRewardsController(getRewardsController()); @@ -213,8 +187,15 @@ contract AaveV3Helper is DSMath { } } - function getIncentivesInfo(address user) internal view returns (ReserveIncentiveData[] memory incentives) { - AggregatedReserveIncentiveData[] memory _aggregateIncentive = uiIncentives.getReservesIncentivesData(provider); + function getIncentivesInfo( + address user, + address poolAddressProvider + ) internal view returns (ReserveIncentiveData[] memory incentives) { + PoolSpecificInfo memory poolInfo = getPoolSpecificInfo(poolAddressProvider); + + AggregatedReserveIncentiveData[] memory _aggregateIncentive = uiIncentives.getReservesIncentivesData( + poolInfo.provider + ); incentives = new ReserveIncentiveData[](_aggregateIncentive.length); for (uint256 i = 0; i < _aggregateIncentive.length; i++) { address[] memory rToken = new address[](1); @@ -249,8 +230,7 @@ contract AaveV3Helper is DSMath { } } - function getRewardInfo(RewardInfo[] memory rewards) internal view returns (RewardsInfo[] memory rewardData) { - // console.log(rewards.length); + function getRewardInfo(RewardInfo[] memory rewards) internal pure returns (RewardsInfo[] memory rewardData) { rewardData = new RewardsInfo[](rewards.length); for (uint256 i = 0; i < rewards.length; i++) { rewardData[i] = RewardsInfo( @@ -263,45 +243,61 @@ contract AaveV3Helper is DSMath { } } - function getTokensPrices(uint256 basePriceInUSD, address[] memory tokens) - internal - view - returns (TokenPrice[] memory tokenPrices, uint256 ethPrice) - { + function getTokensPrices( + uint256 basePriceInUSD, + address[] memory tokens + ) internal view returns (TokenPrice[] memory tokenPrices, uint256 ethPrice) { uint256[] memory _tokenPrices = aaveOracle.getAssetsPrices(tokens); tokenPrices = new TokenPrice[](_tokenPrices.length); ethPrice = uint256(AggregatorV3Interface(getChainLinkFeed()).latestAnswer()); for (uint256 i = 0; i < _tokenPrices.length; i++) { tokenPrices[i] = TokenPrice( - (_tokenPrices[i] * basePriceInUSD * 10**10) / ethPrice, - wmul(_tokenPrices[i] * 10**10, basePriceInUSD * 10**10) + (_tokenPrices[i] * basePriceInUSD * 10 ** 10) / ethPrice, + wmul(_tokenPrices[i] * 10 ** 10, basePriceInUSD * 10 ** 10) ); } } - function getEmodePrices(address priceOracleAddr, address[] memory tokens) - internal - view - returns (uint256[] memory tokenPrices) - { + function getEmodePrices( + address priceOracleAddr, + address[] memory tokens + ) internal view returns (uint256[] memory tokenPrices) { tokenPrices = IPriceOracle(priceOracleAddr).getAssetsPrices(tokens); + // tokenPrices = new uint256[](tokens.length); + // for (uint256 i = 0; i < tokens.length; i++) { + // tokenPrices[i] = IPriceOracle(priceOracleAddr).getAssetPrice(tokens[i]); + // } } - function getPendingRewards(address user, address[] memory _tokens) internal view returns (uint256 rewards) { + function getPendingRewards( + address user, + address[] memory _tokens, + address poolAddressProvider + ) internal view returns (uint256 rewards) { + PoolSpecificInfo memory poolInfo = getPoolSpecificInfo(poolAddressProvider); + uint256 arrLength = 2 * _tokens.length; address[] memory _atokens = new address[](arrLength); for (uint256 i = 0; i < _tokens.length; i++) { - (_atokens[2 * i], , _atokens[2 * i + 1]) = aaveData.getReserveTokensAddresses(_tokens[i]); + (_atokens[2 * i], , _atokens[2 * i + 1]) = poolInfo.aaveData.getReserveTokensAddresses(_tokens[i]); } rewards = IAaveIncentivesController(getAaveIncentivesAddress()).getRewardsBalance(_atokens, user); } - function getIsolationDebt(address token) internal view returns (uint256 isolationDebt) { - isolationDebt = uint256(pool.getReserveData(token).isolationModeTotalDebt); + function getIsolationDebt( + address token, + address poolAddressProvider + ) internal view returns (uint256 isolationDebt) { + PoolSpecificInfo memory poolInfo = getPoolSpecificInfo(poolAddressProvider); + isolationDebt = uint256(poolInfo.pool.getReserveData(token).isolationModeTotalDebt); } - function getUserData(address user) internal view returns (AaveV3UserData memory userData) { + function getUserData( + address user, + address poolAddressProvider + ) internal view returns (AaveV3UserData memory userData) { + PoolSpecificInfo memory poolInfo = getPoolSpecificInfo(poolAddressProvider); ( userData.totalCollateralBase, userData.totalBorrowsBase, @@ -309,14 +305,14 @@ contract AaveV3Helper is DSMath { userData.currentLiquidationThreshold, userData.ltv, userData.healthFactor - ) = pool.getUserAccountData(user); + ) = poolInfo.pool.getUserAccountData(user); userData.base = getBaseCurrencyDetails(); - userData.eModeId = pool.getUserEMode(user); + userData.eModeId = poolInfo.pool.getUserEMode(user); // userData.pendingRewards = getPendingRewards(tokens, user); } - function getFlags(address token) internal view returns (Flags memory flag) { + function getFlags(address token, IAaveProtocolDataProvider aaveData) internal view returns (Flags memory flag) { ( , , @@ -331,90 +327,96 @@ contract AaveV3Helper is DSMath { ) = aaveData.getReserveConfigurationData(token); } - function getIsolationBorrowStatus(address token) internal view returns (bool iBorrowStatus) { + function getIsolationBorrowStatus(address token, IPool pool) internal view returns (bool iBorrowStatus) { ReserveConfigurationMap memory self = (pool.getReserveData(token)).configuration; uint256 BORROWABLE_IN_ISOLATION_MASK = 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDFFFFFFFFFFFFFFF; return (self.data & ~BORROWABLE_IN_ISOLATION_MASK) != 0; } - function getV3Token(address token) internal view returns (AaveV3Token memory tokenData) { + function getV3Token( + address token, + IPool pool, + IAaveProtocolDataProvider aaveData + ) internal view returns (AaveV3Token memory tokenData) { ( (tokenData.borrowCap, tokenData.supplyCap), - tokenData.eModeCategory, tokenData.debtCeiling, tokenData.debtCeilingDecimals, tokenData.liquidationFee, tokenData.isPaused ) = ( aaveData.getReserveCaps(token), - aaveData.getReserveEModeCategory(token), aaveData.getDebtCeiling(token), aaveData.getDebtCeilingDecimals(), aaveData.getLiquidationProtocolFee(token), aaveData.getPaused(token) ); { - (tokenData.isolationBorrowEnabled) = getIsolationBorrowStatus(token); + (tokenData.isolationBorrowEnabled) = getIsolationBorrowStatus(token, pool); } // (tokenData.isolationModeTotalDebt) = getIsolationDebt(token); } - function getEthPrice() public view returns (uint256 ethPrice) { - ethPrice = uint256(AggregatorV3Interface(getChainLinkFeed()).latestAnswer()); - } - - function getEmodeCategoryData(uint8 id, address[] memory tokens) - external - view - returns (EmodeData memory eModeData) - { - EModeCategory memory data_ = pool.getEModeCategoryData(id); + function getEmodeCategoryData( + uint8 id, + address poolAddressProvider + ) external view returns (EmodeData memory eModeData) { + PoolSpecificInfo memory poolInfo = getPoolSpecificInfo(poolAddressProvider); + EModeCollateralConfig memory config_ = poolInfo.pool.getEModeCategoryCollateralConfig(id); + string memory label = poolInfo.pool.getEModeCategoryLabel(id); + uint128 isCollateralBitmap = poolInfo.pool.getEModeCategoryCollateralBitmap(id); + uint128 isBorrowableBitmap = poolInfo.pool.getEModeCategoryBorrowableBitmap(id); + + EModeCategory memory data_ = EModeCategory( + config_.ltv, + config_.liquidationThreshold, + config_.liquidationBonus, + label, + isCollateralBitmap, + isBorrowableBitmap + ); { eModeData.data = data_; - // eModeData.price = getEmodePrices(data_.priceSource, tokens); //TODO + // eModeData.price = getEmodePrices(data_.priceSource, tokens); } } - function reserveConfig(address token) - internal - view - returns ( - uint256 decimals, - uint256 ltv, - uint256 threshold, - uint256 reserveFactor - ) - { + function reserveConfig( + address token, + IAaveProtocolDataProvider aaveData + ) internal view returns (uint256 decimals, uint256 ltv, uint256 threshold, uint256 reserveFactor) { (decimals, ltv, threshold, , reserveFactor, , , , , ) = aaveData.getReserveConfigurationData(token); } - function resData(address token) - internal - view - returns ( - uint256 availableLiquidity, - uint256 totalStableDebt, - uint256 totalVariableDebt - ) - { + function resData( + address token, + IAaveProtocolDataProvider aaveData + ) internal view returns (uint256 availableLiquidity, uint256 totalStableDebt, uint256 totalVariableDebt) { (, , availableLiquidity, totalStableDebt, totalVariableDebt, , , , , , , ) = aaveData.getReserveData(token); } - function getAaveTokensData(address token) internal view returns (ReserveAddresses memory reserve) { + function getAaveTokensData( + address token, + address poolAddressProvider + ) internal view returns (ReserveAddresses memory reserve) { + PoolSpecificInfo memory poolInfo = getPoolSpecificInfo(poolAddressProvider); ( reserve.aToken.tokenAddress, reserve.stableDebtToken.tokenAddress, reserve.variableDebtToken.tokenAddress - ) = aaveData.getReserveTokensAddresses(token); + ) = poolInfo.aaveData.getReserveTokensAddresses(token); reserve.aToken.symbol = IERC20Detailed(reserve.aToken.tokenAddress).symbol(); - reserve.stableDebtToken.symbol = IERC20Detailed(reserve.stableDebtToken.tokenAddress).symbol(); reserve.variableDebtToken.symbol = IERC20Detailed(reserve.variableDebtToken.tokenAddress).symbol(); reserve.aToken.decimals = IERC20Detailed(reserve.aToken.tokenAddress).decimals(); - reserve.stableDebtToken.decimals = IERC20Detailed(reserve.stableDebtToken.tokenAddress).decimals(); reserve.variableDebtToken.decimals = IERC20Detailed(reserve.variableDebtToken.tokenAddress).decimals(); } - function userCollateralData(address token) internal view returns (AaveV3TokenData memory aaveTokenData) { + function userCollateralData( + address token, + address poolAddressProvider + ) internal view returns (AaveV3TokenData memory aaveTokenData) { + PoolSpecificInfo memory poolInfo = getPoolSpecificInfo(poolAddressProvider); + aaveTokenData.asset = token; aaveTokenData.symbol = IERC20Detailed(token).symbol(); ( @@ -422,22 +424,22 @@ contract AaveV3Helper is DSMath { aaveTokenData.ltv, aaveTokenData.threshold, aaveTokenData.reserveFactor - ) = reserveConfig(token); + ) = reserveConfig(token, poolInfo.aaveData); { ( aaveTokenData.availableLiquidity, aaveTokenData.totalStableDebt, aaveTokenData.totalVariableDebt - ) = resData(token); + ) = resData(token, poolInfo.aaveData); } - aaveTokenData.token = getV3Token(token); + aaveTokenData.token = getV3Token(token, poolInfo.pool, poolInfo.aaveData); // aaveTokenData.tokenPrice = assetPrice; - //-------------INCENTIVE DETAILS--------------- + aaveTokenData.reserves = getAaveTokensData(token, poolAddressProvider); - aaveTokenData.reserves = getAaveTokensData(token); + //-------------INCENTIVE DETAILS--------------- // (, aaveTokenData.collateralEmission, ) = IAaveIncentivesController(getAaveIncentivesAddress()).assets( // aaveTokenData.reserves.aToken.tokenAddress @@ -450,13 +452,13 @@ contract AaveV3Helper is DSMath { // ); } - function getUserTokenData(address user, address token) - internal - view - returns (AaveV3UserTokenData memory tokenData) - { - uint256 basePrice = IPriceOracle(IPoolAddressesProvider(getPoolAddressProvider()).getPriceOracle()) - .getAssetPrice(token); + function getUserTokenData( + address user, + address token, + address poolAddressProvider + ) internal view returns (AaveV3UserTokenData memory tokenData) { + PoolSpecificInfo memory poolInfo = getPoolSpecificInfo(poolAddressProvider); + uint256 basePrice = IPriceOracle(poolInfo.provider.getPriceOracle()).getAssetPrice(token); tokenData.price = basePrice; ( tokenData.supplyBalance, @@ -468,17 +470,21 @@ contract AaveV3Helper is DSMath { tokenData.supplyRate, , tokenData.isCollateral - ) = aaveData.getUserReserveData(token, user); + ) = poolInfo.aaveData.getUserReserveData(token, user); { - tokenData.flag = getFlags(token); - (, , , , , , tokenData.variableBorrowRate, tokenData.stableBorrowRate, , , , ) = aaveData.getReserveData( - token - ); + tokenData.flag = getFlags(token, poolInfo.aaveData); + (, , , , , , tokenData.variableBorrowRate, tokenData.stableBorrowRate, , , , ) = poolInfo + .aaveData + .getReserveData(token); } } - function getPrices(bytes memory data) internal view returns (uint256) { + function getEthPrice() public view returns (uint256 ethPrice) { + ethPrice = uint256(AggregatorV3Interface(getChainLinkFeed()).latestAnswer()); + } + + function getPrices(bytes memory data) internal pure returns (uint256) { (, BaseCurrencyInfo memory baseCurrency) = abi.decode(data, (AggregatedReserveData[], BaseCurrencyInfo)); return uint256(baseCurrency.marketReferenceCurrencyPriceInUsd); } @@ -492,8 +498,8 @@ contract AaveV3Helper is DSMath { baseCurr.baseUnit = aaveOracle.BASE_CURRENCY_UNIT(); baseCurr.baseAddress = aaveOracle.BASE_CURRENCY(); - //TODO + // { // (, bytes memory data) = getUiDataProvider().staticcall( // abi.encodeWithSignature("getReservesData(address)", IPoolAddressesProvider(getPoolAddressProvider())) // ); @@ -501,8 +507,9 @@ contract AaveV3Helper is DSMath { // } } - function getList() public view returns (address[] memory data) { - data = pool.getReservesList(); + function getList(address poolAddressProvider) public view returns (address[] memory data) { + PoolSpecificInfo memory poolInfo = getPoolSpecificInfo(poolAddressProvider); + data = poolInfo.pool.getReservesList(); } function isUsingAsCollateralOrBorrowing(uint256 self, uint256 reserveIndex) public pure returns (bool) { @@ -520,7 +527,17 @@ contract AaveV3Helper is DSMath { return (self >> (reserveIndex * 2)) & 1 != 0; } - function getConfig(address user) public view returns (UserConfigurationMap memory data) { - data = pool.getUserConfiguration(user); + function getConfig( + address user, + address poolAddressProvider + ) public view returns (UserConfigurationMap memory data) { + PoolSpecificInfo memory poolInfo = getPoolSpecificInfo(poolAddressProvider); + data = poolInfo.pool.getUserConfiguration(user); + } + + function getPoolSpecificInfo(address poolAddressProvider) internal view returns (PoolSpecificInfo memory poolInfo) { + poolInfo.provider = IPoolAddressesProvider(poolAddressProvider); + poolInfo.pool = IPool(poolInfo.provider.getPool()); + poolInfo.aaveData = IAaveProtocolDataProvider(poolInfo.provider.getPoolDataProvider()); } } diff --git a/contracts/protocols/polygon/aave_v3/interfaces.sol b/contracts/protocols/polygon/aave_v3/interfaces.sol index 03a838a5..2fd2562d 100644 --- a/contracts/protocols/polygon/aave_v3/interfaces.sol +++ b/contracts/protocols/polygon/aave_v3/interfaces.sol @@ -28,8 +28,15 @@ struct EModeCategory { uint16 liquidationThreshold; uint16 liquidationBonus; // each eMode category may or may not have a custom oracle to override the individual assets price oracles - address priceSource; string label; + uint128 isCollateralBitmap; + uint128 isBorrowableBitmap; +} + +struct EModeCollateralConfig { + uint16 ltv; + uint16 liquidationThreshold; + uint16 liquidationBonus; } struct ReserveConfigurationMap { @@ -146,13 +153,16 @@ struct AggregatedReserveData { uint16 eModeLtv; uint16 eModeLiquidationThreshold; uint16 eModeLiquidationBonus; - address eModePriceSource; + uint128 isCollateralBitmap; + uint128 isBorrowableBitmap; string eModeLabel; bool borrowableInIsolation; } interface IPool { - function getUserAccountData(address user) + function getUserAccountData( + address user + ) external view returns ( @@ -164,12 +174,17 @@ interface IPool { uint256 healthFactor ); - function getEModeCategoryData(uint8 id) external view returns (EModeCategory memory); + // 3.2 Updated Interface for eMode + function getEModeCategoryCollateralConfig(uint8 id) external view returns (EModeCollateralConfig memory); + function getEModeCategoryLabel(uint8 id) external view returns (string memory); + function getEModeCategoryCollateralBitmap(uint8 id) external view returns (uint128); + function getEModeCategoryBorrowableBitmap(uint8 id) external view returns (uint128); + //@return emode id of the user function getUserEMode(address user) external view returns (uint256); - function getReservesList() external view virtual returns (address[] memory); + function getReservesList() external view returns (address[] memory); function getUserConfiguration(address user) external view returns (UserConfigurationMap memory); @@ -201,14 +216,7 @@ interface IAaveIncentivesController { // @dev Returns the configuration of the distribution for a certain asset // @return The asset index, the emission per second and the last updated timestamp - function assets(address asset) - external - view - returns ( - uint128, - uint128, - uint256 - ); + function assets(address asset) external view returns (uint128, uint128, uint256); } interface IAaveOracle is IPriceOracleGetter { @@ -235,7 +243,9 @@ interface IPoolAddressesProvider { interface IPoolDataProvider { // @notice Returns the reserve data - function getReserveData(address asset) + function getReserveData( + address asset + ) external view returns ( @@ -267,7 +277,9 @@ interface IStableDebtToken { } interface IAaveProtocolDataProvider is IPoolDataProvider { - function getReserveConfigurationData(address asset) + function getReserveConfigurationData( + address asset + ) external view returns ( @@ -287,8 +299,6 @@ interface IAaveProtocolDataProvider is IPoolDataProvider { function getLiquidationProtocolFee(address asset) external view returns (uint256); - function getReserveEModeCategory(address asset) external view returns (uint256); - function getReserveCaps(address asset) external view returns (uint256 borrowCap, uint256 supplyCap); // @notice Returns the debt ceiling of the reserve @@ -299,7 +309,9 @@ interface IAaveProtocolDataProvider is IPoolDataProvider { function getATokenTotalSupply(address asset) external view returns (uint256); - function getReserveData(address asset) + function getReserveData( + address asset + ) external view override @@ -318,7 +330,10 @@ interface IAaveProtocolDataProvider is IPoolDataProvider { uint40 lastUpdateTimestamp ); - function getUserReserveData(address asset, address user) + function getUserReserveData( + address asset, + address user + ) external view returns ( @@ -333,14 +348,9 @@ interface IAaveProtocolDataProvider is IPoolDataProvider { bool usageAsCollateralEnabled ); - function getReserveTokensAddresses(address asset) - external - view - returns ( - address aTokenAddress, - address stableDebtTokenAddress, - address variableDebtTokenAddress - ); + function getReserveTokensAddresses( + address asset + ) external view returns (address aTokenAddress, address stableDebtTokenAddress, address variableDebtTokenAddress); } //chainlink price feed @@ -350,13 +360,7 @@ interface AggregatorV3Interface { function latestRoundData() external view - returns ( - uint80 roundId, - int256 answer, - uint256 startedAt, - uint256 updatedAt, - uint80 answeredInRound - ); + returns (uint80 roundId, int256 answer, uint256 startedAt, uint256 updatedAt, uint80 answeredInRound); function latestAnswer() external view returns (int256); } @@ -368,29 +372,24 @@ interface IERC20Detailed { } interface IUiIncentiveDataProviderV3 { - function getReservesIncentivesData(IPoolAddressesProvider provider) - external - view - returns (AggregatedReserveIncentiveData[] memory); + function getReservesIncentivesData( + IPoolAddressesProvider provider + ) external view returns (AggregatedReserveIncentiveData[] memory); - function getUserReservesIncentivesData(IPoolAddressesProvider provider, address user) - external - view - returns (UserReserveIncentiveData[] memory); + function getUserReservesIncentivesData( + IPoolAddressesProvider provider, + address user + ) external view returns (UserReserveIncentiveData[] memory); // generic method with full data - function getFullReservesIncentiveData(IPoolAddressesProvider provider, address user) - external - view - returns (AggregatedReserveIncentiveData[] memory, UserReserveIncentiveData[] memory); + function getFullReservesIncentiveData( + IPoolAddressesProvider provider, + address user + ) external view returns (AggregatedReserveIncentiveData[] memory, UserReserveIncentiveData[] memory); } interface IRewardsDistributor { - function getUserAssetData( - address user, - address asset, - address reward - ) external view returns (uint256); + function getUserAssetData(address user, address asset, address reward) external view returns (uint256); /** * @dev Returns the configuration of the distribution for a certain asset @@ -398,15 +397,7 @@ interface IRewardsDistributor { * @param reward The reward token of the incentivized asset * @return The asset index, the emission per second, the last updated timestamp and the distribution end timestamp **/ - function getRewardsData(address asset, address reward) - external - view - returns ( - uint256, - uint256, - uint256, - uint256 - ); + function getRewardsData(address asset, address reward) external view returns (uint256, uint256, uint256, uint256); /** * @dev Returns the list of available reward token addresses of an incentivized asset @@ -436,11 +427,7 @@ interface IRewardsDistributor { * @param reward The address of the reward token * @return The rewards amount **/ - function getUserRewards( - address[] calldata assets, - address user, - address reward - ) external view returns (uint256); + function getUserRewards(address[] calldata assets, address user, address reward) external view returns (uint256); /** * @dev Returns a list all rewards of an user, including already accrued and unrealized claimable rewards @@ -448,10 +435,10 @@ interface IRewardsDistributor { * @param user The address of the user * @return The function returns a Tuple of rewards list and the unclaimed rewards list **/ - function getAllUserRewards(address[] calldata assets, address user) - external - view - returns (address[] memory, uint256[] memory); + function getAllUserRewards( + address[] calldata assets, + address user + ) external view returns (address[] memory, uint256[] memory); /** * @dev Returns the decimals of an asset to calculate the distribution delta @@ -473,8 +460,7 @@ interface IRewardsController is IRewardsDistributor { } interface IUiPoolDataProviderV3 { - function getReservesData(IPoolAddressesProvider provider) - external - view - returns (AggregatedReserveData[] memory, BaseCurrencyInfo memory); + function getReservesData( + IPoolAddressesProvider provider + ) external view returns (AggregatedReserveData[] memory, BaseCurrencyInfo memory); } diff --git a/contracts/protocols/polygon/aave_v3/main.sol b/contracts/protocols/polygon/aave_v3/main.sol index d0895645..ad0f2cce 100644 --- a/contracts/protocols/polygon/aave_v3/main.sol +++ b/contracts/protocols/polygon/aave_v3/main.sol @@ -18,7 +18,11 @@ contract AaveV3Resolver is AaveV3Helper { *@return AaveV3TokenData details of tokens (e.g. symbol, decimals, ltv etc.). *@return ReserveIncentiveData details of user's rewards corresponding to the tokens passed. */ - function getPosition(address user, address[] memory tokens) + function getPosition( + address user, + address[] memory tokens, + address poolAddressProvider + ) public view returns ( @@ -35,18 +39,18 @@ contract AaveV3Resolver is AaveV3Helper { _tokens[i] = tokens[i] == getEthAddr() ? getWMaticAddr() : tokens[i]; } - AaveV3UserData memory userDetails = getUserData(user); + AaveV3UserData memory userDetails = getUserData(user, poolAddressProvider); // (TokenPrice[] memory tokenPrices, ) = getTokensPrices(userDetails.base.baseInUSD, _tokens); AaveV3UserTokenData[] memory tokensData = new AaveV3UserTokenData[](length); AaveV3TokenData[] memory collData = new AaveV3TokenData[](length); for (uint256 i = 0; i < length; i++) { - tokensData[i] = getUserTokenData(user, _tokens[i]); - collData[i] = userCollateralData(_tokens[i]); + tokensData[i] = getUserTokenData(user, _tokens[i], poolAddressProvider); + collData[i] = userCollateralData(_tokens[i], poolAddressProvider); } - return (userDetails, tokensData, collData, getIncentivesInfo(user)); + return (userDetails, tokensData, collData, getIncentivesInfo(user, poolAddressProvider)); } /** @@ -58,7 +62,10 @@ contract AaveV3Resolver is AaveV3Helper { *@return AaveV3TokenData details of tokens (e.g. symbol, decimals, ltv etc.). *@return ReserveIncentiveData details of user's rewards corresponding to the tokens in the market. */ - function getPositionAll(address user) + function getPositionAll( + address user, + address poolAddressProvider + ) public view returns ( @@ -68,7 +75,8 @@ contract AaveV3Resolver is AaveV3Helper { ReserveIncentiveData[] memory ) { - return getPosition(user, getList()); + address[] memory tokens = getList(poolAddressProvider); + return getPosition(user, tokens, poolAddressProvider); } /** @@ -78,9 +86,12 @@ contract AaveV3Resolver is AaveV3Helper { *@return collateral array with an element as true if the corresponding token is used as collateral by the user, false otherwise. *@return borrowed array with an element as true if the corresponding token is borrowed by the user, false otherwise. */ - function getConfiguration(address user) public view returns (bool[] memory collateral, bool[] memory borrowed) { - uint256 data = getConfig(user).data; - address[] memory reserveIndex = getList(); + function getConfiguration( + address user, + address poolAddressProvider + ) public view returns (bool[] memory collateral, bool[] memory borrowed) { + uint256 data = getConfig(user, poolAddressProvider).data; + address[] memory reserveIndex = getList(poolAddressProvider); collateral = new bool[](reserveIndex.length); borrowed = new bool[](reserveIndex.length); @@ -98,11 +109,11 @@ contract AaveV3Resolver is AaveV3Helper { *@notice get list of all tokens available in the market. *@return data array of token addresses available in the market. */ - function getReservesList() public view returns (address[] memory data) { - data = getList(); + function getReservesList(address poolAddressProvider) public view returns (address[] memory data) { + data = getList(poolAddressProvider); } } contract InstaAaveV3ResolverPolygon is AaveV3Resolver { - string public constant name = "AaveV3-Resolver-v1.0"; + string public constant name = "AaveV3-Resolver-v1.1"; } From 27f08214c67bc24e75fdef7bdb02cdebed462ea4 Mon Sep 17 00:00:00 2001 From: Samarendra Gouda Date: Wed, 9 Oct 2024 06:29:21 +0530 Subject: [PATCH 6/8] fix: add avalanche resolver --- .../protocols/avalanche/aave_v3/helpers.sol | 260 ++++++++++-------- .../avalanche/aave_v3/interfaces.sol | 132 ++++----- .../protocols/avalanche/aave_v3/main.sol | 35 ++- 3 files changed, 223 insertions(+), 204 deletions(-) diff --git a/contracts/protocols/avalanche/aave_v3/helpers.sol b/contracts/protocols/avalanche/aave_v3/helpers.sol index 42ccc8cd..16894d09 100644 --- a/contracts/protocols/avalanche/aave_v3/helpers.sol +++ b/contracts/protocols/avalanche/aave_v3/helpers.sol @@ -20,24 +20,6 @@ contract AaveV3Helper is DSMath { return 0xB31f66AA3C1e785363F0875A1B74E27b85FD66c7; //Avalanche WAVAX Address } - function getUiDataProvider() internal pure returns (address) { - return 0xdBbFaFC45983B4659E368a3025b81f69Ab6E5093; //Avalanche UiPoolDataProvider Address - } - - /** - *@dev Returns Pool AddressProvider Address - */ - function getPoolAddressProvider() internal pure returns (address) { - return 0xa97684ead0e402dC232d5A977953DF7ECBaB3CDb; //Avalanche PoolAddressesProvider address - } - - /** - *@dev Returns Pool DataProvider Address - */ - function getPoolDataProvider() internal pure returns (address) { - return 0x69FA688f1Dc47d4B5d8029D5a35FB7a548310654; //Avalanche PoolDataProvider address - } - /** *@dev Returns Aave Data Provider Address */ @@ -56,22 +38,15 @@ contract AaveV3Helper is DSMath { return 0xEBd36016B3eD09D4693Ed4251c67Bd858c3c7C9C; //Avalanche address } - /** - *@dev Returns StableDebtToken Address - */ - function getStableDebtToken() internal pure returns (address) { - return 0x52A1CeB68Ee6b7B5D13E0376A1E0E4423A8cE26e; //Avalanche address - } - - function getUiIncetivesProvider() internal view returns (address) { - return 0x270f51cf3F681010B46f5c4Ee2aD5120Db33026F; + function getUiIncetivesProvider() internal pure returns (address) { + return 0xC81CCebEA6A14bA007b96C0a1600D0bA0Df383a8; } function getChainLinkFeed() internal pure returns (address) { return 0x976B3D034E162d8bD72D6b9C989d545b839003b0; } - function getRewardsController() internal view returns (address) { + function getRewardsController() internal pure returns (address) { return 0x929EC64c34a17401F460460D4B9390518E5B473e; } @@ -139,8 +114,7 @@ contract AaveV3Helper is DSMath { // TokenPrice tokenPrice; AaveV3Token token; // uint256 collateralEmission; - // uint256 stableDebtEmission; - // uint256 varDebtEmission; + // uint256 debtEmission; } struct Flags { @@ -154,7 +128,6 @@ contract AaveV3Helper is DSMath { struct AaveV3Token { uint256 supplyCap; uint256 borrowCap; - uint256 eModeCategory; uint256 debtCeiling; uint256 debtCeilingDecimals; uint256 liquidationFee; @@ -163,11 +136,6 @@ contract AaveV3Helper is DSMath { bool isPaused; } - struct TokenPrice { - uint256 priceInEth; - uint256 priceInUsd; - } - //Rewards details struct ReserveIncentiveData { address underlyingAsset; @@ -186,6 +154,7 @@ contract AaveV3Helper is DSMath { address[] rewardsToken; uint256[] unbalancedAmounts; } + struct RewardsInfo { string rewardTokenSymbol; address rewardTokenAddress; @@ -194,10 +163,18 @@ contract AaveV3Helper is DSMath { uint256 precision; } - IPoolAddressesProvider internal provider = IPoolAddressesProvider(getPoolAddressProvider()); + struct TokenPrice { + uint256 priceInEth; + uint256 priceInUsd; + } + + struct PoolSpecificInfo { + IPoolAddressesProvider provider; + IPool pool; + IAaveProtocolDataProvider aaveData; + } + IAaveOracle internal aaveOracle = IAaveOracle(getAaveOracle()); - IAaveProtocolDataProvider internal aaveData = IAaveProtocolDataProvider(provider.getPoolDataProvider()); - IPool internal pool = IPool(provider.getPool()); IUiIncentiveDataProviderV3 internal uiIncentives = IUiIncentiveDataProviderV3(getUiIncetivesProvider()); IRewardsController internal rewardsCntr = IRewardsController(getRewardsController()); @@ -212,8 +189,15 @@ contract AaveV3Helper is DSMath { } } - function getIncentivesInfo(address user) internal view returns (ReserveIncentiveData[] memory incentives) { - AggregatedReserveIncentiveData[] memory _aggregateIncentive = uiIncentives.getReservesIncentivesData(provider); + function getIncentivesInfo( + address user, + address poolAddressProvider + ) internal view returns (ReserveIncentiveData[] memory incentives) { + PoolSpecificInfo memory poolInfo = getPoolSpecificInfo(poolAddressProvider); + + AggregatedReserveIncentiveData[] memory _aggregateIncentive = uiIncentives.getReservesIncentivesData( + poolInfo.provider + ); incentives = new ReserveIncentiveData[](_aggregateIncentive.length); for (uint256 i = 0; i < _aggregateIncentive.length; i++) { address[] memory rToken = new address[](1); @@ -248,8 +232,7 @@ contract AaveV3Helper is DSMath { } } - function getRewardInfo(RewardInfo[] memory rewards) internal view returns (RewardsInfo[] memory rewardData) { - // console.log(rewards.length); + function getRewardInfo(RewardInfo[] memory rewards) internal pure returns (RewardsInfo[] memory rewardData) { rewardData = new RewardsInfo[](rewards.length); for (uint256 i = 0; i < rewards.length; i++) { rewardData[i] = RewardsInfo( @@ -262,45 +245,61 @@ contract AaveV3Helper is DSMath { } } - function getTokensPrices(uint256 basePriceInUSD, address[] memory tokens) - internal - view - returns (TokenPrice[] memory tokenPrices, uint256 ethPrice) - { + function getTokensPrices( + uint256 basePriceInUSD, + address[] memory tokens + ) internal view returns (TokenPrice[] memory tokenPrices, uint256 ethPrice) { uint256[] memory _tokenPrices = aaveOracle.getAssetsPrices(tokens); tokenPrices = new TokenPrice[](_tokenPrices.length); ethPrice = uint256(AggregatorV3Interface(getChainLinkFeed()).latestAnswer()); for (uint256 i = 0; i < _tokenPrices.length; i++) { tokenPrices[i] = TokenPrice( - (_tokenPrices[i] * basePriceInUSD * 10**10) / ethPrice, - wmul(_tokenPrices[i] * 10**10, basePriceInUSD * 10**10) + (_tokenPrices[i] * basePriceInUSD * 10 ** 10) / ethPrice, + wmul(_tokenPrices[i] * 10 ** 10, basePriceInUSD * 10 ** 10) ); } } - function getEmodePrices(address priceOracleAddr, address[] memory tokens) - internal - view - returns (uint256[] memory tokenPrices) - { + function getEmodePrices( + address priceOracleAddr, + address[] memory tokens + ) internal view returns (uint256[] memory tokenPrices) { tokenPrices = IPriceOracle(priceOracleAddr).getAssetsPrices(tokens); + // tokenPrices = new uint256[](tokens.length); + // for (uint256 i = 0; i < tokens.length; i++) { + // tokenPrices[i] = IPriceOracle(priceOracleAddr).getAssetPrice(tokens[i]); + // } } - function getPendingRewards(address user, address[] memory _tokens) internal view returns (uint256 rewards) { + function getPendingRewards( + address user, + address[] memory _tokens, + address poolAddressProvider + ) internal view returns (uint256 rewards) { + PoolSpecificInfo memory poolInfo = getPoolSpecificInfo(poolAddressProvider); + uint256 arrLength = 2 * _tokens.length; address[] memory _atokens = new address[](arrLength); for (uint256 i = 0; i < _tokens.length; i++) { - (_atokens[2 * i], , _atokens[2 * i + 1]) = aaveData.getReserveTokensAddresses(_tokens[i]); + (_atokens[2 * i], , _atokens[2 * i + 1]) = poolInfo.aaveData.getReserveTokensAddresses(_tokens[i]); } rewards = IAaveIncentivesController(getAaveIncentivesAddress()).getRewardsBalance(_atokens, user); } - function getIsolationDebt(address token) internal view returns (uint256 isolationDebt) { - isolationDebt = uint256(pool.getReserveData(token).isolationModeTotalDebt); + function getIsolationDebt( + address token, + address poolAddressProvider + ) internal view returns (uint256 isolationDebt) { + PoolSpecificInfo memory poolInfo = getPoolSpecificInfo(poolAddressProvider); + isolationDebt = uint256(poolInfo.pool.getReserveData(token).isolationModeTotalDebt); } - function getUserData(address user) internal view returns (AaveV3UserData memory userData) { + function getUserData( + address user, + address poolAddressProvider + ) internal view returns (AaveV3UserData memory userData) { + PoolSpecificInfo memory poolInfo = getPoolSpecificInfo(poolAddressProvider); ( userData.totalCollateralBase, userData.totalBorrowsBase, @@ -308,14 +307,14 @@ contract AaveV3Helper is DSMath { userData.currentLiquidationThreshold, userData.ltv, userData.healthFactor - ) = pool.getUserAccountData(user); + ) = poolInfo.pool.getUserAccountData(user); userData.base = getBaseCurrencyDetails(); - userData.eModeId = pool.getUserEMode(user); + userData.eModeId = poolInfo.pool.getUserEMode(user); // userData.pendingRewards = getPendingRewards(tokens, user); } - function getFlags(address token) internal view returns (Flags memory flag) { + function getFlags(address token, IAaveProtocolDataProvider aaveData) internal view returns (Flags memory flag) { ( , , @@ -330,86 +329,96 @@ contract AaveV3Helper is DSMath { ) = aaveData.getReserveConfigurationData(token); } - function getIsolationBorrowStatus(address token) internal view returns (bool iBorrowStatus) { + function getIsolationBorrowStatus(address token, IPool pool) internal view returns (bool iBorrowStatus) { ReserveConfigurationMap memory self = (pool.getReserveData(token)).configuration; uint256 BORROWABLE_IN_ISOLATION_MASK = 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDFFFFFFFFFFFFFFF; return (self.data & ~BORROWABLE_IN_ISOLATION_MASK) != 0; } - function getV3Token(address token) internal view returns (AaveV3Token memory tokenData) { + function getV3Token( + address token, + IPool pool, + IAaveProtocolDataProvider aaveData + ) internal view returns (AaveV3Token memory tokenData) { ( (tokenData.borrowCap, tokenData.supplyCap), - tokenData.eModeCategory, tokenData.debtCeiling, tokenData.debtCeilingDecimals, tokenData.liquidationFee, tokenData.isPaused ) = ( aaveData.getReserveCaps(token), - aaveData.getReserveEModeCategory(token), aaveData.getDebtCeiling(token), aaveData.getDebtCeilingDecimals(), aaveData.getLiquidationProtocolFee(token), aaveData.getPaused(token) ); { - (tokenData.isolationBorrowEnabled) = getIsolationBorrowStatus(token); + (tokenData.isolationBorrowEnabled) = getIsolationBorrowStatus(token, pool); } // (tokenData.isolationModeTotalDebt) = getIsolationDebt(token); } - function getEmodeCategoryData(uint8 id, address[] memory tokens) - external - view - returns (EmodeData memory eModeData) - { - EModeCategory memory data_ = pool.getEModeCategoryData(id); + function getEmodeCategoryData( + uint8 id, + address poolAddressProvider + ) external view returns (EmodeData memory eModeData) { + PoolSpecificInfo memory poolInfo = getPoolSpecificInfo(poolAddressProvider); + EModeCollateralConfig memory config_ = poolInfo.pool.getEModeCategoryCollateralConfig(id); + string memory label = poolInfo.pool.getEModeCategoryLabel(id); + uint128 isCollateralBitmap = poolInfo.pool.getEModeCategoryCollateralBitmap(id); + uint128 isBorrowableBitmap = poolInfo.pool.getEModeCategoryBorrowableBitmap(id); + + EModeCategory memory data_ = EModeCategory( + config_.ltv, + config_.liquidationThreshold, + config_.liquidationBonus, + label, + isCollateralBitmap, + isBorrowableBitmap + ); { eModeData.data = data_; - // eModeData.price = getEmodePrices(data_.priceSource, tokens); //TODO + // eModeData.price = getEmodePrices(data_.priceSource, tokens); } } - function reserveConfig(address token) - internal - view - returns ( - uint256 decimals, - uint256 ltv, - uint256 threshold, - uint256 reserveFactor - ) - { + function reserveConfig( + address token, + IAaveProtocolDataProvider aaveData + ) internal view returns (uint256 decimals, uint256 ltv, uint256 threshold, uint256 reserveFactor) { (decimals, ltv, threshold, , reserveFactor, , , , , ) = aaveData.getReserveConfigurationData(token); } - function resData(address token) - internal - view - returns ( - uint256 availableLiquidity, - uint256 totalStableDebt, - uint256 totalVariableDebt - ) - { + function resData( + address token, + IAaveProtocolDataProvider aaveData + ) internal view returns (uint256 availableLiquidity, uint256 totalStableDebt, uint256 totalVariableDebt) { (, , availableLiquidity, totalStableDebt, totalVariableDebt, , , , , , , ) = aaveData.getReserveData(token); } - function getAaveTokensData(address token) internal view returns (ReserveAddresses memory reserve) { + function getAaveTokensData( + address token, + address poolAddressProvider + ) internal view returns (ReserveAddresses memory reserve) { + PoolSpecificInfo memory poolInfo = getPoolSpecificInfo(poolAddressProvider); ( reserve.aToken.tokenAddress, reserve.stableDebtToken.tokenAddress, reserve.variableDebtToken.tokenAddress - ) = aaveData.getReserveTokensAddresses(token); + ) = poolInfo.aaveData.getReserveTokensAddresses(token); reserve.aToken.symbol = IERC20Detailed(reserve.aToken.tokenAddress).symbol(); - reserve.stableDebtToken.symbol = IERC20Detailed(reserve.stableDebtToken.tokenAddress).symbol(); reserve.variableDebtToken.symbol = IERC20Detailed(reserve.variableDebtToken.tokenAddress).symbol(); reserve.aToken.decimals = IERC20Detailed(reserve.aToken.tokenAddress).decimals(); - reserve.stableDebtToken.decimals = IERC20Detailed(reserve.stableDebtToken.tokenAddress).decimals(); reserve.variableDebtToken.decimals = IERC20Detailed(reserve.variableDebtToken.tokenAddress).decimals(); } - function userCollateralData(address token) internal view returns (AaveV3TokenData memory aaveTokenData) { + function userCollateralData( + address token, + address poolAddressProvider + ) internal view returns (AaveV3TokenData memory aaveTokenData) { + PoolSpecificInfo memory poolInfo = getPoolSpecificInfo(poolAddressProvider); + aaveTokenData.asset = token; aaveTokenData.symbol = IERC20Detailed(token).symbol(); ( @@ -417,19 +426,21 @@ contract AaveV3Helper is DSMath { aaveTokenData.ltv, aaveTokenData.threshold, aaveTokenData.reserveFactor - ) = reserveConfig(token); + ) = reserveConfig(token, poolInfo.aaveData); { ( aaveTokenData.availableLiquidity, aaveTokenData.totalStableDebt, aaveTokenData.totalVariableDebt - ) = resData(token); + ) = resData(token, poolInfo.aaveData); } - aaveTokenData.reserves = getAaveTokensData(token); + aaveTokenData.token = getV3Token(token, poolInfo.pool, poolInfo.aaveData); // aaveTokenData.tokenPrice = assetPrice; + aaveTokenData.reserves = getAaveTokensData(token, poolAddressProvider); + //-------------INCENTIVE DETAILS--------------- // (, aaveTokenData.collateralEmission, ) = IAaveIncentivesController(getAaveIncentivesAddress()).assets( @@ -443,13 +454,13 @@ contract AaveV3Helper is DSMath { // ); } - function getUserTokenData(address user, address token) - internal - view - returns (AaveV3UserTokenData memory tokenData) - { - uint256 basePrice = IPriceOracle(IPoolAddressesProvider(getPoolAddressProvider()).getPriceOracle()) - .getAssetPrice(token); + function getUserTokenData( + address user, + address token, + address poolAddressProvider + ) internal view returns (AaveV3UserTokenData memory tokenData) { + PoolSpecificInfo memory poolInfo = getPoolSpecificInfo(poolAddressProvider); + uint256 basePrice = IPriceOracle(poolInfo.provider.getPriceOracle()).getAssetPrice(token); tokenData.price = basePrice; ( tokenData.supplyBalance, @@ -461,13 +472,13 @@ contract AaveV3Helper is DSMath { tokenData.supplyRate, , tokenData.isCollateral - ) = aaveData.getUserReserveData(token, user); + ) = poolInfo.aaveData.getUserReserveData(token, user); { - tokenData.flag = getFlags(token); - (, , , , , , tokenData.variableBorrowRate, tokenData.stableBorrowRate, , , , ) = aaveData.getReserveData( - token - ); + tokenData.flag = getFlags(token, poolInfo.aaveData); + (, , , , , , tokenData.variableBorrowRate, tokenData.stableBorrowRate, , , , ) = poolInfo + .aaveData + .getReserveData(token); } } @@ -475,7 +486,7 @@ contract AaveV3Helper is DSMath { ethPrice = uint256(AggregatorV3Interface(getChainLinkFeed()).latestAnswer()); } - function getPrices(bytes memory data) internal view returns (uint256) { + function getPrices(bytes memory data) internal pure returns (uint256) { (, BaseCurrencyInfo memory baseCurrency) = abi.decode(data, (AggregatedReserveData[], BaseCurrencyInfo)); return uint256(baseCurrency.marketReferenceCurrencyPriceInUsd); } @@ -498,8 +509,9 @@ contract AaveV3Helper is DSMath { // } } - function getList() public view returns (address[] memory data) { - data = pool.getReservesList(); + function getList(address poolAddressProvider) public view returns (address[] memory data) { + PoolSpecificInfo memory poolInfo = getPoolSpecificInfo(poolAddressProvider); + data = poolInfo.pool.getReservesList(); } function isUsingAsCollateralOrBorrowing(uint256 self, uint256 reserveIndex) public pure returns (bool) { @@ -517,7 +529,17 @@ contract AaveV3Helper is DSMath { return (self >> (reserveIndex * 2)) & 1 != 0; } - function getConfig(address user) public view returns (UserConfigurationMap memory data) { - data = pool.getUserConfiguration(user); + function getConfig( + address user, + address poolAddressProvider + ) public view returns (UserConfigurationMap memory data) { + PoolSpecificInfo memory poolInfo = getPoolSpecificInfo(poolAddressProvider); + data = poolInfo.pool.getUserConfiguration(user); + } + + function getPoolSpecificInfo(address poolAddressProvider) internal view returns (PoolSpecificInfo memory poolInfo) { + poolInfo.provider = IPoolAddressesProvider(poolAddressProvider); + poolInfo.pool = IPool(poolInfo.provider.getPool()); + poolInfo.aaveData = IAaveProtocolDataProvider(poolInfo.provider.getPoolDataProvider()); } } diff --git a/contracts/protocols/avalanche/aave_v3/interfaces.sol b/contracts/protocols/avalanche/aave_v3/interfaces.sol index 03a838a5..2fd2562d 100644 --- a/contracts/protocols/avalanche/aave_v3/interfaces.sol +++ b/contracts/protocols/avalanche/aave_v3/interfaces.sol @@ -28,8 +28,15 @@ struct EModeCategory { uint16 liquidationThreshold; uint16 liquidationBonus; // each eMode category may or may not have a custom oracle to override the individual assets price oracles - address priceSource; string label; + uint128 isCollateralBitmap; + uint128 isBorrowableBitmap; +} + +struct EModeCollateralConfig { + uint16 ltv; + uint16 liquidationThreshold; + uint16 liquidationBonus; } struct ReserveConfigurationMap { @@ -146,13 +153,16 @@ struct AggregatedReserveData { uint16 eModeLtv; uint16 eModeLiquidationThreshold; uint16 eModeLiquidationBonus; - address eModePriceSource; + uint128 isCollateralBitmap; + uint128 isBorrowableBitmap; string eModeLabel; bool borrowableInIsolation; } interface IPool { - function getUserAccountData(address user) + function getUserAccountData( + address user + ) external view returns ( @@ -164,12 +174,17 @@ interface IPool { uint256 healthFactor ); - function getEModeCategoryData(uint8 id) external view returns (EModeCategory memory); + // 3.2 Updated Interface for eMode + function getEModeCategoryCollateralConfig(uint8 id) external view returns (EModeCollateralConfig memory); + function getEModeCategoryLabel(uint8 id) external view returns (string memory); + function getEModeCategoryCollateralBitmap(uint8 id) external view returns (uint128); + function getEModeCategoryBorrowableBitmap(uint8 id) external view returns (uint128); + //@return emode id of the user function getUserEMode(address user) external view returns (uint256); - function getReservesList() external view virtual returns (address[] memory); + function getReservesList() external view returns (address[] memory); function getUserConfiguration(address user) external view returns (UserConfigurationMap memory); @@ -201,14 +216,7 @@ interface IAaveIncentivesController { // @dev Returns the configuration of the distribution for a certain asset // @return The asset index, the emission per second and the last updated timestamp - function assets(address asset) - external - view - returns ( - uint128, - uint128, - uint256 - ); + function assets(address asset) external view returns (uint128, uint128, uint256); } interface IAaveOracle is IPriceOracleGetter { @@ -235,7 +243,9 @@ interface IPoolAddressesProvider { interface IPoolDataProvider { // @notice Returns the reserve data - function getReserveData(address asset) + function getReserveData( + address asset + ) external view returns ( @@ -267,7 +277,9 @@ interface IStableDebtToken { } interface IAaveProtocolDataProvider is IPoolDataProvider { - function getReserveConfigurationData(address asset) + function getReserveConfigurationData( + address asset + ) external view returns ( @@ -287,8 +299,6 @@ interface IAaveProtocolDataProvider is IPoolDataProvider { function getLiquidationProtocolFee(address asset) external view returns (uint256); - function getReserveEModeCategory(address asset) external view returns (uint256); - function getReserveCaps(address asset) external view returns (uint256 borrowCap, uint256 supplyCap); // @notice Returns the debt ceiling of the reserve @@ -299,7 +309,9 @@ interface IAaveProtocolDataProvider is IPoolDataProvider { function getATokenTotalSupply(address asset) external view returns (uint256); - function getReserveData(address asset) + function getReserveData( + address asset + ) external view override @@ -318,7 +330,10 @@ interface IAaveProtocolDataProvider is IPoolDataProvider { uint40 lastUpdateTimestamp ); - function getUserReserveData(address asset, address user) + function getUserReserveData( + address asset, + address user + ) external view returns ( @@ -333,14 +348,9 @@ interface IAaveProtocolDataProvider is IPoolDataProvider { bool usageAsCollateralEnabled ); - function getReserveTokensAddresses(address asset) - external - view - returns ( - address aTokenAddress, - address stableDebtTokenAddress, - address variableDebtTokenAddress - ); + function getReserveTokensAddresses( + address asset + ) external view returns (address aTokenAddress, address stableDebtTokenAddress, address variableDebtTokenAddress); } //chainlink price feed @@ -350,13 +360,7 @@ interface AggregatorV3Interface { function latestRoundData() external view - returns ( - uint80 roundId, - int256 answer, - uint256 startedAt, - uint256 updatedAt, - uint80 answeredInRound - ); + returns (uint80 roundId, int256 answer, uint256 startedAt, uint256 updatedAt, uint80 answeredInRound); function latestAnswer() external view returns (int256); } @@ -368,29 +372,24 @@ interface IERC20Detailed { } interface IUiIncentiveDataProviderV3 { - function getReservesIncentivesData(IPoolAddressesProvider provider) - external - view - returns (AggregatedReserveIncentiveData[] memory); + function getReservesIncentivesData( + IPoolAddressesProvider provider + ) external view returns (AggregatedReserveIncentiveData[] memory); - function getUserReservesIncentivesData(IPoolAddressesProvider provider, address user) - external - view - returns (UserReserveIncentiveData[] memory); + function getUserReservesIncentivesData( + IPoolAddressesProvider provider, + address user + ) external view returns (UserReserveIncentiveData[] memory); // generic method with full data - function getFullReservesIncentiveData(IPoolAddressesProvider provider, address user) - external - view - returns (AggregatedReserveIncentiveData[] memory, UserReserveIncentiveData[] memory); + function getFullReservesIncentiveData( + IPoolAddressesProvider provider, + address user + ) external view returns (AggregatedReserveIncentiveData[] memory, UserReserveIncentiveData[] memory); } interface IRewardsDistributor { - function getUserAssetData( - address user, - address asset, - address reward - ) external view returns (uint256); + function getUserAssetData(address user, address asset, address reward) external view returns (uint256); /** * @dev Returns the configuration of the distribution for a certain asset @@ -398,15 +397,7 @@ interface IRewardsDistributor { * @param reward The reward token of the incentivized asset * @return The asset index, the emission per second, the last updated timestamp and the distribution end timestamp **/ - function getRewardsData(address asset, address reward) - external - view - returns ( - uint256, - uint256, - uint256, - uint256 - ); + function getRewardsData(address asset, address reward) external view returns (uint256, uint256, uint256, uint256); /** * @dev Returns the list of available reward token addresses of an incentivized asset @@ -436,11 +427,7 @@ interface IRewardsDistributor { * @param reward The address of the reward token * @return The rewards amount **/ - function getUserRewards( - address[] calldata assets, - address user, - address reward - ) external view returns (uint256); + function getUserRewards(address[] calldata assets, address user, address reward) external view returns (uint256); /** * @dev Returns a list all rewards of an user, including already accrued and unrealized claimable rewards @@ -448,10 +435,10 @@ interface IRewardsDistributor { * @param user The address of the user * @return The function returns a Tuple of rewards list and the unclaimed rewards list **/ - function getAllUserRewards(address[] calldata assets, address user) - external - view - returns (address[] memory, uint256[] memory); + function getAllUserRewards( + address[] calldata assets, + address user + ) external view returns (address[] memory, uint256[] memory); /** * @dev Returns the decimals of an asset to calculate the distribution delta @@ -473,8 +460,7 @@ interface IRewardsController is IRewardsDistributor { } interface IUiPoolDataProviderV3 { - function getReservesData(IPoolAddressesProvider provider) - external - view - returns (AggregatedReserveData[] memory, BaseCurrencyInfo memory); + function getReservesData( + IPoolAddressesProvider provider + ) external view returns (AggregatedReserveData[] memory, BaseCurrencyInfo memory); } diff --git a/contracts/protocols/avalanche/aave_v3/main.sol b/contracts/protocols/avalanche/aave_v3/main.sol index 9b16057f..c7a1c725 100644 --- a/contracts/protocols/avalanche/aave_v3/main.sol +++ b/contracts/protocols/avalanche/aave_v3/main.sol @@ -18,7 +18,11 @@ contract AaveV3Resolver is AaveV3Helper { *@return AaveV3TokenData details of tokens (e.g. symbol, decimals, ltv etc.). *@return ReserveIncentiveData details of user's rewards corresponding to the tokens passed. */ - function getPosition(address user, address[] memory tokens) + function getPosition( + address user, + address[] memory tokens, + address poolAddressProvider + ) public view returns ( @@ -35,18 +39,18 @@ contract AaveV3Resolver is AaveV3Helper { _tokens[i] = tokens[i] == getAvaxAddr() ? getWavaxAddr() : tokens[i]; } - AaveV3UserData memory userDetails = getUserData(user); + AaveV3UserData memory userDetails = getUserData(user, poolAddressProvider); // (TokenPrice[] memory tokenPrices, ) = getTokensPrices(userDetails.base.baseInUSD, _tokens); AaveV3UserTokenData[] memory tokensData = new AaveV3UserTokenData[](length); AaveV3TokenData[] memory collData = new AaveV3TokenData[](length); for (uint256 i = 0; i < length; i++) { - tokensData[i] = getUserTokenData(user, _tokens[i]); - collData[i] = userCollateralData(_tokens[i]); + tokensData[i] = getUserTokenData(user, _tokens[i], poolAddressProvider); + collData[i] = userCollateralData(_tokens[i], poolAddressProvider); } - return (userDetails, tokensData, collData, getIncentivesInfo(user)); + return (userDetails, tokensData, collData, getIncentivesInfo(user, poolAddressProvider)); } /** @@ -58,7 +62,10 @@ contract AaveV3Resolver is AaveV3Helper { *@return AaveV3TokenData details of tokens (e.g. symbol, decimals, ltv etc.). *@return ReserveIncentiveData details of user's rewards corresponding to the tokens in the market. */ - function getPositionAll(address user) + function getPositionAll( + address user, + address poolAddressProvider + ) public view returns ( @@ -68,7 +75,8 @@ contract AaveV3Resolver is AaveV3Helper { ReserveIncentiveData[] memory ) { - return getPosition(user, getList()); + address[] memory tokens = getList(poolAddressProvider); + return getPosition(user, tokens, poolAddressProvider); } /** @@ -78,9 +86,12 @@ contract AaveV3Resolver is AaveV3Helper { *@return collateral array with an element as true if the corresponding token is used as collateral by the user, false otherwise. *@return borrowed array with an element as true if the corresponding token is borrowed by the user, false otherwise. */ - function getConfiguration(address user) public view returns (bool[] memory collateral, bool[] memory borrowed) { - uint256 data = getConfig(user).data; - address[] memory reserveIndex = getList(); + function getConfiguration( + address user, + address poolAddressProvider + ) public view returns (bool[] memory collateral, bool[] memory borrowed) { + uint256 data = getConfig(user, poolAddressProvider).data; + address[] memory reserveIndex = getList(poolAddressProvider); collateral = new bool[](reserveIndex.length); borrowed = new bool[](reserveIndex.length); @@ -98,8 +109,8 @@ contract AaveV3Resolver is AaveV3Helper { *@notice get list of all tokens available in the market. *@return data array of token addresses available in the market. */ - function getReservesList() public view returns (address[] memory data) { - data = getList(); + function getReservesList(address poolAddressProvider) public view returns (address[] memory data) { + data = getList(poolAddressProvider); } } From 1f3478c612c71c6c7aa5315747ed4499bd8f8464 Mon Sep 17 00:00:00 2001 From: Samarendra Gouda Date: Thu, 10 Oct 2024 15:30:25 +0530 Subject: [PATCH 7/8] fix: update base resolver --- contracts/protocols/base/aave_v3/helpers.sol | 214 ++++++++++-------- .../protocols/base/aave_v3/interfaces.sol | 124 +++++----- contracts/protocols/base/aave_v3/main.sol | 37 +-- 3 files changed, 203 insertions(+), 172 deletions(-) diff --git a/contracts/protocols/base/aave_v3/helpers.sol b/contracts/protocols/base/aave_v3/helpers.sol index 54642daa..e174bc7e 100644 --- a/contracts/protocols/base/aave_v3/helpers.sol +++ b/contracts/protocols/base/aave_v3/helpers.sol @@ -4,8 +4,6 @@ import "./interfaces.sol"; import { DSMath } from "../../../utils/dsmath.sol"; contract AaveV3Helper is DSMath { - // ----------------------- USING LATEST ADDRESSES ----------------------------- - /** *@dev Returns ethereum address */ @@ -20,20 +18,6 @@ contract AaveV3Helper is DSMath { return 0x4200000000000000000000000000000000000006; } - /** - *@dev Returns Pool AddressProvider Address - */ - function getPoolAddressProvider() internal pure returns (address) { - return 0xe20fCBdBfFC4Dd138cE8b2E6FBb6CB49777ad64D; - } - - /** - *@dev Returns Pool DataProvider Address - */ - function getPoolDataProvider() internal pure returns (address) { - return 0x2d8A3C5677189723C4cB8873CfC9C8976FDF38Ac; - } - /** *@dev Returns AaveOracle Address */ @@ -41,14 +25,23 @@ contract AaveV3Helper is DSMath { return 0x2Cc0Fc26eD4563A5ce5e8bdcfe1A2878676Ae156; } + /** + *@dev Returns Chainlink Feed Address + */ function getChainLinkFeed() internal pure returns (address) { return 0x71041dddad3595F9CEd3DcCFBe3D1F4b0a16Bb70; } + /** + *@dev Returns UI Incentives Provider Feed Address + */ function getUiIncetivesProvider() internal pure returns (address) { - return 0xEdD3b4737C1a0011626631a977b91Cf3E944982d; + return 0x5c5228aC8BC1528482514aF3e27E692495148717; } + /** + *@dev Returns Rewards Controller Address + */ function getRewardsController() internal pure returns (address) { return 0xf9cc4F0D883F1a1eb2c253bdb46c254Ca51E1F44; } @@ -125,7 +118,6 @@ contract AaveV3Helper is DSMath { struct AaveV3Token { uint256 supplyCap; uint256 borrowCap; - uint256 eModeCategory; uint256 debtCeiling; uint256 debtCeilingDecimals; uint256 liquidationFee; @@ -166,10 +158,13 @@ contract AaveV3Helper is DSMath { uint256 precision; } - IPoolAddressesProvider internal provider = IPoolAddressesProvider(getPoolAddressProvider()); + struct PoolSpecificInfo { + IPoolAddressesProvider provider; + IPool pool; + IAaveProtocolDataProvider aaveData; + } + IAaveOracle internal aaveOracle = IAaveOracle(getAaveOracle()); - IAaveProtocolDataProvider internal aaveData = IAaveProtocolDataProvider(provider.getPoolDataProvider()); - IPool internal pool = IPool(provider.getPool()); IUiIncentiveDataProviderV3 internal uiIncentives = IUiIncentiveDataProviderV3(getUiIncetivesProvider()); IRewardsController internal rewardsCntr = IRewardsController(getRewardsController()); @@ -184,8 +179,15 @@ contract AaveV3Helper is DSMath { } } - function getIncentivesInfo(address user) internal view returns (ReserveIncentiveData[] memory incentives) { - AggregatedReserveIncentiveData[] memory _aggregateIncentive = uiIncentives.getReservesIncentivesData(provider); + function getIncentivesInfo( + address user, + address poolAddressProvider + ) internal view returns (ReserveIncentiveData[] memory incentives) { + PoolSpecificInfo memory poolInfo = getPoolSpecificInfo(poolAddressProvider); + + AggregatedReserveIncentiveData[] memory _aggregateIncentive = uiIncentives.getReservesIncentivesData( + poolInfo.provider + ); incentives = new ReserveIncentiveData[](_aggregateIncentive.length); for (uint256 i = 0; i < _aggregateIncentive.length; i++) { address[] memory rToken = new address[](1); @@ -234,36 +236,39 @@ contract AaveV3Helper is DSMath { } } - function getTokensPrices(uint256 basePriceInUSD, address[] memory tokens) - internal - view - returns (TokenPrice[] memory tokenPrices, uint256 ethPrice) - { + function getTokensPrices( + uint256 basePriceInUSD, + address[] memory tokens + ) internal view returns (TokenPrice[] memory tokenPrices, uint256 ethPrice) { uint256[] memory _tokenPrices = aaveOracle.getAssetsPrices(tokens); tokenPrices = new TokenPrice[](_tokenPrices.length); ethPrice = uint256(AggregatorV3Interface(getChainLinkFeed()).latestAnswer()); for (uint256 i = 0; i < _tokenPrices.length; i++) { tokenPrices[i] = TokenPrice( - (_tokenPrices[i] * basePriceInUSD * 10**10) / ethPrice, - wmul(_tokenPrices[i] * 10**10, basePriceInUSD * 10**10) + (_tokenPrices[i] * basePriceInUSD * 10 ** 10) / ethPrice, + wmul(_tokenPrices[i] * 10 ** 10, basePriceInUSD * 10 ** 10) ); } } - function getEmodePrices(address priceOracleAddr, address[] memory tokens) - internal - view - returns (uint256[] memory tokenPrices) - { + function getEmodePrices( + address priceOracleAddr, + address[] memory tokens + ) internal view returns (uint256[] memory tokenPrices) { tokenPrices = IPriceOracle(priceOracleAddr).getAssetsPrices(tokens); } - function getIsolationDebt(address token) internal view returns (uint256 isolationDebt) { + function getIsolationDebt(address token, IPool pool) internal view returns (uint256 isolationDebt) { isolationDebt = uint256(pool.getReserveData(token).isolationModeTotalDebt); } - function getUserData(address user) internal view returns (AaveV3UserData memory userData) { + function getUserData( + address user, + address poolAddressProvider + ) internal view returns (AaveV3UserData memory userData) { + PoolSpecificInfo memory poolInfo = getPoolSpecificInfo(poolAddressProvider); + ( userData.totalCollateralBase, userData.totalBorrowsBase, @@ -271,13 +276,13 @@ contract AaveV3Helper is DSMath { userData.currentLiquidationThreshold, userData.ltv, userData.healthFactor - ) = pool.getUserAccountData(user); + ) = poolInfo.pool.getUserAccountData(user); userData.base = getBaseCurrencyDetails(); - userData.eModeId = pool.getUserEMode(user); + userData.eModeId = poolInfo.pool.getUserEMode(user); } - function getFlags(address token) internal view returns (Flags memory flag) { + function getFlags(address token, IAaveProtocolDataProvider aaveData) internal view returns (Flags memory flag) { ( , , @@ -292,16 +297,19 @@ contract AaveV3Helper is DSMath { ) = aaveData.getReserveConfigurationData(token); } - function getIsolationBorrowStatus(address token) internal view returns (bool iBorrowStatus) { + function getIsolationBorrowStatus(address token, IPool pool) internal view returns (bool iBorrowStatus) { ReserveConfigurationMap memory self = (pool.getReserveData(token)).configuration; uint256 BORROWABLE_IN_ISOLATION_MASK = 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDFFFFFFFFFFFFFFF; return (self.data & ~BORROWABLE_IN_ISOLATION_MASK) != 0; } - function getV3Token(address token) internal view returns (AaveV3Token memory tokenData) { + function getV3Token( + address token, + IPool pool, + IAaveProtocolDataProvider aaveData + ) internal view returns (AaveV3Token memory tokenData) { ( (tokenData.borrowCap, tokenData.supplyCap), - tokenData.eModeCategory, tokenData.debtCeiling, tokenData.debtCeilingDecimals, tokenData.liquidationFee, @@ -309,7 +317,6 @@ contract AaveV3Helper is DSMath { tokenData.flashLoanEnabled ) = ( aaveData.getReserveCaps(token), - aaveData.getReserveEModeCategory(token), aaveData.getDebtCeiling(token), aaveData.getDebtCeilingDecimals(), aaveData.getLiquidationProtocolFee(token), @@ -317,7 +324,7 @@ contract AaveV3Helper is DSMath { aaveData.getFlashLoanEnabled(token) ); { - (tokenData.isolationBorrowEnabled) = getIsolationBorrowStatus(token); + (tokenData.isolationBorrowEnabled) = getIsolationBorrowStatus(token, pool); } } @@ -325,53 +332,66 @@ contract AaveV3Helper is DSMath { ethPrice = uint256(AggregatorV3Interface(getChainLinkFeed()).latestAnswer()); } - function getEmodeCategoryData(uint8 id) external view returns (EmodeData memory eModeData) { - EModeCategory memory data_ = pool.getEModeCategoryData(id); + function getEmodeCategoryData( + uint8 id, + address poolAddressProvider + ) external view returns (EmodeData memory eModeData) { + PoolSpecificInfo memory poolInfo = getPoolSpecificInfo(poolAddressProvider); + + EModeCollateralConfig memory config_ = poolInfo.pool.getEModeCategoryCollateralConfig(id); + string memory label = poolInfo.pool.getEModeCategoryLabel(id); + uint128 isCollateralBitmap = poolInfo.pool.getEModeCategoryCollateralBitmap(id); + uint128 isBorrowableBitmap = poolInfo.pool.getEModeCategoryBorrowableBitmap(id); + + EModeCategory memory data_ = EModeCategory( + config_.ltv, + config_.liquidationThreshold, + config_.liquidationBonus, + label, + isCollateralBitmap, + isBorrowableBitmap + ); { eModeData.data = data_; } } - function reserveConfig(address token) - internal - view - returns ( - uint256 decimals, - uint256 ltv, - uint256 threshold, - uint256 reserveFactor - ) - { + function reserveConfig( + address token, + IAaveProtocolDataProvider aaveData + ) internal view returns (uint256 decimals, uint256 ltv, uint256 threshold, uint256 reserveFactor) { (decimals, ltv, threshold, , reserveFactor, , , , , ) = aaveData.getReserveConfigurationData(token); } - function resData(address token) - internal - view - returns ( - uint256 availableLiquidity, - uint256 totalStableDebt, - uint256 totalVariableDebt - ) - { + function resData( + address token, + IAaveProtocolDataProvider aaveData + ) internal view returns (uint256 availableLiquidity, uint256 totalStableDebt, uint256 totalVariableDebt) { (, , availableLiquidity, totalStableDebt, totalVariableDebt, , , , , , , ) = aaveData.getReserveData(token); } - function getAaveTokensData(address token) internal view returns (ReserveAddresses memory reserve) { + function getAaveTokensData( + address token, + IAaveProtocolDataProvider aaveData + ) internal view returns (ReserveAddresses memory reserve) { ( reserve.aToken.tokenAddress, reserve.stableDebtToken.tokenAddress, reserve.variableDebtToken.tokenAddress ) = aaveData.getReserveTokensAddresses(token); + reserve.aToken.symbol = IERC20Detailed(reserve.aToken.tokenAddress).symbol(); - reserve.stableDebtToken.symbol = IERC20Detailed(reserve.stableDebtToken.tokenAddress).symbol(); reserve.variableDebtToken.symbol = IERC20Detailed(reserve.variableDebtToken.tokenAddress).symbol(); reserve.aToken.decimals = IERC20Detailed(reserve.aToken.tokenAddress).decimals(); - reserve.stableDebtToken.decimals = IERC20Detailed(reserve.stableDebtToken.tokenAddress).decimals(); reserve.variableDebtToken.decimals = IERC20Detailed(reserve.variableDebtToken.tokenAddress).decimals(); } - function userCollateralData(address token) internal view returns (AaveV3TokenData memory aaveTokenData) { + function userCollateralData( + address token, + address poolAddressProvider + ) internal view returns (AaveV3TokenData memory aaveTokenData) { + PoolSpecificInfo memory poolInfo = getPoolSpecificInfo(poolAddressProvider); + aaveTokenData.asset = token; aaveTokenData.symbol = IERC20Detailed(token).symbol(); ( @@ -379,30 +399,33 @@ contract AaveV3Helper is DSMath { aaveTokenData.ltv, aaveTokenData.threshold, aaveTokenData.reserveFactor - ) = reserveConfig(token); + ) = reserveConfig(token, poolInfo.aaveData); { ( aaveTokenData.availableLiquidity, aaveTokenData.totalStableDebt, aaveTokenData.totalVariableDebt - ) = resData(token); + ) = resData(token, poolInfo.aaveData); } - aaveTokenData.token = getV3Token(token); + aaveTokenData.token = getV3Token(token, poolInfo.pool, poolInfo.aaveData); //-------------INCENTIVE DETAILS--------------- - aaveTokenData.reserves = getAaveTokensData(token); + aaveTokenData.reserves = getAaveTokensData(token, poolInfo.aaveData); } - function getUserTokenData(address user, address token) - internal - view - returns (AaveV3UserTokenData memory tokenData) - { - uint256 basePrice = IPriceOracle(IPoolAddressesProvider(getPoolAddressProvider()).getPriceOracle()) - .getAssetPrice(token); + function getUserTokenData( + address user, + address token, + address poolAddressProvider + ) internal view returns (AaveV3UserTokenData memory tokenData) { + PoolSpecificInfo memory poolInfo = getPoolSpecificInfo(poolAddressProvider); + + uint256 basePrice = IPriceOracle(IPoolAddressesProvider(poolInfo.provider).getPriceOracle()).getAssetPrice( + token + ); tokenData.price = basePrice; ( tokenData.supplyBalance, @@ -414,13 +437,13 @@ contract AaveV3Helper is DSMath { tokenData.supplyRate, , tokenData.isCollateral - ) = aaveData.getUserReserveData(token, user); + ) = poolInfo.aaveData.getUserReserveData(token, user); { - tokenData.flag = getFlags(token); - (, , , , , , tokenData.variableBorrowRate, tokenData.stableBorrowRate, , , , ) = aaveData.getReserveData( - token - ); + tokenData.flag = getFlags(token, poolInfo.aaveData); + (, , , , , , tokenData.variableBorrowRate, tokenData.stableBorrowRate, , , , ) = poolInfo + .aaveData + .getReserveData(token); } } @@ -447,8 +470,9 @@ contract AaveV3Helper is DSMath { // } } - function getList() public view returns (address[] memory data) { - data = pool.getReservesList(); + function getList(address poolAddressProvider) public view returns (address[] memory data) { + PoolSpecificInfo memory poolInfo = getPoolSpecificInfo(poolAddressProvider); + data = poolInfo.pool.getReservesList(); } function isUsingAsCollateralOrBorrowing(uint256 self, uint256 reserveIndex) public pure returns (bool) { @@ -466,7 +490,17 @@ contract AaveV3Helper is DSMath { return (self >> (reserveIndex * 2)) & 1 != 0; } - function getConfig(address user) public view returns (UserConfigurationMap memory data) { - data = pool.getUserConfiguration(user); + function getConfig( + address user, + address poolAddressProvider + ) public view returns (UserConfigurationMap memory data) { + PoolSpecificInfo memory poolInfo = getPoolSpecificInfo(poolAddressProvider); + data = poolInfo.pool.getUserConfiguration(user); + } + + function getPoolSpecificInfo(address poolAddressProvider) internal view returns (PoolSpecificInfo memory poolInfo) { + poolInfo.provider = IPoolAddressesProvider(poolAddressProvider); + poolInfo.pool = IPool(poolInfo.provider.getPool()); + poolInfo.aaveData = IAaveProtocolDataProvider(poolInfo.provider.getPoolDataProvider()); } } diff --git a/contracts/protocols/base/aave_v3/interfaces.sol b/contracts/protocols/base/aave_v3/interfaces.sol index fd20de9c..e3dfd93c 100644 --- a/contracts/protocols/base/aave_v3/interfaces.sol +++ b/contracts/protocols/base/aave_v3/interfaces.sol @@ -28,8 +28,15 @@ struct EModeCategory { uint16 liquidationThreshold; uint16 liquidationBonus; // each eMode category may or may not have a custom oracle to override the individual assets price oracles - address priceSource; string label; + uint128 isCollateralBitmap; + uint128 isBorrowableBitmap; +} + +struct EModeCollateralConfig { + uint16 ltv; + uint16 liquidationThreshold; + uint16 liquidationBonus; } struct ReserveConfigurationMap { @@ -153,13 +160,16 @@ struct AggregatedReserveData { uint16 eModeLtv; uint16 eModeLiquidationThreshold; uint16 eModeLiquidationBonus; - address eModePriceSource; + uint128 isCollateralBitmap; + uint128 isBorrowableBitmap; string eModeLabel; bool borrowableInIsolation; } interface IPool { - function getUserAccountData(address user) + function getUserAccountData( + address user + ) external view returns ( @@ -171,12 +181,16 @@ interface IPool { uint256 healthFactor ); - function getEModeCategoryData(uint8 id) external view returns (EModeCategory memory); + // 3.2 Updated Interface for eMode + function getEModeCategoryCollateralConfig(uint8 id) external view returns (EModeCollateralConfig memory); + function getEModeCategoryLabel(uint8 id) external view returns (string memory); + function getEModeCategoryCollateralBitmap(uint8 id) external view returns (uint128); + function getEModeCategoryBorrowableBitmap(uint8 id) external view returns (uint128); //@return emode id of the user function getUserEMode(address user) external view returns (uint256); - function getReservesList() external view virtual returns (address[] memory); + function getReservesList() external view returns (address[] memory); function getUserConfiguration(address user) external view returns (UserConfigurationMap memory); @@ -208,14 +222,7 @@ interface IAaveIncentivesController { // @dev Returns the configuration of the distribution for a certain asset // @return The asset index, the emission per second and the last updated timestamp - function assets(address asset) - external - view - returns ( - uint128, - uint128, - uint256 - ); + function assets(address asset) external view returns (uint128, uint128, uint256); } interface IAaveOracle is IPriceOracleGetter { @@ -242,7 +249,9 @@ interface IPoolAddressesProvider { interface IPoolDataProvider { // @notice Returns the reserve data - function getReserveData(address asset) + function getReserveData( + address asset + ) external view returns ( @@ -274,7 +283,9 @@ interface IStableDebtToken { } interface IAaveProtocolDataProvider is IPoolDataProvider { - function getReserveConfigurationData(address asset) + function getReserveConfigurationData( + address asset + ) external view returns ( @@ -301,8 +312,6 @@ interface IAaveProtocolDataProvider is IPoolDataProvider { function getLiquidationProtocolFee(address asset) external view returns (uint256); - function getReserveEModeCategory(address asset) external view returns (uint256); - function getReserveCaps(address asset) external view returns (uint256 borrowCap, uint256 supplyCap); // @notice Returns the debt ceiling of the reserve @@ -313,7 +322,9 @@ interface IAaveProtocolDataProvider is IPoolDataProvider { function getATokenTotalSupply(address asset) external view returns (uint256); - function getReserveData(address asset) + function getReserveData( + address asset + ) external view override @@ -332,7 +343,10 @@ interface IAaveProtocolDataProvider is IPoolDataProvider { uint40 lastUpdateTimestamp ); - function getUserReserveData(address asset, address user) + function getUserReserveData( + address asset, + address user + ) external view returns ( @@ -347,14 +361,9 @@ interface IAaveProtocolDataProvider is IPoolDataProvider { bool usageAsCollateralEnabled ); - function getReserveTokensAddresses(address asset) - external - view - returns ( - address aTokenAddress, - address stableDebtTokenAddress, - address variableDebtTokenAddress - ); + function getReserveTokensAddresses( + address asset + ) external view returns (address aTokenAddress, address stableDebtTokenAddress, address variableDebtTokenAddress); } //chainlink price feed @@ -364,13 +373,7 @@ interface AggregatorV3Interface { function latestRoundData() external view - returns ( - uint80 roundId, - int256 answer, - uint256 startedAt, - uint256 updatedAt, - uint80 answeredInRound - ); + returns (uint80 roundId, int256 answer, uint256 startedAt, uint256 updatedAt, uint80 answeredInRound); function latestAnswer() external view returns (int256); } @@ -382,29 +385,24 @@ interface IERC20Detailed { } interface IUiIncentiveDataProviderV3 { - function getReservesIncentivesData(IPoolAddressesProvider provider) - external - view - returns (AggregatedReserveIncentiveData[] memory); + function getReservesIncentivesData( + IPoolAddressesProvider provider + ) external view returns (AggregatedReserveIncentiveData[] memory); - function getUserReservesIncentivesData(IPoolAddressesProvider provider, address user) - external - view - returns (UserReserveIncentiveData[] memory); + function getUserReservesIncentivesData( + IPoolAddressesProvider provider, + address user + ) external view returns (UserReserveIncentiveData[] memory); // generic method with full data - function getFullReservesIncentiveData(IPoolAddressesProvider provider, address user) - external - view - returns (AggregatedReserveIncentiveData[] memory, UserReserveIncentiveData[] memory); + function getFullReservesIncentiveData( + IPoolAddressesProvider provider, + address user + ) external view returns (AggregatedReserveIncentiveData[] memory, UserReserveIncentiveData[] memory); } interface IRewardsDistributor { - function getUserAssetData( - address user, - address asset, - address reward - ) external view returns (uint256); + function getUserAssetData(address user, address asset, address reward) external view returns (uint256); /** * @dev Returns the configuration of the distribution for a certain asset @@ -412,15 +410,7 @@ interface IRewardsDistributor { * @param reward The reward token of the incentivized asset * @return The asset index, the emission per second, the last updated timestamp and the distribution end timestamp **/ - function getRewardsData(address asset, address reward) - external - view - returns ( - uint256, - uint256, - uint256, - uint256 - ); + function getRewardsData(address asset, address reward) external view returns (uint256, uint256, uint256, uint256); /** * @dev Returns the list of available reward token addresses of an incentivized asset @@ -451,11 +441,7 @@ interface IRewardsDistributor { * @param reward The address of the reward token * @return The rewards amount **/ - function getUserRewards( - address[] calldata assets, - address user, - address reward - ) external view returns (uint256); + function getUserRewards(address[] calldata assets, address user, address reward) external view returns (uint256); /** * @dev Returns a list all rewards of an user, including already accrued and unrealized claimable rewards @@ -463,10 +449,10 @@ interface IRewardsDistributor { * @param user The address of the user * @return The function returns a Tuple of rewards list and the unclaimed rewards list **/ - function getAllUserRewards(address[] calldata assets, address user) - external - view - returns (address[] memory, uint256[] memory); + function getAllUserRewards( + address[] calldata assets, + address user + ) external view returns (address[] memory, uint256[] memory); /** * @dev Returns the decimals of an asset to calculate the distribution delta diff --git a/contracts/protocols/base/aave_v3/main.sol b/contracts/protocols/base/aave_v3/main.sol index 7190ec5e..a83eb490 100644 --- a/contracts/protocols/base/aave_v3/main.sol +++ b/contracts/protocols/base/aave_v3/main.sol @@ -20,7 +20,11 @@ contract AaveV3Resolver is AaveV3Helper { *@return AaveV3TokenData details of tokens (e.g. symbol, decimals, ltv etc.). *@return ReserveIncentiveData details of user's rewards corresponding to the tokens passed. */ - function getPosition(address user, address[] memory tokens) + function getPosition( + address user, + address[] memory tokens, + address poolAddressProvider + ) public view returns ( @@ -37,17 +41,17 @@ contract AaveV3Resolver is AaveV3Helper { _tokens[i] = tokens[i] == getEthAddr() ? getWethAddr() : tokens[i]; } - AaveV3UserData memory userDetails = getUserData(user); + AaveV3UserData memory userDetails = getUserData(user, poolAddressProvider); AaveV3UserTokenData[] memory tokensData = new AaveV3UserTokenData[](length); AaveV3TokenData[] memory collData = new AaveV3TokenData[](length); for (uint256 i = 0; i < length; i++) { - tokensData[i] = getUserTokenData(user, _tokens[i]); - collData[i] = userCollateralData(_tokens[i]); + tokensData[i] = getUserTokenData(user, _tokens[i], poolAddressProvider); + collData[i] = userCollateralData(_tokens[i], poolAddressProvider); } - return (userDetails, tokensData, collData, getIncentivesInfo(user)); + return (userDetails, tokensData, collData, getIncentivesInfo(user, poolAddressProvider)); } /** @@ -60,7 +64,10 @@ contract AaveV3Resolver is AaveV3Helper { *@return AaveV3TokenData details of tokens (e.g. symbol, decimals, ltv etc.). *@return ReserveIncentiveData details of user's rewards corresponding to the tokens in the market. */ - function getPositionAll(address user) + function getPositionAll( + address user, + address poolAddressProvider + ) public view returns ( @@ -70,7 +77,8 @@ contract AaveV3Resolver is AaveV3Helper { ReserveIncentiveData[] memory ) { - return getPosition(user, getList()); + address[] memory tokens = getList(poolAddressProvider); + return getPosition(user, tokens, poolAddressProvider); } /** @@ -82,9 +90,12 @@ contract AaveV3Resolver is AaveV3Helper { *@return borrowed array with an element as true if the corresponding token is borrowed by the user, false otherwise. */ - function getConfiguration(address user) public view returns (bool[] memory collateral, bool[] memory borrowed) { - uint256 data = getConfig(user).data; - address[] memory reserveIndex = getList(); + function getConfiguration( + address user, + address poolAddressProvider + ) public view returns (bool[] memory collateral, bool[] memory borrowed) { + uint256 data = getConfig(user, poolAddressProvider).data; + address[] memory reserveIndex = getList(poolAddressProvider); collateral = new bool[](reserveIndex.length); borrowed = new bool[](reserveIndex.length); @@ -102,11 +113,11 @@ contract AaveV3Resolver is AaveV3Helper { *@notice get list of all tokens available in the market. *@return data array of token addresses available in the market. */ - function getReservesList() public view returns (address[] memory data) { - data = getList(); + function getReservesList(address poolAddressProvider) public view returns (address[] memory data) { + data = getList(poolAddressProvider); } } contract InstaAaveV3ResolverBase is AaveV3Resolver { - string public constant name = "AaveV3-Resolver-v1.0"; + string public constant name = "AaveV3-Resolver-v1.1"; } From 16c9e452eecc3570e2e9f26f70274e88d02e68c3 Mon Sep 17 00:00:00 2001 From: Samarendra Gouda Date: Thu, 10 Oct 2024 20:28:00 +0530 Subject: [PATCH 8/8] fix: add emode assets and test --- contracts/protocols/base/aave_v3/helpers.sol | 40 +++- test/base/aave_v3.test.ts | 239 +++++++++++++++++++ 2 files changed, 278 insertions(+), 1 deletion(-) create mode 100644 test/base/aave_v3.test.ts diff --git a/contracts/protocols/base/aave_v3/helpers.sol b/contracts/protocols/base/aave_v3/helpers.sol index e174bc7e..b0ec8f2f 100644 --- a/contracts/protocols/base/aave_v3/helpers.sol +++ b/contracts/protocols/base/aave_v3/helpers.sol @@ -4,6 +4,8 @@ import "./interfaces.sol"; import { DSMath } from "../../../utils/dsmath.sol"; contract AaveV3Helper is DSMath { + uint16 internal constant MAX_RESERVES_COUNT = 128; + /** *@dev Returns ethereum address */ @@ -66,6 +68,8 @@ contract AaveV3Helper is DSMath { struct EmodeData { EModeCategory data; + address[] collateralTokens; + address[] borrowableTokens; } struct AaveV3UserTokenData { @@ -337,12 +341,31 @@ contract AaveV3Helper is DSMath { address poolAddressProvider ) external view returns (EmodeData memory eModeData) { PoolSpecificInfo memory poolInfo = getPoolSpecificInfo(poolAddressProvider); - + + // Get Reserves List + address[] memory list = getList(poolAddressProvider); + EModeCollateralConfig memory config_ = poolInfo.pool.getEModeCategoryCollateralConfig(id); string memory label = poolInfo.pool.getEModeCategoryLabel(id); uint128 isCollateralBitmap = poolInfo.pool.getEModeCategoryCollateralBitmap(id); uint128 isBorrowableBitmap = poolInfo.pool.getEModeCategoryBorrowableBitmap(id); + address[] memory collateralTokens_ = new address[](list.length); + address[] memory borrowableTokens_ = new address[](list.length); + + // Iterate over the list of reserves and populate the collateral and borrowable tokens for the eMode + for (uint16 i = 0; i < list.length;) { + if (isReserveEnabledOnBitmap(isCollateralBitmap, i)) { + collateralTokens_[i] = list[i]; + } + if (isReserveEnabledOnBitmap(isBorrowableBitmap, i)) { + borrowableTokens_[i] = list[i]; + } + unchecked { + i++; + } + } + EModeCategory memory data_ = EModeCategory( config_.ltv, config_.liquidationThreshold, @@ -353,6 +376,8 @@ contract AaveV3Helper is DSMath { ); { eModeData.data = data_; + eModeData.collateralTokens = collateralTokens_; + eModeData.borrowableTokens = borrowableTokens_; } } @@ -503,4 +528,17 @@ contract AaveV3Helper is DSMath { poolInfo.pool = IPool(poolInfo.provider.getPool()); poolInfo.aaveData = IAaveProtocolDataProvider(poolInfo.provider.getPoolDataProvider()); } + + /** + * @notice Validates if a reserveIndex is flagged as enabled on a given bitmap + * @param bitmap The bitmap + * @param reserveIndex The index of the reserve in the bitmap + * @return True if the reserveindex is flagged true + */ + function isReserveEnabledOnBitmap(uint128 bitmap, uint256 reserveIndex) internal pure returns (bool) { + unchecked { + require(reserveIndex < MAX_RESERVES_COUNT, "74"); //'Invalid reserve index' + return (bitmap >> reserveIndex) & 1 != 0; + } + } } diff --git a/test/base/aave_v3.test.ts b/test/base/aave_v3.test.ts new file mode 100644 index 00000000..30cef7a0 --- /dev/null +++ b/test/base/aave_v3.test.ts @@ -0,0 +1,239 @@ +import { SignerWithAddress } from "@nomiclabs/hardhat-ethers/signers"; +import hre from "hardhat"; +import { expect } from "chai"; +import { formatUnits } from "ethers/lib/utils"; +import { ethers } from "hardhat"; +import { InstaAaveV3ResolverBase, InstaAaveV3ResolverBase__factory } from "../../typechain"; +import { Tokens } from "../consts"; + +describe("Aave", () => { + const POOL_ADDRESS_PROVIDER_BASE = '0xe20fCBdBfFC4Dd138cE8b2E6FBb6CB49777ad64D' + let signer: SignerWithAddress; + const account = "0x28B41cf49c00fE3787Cd962feEF93238F569C77B"; + + before(async () => { + [signer] = await ethers.getSigners(); + }); + + describe("Aave V3 Resolver", () => { + let resolver: InstaAaveV3ResolverBase; + before(async () => { + await hre.network.provider.request({ + method: "hardhat_reset", + params: [ + { + forking: { + // eslint-disable-next-line @typescript-eslint/ban-ts-comment + // @ts-ignore + jsonRpcUrl: hre.config.networks.base.url, + blockNumber: 20889691, + }, + }, + ], + }); + + const deployer = new InstaAaveV3ResolverBase__factory(signer); + resolver = await deployer.deploy(); + await resolver.deployed(); + }); + + it("should get user configurations and reserves list", async () => { + const reservesList = await resolver.getReservesList(POOL_ADDRESS_PROVIDER_BASE); + const reserves = await resolver.getConfiguration(account, POOL_ADDRESS_PROVIDER_BASE); + console.log("Collateral Reserves Address"); + console.log(reservesList); + console.log(reserves); + for (let i = 0; i < reserves[0].length; i++) { + if (reserves[0][i]) { + console.log(`- ${reservesList[i]}`); + } + } + console.log("Borrowed Reserves Address"); + for (let i = 0; i < reserves[1].length; i++) { + if (reserves[1][i]) { + console.log(`- ${reservesList[i]}`); + } + } + }); + + it("Returns the positions on AaveV3", async () => { + const results = await resolver.callStatic.getPosition(account, [ + "0xDA10009cBd5D07dd0CeCc66161FC93D7c9000da1", + "0xf97f4df75117a78c1A5a0DBb814Af92458539FB4", + ], POOL_ADDRESS_PROVIDER_BASE); + const userTokenData = results[1]; + const tokenData = results[2]; + const userData = results[0]; + + //check tokenPrice + // const daiPriceInETH = tokenData[0].tokenPrice.priceInEth; + // const daiPriceInUsd = tokenData[0].tokenPrice.priceInUsd; + + // console.log(`Price of DAI in ETH: ${Number(daiPriceInETH) / 10 ** 18}`); + // console.log(`Price of DAI in Usd: ${Number(daiPriceInUsd) / 10 ** 18}`); + + // check for token balances + console.log("Supply Balance USDC: ", formatUnits(userTokenData[0].supplyBalance, Tokens.USDC.decimals)); + expect(userTokenData[0].supplyBalance).to.gte(0); + console.log( + "Stable Borrow Balance USDC: ", + formatUnits(userTokenData[1].stableBorrowBalance, Tokens.USDC.decimals), + ); + console.log(`ltv: ${tokenData[1].ltv}`); + + expect(userTokenData[0].variableBorrowBalance).to.gte(0); + // check for user data + expect(userData.totalBorrowsBase).to.gte(0); + expect(userData.totalCollateralBase).to.gte(0); + }); + + it("Returns the user's positions on AaveV3 for all assets", async () => { + const results = await resolver.callStatic.getPositionAll(account, POOL_ADDRESS_PROVIDER_BASE); + const userTokenData = results[1]; + const tokenData = results[2]; + const userData = results[0]; + const rewards = results[3]; + + // check for user data + expect(userData.totalBorrowsBase).to.gte(0); + expect(userData.totalCollateralBase).to.gte(0); + console.log(); + console.log("*************************************************"); + console.log("User Data"); + console.log("*************************************************"); + console.log(`totalCollateralInBase: ${userData.totalCollateralBase}`); + console.log(`totalBorrowsInBase: ${userData.totalBorrowsBase}`); + console.log(`availableBorrowsInBase: ${userData.availableBorrowsBase}`); + console.log(`liquidationThreshold: ${userData.currentLiquidationThreshold}`); + console.log(`ltv: ${userData.ltv}`); + console.log(`healthFactor: ${userData.healthFactor}`); + console.log(`eModeId: ${userData.eModeId}`); + console.log(`BaseAddress: ${userData.base.baseAddress}`); + // console.log(`BaseInUsd: ${userData.base.baseInUSD}`); + console.log(`BaseSymbol: ${userData.base.symbol}`); + + console.log(); + console.log("*************************************************"); + console.log("Assets Data"); + console.log("*************************************************"); + for (let i = 0; i < tokenData.length; i++) { + console.log(); + console.log(`Reserve: ${tokenData[i].asset}`); + console.log(`Symbol: ${tokenData[i].symbol}`); + console.log("Supply Balance: ", formatUnits(userTokenData[i].supplyBalance, tokenData[i].decimals)); + console.log( + "Stable Borrow Balance: ", + formatUnits(userTokenData[i].stableBorrowBalance, tokenData[i].decimals), + ); + console.log( + "Variable Borrow Balance: ", + formatUnits(userTokenData[i].variableBorrowBalance, tokenData[i].decimals), + ); + console.log(`Supply rate: ${userTokenData[i].supplyRate}`); + console.log(`Stable Borrow Rate: ${userTokenData[i].stableBorrowRate}`); + console.log(`User Stable Borrow Rate: ${userTokenData[i].userStableBorrowRate}`); + console.log(`Variable Borrow Rate: ${userTokenData[i].variableBorrowRate}`); + console.log(`ltv: ${tokenData[i].ltv}`); + console.log(`liquidation threshold: ${tokenData[i].threshold}`); + console.log(`Reserve factor: ${tokenData[i].reserveFactor}`); + console.log(`Total Supply: ${tokenData[i].totalSupply}`); + console.log(`Available liquidity: ${tokenData[i].availableLiquidity}`); + console.log("Total stable debt: ", formatUnits(tokenData[i].totalStableDebt, tokenData[i].decimals)); + console.log("Total variable debt: ", formatUnits(tokenData[i].totalVariableDebt, tokenData[i].decimals)); + console.log(`Price in base: ${userTokenData[i].price}`); + // console.log(`Price in ETH: ${Number(tokenData[i].tokenPrice.priceInEth) / 10 ** 18}`); + // console.log(`Price in Usd: ${Number(tokenData[i].tokenPrice.priceInUsd) / 10 ** 18}`); + console.log(`Supply cap: ${tokenData[i].token.supplyCap}`); + console.log(`Borrow cap: ${tokenData[i].token.borrowCap}`); + console.log(`Borrowable in isolation mode: ${tokenData[i].token.isolationBorrowEnabled}`); + console.log("----------------------------------------------------"); + console.log("aToken Rewards Details - "); + console.log("----------------------------------------------------"); + console.log(`aToken: ${tokenData[i].reserves.aToken.tokenAddress}`); + console.log(`aToken symbol: ${tokenData[i].reserves.aToken.symbol}`); + console.log(`aToken decimals: ${tokenData[i].reserves.aToken.decimals}`); + + for (let j = 0; j < rewards[i].aIncentiveData.rewardsTokenInfo.length; j++) { + console.log(`Reward token address: ${rewards[i].aIncentiveData.rewardsTokenInfo[j].rewardTokenAddress}`); + console.log(`Reward token symbol: ${rewards[i].aIncentiveData.rewardsTokenInfo[j].rewardTokenSymbol}`); + console.log(`Reward token decimals: ${rewards[i].aIncentiveData.rewardsTokenInfo[j].rewardTokenDecimals}`); + console.log(`Reward token precision: ${rewards[i].aIncentiveData.rewardsTokenInfo[j].precision}`); + console.log(`Emission rate per second: ${rewards[i].aIncentiveData.rewardsTokenInfo[j].emissionPerSecond}`); + } + for (let j = 0; j < rewards[i].aIncentiveData.userRewards.rewardsToken.length; j++) { + console.log( + `Unclaimed Reward: ${rewards[i].aIncentiveData.userRewards.unbalancedAmounts[j]} for ${rewards[i].aIncentiveData.userRewards.rewardsToken[j]}`, + ); + } + console.log("----------------------------------------------------"); + console.log("sToken Rewards Details - "); + console.log("----------------------------------------------------"); + console.log(`Stable Debt Token: ${tokenData[i].reserves.stableDebtToken.tokenAddress}`); + console.log(`Stable Debt symbol: ${tokenData[i].reserves.stableDebtToken.symbol}`); + console.log(`Stable Debt decimals: ${tokenData[i].reserves.stableDebtToken.decimals}`); + for (let j = 0; j < rewards[i].sIncentiveData.rewardsTokenInfo.length; j++) { + console.log(`Reward token address: ${rewards[i].sIncentiveData.rewardsTokenInfo[j].rewardTokenAddress}`); + console.log(`Reward token symbol: ${rewards[i].sIncentiveData.rewardsTokenInfo[j].rewardTokenSymbol}`); + console.log(`Reward token decimals: ${rewards[i].sIncentiveData.rewardsTokenInfo[j].rewardTokenDecimals}`); + console.log(`Reward token precision: ${rewards[i].sIncentiveData.rewardsTokenInfo[j].precision}`); + console.log(`Emission rate per second: ${rewards[i].sIncentiveData.rewardsTokenInfo[j].emissionPerSecond}`); + } + for (let j = 0; j < rewards[i].sIncentiveData.userRewards.rewardsToken.length; j++) { + console.log( + `Unclaimed Reward: ${rewards[i].sIncentiveData.userRewards.unbalancedAmounts[j]} for ${rewards[i].sIncentiveData.userRewards.rewardsToken[j]}`, + ); + } + console.log("----------------------------------------------------"); + console.log("vToken Rewards Details - "); + console.log("----------------------------------------------------"); + console.log(`Variable Debt Token: ${tokenData[i].reserves.variableDebtToken.tokenAddress}`); + console.log(`Variable Debt symbol: ${tokenData[i].reserves.variableDebtToken.symbol}`); + console.log(`Variable Debt decimals: ${tokenData[i].reserves.variableDebtToken.decimals}`); + for (let j = 0; j < rewards[i].vIncentiveData.rewardsTokenInfo.length; j++) { + console.log(`Reward token address: ${rewards[i].vIncentiveData.rewardsTokenInfo[j].rewardTokenAddress}`); + console.log(`Reward token symbol: ${rewards[i].vIncentiveData.rewardsTokenInfo[j].rewardTokenSymbol}`); + console.log(`Reward token decimals: ${rewards[i].vIncentiveData.rewardsTokenInfo[j].rewardTokenDecimals}`); + console.log(`Reward token precision: ${rewards[i].vIncentiveData.rewardsTokenInfo[j].precision}`); + console.log(`Emission rate per second: ${rewards[i].vIncentiveData.rewardsTokenInfo[j].emissionPerSecond}`); + } + for (let j = 0; j < rewards[i].vIncentiveData.userRewards.rewardsToken.length; j++) { + console.log( + `Unclaimed Reward: ${rewards[i].vIncentiveData.userRewards.unbalancedAmounts[j]} for ${rewards[i].vIncentiveData.userRewards.rewardsToken[j]}`, + ); + } + console.log(); + + // console.log(`E-Mode category: ${tokenData[i].token.eModeCategory}`); + console.log( + "Debt ceiling: ", + formatUnits(tokenData[i].token.debtCeiling, tokenData[i].token.debtCeilingDecimals), + ); + console.log(`Liquidation Fee: ${tokenData[i].token.liquidationFee}`); + } + + expect(userTokenData[0].supplyBalance).to.gte(0); + expect(userTokenData[0].variableBorrowBalance).to.gte(0); + }); + + it("Returns the e-mode category details of e-modeID", async () => { + const emodeData = await resolver.getEmodeCategoryData(1, POOL_ADDRESS_PROVIDER_BASE); + console.log(); + console.log("*************************************************"); + console.log("E-Mode category Data"); + console.log("*************************************************"); + console.log(`e-mode LTV: ${emodeData.data.ltv}`); + console.log(`e-mode liquidation threshold: ${emodeData.data.liquidationThreshold}`); + console.log(`e-mode liquidation bonus: ${emodeData.data.liquidationBonus}`); + console.log(`e-mode label: ${emodeData.data.label}`); + console.log(`e-mode is colleteral bitmap: ${emodeData.data.isCollateralBitmap}`); + console.log(`e-mode is borrowable bitmap: ${emodeData.data.isBorrowableBitmap}`); + console.log(`e-mode collaterals: ${emodeData.collateralTokens}`); + console.log(`e-mode borrowables: ${emodeData.borrowableTokens}`); + }); + + it("Returns the ethPrice", async () => { + const ethPrice = await resolver.getEthPrice(); + console.log(`ethPrice: ${ethPrice}`); + }); + }); +});