From 640f30c7861f2a772c70276267dfd762f0ae2dca Mon Sep 17 00:00:00 2001 From: The3D Date: Fri, 9 Oct 2020 16:35:02 +0200 Subject: [PATCH 01/10] Removed getters --- contracts/interfaces/ILendingPool.sol | 61 ----------- contracts/lendingpool/LendingPool.sol | 147 ++++---------------------- 2 files changed, 22 insertions(+), 186 deletions(-) diff --git a/contracts/interfaces/ILendingPool.sol b/contracts/interfaces/ILendingPool.sol index 3fc461b6..82f5f773 100644 --- a/contracts/interfaces/ILendingPool.sol +++ b/contracts/interfaces/ILendingPool.sol @@ -315,52 +315,6 @@ interface ILendingPool { bytes calldata params ) external; - /** - * @dev accessory functions to fetch data from the core contract - **/ - - function getReserveConfigurationData(address reserve) - external - view - returns ( - uint256 decimals, - uint256 ltv, - uint256 liquidationThreshold, - uint256 liquidationBonus, - uint256 reserveFactor, - address interestRateStrategyAddress, - bool usageAsCollateralEnabled, - bool borrowingEnabled, - bool stableBorrowRateEnabled, - bool isActive, - bool isFreezed - ); - - function getReserveTokensAddresses(address reserve) - external - view - returns ( - address aTokenAddress, - address stableDebtTokenAddress, - address variableDebtTokenAddress - ); - - function getReserveData(address reserve) - external - view - returns ( - uint256 availableLiquidity, - uint256 totalStableDebt, - uint256 totalVariableDebt, - uint256 liquidityRate, - uint256 variableBorrowRate, - uint256 stableBorrowRate, - uint256 averageStableBorrowRate, - uint256 liquidityIndex, - uint256 variableBorrowIndex, - uint40 lastUpdateTimestamp - ); - function getUserAccountData(address user) external view @@ -373,21 +327,6 @@ interface ILendingPool { uint256 healthFactor ); - function getUserReserveData(address reserve, address user) - external - view - returns ( - uint256 currentATokenBalance, - uint256 currentStableDebt, - uint256 currentVariableDebt, - uint256 principalStableDebt, - uint256 scaledVariableDebt, - uint256 stableBorrowRate, - uint256 liquidityRate, - uint40 stableRateLastUpdated, - bool usageAsCollateralEnabled - ); - /** * @dev initializes a reserve * @param reserve the address of the reserve diff --git a/contracts/lendingpool/LendingPool.sol b/contracts/lendingpool/LendingPool.sol index 6016ee95..8171f4e4 100644 --- a/contracts/lendingpool/LendingPool.sol +++ b/contracts/lendingpool/LendingPool.sol @@ -29,6 +29,7 @@ import {SafeERC20} from '@openzeppelin/contracts/token/ERC20/SafeERC20.sol'; import {ILendingPool} from '../interfaces/ILendingPool.sol'; import {LendingPoolStorage} from './LendingPoolStorage.sol'; import {IReserveInterestRateStrategy} from '../interfaces/IReserveInterestRateStrategy.sol'; + /** * @title LendingPool contract * @notice Implements the actions of the LendingPool, and exposes accessory methods to fetch the users and reserve data @@ -57,6 +58,7 @@ contract LendingPool is VersionedInitializable, ILendingPool, LendingPoolStorage Errors.CALLER_NOT_LENDING_POOL_CONFIGURATOR ); } + /** * @dev Function to make a function callable only when the contract is not paused. * @@ -364,9 +366,8 @@ contract LendingPool is VersionedInitializable, ILendingPool, LendingPoolStorage * @param user the address of the user to be rebalanced **/ function rebalanceStableBorrowRate(address asset, address user) external override { - _whenNotPaused(); - + ReserveLogic.ReserveData storage reserve = _reserves[asset]; IERC20 stableDebtToken = IERC20(reserve.stableDebtTokenAddress); @@ -376,7 +377,10 @@ contract LendingPool is VersionedInitializable, ILendingPool, LendingPoolStorage uint256 stableBorrowBalance = IERC20(stableDebtToken).balanceOf(user); //if the utilization rate is below 95%, no rebalances are needed - uint256 totalBorrows = stableDebtToken.totalSupply().add(variableDebtToken.totalSupply()).wadToRay(); + uint256 totalBorrows = stableDebtToken + .totalSupply() + .add(variableDebtToken.totalSupply()) + .wadToRay(); uint256 availableLiquidity = IERC20(asset).balanceOf(aTokenAddress).wadToRay(); uint256 usageRatio = totalBorrows == 0 ? 0 @@ -394,7 +398,7 @@ contract LendingPool is VersionedInitializable, ILendingPool, LendingPoolStorage require( usageRatio >= REBALANCE_UP_USAGE_RATIO_THRESHOLD && - currentLiquidityRate <= + currentLiquidityRate <= maxVariableBorrowRate.percentMul(REBALANCE_UP_LIQUIDITY_RATE_THRESHOLD), Errors.INTEREST_RATE_REBALANCE_CONDITIONS_NOT_MET ); @@ -402,12 +406,15 @@ contract LendingPool is VersionedInitializable, ILendingPool, LendingPoolStorage reserve.updateState(); IStableDebtToken(address(stableDebtToken)).burn(user, stableBorrowBalance); - IStableDebtToken(address(stableDebtToken)).mint(user, stableBorrowBalance, reserve.currentStableBorrowRate); + IStableDebtToken(address(stableDebtToken)).mint( + user, + stableBorrowBalance, + reserve.currentStableBorrowRate + ); reserve.updateInterestRates(asset, aTokenAddress, 0, 0); emit RebalanceStableBorrowRate(asset, user); - } /** @@ -585,8 +592,8 @@ contract LendingPool is VersionedInitializable, ILendingPool, LendingPoolStorage emit FlashLoan(receiverAddress, asset, amount, vars.premium, referralCode); } else { - //if the user didn't choose to return the funds, the system checks if there - //is enough collateral and eventually open a position + //if the user didn't choose to return the funds, the system checks if there + //is enough collateral and eventually open a position _executeBorrow( ExecuteBorrowParams( asset, @@ -644,91 +651,13 @@ contract LendingPool is VersionedInitializable, ILendingPool, LendingPoolStorage * @dev accessory functions to fetch data from the core contract **/ - function getReserveConfigurationData(address asset) - external - override - view - returns ( - uint256 decimals, - uint256 ltv, - uint256 liquidationThreshold, - uint256 liquidationBonus, - uint256 reserveFactor, - address interestRateStrategyAddress, - bool usageAsCollateralEnabled, - bool borrowingEnabled, - bool stableBorrowRateEnabled, - bool isActive, - bool isFreezed - ) - { - ReserveLogic.ReserveData storage reserve = _reserves[asset]; - - return ( - reserve.configuration.getDecimals(), - reserve.configuration.getLtv(), - reserve.configuration.getLiquidationThreshold(), - reserve.configuration.getLiquidationBonus(), - reserve.configuration.getReserveFactor(), - reserve.interestRateStrategyAddress, - reserve.configuration.getLtv() != 0, - reserve.configuration.getBorrowingEnabled(), - reserve.configuration.getStableRateBorrowingEnabled(), - reserve.configuration.getActive(), - reserve.configuration.getFrozen() - ); - } - - function getReserveTokensAddresses(address asset) - external - override - view - returns ( - address aTokenAddress, - address stableDebtTokenAddress, - address variableDebtTokenAddress - ) - { - ReserveLogic.ReserveData storage reserve = _reserves[asset]; - - return ( - reserve.aTokenAddress, - reserve.stableDebtTokenAddress, - reserve.variableDebtTokenAddress - ); - } - function getReserveData(address asset) external override view - returns ( - uint256 availableLiquidity, - uint256 totalStableDebt, - uint256 totalVariableDebt, - uint256 liquidityRate, - uint256 variableBorrowRate, - uint256 stableBorrowRate, - uint256 averageStableBorrowRate, - uint256 liquidityIndex, - uint256 variableBorrowIndex, - uint40 lastUpdateTimestamp - ) + returns (ReserveLogic.ReserveData memory) { - ReserveLogic.ReserveData memory reserve = _reserves[asset]; - - return ( - IERC20(asset).balanceOf(reserve.aTokenAddress), - IERC20(reserve.stableDebtTokenAddress).totalSupply(), - IERC20(reserve.variableDebtTokenAddress).totalSupply(), - reserve.currentLiquidityRate, - reserve.currentVariableBorrowRate, - reserve.currentStableBorrowRate, - IStableDebtToken(reserve.stableDebtTokenAddress).getAverageStableRate(), - reserve.liquidityIndex, - reserve.variableBorrowIndex, - reserve.lastUpdateTimestamp - ); + return _reserves[asset]; } function getUserAccountData(address user) @@ -758,7 +687,7 @@ contract LendingPool is VersionedInitializable, ILendingPool, LendingPoolStorage _reservesCount, _addressesProvider.getPriceOracle() ); - + availableBorrowsETH = GenericLogic.calculateAvailableBorrowsETH( totalCollateralETH, totalBorrowsETH, @@ -766,36 +695,6 @@ contract LendingPool is VersionedInitializable, ILendingPool, LendingPoolStorage ); } - function getUserReserveData(address asset, address user) - external - override - view - returns ( - uint256 currentATokenBalance, - uint256 currentStableDebt, - uint256 currentVariableDebt, - uint256 principalStableDebt, - uint256 scaledVariableDebt, - uint256 stableBorrowRate, - uint256 liquidityRate, - uint40 stableRateLastUpdated, - bool usageAsCollateralEnabled - ) - { - ReserveLogic.ReserveData storage reserve = _reserves[asset]; - - currentATokenBalance = IERC20(reserve.aTokenAddress).balanceOf(user); - (currentStableDebt, currentVariableDebt) = Helpers.getUserCurrentDebt(user, reserve); - principalStableDebt = IStableDebtToken(reserve.stableDebtTokenAddress).principalBalanceOf(user); - scaledVariableDebt = IVariableDebtToken(reserve.variableDebtTokenAddress).scaledBalanceOf(user); - liquidityRate = reserve.currentLiquidityRate; - stableBorrowRate = IStableDebtToken(reserve.stableDebtTokenAddress).getUserStableRate(user); - stableRateLastUpdated = IStableDebtToken(reserve.stableDebtTokenAddress).getUserLastUpdated( - user - ); - usageAsCollateralEnabled = _usersConfig[user].isUsingAsCollateral(reserve.id); - } - receive() external payable { revert(); } @@ -852,7 +751,6 @@ contract LendingPool is VersionedInitializable, ILendingPool, LendingPoolStorage } // internal functions - struct ExecuteBorrowParams { address asset; address user; @@ -948,12 +846,11 @@ contract LendingPool is VersionedInitializable, ILendingPool, LendingPoolStorage * @dev adds a reserve to the array of the _reserves address **/ function _addReserveToList(address asset) internal { - require(_reservesCount < MAX_NUMBER_RESERVES, Errors.NO_MORE_RESERVES_ALLOWED); - - bool reserveAlreadyAdded = _reserves[asset].id != 0 || _reservesList[0]==asset; - if(!reserveAlreadyAdded){ + bool reserveAlreadyAdded = _reserves[asset].id != 0 || _reservesList[0] == asset; + + if (!reserveAlreadyAdded) { _reserves[asset].id = uint8(_reservesCount); _reservesList[_reservesCount] = asset; @@ -1038,7 +935,7 @@ contract LendingPool is VersionedInitializable, ILendingPool, LendingPoolStorage function getReservesList() external override view returns (address[] memory) { address[] memory _activeReserves = new address[](_reservesCount); - for(uint256 i = 0; i < _reservesCount; i++){ + for (uint256 i = 0; i < _reservesCount; i++) { _activeReserves[i] = _reservesList[i]; } return _activeReserves; From 44ba72540c1e8cc598ce86731e2c73e56770a02c Mon Sep 17 00:00:00 2001 From: The3D Date: Fri, 9 Oct 2020 17:59:10 +0200 Subject: [PATCH 02/10] Updated configurator, LendingPool interface --- contracts/interfaces/ILendingPool.sol | 4 ++ .../lendingpool/LendingPoolConfigurator.sol | 42 ++++++++----------- 2 files changed, 22 insertions(+), 24 deletions(-) diff --git a/contracts/interfaces/ILendingPool.sol b/contracts/interfaces/ILendingPool.sol index 82f5f773..3a774e1f 100644 --- a/contracts/interfaces/ILendingPool.sol +++ b/contracts/interfaces/ILendingPool.sol @@ -3,6 +3,8 @@ pragma solidity ^0.6.8; import {LendingPoolAddressesProvider} from '../configuration/LendingPoolAddressesProvider.sol'; import {ReserveConfiguration} from '../libraries/configuration/ReserveConfiguration.sol'; +import {ReserveLogic} from '../libraries/logic/ReserveLogic.sol'; + pragma experimental ABIEncoderV2; interface ILendingPool { @@ -361,6 +363,8 @@ interface ILendingPool { function getReserveNormalizedVariableDebt(address reserve) external view returns (uint256); + function getReserveData(address asset) external view returns (ReserveLogic.ReserveData memory); + function balanceDecreaseAllowed( address reserve, address user, diff --git a/contracts/lendingpool/LendingPoolConfigurator.sol b/contracts/lendingpool/LendingPoolConfigurator.sol index 6bedff76..c9e34f3e 100644 --- a/contracts/lendingpool/LendingPoolConfigurator.sol +++ b/contracts/lendingpool/LendingPoolConfigurator.sol @@ -14,6 +14,7 @@ import {ILendingPoolAddressesProvider} from '../interfaces/ILendingPoolAddresses import {ILendingPool} from '../interfaces/ILendingPool.sol'; import {IERC20Detailed} from '../interfaces/IERC20Detailed.sol'; import {Errors} from '../libraries/helpers/Errors.sol'; +import {ReserveLogic} from '../libraries/logic/ReserveLogic.sol'; /** * @title LendingPoolConfigurator contract @@ -260,11 +261,11 @@ contract LendingPoolConfigurator is VersionedInitializable { * @param implementation the address of the new aToken implementation **/ function updateAToken(address asset, address implementation) external onlyAaveAdmin { - (address aTokenAddress, , ) = pool.getReserveTokensAddresses(asset); + ReserveLogic.ReserveData memory reserveData = pool.getReserveData(asset); - _upgradeTokenImplementation(asset, aTokenAddress, implementation); + _upgradeTokenImplementation(asset, reserveData.aTokenAddress, implementation); - emit ATokenUpgraded(asset, aTokenAddress, implementation); + emit ATokenUpgraded(asset, reserveData.aTokenAddress, implementation); } /** @@ -273,11 +274,11 @@ contract LendingPoolConfigurator is VersionedInitializable { * @param implementation the address of the new aToken implementation **/ function updateStableDebtToken(address asset, address implementation) external onlyAaveAdmin { - (, address stableDebtToken, ) = pool.getReserveTokensAddresses(asset); + ReserveLogic.ReserveData memory reserveData = pool.getReserveData(asset); - _upgradeTokenImplementation(asset, stableDebtToken, implementation); + _upgradeTokenImplementation(asset, reserveData.stableDebtTokenAddress, implementation); - emit StableDebtTokenUpgraded(asset, stableDebtToken, implementation); + emit StableDebtTokenUpgraded(asset, reserveData.stableDebtTokenAddress, implementation); } /** @@ -286,11 +287,11 @@ contract LendingPoolConfigurator is VersionedInitializable { * @param implementation the address of the new aToken implementation **/ function updateVariableDebtToken(address asset, address implementation) external onlyAaveAdmin { - (, , address variableDebtToken) = pool.getReserveTokensAddresses(asset); + ReserveLogic.ReserveData memory reserveData = pool.getReserveData(asset); - _upgradeTokenImplementation(asset, variableDebtToken, implementation); + _upgradeTokenImplementation(asset, reserveData.variableDebtTokenAddress, implementation); - emit VariableDebtTokenUpgraded(asset, variableDebtToken, implementation); + emit VariableDebtTokenUpgraded(asset, reserveData.variableDebtTokenAddress, implementation); } /** @@ -410,18 +411,12 @@ contract LendingPoolConfigurator is VersionedInitializable { * @param asset the address of the reserve **/ function deactivateReserve(address asset) external onlyAaveAdmin { - ( - uint256 availableLiquidity, - uint256 totalStableDebt, - uint256 totalVariableDebt, - , - , - , - , - , - , + ReserveLogic.ReserveData memory reserveData = pool.getReserveData(asset); + + uint256 availableLiquidity = IERC20Detailed(reserveData.aTokenAddress).totalSupply(); + uint256 totalStableDebt = IERC20Detailed(reserveData.stableDebtTokenAddress).totalSupply(); + uint256 totalVariableDebt = IERC20Detailed(reserveData.variableDebtTokenAddress).totalSupply(); - ) = pool.getReserveData(asset); require( availableLiquidity == 0 && totalStableDebt == 0 && totalVariableDebt == 0, Errors.RESERVE_LIQUIDITY_NOT_0 @@ -479,7 +474,7 @@ contract LendingPoolConfigurator is VersionedInitializable { emit ReserveBaseLtvChanged(asset, ltv); } - /** + /** * @dev updates the reserve factor of a reserve * @param asset the address of the reserve * @param reserveFactor the new reserve factor of the reserve @@ -494,7 +489,6 @@ contract LendingPoolConfigurator is VersionedInitializable { emit ReserveFactorChanged(asset, reserveFactor); } - /** * @dev updates the liquidation threshold of a reserve. * @param asset the address of the reserve @@ -582,11 +576,11 @@ contract LendingPoolConfigurator is VersionedInitializable { payable(proxyAddress) ); - (uint256 decimals, , , , , , , , , , ) = pool.getReserveConfigurationData(asset); + ReserveConfiguration.Map memory configuration = pool.getConfiguration(asset); bytes memory params = abi.encodeWithSignature( 'initialize(uint8,string,string)', - uint8(decimals), + uint8(configuration.getDecimals()), IERC20Detailed(implementation).name(), IERC20Detailed(implementation).symbol() ); From 40ff898011ac686aed4ed2f70a1a8a42b42018df Mon Sep 17 00:00:00 2001 From: The3D Date: Mon, 12 Oct 2020 10:50:06 +0200 Subject: [PATCH 03/10] Refactored LendingPool --- contracts/lendingpool/LendingPool.sol | 229 ++++++++++++++------------ 1 file changed, 126 insertions(+), 103 deletions(-) diff --git a/contracts/lendingpool/LendingPool.sol b/contracts/lendingpool/LendingPool.sol index 8171f4e4..7aed331c 100644 --- a/contracts/lendingpool/LendingPool.sol +++ b/contracts/lendingpool/LendingPool.sol @@ -648,9 +648,10 @@ contract LendingPool is VersionedInitializable, ILendingPool, LendingPoolStorage } /** - * @dev accessory functions to fetch data from the core contract + * @dev returns the state and configuration of the reserve + * @param asset the address of the reserve + * @return the state of the reserve **/ - function getReserveData(address asset) external override @@ -660,13 +661,23 @@ contract LendingPool is VersionedInitializable, ILendingPool, LendingPoolStorage return _reserves[asset]; } + /** + * @dev returns the user account data across all the reserves + * @param user the address of the user + * @return totalCollateralETH the total collateral in ETH of the user + * @return totalDebtETH the total debt in ETH of the user + * @return availableBorrowsETH the borrowing power left of the user + * @return currentLiquidationThreshold the liquidation threshold of the user + * @return ltv the loan to value of the user + * @return healthFactor the current health factor of the user + **/ function getUserAccountData(address user) external override view returns ( uint256 totalCollateralETH, - uint256 totalBorrowsETH, + uint256 totalDebtETH, uint256 availableBorrowsETH, uint256 currentLiquidationThreshold, uint256 ltv, @@ -675,7 +686,7 @@ contract LendingPool is VersionedInitializable, ILendingPool, LendingPoolStorage { ( totalCollateralETH, - totalBorrowsETH, + totalDebtETH, ltv, currentLiquidationThreshold, healthFactor @@ -690,11 +701,103 @@ contract LendingPool is VersionedInitializable, ILendingPool, LendingPoolStorage availableBorrowsETH = GenericLogic.calculateAvailableBorrowsETH( totalCollateralETH, - totalBorrowsETH, + totalDebtETH, ltv ); } + /** + * @dev returns the configuration of the reserve + * @param asset the address of the reserve + * @return the configuration of the reserve + **/ + function getConfiguration(address asset) + external + override + view + returns (ReserveConfiguration.Map memory) + { + return _reserves[asset].configuration; + } + + /** + * @dev returns the normalized income per unit of asset + * @param asset the address of the reserve + * @return the reserve normalized income + */ + function getReserveNormalizedIncome(address asset) external override view returns (uint256) { + return _reserves[asset].getNormalizedIncome(); + } + + /** + * @dev returns the normalized variable debt per unit of asset + * @param asset the address of the reserve + * @return the reserve normalized debt + */ + function getReserveNormalizedVariableDebt(address asset) + external + override + view + returns (uint256) + { + return _reserves[asset].getNormalizedDebt(); + } + + /** + * @dev Returns if the LendingPool is paused + */ + function paused() external override view returns (bool) { + return _paused; + } + + /** + * @dev returns the list of the initialized reserves + **/ + function getReservesList() external override view returns (address[] memory) { + address[] memory _activeReserves = new address[](_reservesCount); + + for (uint256 i = 0; i < _reservesCount; i++) { + _activeReserves[i] = _reservesList[i]; + } + return _activeReserves; + } + + /** + * @dev returns the addresses provider + **/ + function getAddressesProvider() external view returns (ILendingPoolAddressesProvider) { + return _addressesProvider; + } + + /** + * @dev validate if a balance decrease for an asset is allowed + * @param asset the address of the reserve + * @param user the user related to the balance decrease + * @param amount the amount being transferred/redeemed + * @return true if the balance decrease can be allowed, false otherwise + */ + function balanceDecreaseAllowed( + address asset, + address user, + uint256 amount + ) external override view returns (bool) { + _whenNotPaused(); + return + GenericLogic.balanceDecreaseAllowed( + asset, + user, + amount, + _reserves, + _usersConfig[user], + _reservesList, + _reservesCount, + _addressesProvider.getPriceOracle() + ); + } + + /** + * @dev avoids direct transfers of ETH + **/ receive() external payable { revert(); } @@ -727,7 +830,6 @@ contract LendingPool is VersionedInitializable, ILendingPool, LendingPoolStorage * @param asset the address of the reserve * @param rateStrategyAddress the address of the interest rate strategy contract **/ - function setReserveInterestRateStrategyAddress(address asset, address rateStrategyAddress) external override @@ -736,20 +838,30 @@ contract LendingPool is VersionedInitializable, ILendingPool, LendingPoolStorage _reserves[asset].interestRateStrategyAddress = rateStrategyAddress; } + /** + * @dev sets the configuration map of the reserve + * @param asset the address of the reserve + * @param configuration the configuration map + **/ function setConfiguration(address asset, uint256 configuration) external override { _onlyLendingPoolConfigurator(); _reserves[asset].configuration.data = configuration; } - function getConfiguration(address asset) - external - override - view - returns (ReserveConfiguration.Map memory) - { - return _reserves[asset].configuration; - } + /** + * @dev Set the _pause state + * @param val the boolean value to set the current pause state of LendingPool + */ + function setPause(bool val) external override { + _onlyLendingPoolConfigurator(); + _paused = val; + if (_paused) { + emit Paused(); + } else { + emit Unpaused(); + } + } // internal functions struct ExecuteBorrowParams { address asset; @@ -858,93 +970,4 @@ contract LendingPool is VersionedInitializable, ILendingPool, LendingPoolStorage } } - /** - * @dev returns the normalized income per unit of asset - * @param asset the address of the reserve - * @return the reserve normalized income - */ - function getReserveNormalizedIncome(address asset) external override view returns (uint256) { - return _reserves[asset].getNormalizedIncome(); - } - - /** - * @dev returns the normalized variable debt per unit of asset - * @param asset the address of the reserve - * @return the reserve normalized debt - */ - function getReserveNormalizedVariableDebt(address asset) - external - override - view - returns (uint256) - { - return _reserves[asset].getNormalizedDebt(); - } - - /** - * @dev validate if a balance decrease for an asset is allowed - * @param asset the address of the reserve - * @param user the user related to the balance decrease - * @param amount the amount being transferred/redeemed - * @return true if the balance decrease can be allowed, false otherwise - */ - function balanceDecreaseAllowed( - address asset, - address user, - uint256 amount - ) external override view returns (bool) { - _whenNotPaused(); - return - GenericLogic.balanceDecreaseAllowed( - asset, - user, - amount, - _reserves, - _usersConfig[user], - _reservesList, - _reservesCount, - _addressesProvider.getPriceOracle() - ); - } - - /** - * @dev Set the _pause state - * @param val the boolean value to set the current pause state of LendingPool - */ - function setPause(bool val) external override { - _onlyLendingPoolConfigurator(); - - _paused = val; - if (_paused) { - emit Paused(); - } else { - emit Unpaused(); - } - } - - /** - * @dev Returns if the LendingPool is paused - */ - function paused() external override view returns (bool) { - return _paused; - } - - /** - * @dev returns the list of the initialized reserves - **/ - function getReservesList() external override view returns (address[] memory) { - address[] memory _activeReserves = new address[](_reservesCount); - - for (uint256 i = 0; i < _reservesCount; i++) { - _activeReserves[i] = _reservesList[i]; - } - return _activeReserves; - } - - /** - * @dev returns the addresses provider - **/ - function getAddressesProvider() external view returns (ILendingPoolAddressesProvider) { - return _addressesProvider; - } } From be517ad960c8e937e3a136cf2629c31cc29729e8 Mon Sep 17 00:00:00 2001 From: The3D Date: Mon, 12 Oct 2020 11:23:18 +0200 Subject: [PATCH 04/10] Added memory accessors to reserveConfiguration --- .../configuration/ReserveConfiguration.sol | 57 ++++++++++++++++++- 1 file changed, 56 insertions(+), 1 deletion(-) diff --git a/contracts/libraries/configuration/ReserveConfiguration.sol b/contracts/libraries/configuration/ReserveConfiguration.sol index 5053c0fd..78d1fcf2 100644 --- a/contracts/libraries/configuration/ReserveConfiguration.sol +++ b/contracts/libraries/configuration/ReserveConfiguration.sol @@ -282,6 +282,7 @@ library ReserveConfiguration { uint256, uint256, uint256, + uint256, uint256 ) { @@ -291,7 +292,61 @@ library ReserveConfiguration { dataLocal & ~LTV_MASK, (dataLocal & ~LIQUIDATION_THRESHOLD_MASK) >> LIQUIDATION_THRESHOLD_START_BIT_POSITION, (dataLocal & ~LIQUIDATION_BONUS_MASK) >> LIQUIDATION_BONUS_START_BIT_POSITION, - (dataLocal & ~DECIMALS_MASK) >> RESERVE_DECIMALS_START_BIT_POSITION + (dataLocal & ~DECIMALS_MASK) >> RESERVE_DECIMALS_START_BIT_POSITION, + (dataLocal & ~RESERVE_FACTOR_MASK) >> RESERVE_FACTOR_START_BIT_POSITION + ); + } + + /** + * @dev gets the configuration paramters of the reserve from a memory object + * @param self the reserve configuration + * @return the state params representing ltv, liquidation threshold, liquidation bonus, the reserve decimals + **/ + function getParamsMemory(ReserveConfiguration.Map memory self) + internal + pure + returns ( + uint256, + uint256, + uint256, + uint256, + uint256 + ) + { + uint256 dataLocal = self.data; + + return ( + dataLocal & ~LTV_MASK, + (dataLocal & ~LIQUIDATION_THRESHOLD_MASK) >> LIQUIDATION_THRESHOLD_START_BIT_POSITION, + (dataLocal & ~LIQUIDATION_BONUS_MASK) >> LIQUIDATION_BONUS_START_BIT_POSITION, + (dataLocal & ~DECIMALS_MASK) >> RESERVE_DECIMALS_START_BIT_POSITION, + (dataLocal & ~RESERVE_FACTOR_MASK) >> RESERVE_FACTOR_START_BIT_POSITION + ); + } + + + /** + * @dev gets the configuration flags of the reserve from a memory object + * @param self the reserve configuration + * @return the state flags representing active, freezed, borrowing enabled, stableRateBorrowing enabled + **/ + function getFlagsMemory(ReserveConfiguration.Map memory self) + internal + pure + returns ( + bool, + bool, + bool, + bool + ) + { + uint256 dataLocal = self.data; + + return ( + (dataLocal & ~ACTIVE_MASK) >> IS_ACTIVE_START_BIT_POSITION != 0, + (dataLocal & ~FROZEN_MASK) >> IS_FROZEN_START_BIT_POSITION != 0, + (dataLocal & ~BORROWING_MASK) >> BORROWING_ENABLED_START_BIT_POSITION != 0, + (dataLocal & ~STABLE_BORROWING_MASK) >> STABLE_BORROWING_ENABLED_START_BIT_POSITION != 0 ); } } From 645ea913b0fc25c8f808c8d388f0557de5422e0c Mon Sep 17 00:00:00 2001 From: The3D Date: Mon, 12 Oct 2020 14:25:03 +0200 Subject: [PATCH 05/10] Moved accessors to AaveProtocolTestHelpers --- .../LendingPoolCollateralManager.sol | 2 +- .../lendingpool/LendingPoolConfigurator.sol | 4 +- .../configuration/ReserveConfiguration.sol | 22 ++-- contracts/misc/AaveProtocolTestHelpers.sol | 107 +++++++++++++++++- contracts/misc/WalletBalanceProvider.sol | 8 +- 5 files changed, 124 insertions(+), 19 deletions(-) diff --git a/contracts/lendingpool/LendingPoolCollateralManager.sol b/contracts/lendingpool/LendingPoolCollateralManager.sol index 356ce1a4..16c0d2a9 100644 --- a/contracts/lendingpool/LendingPoolCollateralManager.sol +++ b/contracts/lendingpool/LendingPoolCollateralManager.sol @@ -579,7 +579,7 @@ contract LendingPoolCollateralManager is VersionedInitializable, LendingPoolStor vars.collateralPrice = oracle.getAssetPrice(collateralAddress); vars.principalCurrencyPrice = oracle.getAssetPrice(principalAddress); - (, , vars.liquidationBonus, vars.collateralDecimals) = collateralReserve + (, , vars.liquidationBonus, vars.collateralDecimals, ) = collateralReserve .configuration .getParams(); vars.principalDecimals = principalReserve.configuration.getDecimals(); diff --git a/contracts/lendingpool/LendingPoolConfigurator.sol b/contracts/lendingpool/LendingPoolConfigurator.sol index c9e34f3e..c122730d 100644 --- a/contracts/lendingpool/LendingPoolConfigurator.sol +++ b/contracts/lendingpool/LendingPoolConfigurator.sol @@ -578,9 +578,11 @@ contract LendingPoolConfigurator is VersionedInitializable { ReserveConfiguration.Map memory configuration = pool.getConfiguration(asset); + (, , , uint256 decimals, ) = configuration.getParamsMemory(); + bytes memory params = abi.encodeWithSignature( 'initialize(uint8,string,string)', - uint8(configuration.getDecimals()), + uint8(decimals), IERC20Detailed(implementation).name(), IERC20Detailed(implementation).symbol() ); diff --git a/contracts/libraries/configuration/ReserveConfiguration.sol b/contracts/libraries/configuration/ReserveConfiguration.sol index 78d1fcf2..864c1b48 100644 --- a/contracts/libraries/configuration/ReserveConfiguration.sol +++ b/contracts/libraries/configuration/ReserveConfiguration.sol @@ -313,14 +313,12 @@ library ReserveConfiguration { uint256 ) { - uint256 dataLocal = self.data; - return ( - dataLocal & ~LTV_MASK, - (dataLocal & ~LIQUIDATION_THRESHOLD_MASK) >> LIQUIDATION_THRESHOLD_START_BIT_POSITION, - (dataLocal & ~LIQUIDATION_BONUS_MASK) >> LIQUIDATION_BONUS_START_BIT_POSITION, - (dataLocal & ~DECIMALS_MASK) >> RESERVE_DECIMALS_START_BIT_POSITION, - (dataLocal & ~RESERVE_FACTOR_MASK) >> RESERVE_FACTOR_START_BIT_POSITION + self.data & ~LTV_MASK, + (self.data & ~LIQUIDATION_THRESHOLD_MASK) >> LIQUIDATION_THRESHOLD_START_BIT_POSITION, + (self.data & ~LIQUIDATION_BONUS_MASK) >> LIQUIDATION_BONUS_START_BIT_POSITION, + (self.data & ~DECIMALS_MASK) >> RESERVE_DECIMALS_START_BIT_POSITION, + (self.data & ~RESERVE_FACTOR_MASK) >> RESERVE_FACTOR_START_BIT_POSITION ); } @@ -340,13 +338,11 @@ library ReserveConfiguration { bool ) { - uint256 dataLocal = self.data; - return ( - (dataLocal & ~ACTIVE_MASK) >> IS_ACTIVE_START_BIT_POSITION != 0, - (dataLocal & ~FROZEN_MASK) >> IS_FROZEN_START_BIT_POSITION != 0, - (dataLocal & ~BORROWING_MASK) >> BORROWING_ENABLED_START_BIT_POSITION != 0, - (dataLocal & ~STABLE_BORROWING_MASK) >> STABLE_BORROWING_ENABLED_START_BIT_POSITION != 0 + (self.data & ~ACTIVE_MASK) >> IS_ACTIVE_START_BIT_POSITION != 0, + (self.data & ~FROZEN_MASK) >> IS_FROZEN_START_BIT_POSITION != 0, + (self.data & ~BORROWING_MASK) >> BORROWING_ENABLED_START_BIT_POSITION != 0, + (self.data & ~STABLE_BORROWING_MASK) >> STABLE_BORROWING_ENABLED_START_BIT_POSITION != 0 ); } } diff --git a/contracts/misc/AaveProtocolTestHelpers.sol b/contracts/misc/AaveProtocolTestHelpers.sol index 75778f42..c98e54b9 100644 --- a/contracts/misc/AaveProtocolTestHelpers.sol +++ b/contracts/misc/AaveProtocolTestHelpers.sol @@ -5,8 +5,13 @@ pragma experimental ABIEncoderV2; import {ILendingPoolAddressesProvider} from '../interfaces/ILendingPoolAddressesProvider.sol'; import {IERC20Detailed} from '../interfaces/IERC20Detailed.sol'; import {ILendingPool} from '../interfaces/ILendingPool.sol'; +import {ReserveLogic} from '../libraries/logic/ReserveLogic.sol'; +import {ReserveConfiguration} from '../libraries/configuration/ReserveConfiguration.sol'; +import {IStableDebtToken} from '../tokenization/interfaces/IStableDebtToken.sol'; contract AaveProtocolTestHelpers { + using ReserveConfiguration for ReserveConfiguration.Map; + struct TokenData { string symbol; address tokenAddress; @@ -38,12 +43,108 @@ contract AaveProtocolTestHelpers { address[] memory reserves = pool.getReservesList(); TokenData[] memory aTokens = new TokenData[](reserves.length); for (uint256 i = 0; i < reserves.length; i++) { - (address aTokenAddress, , ) = pool.getReserveTokensAddresses(reserves[i]); + ReserveLogic.ReserveData memory reserveData = pool.getReserveData(reserves[i]); aTokens[i] = TokenData({ - symbol: IERC20Detailed(aTokenAddress).symbol(), - tokenAddress: aTokenAddress + symbol: IERC20Detailed(reserveData.aTokenAddress).symbol(), + tokenAddress: reserveData.aTokenAddress }); } return aTokens; } + + function getReserveConfigurationData(address asset) + external + view + returns ( + uint256 decimals, + uint256 ltv, + uint256 liquidationThreshold, + uint256 liquidationBonus, + uint256 reserveFactor, + bool usageAsCollateralEnabled, + bool borrowingEnabled, + bool stableBorrowRateEnabled, + bool isActive, + bool isFrozen + ) + { + ReserveConfiguration.Map memory configuration = ILendingPool( + ADDRESSES_PROVIDER.getLendingPool() + ) + .getConfiguration(asset); + + (ltv, liquidationThreshold, liquidationBonus, decimals, reserveFactor) = configuration + .getParamsMemory(); + + (isActive, isFrozen, borrowingEnabled, stableBorrowRateEnabled) = configuration + .getFlagsMemory(); + + usageAsCollateralEnabled = liquidationThreshold == 0; + } + + function getReserveData(address asset) + external + view + returns ( + uint256 availableLiquidity, + uint256 totalStableDebt, + uint256 totalVariableDebt, + uint256 liquidityRate, + uint256 variableBorrowRate, + uint256 stableBorrowRate, + uint256 averageStableBorrowRate, + uint256 liquidityIndex, + uint256 variableBorrowIndex, + uint40 lastUpdateTimestamp + ) + { + ReserveLogic.ReserveData memory reserve = ILendingPool(ADDRESSES_PROVIDER.getLendingPool()) + .getReserveData(asset); + + return ( + IERC20Detailed(asset).balanceOf(reserve.aTokenAddress), + IERC20Detailed(reserve.stableDebtTokenAddress).totalSupply(), + IERC20Detailed(reserve.variableDebtTokenAddress).totalSupply(), + reserve.currentLiquidityRate, + reserve.currentVariableBorrowRate, + reserve.currentStableBorrowRate, + IStableDebtToken(reserve.stableDebtTokenAddress).getAverageStableRate(), + reserve.liquidityIndex, + reserve.variableBorrowIndex, + reserve.lastUpdateTimestamp + ); + } +/* + function getUserReserveData(address asset, address user) + external + view + returns ( + uint256 currentATokenBalance, + uint256 currentStableDebt, + uint256 currentVariableDebt, + uint256 principalStableDebt, + uint256 scaledVariableDebt, + uint256 stableBorrowRate, + uint256 liquidityRate, + uint40 stableRateLastUpdated, + bool usageAsCollateralEnabled + ) + { + + ReserveLogic.ReserveData memory reserve = ILendingPool(ADDRESSES_PROVIDER.getLendingPool()) + .getReserveData(asset); + + currentATokenBalance = IERC20(reserve.aTokenAddress).balanceOf(user); + (currentStableDebt, currentVariableDebt) = Helpers.getUserCurrentDebt(user, reserve); + principalStableDebt = IStableDebtToken(reserve.stableDebtTokenAddress).principalBalanceOf(user); + scaledVariableDebt = IVariableDebtToken(reserve.variableDebtTokenAddress).scaledBalanceOf(user); + liquidityRate = reserve.currentLiquidityRate; + stableBorrowRate = IStableDebtToken(reserve.stableDebtTokenAddress).getUserStableRate(user); + stableRateLastUpdated = IStableDebtToken(reserve.stableDebtTokenAddress).getUserLastUpdated( + user + ); + usageAsCollateralEnabled = _usersConfig[user].isUsingAsCollateral(reserve.id); + + } + */ } diff --git a/contracts/misc/WalletBalanceProvider.sol b/contracts/misc/WalletBalanceProvider.sol index 1c46922a..5ddcf0bb 100644 --- a/contracts/misc/WalletBalanceProvider.sol +++ b/contracts/misc/WalletBalanceProvider.sol @@ -1,12 +1,15 @@ // SPDX-License-Identifier: agpl-3.0 pragma solidity ^0.6.8; +pragma experimental ABIEncoderV2; + import {Address} from '@openzeppelin/contracts/utils/Address.sol'; import {IERC20} from '@openzeppelin/contracts/token/ERC20/IERC20.sol'; import {LendingPoolAddressesProvider} from '../configuration/LendingPoolAddressesProvider.sol'; import {ILendingPool} from '../interfaces/ILendingPool.sol'; import {SafeERC20} from '@openzeppelin/contracts/token/ERC20/SafeERC20.sol'; +import {ReserveConfiguration} from '../libraries/configuration/ReserveConfiguration.sol'; /** * @title WalletBalanceProvider contract @@ -19,6 +22,7 @@ contract WalletBalanceProvider { using Address for address payable; using Address for address; using SafeERC20 for IERC20; + using ReserveConfiguration for ReserveConfiguration.Map; LendingPoolAddressesProvider internal immutable _provider; @@ -91,7 +95,9 @@ contract WalletBalanceProvider { uint256[] memory balances = new uint256[](reserves.length); for (uint256 j = 0; j < reserves.length; j++) { - (, , , , , , , , , bool isActive, ) = pool.getReserveConfigurationData(reserves[j]); + ReserveConfiguration.Map memory configuration = pool.getConfiguration(reserves[j]); + + (bool isActive, , , ) = configuration.getFlagsMemory(); if (!isActive) { balances[j] = 0; From b450a0464212414d7064b50b43ccbb4e47f10d87 Mon Sep 17 00:00:00 2001 From: The3D Date: Mon, 12 Oct 2020 14:37:53 +0200 Subject: [PATCH 06/10] Added getter for userconfiguration --- contracts/interfaces/ILendingPool.sol | 3 +++ contracts/lendingpool/LendingPool.sol | 15 ++++++++++++++- contracts/libraries/logic/GenericLogic.sol | 4 ++-- 3 files changed, 19 insertions(+), 3 deletions(-) diff --git a/contracts/interfaces/ILendingPool.sol b/contracts/interfaces/ILendingPool.sol index 3a774e1f..373c4214 100644 --- a/contracts/interfaces/ILendingPool.sol +++ b/contracts/interfaces/ILendingPool.sol @@ -3,6 +3,7 @@ pragma solidity ^0.6.8; import {LendingPoolAddressesProvider} from '../configuration/LendingPoolAddressesProvider.sol'; import {ReserveConfiguration} from '../libraries/configuration/ReserveConfiguration.sol'; +import {UserConfiguration} from '../libraries/configuration/UserConfiguration.sol'; import {ReserveLogic} from '../libraries/logic/ReserveLogic.sol'; pragma experimental ABIEncoderV2; @@ -359,6 +360,8 @@ interface ILendingPool { view returns (ReserveConfiguration.Map memory); + function getUserConfiguration(address user) external view returns (UserConfiguration.Map memory); + function getReserveNormalizedIncome(address reserve) external view returns (uint256); function getReserveNormalizedVariableDebt(address reserve) external view returns (uint256); diff --git a/contracts/lendingpool/LendingPool.sol b/contracts/lendingpool/LendingPool.sol index 7aed331c..948df2c9 100644 --- a/contracts/lendingpool/LendingPool.sol +++ b/contracts/lendingpool/LendingPool.sol @@ -720,6 +720,20 @@ contract LendingPool is VersionedInitializable, ILendingPool, LendingPoolStorage return _reserves[asset].configuration; } + /** + * @dev returns the configuration of the user for the specific reserve + * @param user the user + * @return the configuration of the user + **/ + function getUserConfiguration(address user) + external + override + view + returns (UserConfiguration.Map memory) + { + return _usersConfig[user]; + } + /** * @dev returns the normalized income per unit of asset * @param asset the address of the reserve @@ -969,5 +983,4 @@ contract LendingPool is VersionedInitializable, ILendingPool, LendingPoolStorage _reservesCount++; } } - } diff --git a/contracts/libraries/logic/GenericLogic.sol b/contracts/libraries/logic/GenericLogic.sol index 5c7dc3dc..e5135fc7 100644 --- a/contracts/libraries/logic/GenericLogic.sol +++ b/contracts/libraries/logic/GenericLogic.sol @@ -68,7 +68,7 @@ library GenericLogic { balanceDecreaseAllowedLocalVars memory vars; - (, vars.liquidationThreshold, , vars.decimals) = reservesData[asset].configuration.getParams(); + (, vars.liquidationThreshold, , vars.decimals, ) = reservesData[asset].configuration.getParams(); if (vars.liquidationThreshold == 0) { return true; //if reserve is not used as collateral, no reasons to block the transfer @@ -177,7 +177,7 @@ library GenericLogic { vars.currentReserveAddress = reserves[vars.i]; ReserveLogic.ReserveData storage currentReserve = reservesData[vars.currentReserveAddress]; - (vars.ltv, vars.liquidationThreshold, , vars.decimals) = currentReserve + (vars.ltv, vars.liquidationThreshold, , vars.decimals, ) = currentReserve .configuration .getParams(); From fb9f981efaea6f9a83074e95357bdd6cffe35a6c Mon Sep 17 00:00:00 2001 From: The3D Date: Mon, 12 Oct 2020 15:10:16 +0200 Subject: [PATCH 07/10] Added getUserReserveData to test helpers --- contracts/misc/AaveProtocolTestHelpers.sol | 22 +++++++++++++--------- 1 file changed, 13 insertions(+), 9 deletions(-) diff --git a/contracts/misc/AaveProtocolTestHelpers.sol b/contracts/misc/AaveProtocolTestHelpers.sol index c98e54b9..615f13a2 100644 --- a/contracts/misc/AaveProtocolTestHelpers.sol +++ b/contracts/misc/AaveProtocolTestHelpers.sol @@ -7,10 +7,13 @@ import {IERC20Detailed} from '../interfaces/IERC20Detailed.sol'; import {ILendingPool} from '../interfaces/ILendingPool.sol'; import {ReserveLogic} from '../libraries/logic/ReserveLogic.sol'; import {ReserveConfiguration} from '../libraries/configuration/ReserveConfiguration.sol'; +import {UserConfiguration} from '../libraries/configuration/UserConfiguration.sol'; import {IStableDebtToken} from '../tokenization/interfaces/IStableDebtToken.sol'; +import {IVariableDebtToken} from '../tokenization/interfaces/IVariableDebtToken.sol'; contract AaveProtocolTestHelpers { using ReserveConfiguration for ReserveConfiguration.Map; + using UserConfiguration for UserConfiguration.Map; struct TokenData { string symbol; @@ -114,7 +117,7 @@ contract AaveProtocolTestHelpers { reserve.lastUpdateTimestamp ); } -/* + function getUserReserveData(address asset, address user) external view @@ -130,12 +133,15 @@ contract AaveProtocolTestHelpers { bool usageAsCollateralEnabled ) { - - ReserveLogic.ReserveData memory reserve = ILendingPool(ADDRESSES_PROVIDER.getLendingPool()) + ReserveLogic.ReserveData memory reserve = ILendingPool(ADDRESSES_PROVIDER.getLendingPool()) .getReserveData(asset); - - currentATokenBalance = IERC20(reserve.aTokenAddress).balanceOf(user); - (currentStableDebt, currentVariableDebt) = Helpers.getUserCurrentDebt(user, reserve); + + UserConfiguration.Map memory userConfig = ILendingPool(ADDRESSES_PROVIDER.getLendingPool()) + .getUserConfiguration(user); + + currentATokenBalance = IERC20Detailed(reserve.aTokenAddress).balanceOf(user); + currentVariableDebt = IERC20Detailed(reserve.variableDebtTokenAddress).balanceOf(user); + currentStableDebt = IERC20Detailed(reserve.stableDebtTokenAddress).balanceOf(user); principalStableDebt = IStableDebtToken(reserve.stableDebtTokenAddress).principalBalanceOf(user); scaledVariableDebt = IVariableDebtToken(reserve.variableDebtTokenAddress).scaledBalanceOf(user); liquidityRate = reserve.currentLiquidityRate; @@ -143,8 +149,6 @@ contract AaveProtocolTestHelpers { stableRateLastUpdated = IStableDebtToken(reserve.stableDebtTokenAddress).getUserLastUpdated( user ); - usageAsCollateralEnabled = _usersConfig[user].isUsingAsCollateral(reserve.id); - + usageAsCollateralEnabled = userConfig.isUsingAsCollateral(reserve.id); } - */ } From aea61d57abbb6cf11bbbdc37fc46a1a4cfe01cd8 Mon Sep 17 00:00:00 2001 From: The3D Date: Mon, 12 Oct 2020 20:07:17 +0200 Subject: [PATCH 08/10] Fixed tests code --- contracts/misc/AaveProtocolTestHelpers.sol | 21 +++- deployed-contracts.json | 18 +-- test/__setup.spec.ts | 25 +++-- test/collateral-swap.spec.ts | 4 +- test/configurator.spec.ts | 106 +++++++++--------- .../flash-liquidation-with-collateral.spec.ts | 49 ++++---- test/flashloan.spec.ts | 32 +++--- test/helpers/actions.ts | 8 +- test/helpers/make-suite.ts | 11 +- test/helpers/utils/helpers.ts | 26 +++-- test/liquidation-atoken.spec.ts | 50 ++++++--- test/liquidation-underlying.spec.ts | 85 ++++++++------ test/pausable-functions.spec.ts | 7 +- test/repay-with-collateral.spec.ts | 35 +++--- test/stable-token.spec.ts | 8 +- test/upgradeability.spec.ts | 10 +- test/variable-debt-token.spec.ts | 14 ++- 17 files changed, 293 insertions(+), 216 deletions(-) diff --git a/contracts/misc/AaveProtocolTestHelpers.sol b/contracts/misc/AaveProtocolTestHelpers.sol index 615f13a2..158d38bd 100644 --- a/contracts/misc/AaveProtocolTestHelpers.sol +++ b/contracts/misc/AaveProtocolTestHelpers.sol @@ -82,7 +82,7 @@ contract AaveProtocolTestHelpers { (isActive, isFrozen, borrowingEnabled, stableBorrowRateEnabled) = configuration .getFlagsMemory(); - usageAsCollateralEnabled = liquidationThreshold == 0; + usageAsCollateralEnabled = liquidationThreshold > 0; } function getReserveData(address asset) @@ -151,4 +151,23 @@ contract AaveProtocolTestHelpers { ); usageAsCollateralEnabled = userConfig.isUsingAsCollateral(reserve.id); } + + function getReserveTokensAddresses(address asset) + external + view + returns ( + address aTokenAddress, + address stableDebtTokenAddress, + address variableDebtTokenAddress + ) + { + ReserveLogic.ReserveData memory reserve = ILendingPool(ADDRESSES_PROVIDER.getLendingPool()) + .getReserveData(asset); + + return ( + reserve.aTokenAddress, + reserve.stableDebtTokenAddress, + reserve.variableDebtTokenAddress + ); + } } diff --git a/deployed-contracts.json b/deployed-contracts.json index ca9221df..df6ed994 100644 --- a/deployed-contracts.json +++ b/deployed-contracts.json @@ -145,7 +145,7 @@ }, "DefaultReserveInterestRateStrategy": { "buidlerevm": { - "address": "0x626FdE749F9d499d3777320CAf29484B624ab84a", + "address": "0xB660Fdd109a95718cB9d20E3A89EE6cE342aDcB6", "deployer": "0xc783df8a850f42e7F7e57013759C285caa701eB6" }, "localhost": { @@ -204,7 +204,7 @@ }, "MockFlashLoanReceiver": { "buidlerevm": { - "address": "0x2B681757d757fbB80cc51c6094cEF5eE75bF55aA" + "address": "0xBEF0d4b9c089a5883741fC14cbA352055f35DDA2" }, "localhost": { "address": "0x2B681757d757fbB80cc51c6094cEF5eE75bF55aA" @@ -215,7 +215,7 @@ }, "WalletBalanceProvider": { "buidlerevm": { - "address": "0xDf73fC454FA018051D4a1509e63D11530A59DE10", + "address": "0x2cfcA5785261fbC88EFFDd46fCFc04c22525F9e4", "deployer": "0xc783df8a850f42e7F7e57013759C285caa701eB6" }, "localhost": { @@ -551,7 +551,7 @@ }, "AaveProtocolTestHelpers": { "buidlerevm": { - "address": "0x2cfcA5785261fbC88EFFDd46fCFc04c22525F9e4" + "address": "0xe7536f450378748E1BD4645D3c77ec38e0F3ba28" }, "localhost": { "address": "0x2cfcA5785261fbC88EFFDd46fCFc04c22525F9e4" @@ -562,7 +562,7 @@ }, "StableDebtToken": { "buidlerevm": { - "address": "0xB660Fdd109a95718cB9d20E3A89EE6cE342aDcB6", + "address": "0x830bceA96E56DBC1F8578f75fBaC0AF16B32A07d", "deployer": "0xc783df8a850f42e7F7e57013759C285caa701eB6" }, "localhost": { @@ -576,7 +576,7 @@ }, "VariableDebtToken": { "buidlerevm": { - "address": "0x830bceA96E56DBC1F8578f75fBaC0AF16B32A07d", + "address": "0xA0AB1cB92A4AF81f84dCd258155B5c25D247b54E", "deployer": "0xc783df8a850f42e7F7e57013759C285caa701eB6" }, "localhost": { @@ -594,7 +594,7 @@ "deployer": "0xc783df8a850f42e7F7e57013759C285caa701eB6" }, "buidlerevm": { - "address": "0xA0AB1cB92A4AF81f84dCd258155B5c25D247b54E", + "address": "0x5f7134cd38C826a7649f9Cc47dda24d834DD2967", "deployer": "0xc783df8a850f42e7F7e57013759C285caa701eB6" }, "coverage": { @@ -660,7 +660,7 @@ }, "MockSwapAdapter": { "buidlerevm": { - "address": "0xBEF0d4b9c089a5883741fC14cbA352055f35DDA2" + "address": "0xDf73fC454FA018051D4a1509e63D11530A59DE10" }, "coverage": { "address": "0xBEF0d4b9c089a5883741fC14cbA352055f35DDA2" @@ -669,4 +669,4 @@ "address": "0xBEF0d4b9c089a5883741fC14cbA352055f35DDA2" } } -} \ No newline at end of file +} diff --git a/test/__setup.spec.ts b/test/__setup.spec.ts index 42934f7c..62e11e35 100644 --- a/test/__setup.spec.ts +++ b/test/__setup.spec.ts @@ -57,6 +57,7 @@ import {LendingPoolConfigurator} from '../types/LendingPoolConfigurator'; import {initializeMakeSuite} from './helpers/make-suite'; import path from 'path'; import fs from 'fs'; +import {AaveProtocolTestHelpers} from '../types/AaveProtocolTestHelpers'; ['misc'].forEach((folder) => { const tasksPath = path.join(__dirname, '../', 'tasks', folder); @@ -175,6 +176,7 @@ const initReserves = async ( lendingPoolAddressesProvider: LendingPoolAddressesProvider, lendingPool: LendingPool, lendingPoolConfigurator: LendingPoolConfigurator, + helpersContract: AaveProtocolTestHelpers, aavePool: AavePools, incentivesController: tEthereumAddress ) => { @@ -194,7 +196,7 @@ const initReserves = async ( assetAddressIndex ]; - const {isActive: reserveInitialized} = await lendingPool.getReserveConfigurationData( + const {isActive: reserveInitialized} = await helpersContract.getReserveConfigurationData( tokenAddress ); @@ -276,7 +278,7 @@ const initReserves = async ( const enableReservesToBorrow = async ( reservesParams: iMultiPoolsAssets, tokenAddresses: {[symbol: string]: tEthereumAddress}, - lendingPool: LendingPool, + helpersContract: AaveProtocolTestHelpers, lendingPoolConfigurator: LendingPoolConfigurator ) => { for (const [assetSymbol, {borrowingEnabled, stableBorrowRateEnabled}] of Object.entries( @@ -292,7 +294,7 @@ const enableReservesToBorrow = async ( ]; const { borrowingEnabled: borrowingAlreadyEnabled, - } = await lendingPool.getReserveConfigurationData(tokenAddress); + } = await helpersContract.getReserveConfigurationData(tokenAddress); if (borrowingAlreadyEnabled) { console.log(`Reserve ${assetSymbol} is already enabled for borrowing, skipping`); @@ -311,7 +313,7 @@ const enableReservesToBorrow = async ( const enableReservesAsCollateral = async ( reservesParams: iMultiPoolsAssets, tokenAddresses: {[symbol: string]: tEthereumAddress}, - lendingPool: LendingPool, + helpersContract: AaveProtocolTestHelpers, lendingPoolConfigurator: LendingPoolConfigurator ) => { for (const [ @@ -328,7 +330,7 @@ const enableReservesAsCollateral = async ( ]; const { usageAsCollateralEnabled: alreadyEnabled, - } = await lendingPool.getReserveConfigurationData(tokenAddress); + } = await helpersContract.getReserveConfigurationData(tokenAddress); if (alreadyEnabled) { console.log(`Reserve ${assetSymbol} is already enabled as collateral, skipping`); @@ -479,6 +481,10 @@ const buildTestEnv = async (deployer: Signer, secondaryWallet: Signer) => { const reservesParams = getReservesConfigByPool(AavePools.proto); + const testHelpers = await deployAaveProtocolTestHelpers(addressesProvider.address); + + await insertContractAddressInDb(eContractid.AaveProtocolTestHelpers, testHelpers.address); + console.log('Initialize configuration'); await initReserves( reservesParams, @@ -486,19 +492,20 @@ const buildTestEnv = async (deployer: Signer, secondaryWallet: Signer) => { addressesProvider, lendingPoolProxy, lendingPoolConfiguratorProxy, + testHelpers, AavePools.proto, ZERO_ADDRESS ); await enableReservesToBorrow( reservesParams, protoPoolReservesAddresses, - lendingPoolProxy, + testHelpers, lendingPoolConfiguratorProxy ); await enableReservesAsCollateral( reservesParams, protoPoolReservesAddresses, - lendingPoolProxy, + testHelpers, lendingPoolConfiguratorProxy ); @@ -515,10 +522,6 @@ const buildTestEnv = async (deployer: Signer, secondaryWallet: Signer) => { await deployWalletBalancerProvider(addressesProvider.address); - const testHelpers = await deployAaveProtocolTestHelpers(addressesProvider.address); - - await insertContractAddressInDb(eContractid.AaveProtocolTestHelpers, testHelpers.address); - console.timeEnd('setup'); }; diff --git a/test/collateral-swap.spec.ts b/test/collateral-swap.spec.ts index c2bd9024..d57790f0 100644 --- a/test/collateral-swap.spec.ts +++ b/test/collateral-swap.spec.ts @@ -115,7 +115,7 @@ makeSuite('LendingPool SwapDeposit function', (testEnv: TestEnv) => { }); it('User tries to swap correct amount', async () => { - const {pool, weth, dai, aEth, aDai} = testEnv; + const {pool, weth, dai, aEth, aDai, helpersContract} = testEnv; const userAddress = await pool.signer.getAddress(); const amountToSwap = ethers.utils.parseEther('0.25'); @@ -174,7 +174,7 @@ makeSuite('LendingPool SwapDeposit function', (testEnv: TestEnv) => { 'was received incorrect amount if reserve funds' ); expect( - (await pool.getUserReserveData(dai.address, userAddress)).usageAsCollateralEnabled + (await helpersContract.getUserReserveData(dai.address, userAddress)).usageAsCollateralEnabled ).to.be.equal(true, 'usage as collateral was not enabled on destination reserve for the user'); }); diff --git a/test/configurator.spec.ts b/test/configurator.spec.ts index 3ed53984..e56d2acb 100644 --- a/test/configurator.spec.ts +++ b/test/configurator.spec.ts @@ -9,17 +9,17 @@ makeSuite('LendingPoolConfigurator', (testEnv: TestEnv) => { const {CALLER_NOT_AAVE_ADMIN, RESERVE_LIQUIDITY_NOT_0} = ProtocolErrors; it('Deactivates the ETH reserve', async () => { - const {configurator, pool, weth} = testEnv; + const {configurator, weth, helpersContract} = testEnv; await configurator.deactivateReserve(weth.address); - const {isActive} = await pool.getReserveConfigurationData(weth.address); + const {isActive} = await helpersContract.getReserveConfigurationData(weth.address); expect(isActive).to.be.equal(false); }); it('Rectivates the ETH reserve', async () => { - const {configurator, pool, weth} = testEnv; + const {configurator, weth, helpersContract} = testEnv; await configurator.activateReserve(weth.address); - const {isActive} = await pool.getReserveConfigurationData(weth.address); + const {isActive} = await helpersContract.getReserveConfigurationData(weth.address); expect(isActive).to.be.equal(true); }); @@ -40,7 +40,7 @@ makeSuite('LendingPoolConfigurator', (testEnv: TestEnv) => { }); it('Freezes the ETH reserve', async () => { - const {configurator, pool, weth} = testEnv; + const {configurator, pool, weth, helpersContract} = testEnv; await configurator.freezeReserve(weth.address); const { decimals, @@ -51,12 +51,12 @@ makeSuite('LendingPoolConfigurator', (testEnv: TestEnv) => { stableBorrowRateEnabled, borrowingEnabled, isActive, - isFreezed, - } = await pool.getReserveConfigurationData(weth.address); + isFrozen, + } = await helpersContract.getReserveConfigurationData(weth.address); expect(borrowingEnabled).to.be.equal(true); expect(isActive).to.be.equal(true); - expect(isFreezed).to.be.equal(true); + expect(isFrozen).to.be.equal(true); expect(decimals).to.be.equal(18); expect(ltv).to.be.equal(7500); expect(liquidationThreshold).to.be.equal(8000); @@ -66,7 +66,7 @@ makeSuite('LendingPoolConfigurator', (testEnv: TestEnv) => { }); it('Unfreezes the ETH reserve', async () => { - const {configurator, pool, weth} = testEnv; + const {configurator, helpersContract, weth} = testEnv; await configurator.unfreezeReserve(weth.address); const { @@ -78,12 +78,12 @@ makeSuite('LendingPoolConfigurator', (testEnv: TestEnv) => { stableBorrowRateEnabled, borrowingEnabled, isActive, - isFreezed, - } = await pool.getReserveConfigurationData(weth.address); + isFrozen, + } = await helpersContract.getReserveConfigurationData(weth.address); expect(borrowingEnabled).to.be.equal(true); expect(isActive).to.be.equal(true); - expect(isFreezed).to.be.equal(false); + expect(isFrozen).to.be.equal(false); expect(decimals).to.be.equal(18); expect(ltv).to.be.equal(7500); expect(liquidationThreshold).to.be.equal(8000); @@ -109,7 +109,7 @@ makeSuite('LendingPoolConfigurator', (testEnv: TestEnv) => { }); it('Deactivates the ETH reserve for borrowing', async () => { - const {configurator, pool, weth} = testEnv; + const {configurator, helpersContract, weth} = testEnv; await configurator.disableBorrowingOnReserve(weth.address); const { decimals, @@ -120,12 +120,12 @@ makeSuite('LendingPoolConfigurator', (testEnv: TestEnv) => { stableBorrowRateEnabled, borrowingEnabled, isActive, - isFreezed, - } = await pool.getReserveConfigurationData(weth.address); + isFrozen, + } = await helpersContract.getReserveConfigurationData(weth.address); expect(borrowingEnabled).to.be.equal(false); expect(isActive).to.be.equal(true); - expect(isFreezed).to.be.equal(false); + expect(isFrozen).to.be.equal(false); expect(decimals).to.be.equal(18); expect(ltv).to.be.equal(7500); expect(liquidationThreshold).to.be.equal(8000); @@ -135,9 +135,9 @@ makeSuite('LendingPoolConfigurator', (testEnv: TestEnv) => { }); it('Activates the ETH reserve for borrowing', async () => { - const {configurator, pool, weth} = testEnv; + const {configurator, weth, helpersContract} = testEnv; await configurator.enableBorrowingOnReserve(weth.address, true); - const {variableBorrowIndex} = await pool.getReserveData(weth.address); + const {variableBorrowIndex} = await helpersContract.getReserveData(weth.address); const { decimals, @@ -148,12 +148,12 @@ makeSuite('LendingPoolConfigurator', (testEnv: TestEnv) => { stableBorrowRateEnabled, borrowingEnabled, isActive, - isFreezed, - } = await pool.getReserveConfigurationData(weth.address); + isFrozen, + } = await helpersContract.getReserveConfigurationData(weth.address); expect(borrowingEnabled).to.be.equal(true); expect(isActive).to.be.equal(true); - expect(isFreezed).to.be.equal(false); + expect(isFrozen).to.be.equal(false); expect(decimals).to.be.equal(18); expect(ltv).to.be.equal(7500); expect(liquidationThreshold).to.be.equal(8000); @@ -181,7 +181,7 @@ makeSuite('LendingPoolConfigurator', (testEnv: TestEnv) => { }); it('Deactivates the ETH reserve as collateral', async () => { - const {configurator, pool, weth} = testEnv; + const {configurator, helpersContract, weth} = testEnv; await configurator.disableReserveAsCollateral(weth.address); const { decimals, @@ -192,12 +192,12 @@ makeSuite('LendingPoolConfigurator', (testEnv: TestEnv) => { stableBorrowRateEnabled, borrowingEnabled, isActive, - isFreezed, - } = await pool.getReserveConfigurationData(weth.address); + isFrozen, + } = await helpersContract.getReserveConfigurationData(weth.address); expect(borrowingEnabled).to.be.equal(true); expect(isActive).to.be.equal(true); - expect(isFreezed).to.be.equal(false); + expect(isFrozen).to.be.equal(false); expect(decimals).to.be.equal(18); expect(ltv).to.be.equal(0); expect(liquidationThreshold).to.be.equal(8000); @@ -207,7 +207,7 @@ makeSuite('LendingPoolConfigurator', (testEnv: TestEnv) => { }); it('Activates the ETH reserve as collateral', async () => { - const {configurator, pool, weth} = testEnv; + const {configurator, helpersContract, weth} = testEnv; await configurator.enableReserveAsCollateral(weth.address, '7500', '8000', '10500'); const { @@ -219,12 +219,12 @@ makeSuite('LendingPoolConfigurator', (testEnv: TestEnv) => { stableBorrowRateEnabled, borrowingEnabled, isActive, - isFreezed, - } = await pool.getReserveConfigurationData(weth.address); + isFrozen, + } = await helpersContract.getReserveConfigurationData(weth.address); expect(borrowingEnabled).to.be.equal(true); expect(isActive).to.be.equal(true); - expect(isFreezed).to.be.equal(false); + expect(isFrozen).to.be.equal(false); expect(decimals).to.be.equal(18); expect(ltv).to.be.equal(7500); expect(liquidationThreshold).to.be.equal(8000); @@ -252,7 +252,7 @@ makeSuite('LendingPoolConfigurator', (testEnv: TestEnv) => { }); it('Disable stable borrow rate on the ETH reserve', async () => { - const {configurator, pool, weth} = testEnv; + const {configurator, helpersContract, weth} = testEnv; await configurator.disableReserveStableRate(weth.address); const { decimals, @@ -263,12 +263,12 @@ makeSuite('LendingPoolConfigurator', (testEnv: TestEnv) => { stableBorrowRateEnabled, borrowingEnabled, isActive, - isFreezed, - } = await pool.getReserveConfigurationData(weth.address); + isFrozen, + } = await helpersContract.getReserveConfigurationData(weth.address); expect(borrowingEnabled).to.be.equal(true); expect(isActive).to.be.equal(true); - expect(isFreezed).to.be.equal(false); + expect(isFrozen).to.be.equal(false); expect(decimals).to.be.equal(18); expect(ltv).to.be.equal(7500); expect(liquidationThreshold).to.be.equal(8000); @@ -278,7 +278,7 @@ makeSuite('LendingPoolConfigurator', (testEnv: TestEnv) => { }); it('Enables stable borrow rate on the ETH reserve', async () => { - const {configurator, pool, weth} = testEnv; + const {configurator, helpersContract, weth} = testEnv; await configurator.enableReserveStableRate(weth.address); const { decimals, @@ -289,12 +289,12 @@ makeSuite('LendingPoolConfigurator', (testEnv: TestEnv) => { stableBorrowRateEnabled, borrowingEnabled, isActive, - isFreezed, - } = await pool.getReserveConfigurationData(weth.address); + isFrozen, + } = await helpersContract.getReserveConfigurationData(weth.address); expect(borrowingEnabled).to.be.equal(true); expect(isActive).to.be.equal(true); - expect(isFreezed).to.be.equal(false); + expect(isFrozen).to.be.equal(false); expect(decimals).to.be.equal(18); expect(ltv).to.be.equal(7500); expect(liquidationThreshold).to.be.equal(8000); @@ -320,7 +320,7 @@ makeSuite('LendingPoolConfigurator', (testEnv: TestEnv) => { }); it('Changes LTV of the reserve', async () => { - const {configurator, pool, weth} = testEnv; + const {configurator, helpersContract, weth} = testEnv; await configurator.setLtv(weth.address, '6000'); const { decimals, @@ -331,12 +331,12 @@ makeSuite('LendingPoolConfigurator', (testEnv: TestEnv) => { stableBorrowRateEnabled, borrowingEnabled, isActive, - isFreezed, - } = await pool.getReserveConfigurationData(weth.address); + isFrozen, + } = await helpersContract.getReserveConfigurationData(weth.address); expect(borrowingEnabled).to.be.equal(true); expect(isActive).to.be.equal(true); - expect(isFreezed).to.be.equal(false); + expect(isFrozen).to.be.equal(false); expect(decimals).to.be.equal(18); expect(ltv).to.be.equal(6000); expect(liquidationThreshold).to.be.equal(8000); @@ -354,7 +354,7 @@ makeSuite('LendingPoolConfigurator', (testEnv: TestEnv) => { }); it('Changes the reserve factor of the reserve', async () => { - const {configurator, pool, weth} = testEnv; + const {configurator, helpersContract, weth} = testEnv; await configurator.setReserveFactor(weth.address, '1000'); const { decimals, @@ -365,12 +365,12 @@ makeSuite('LendingPoolConfigurator', (testEnv: TestEnv) => { stableBorrowRateEnabled, borrowingEnabled, isActive, - isFreezed, - } = await pool.getReserveConfigurationData(weth.address); + isFrozen, + } = await helpersContract.getReserveConfigurationData(weth.address); expect(borrowingEnabled).to.be.equal(true); expect(isActive).to.be.equal(true); - expect(isFreezed).to.be.equal(false); + expect(isFrozen).to.be.equal(false); expect(decimals).to.be.equal(18); expect(ltv).to.be.equal(6000); expect(liquidationThreshold).to.be.equal(8000); @@ -388,7 +388,7 @@ makeSuite('LendingPoolConfigurator', (testEnv: TestEnv) => { }); it('Changes liquidation threshold of the reserve', async () => { - const {configurator, pool, weth} = testEnv; + const {configurator, helpersContract, weth} = testEnv; await configurator.setLiquidationThreshold(weth.address, '7500'); const { decimals, @@ -399,12 +399,12 @@ makeSuite('LendingPoolConfigurator', (testEnv: TestEnv) => { stableBorrowRateEnabled, borrowingEnabled, isActive, - isFreezed, - } = await pool.getReserveConfigurationData(weth.address); + isFrozen, + } = await helpersContract.getReserveConfigurationData(weth.address); expect(borrowingEnabled).to.be.equal(true); expect(isActive).to.be.equal(true); - expect(isFreezed).to.be.equal(false); + expect(isFrozen).to.be.equal(false); expect(decimals).to.be.equal(18); expect(ltv).to.be.equal(6000); expect(liquidationThreshold).to.be.equal(7500); @@ -422,7 +422,7 @@ makeSuite('LendingPoolConfigurator', (testEnv: TestEnv) => { }); it('Changes liquidation bonus of the reserve', async () => { - const {configurator, pool, weth} = testEnv; + const {configurator, helpersContract, weth} = testEnv; await configurator.setLiquidationBonus(weth.address, '11000'); const { decimals, @@ -433,12 +433,12 @@ makeSuite('LendingPoolConfigurator', (testEnv: TestEnv) => { stableBorrowRateEnabled, borrowingEnabled, isActive, - isFreezed, - } = await pool.getReserveConfigurationData(weth.address); + isFrozen, + } = await helpersContract.getReserveConfigurationData(weth.address); expect(borrowingEnabled).to.be.equal(true); expect(isActive).to.be.equal(true); - expect(isFreezed).to.be.equal(false); + expect(isFrozen).to.be.equal(false); expect(decimals).to.be.equal(18); expect(ltv).to.be.equal(6000); expect(liquidationThreshold).to.be.equal(7500); diff --git a/test/flash-liquidation-with-collateral.spec.ts b/test/flash-liquidation-with-collateral.spec.ts index 15dac674..eb9dc688 100644 --- a/test/flash-liquidation-with-collateral.spec.ts +++ b/test/flash-liquidation-with-collateral.spec.ts @@ -34,7 +34,7 @@ makeSuite('LendingPool. repayWithCollateral() with liquidator', (testEnv: TestEn }); it('User 5 liquidate User 3 collateral, all his variable debt and part of the stable', async () => { - const {pool, weth, usdc, users, mockSwapAdapter, oracle} = testEnv; + const {pool, weth, usdc, users, mockSwapAdapter, oracle, helpersContract} = testEnv; const user = users[2]; const liquidator = users[4]; const amountToDeposit = parseEther('20'); @@ -103,10 +103,10 @@ makeSuite('LendingPool. repayWithCollateral() with liquidator', (testEnv: TestEn const principalPrice = await oracle.getAssetPrice(usdc.address); const collateralDecimals = ( - await pool.getReserveConfigurationData(weth.address) + await helpersContract.getReserveConfigurationData(weth.address) ).decimals.toString(); const principalDecimals = ( - await pool.getReserveConfigurationData(usdc.address) + await helpersContract.getReserveConfigurationData(usdc.address) ).decimals.toString(); const expectedCollateralLiquidated = new BigNumber(principalPrice.toString()) @@ -209,7 +209,7 @@ makeSuite('LendingPool. repayWithCollateral() with liquidator', (testEnv: TestEn }); it('User 5 liquidates half the USDC loan of User 3 by swapping his WETH collateral', async () => { - const {pool, weth, usdc, users, mockSwapAdapter, oracle} = testEnv; + const {pool, weth, usdc, users, mockSwapAdapter, oracle, helpersContract} = testEnv; const user = users[2]; const liquidator = users[4]; // Sets USDC Price higher to decrease health factor below 1 @@ -268,10 +268,10 @@ makeSuite('LendingPool. repayWithCollateral() with liquidator', (testEnv: TestEn const principalPrice = await oracle.getAssetPrice(usdc.address); const collateralDecimals = ( - await pool.getReserveConfigurationData(weth.address) + await helpersContract.getReserveConfigurationData(weth.address) ).decimals.toString(); const principalDecimals = ( - await pool.getReserveConfigurationData(usdc.address) + await helpersContract.getReserveConfigurationData(usdc.address) ).decimals.toString(); const expectedCollateralLiquidated = new BigNumber(principalPrice.toString()) @@ -344,7 +344,7 @@ makeSuite('LendingPool. repayWithCollateral() with liquidator', (testEnv: TestEn }); it('User 5 liquidates all the USDC loan of User 3 by swapping his WETH collateral', async () => { - const {pool, weth, usdc, users, mockSwapAdapter, oracle} = testEnv; + const {pool, weth, usdc, users, mockSwapAdapter, oracle, helpersContract} = testEnv; const user = users[2]; const liquidator = users[4]; // Sets USDC Price higher to decrease health factor below 1 @@ -403,10 +403,10 @@ makeSuite('LendingPool. repayWithCollateral() with liquidator', (testEnv: TestEn const principalPrice = await oracle.getAssetPrice(usdc.address); const collateralDecimals = ( - await pool.getReserveConfigurationData(weth.address) + await helpersContract.getReserveConfigurationData(weth.address) ).decimals.toString(); const principalDecimals = ( - await pool.getReserveConfigurationData(usdc.address) + await helpersContract.getReserveConfigurationData(usdc.address) ).decimals.toString(); const expectedCollateralLiquidated = new BigNumber(principalPrice.toString()) @@ -541,7 +541,7 @@ makeSuite('LendingPool. repayWithCollateral() with liquidator', (testEnv: TestEn ).to.be.revertedWith('38'); }); it('User 5 liquidates User 2 DAI Variable loan using his WETH collateral, half the amount', async () => { - const {pool, weth, dai, users, mockSwapAdapter, oracle} = testEnv; + const {pool, weth, dai, users, mockSwapAdapter, oracle, helpersContract} = testEnv; const user = users[1]; const liquidator = users[4]; @@ -570,7 +570,10 @@ makeSuite('LendingPool. repayWithCollateral() with liquidator', (testEnv: TestEn ); // First half - const amountToRepay = daiReserveDataBefore.totalVariableDebt.multipliedBy(0.6).toFixed(0).toString(); + const amountToRepay = daiReserveDataBefore.totalVariableDebt + .multipliedBy(0.6) + .toFixed(0) + .toString(); await mockSwapAdapter.setAmountToReturn(amountToRepay); await waitForTx( @@ -599,10 +602,10 @@ makeSuite('LendingPool. repayWithCollateral() with liquidator', (testEnv: TestEn const principalPrice = await oracle.getAssetPrice(dai.address); const collateralDecimals = ( - await pool.getReserveConfigurationData(weth.address) + await helpersContract.getReserveConfigurationData(weth.address) ).decimals.toString(); const principalDecimals = ( - await pool.getReserveConfigurationData(dai.address) + await helpersContract.getReserveConfigurationData(dai.address) ).decimals.toString(); const expectedCollateralLiquidated = new BigNumber(principalPrice.toString()) @@ -639,7 +642,7 @@ makeSuite('LendingPool. repayWithCollateral() with liquidator', (testEnv: TestEn }); it('User 2 tries to repay remaining DAI Variable loan using his WETH collateral', async () => { - const {pool, weth, dai, users, mockSwapAdapter, oracle} = testEnv; + const {pool, weth, dai, users, mockSwapAdapter, oracle, helpersContract} = testEnv; const user = users[1]; const {userData: wethUserDataBefore} = await getContractsData( @@ -686,10 +689,10 @@ makeSuite('LendingPool. repayWithCollateral() with liquidator', (testEnv: TestEn const principalPrice = await oracle.getAssetPrice(dai.address); const collateralDecimals = ( - await pool.getReserveConfigurationData(weth.address) + await helpersContract.getReserveConfigurationData(weth.address) ).decimals.toString(); const principalDecimals = ( - await pool.getReserveConfigurationData(dai.address) + await helpersContract.getReserveConfigurationData(dai.address) ).decimals.toString(); const expectedCollateralLiquidated = new BigNumber(principalPrice.toString()) @@ -722,7 +725,7 @@ makeSuite('LendingPool. repayWithCollateral() with liquidator', (testEnv: TestEn }); it('Liquidator tries to repay 4 user a bigger amount that what can be swapped of a particular collateral, repaying only the maximum allowed by that collateral', async () => { - const {pool, weth, dai, usdc, users, mockSwapAdapter, oracle} = testEnv; + const {pool, weth, dai, usdc, users, mockSwapAdapter, oracle, helpersContract} = testEnv; const user = users[3]; const liquidator = users[5]; @@ -795,11 +798,11 @@ makeSuite('LendingPool. repayWithCollateral() with liquidator', (testEnv: TestEn const collateralPrice = await oracle.getAssetPrice(weth.address); const principalPrice = await oracle.getAssetPrice(usdc.address); - const collateralConfig = await pool.getReserveConfigurationData(weth.address); + const collateralConfig = await helpersContract.getReserveConfigurationData(weth.address); const collateralDecimals = collateralConfig.decimals.toString(); const principalDecimals = ( - await pool.getReserveConfigurationData(usdc.address) + await helpersContract.getReserveConfigurationData(usdc.address) ).decimals.toString(); const collateralLiquidationBonus = collateralConfig.liquidationBonus.toString(); @@ -879,10 +882,10 @@ makeSuite('LendingPool. repayWithCollateral() with liquidator', (testEnv: TestEn const daiPrice = await oracle.getAssetPrice(dai.address); await oracle.setAssetPrice( - dai.address, - new BigNumber(daiPrice.toString()).multipliedBy(0.9).toFixed(0) - ); - + dai.address, + new BigNumber(daiPrice.toString()).multipliedBy(0.9).toFixed(0) + ); + // Liquidator should NOT be able to liquidate himself with WETH, even if is disabled await mockSwapAdapter.setAmountToReturn(amountToRepay); await expect( diff --git a/test/flashloan.spec.ts b/test/flashloan.spec.ts index c2be90ed..7b02e021 100644 --- a/test/flashloan.spec.ts +++ b/test/flashloan.spec.ts @@ -43,7 +43,7 @@ makeSuite('LendingPool FlashLoan function', (testEnv: TestEnv) => { }); it('Takes WETH flashloan with mode = 0, returns the funds correctly', async () => { - const {pool, deployer, weth} = testEnv; + const {pool, helpersContract, weth} = testEnv; await pool.flashLoan( _mockFlashLoanReceiver.address, @@ -56,7 +56,7 @@ makeSuite('LendingPool FlashLoan function', (testEnv: TestEnv) => { ethers.utils.parseUnits('10000'); - const reserveData = await pool.getReserveData(weth.address); + const reserveData = await helpersContract.getReserveData(weth.address); const currentLiquidityRate = reserveData.liquidityRate; const currentLiquidityIndex = reserveData.liquidityIndex; @@ -71,9 +71,9 @@ makeSuite('LendingPool FlashLoan function', (testEnv: TestEnv) => { }); it('Takes an ETH flashloan with mode = 0 as big as the available liquidity', async () => { - const {pool, weth} = testEnv; + const {pool, helpersContract, weth} = testEnv; - const reserveDataBefore = await pool.getReserveData(weth.address); + const reserveDataBefore = await helpersContract.getReserveData(weth.address); const txResult = await pool.flashLoan( _mockFlashLoanReceiver.address, weth.address, @@ -83,7 +83,7 @@ makeSuite('LendingPool FlashLoan function', (testEnv: TestEnv) => { '0' ); - const reserveData = await pool.getReserveData(weth.address); + const reserveData = await helpersContract.getReserveData(weth.address); const currentLiqudityRate = reserveData.liquidityRate; const currentLiquidityIndex = reserveData.liquidityIndex; @@ -136,7 +136,7 @@ makeSuite('LendingPool FlashLoan function', (testEnv: TestEnv) => { }); it('Caller deposits 1000 DAI as collateral, Takes WETH flashloan with mode = 2, does not return the funds. A variable loan for caller is created', async () => { - const {dai, pool, weth, users} = testEnv; + const {dai, pool, weth, users, helpersContract} = testEnv; const caller = users[1]; @@ -160,7 +160,9 @@ makeSuite('LendingPool FlashLoan function', (testEnv: TestEnv) => { '0x10', '0' ); - const {variableDebtTokenAddress} = await pool.getReserveTokensAddresses(weth.address); + const {variableDebtTokenAddress} = await helpersContract.getReserveTokensAddresses( + weth.address + ); const wethDebtToken = await getContract( eContractid.VariableDebtToken, @@ -225,7 +227,7 @@ makeSuite('LendingPool FlashLoan function', (testEnv: TestEnv) => { }); it('Takes out a 500 USDC flashloan, returns the funds correctly', async () => { - const {usdc, pool, deployer: depositor} = testEnv; + const {usdc, pool, helpersContract, deployer: depositor} = testEnv; await _mockFlashLoanReceiver.setFailExecutionTransfer(false); @@ -240,8 +242,8 @@ makeSuite('LendingPool FlashLoan function', (testEnv: TestEnv) => { '0' ); - const reserveData = await pool.getReserveData(usdc.address); - const userData = await pool.getUserReserveData(usdc.address, depositor.address); + const reserveData = await helpersContract.getReserveData(usdc.address); + const userData = await helpersContract.getUserReserveData(usdc.address, depositor.address); const totalLiquidity = reserveData.availableLiquidity .add(reserveData.totalStableDebt) @@ -278,7 +280,7 @@ makeSuite('LendingPool FlashLoan function', (testEnv: TestEnv) => { }); it('Caller deposits 5 WETH as collateral, Takes a USDC flashloan with mode = 2, does not return the funds. A loan for caller is created', async () => { - const {usdc, pool, weth, users} = testEnv; + const {usdc, pool, weth, users, helpersContract} = testEnv; const caller = users[2]; @@ -297,7 +299,9 @@ makeSuite('LendingPool FlashLoan function', (testEnv: TestEnv) => { await pool .connect(caller.signer) .flashLoan(_mockFlashLoanReceiver.address, usdc.address, flashloanAmount, 2, '0x10', '0'); - const {variableDebtTokenAddress} = await pool.getReserveTokensAddresses(usdc.address); + const {variableDebtTokenAddress} = await helpersContract.getReserveTokensAddresses( + usdc.address + ); const usdcDebtToken = await getContract( eContractid.VariableDebtToken, @@ -334,7 +338,7 @@ makeSuite('LendingPool FlashLoan function', (testEnv: TestEnv) => { }); it('Caller takes a WETH flashloan with mode = 1', async () => { - const {dai, pool, weth, users} = testEnv; + const {dai, pool, weth, users, helpersContract} = testEnv; const caller = users[3]; @@ -346,7 +350,7 @@ makeSuite('LendingPool FlashLoan function', (testEnv: TestEnv) => { .connect(caller.signer) .flashLoan(_mockFlashLoanReceiver.address, weth.address, flashAmount, 1, '0x10', '0'); - const {stableDebtTokenAddress} = await pool.getReserveTokensAddresses(weth.address); + const {stableDebtTokenAddress} = await helpersContract.getReserveTokensAddresses(weth.address); const wethDebtToken = await getContract( eContractid.VariableDebtToken, diff --git a/test/helpers/actions.ts b/test/helpers/actions.ts index 69c9c6ce..968d854a 100644 --- a/test/helpers/actions.ts +++ b/test/helpers/actions.ts @@ -32,7 +32,7 @@ import {waitForTx} from '../__setup.spec'; import {ContractReceipt} from 'ethers'; import {AToken} from '../../types/AToken'; import {RateMode, tEthereumAddress} from '../../helpers/types'; -import { time } from 'console'; +import {time} from 'console'; const {expect} = chai; @@ -736,11 +736,11 @@ export const getContractsData = async ( testEnv: TestEnv, sender?: string ) => { - const {pool} = testEnv; + const {pool, helpersContract} = testEnv; const [userData, reserveData, timestamp] = await Promise.all([ - getUserData(pool, reserve, user, sender || user), - getReserveData(pool, reserve), + getUserData(pool, helpersContract, reserve, user, sender || user), + getReserveData(helpersContract, reserve), timeLatest(), ]); diff --git a/test/helpers/make-suite.ts b/test/helpers/make-suite.ts index 2a5bf6f6..a951e86b 100644 --- a/test/helpers/make-suite.ts +++ b/test/helpers/make-suite.ts @@ -9,7 +9,8 @@ import { getMintableErc20, getLendingPoolConfiguratorProxy, getPriceOracle, - getMockSwapAdapter, getLendingPoolAddressesProviderRegistry + getMockSwapAdapter, + getLendingPoolAddressesProviderRegistry, } from '../../helpers/contracts-helpers'; import {tEthereumAddress} from '../../helpers/types'; import {LendingPool} from '../../types/LendingPool'; @@ -24,8 +25,8 @@ import bignumberChai from 'chai-bignumber'; import {almostEqual} from './almost-equal'; import {PriceOracle} from '../../types/PriceOracle'; import {LendingPoolAddressesProvider} from '../../types/LendingPoolAddressesProvider'; -import { MockSwapAdapter } from '../../types/MockSwapAdapter'; -import { LendingPoolAddressesProviderRegistry } from '../../types/LendingPoolAddressesProviderRegistry'; +import {MockSwapAdapter} from '../../types/MockSwapAdapter'; +import {LendingPoolAddressesProviderRegistry} from '../../types/LendingPoolAddressesProviderRegistry'; chai.use(bignumberChai()); chai.use(almostEqual()); @@ -73,7 +74,7 @@ const testEnv: TestEnv = { lend: {} as MintableErc20, addressesProvider: {} as LendingPoolAddressesProvider, mockSwapAdapter: {} as MockSwapAdapter, - registry: {} as LendingPoolAddressesProviderRegistry + registry: {} as LendingPoolAddressesProviderRegistry, } as TestEnv; export async function initializeMakeSuite() { @@ -134,7 +135,7 @@ export async function initializeMakeSuite() { testEnv.lend = await getMintableErc20(lendAddress); testEnv.weth = await getMintableErc20(wethAddress); - testEnv.mockSwapAdapter = await getMockSwapAdapter() + testEnv.mockSwapAdapter = await getMockSwapAdapter(); } export function makeSuite(name: string, tests: (testEnv: TestEnv) => void) { diff --git a/test/helpers/utils/helpers.ts b/test/helpers/utils/helpers.ts index 7c3dbd2a..d729d327 100644 --- a/test/helpers/utils/helpers.ts +++ b/test/helpers/utils/helpers.ts @@ -4,19 +4,22 @@ import { getLendingRateOracle, getIErc20Detailed, getMintableErc20, - getAToken, getStableDebtToken, getVariableDebtToken + getAToken, + getStableDebtToken, + getVariableDebtToken, } from '../../../helpers/contracts-helpers'; import {tEthereumAddress} from '../../../helpers/types'; import BigNumber from 'bignumber.js'; import {getDb, BRE} from '../../../helpers/misc-utils'; +import {AaveProtocolTestHelpers} from '../../../types/AaveProtocolTestHelpers'; export const getReserveData = async ( - pool: LendingPool, + helper: AaveProtocolTestHelpers, reserve: tEthereumAddress ): Promise => { const [reserveData, tokenAddresses, rateOracle, token] = await Promise.all([ - pool.getReserveData(reserve), - pool.getReserveTokensAddresses(reserve), + helper.getReserveData(reserve), + helper.getReserveTokensAddresses(reserve), getLendingRateOracle(), getIErc20Detailed(reserve), ]); @@ -27,7 +30,6 @@ export const getReserveData = async ( const [principalStableDebt] = await stableDebtToken.getSupplyData(); const totalStableDebtLastUpdated = await stableDebtToken.getTotalSupplyLastUpdated(); - const scaledVariableDebt = await variableDebtToken.scaledTotalSupply(); const rate = (await rateOracle.getMarketBorrowRate(reserve)).toString(); @@ -72,13 +74,14 @@ export const getReserveData = async ( export const getUserData = async ( pool: LendingPool, + helper: AaveProtocolTestHelpers, reserve: string, user: tEthereumAddress, sender?: tEthereumAddress ): Promise => { const [userData, scaledATokenBalance] = await Promise.all([ - pool.getUserReserveData(reserve, user), - getATokenUserData(reserve, user, pool), + helper.getUserReserveData(reserve, user), + getATokenUserData(reserve, user, helper), ]); const token = await getMintableErc20(reserve); @@ -110,8 +113,13 @@ export const getReserveAddressFromSymbol = async (symbol: string) => { return token.address; }; -const getATokenUserData = async (reserve: string, user: string, pool: LendingPool) => { - const aTokenAddress: string = (await pool.getReserveTokensAddresses(reserve)).aTokenAddress; +const getATokenUserData = async ( + reserve: string, + user: string, + helpersContract: AaveProtocolTestHelpers +) => { + const aTokenAddress: string = (await helpersContract.getReserveTokensAddresses(reserve)) + .aTokenAddress; const aToken = await getAToken(aTokenAddress); diff --git a/test/liquidation-atoken.spec.ts b/test/liquidation-atoken.spec.ts index 97d9507d..e32459d5 100644 --- a/test/liquidation-atoken.spec.ts +++ b/test/liquidation-atoken.spec.ts @@ -114,7 +114,7 @@ makeSuite('LendingPool liquidation - liquidator receiving aToken', (testEnv) => }); it('LIQUIDATION - Liquidates the borrow', async () => { - const {pool, dai, weth, users, oracle} = testEnv; + const {pool, dai, weth, users, oracle, helpersContract} = testEnv; const borrower = users[1]; //mints dai to the caller @@ -124,10 +124,15 @@ makeSuite('LendingPool liquidation - liquidator receiving aToken', (testEnv) => //approve protocol to access depositor wallet await dai.approve(pool.address, APPROVAL_AMOUNT_LENDING_POOL); - const daiReserveDataBefore = await getReserveData(pool, dai.address); - const ethReserveDataBefore = await pool.getReserveData(weth.address); + const daiReserveDataBefore = await getReserveData(helpersContract, dai.address); + const ethReserveDataBefore = await helpersContract.getReserveData(weth.address); - const userReserveDataBefore = await getUserData(pool, dai.address, borrower.address); + const userReserveDataBefore = await getUserData( + pool, + helpersContract, + dai.address, + borrower.address + ); const amountToLiquidate = new BigNumber(userReserveDataBefore.currentVariableDebt.toString()) .div(2) @@ -141,21 +146,24 @@ makeSuite('LendingPool liquidation - liquidator receiving aToken', (testEnv) => true ); - const userReserveDataAfter = await pool.getUserReserveData(dai.address, borrower.address); + const userReserveDataAfter = await helpersContract.getUserReserveData( + dai.address, + borrower.address + ); const userGlobalDataAfter = await pool.getUserAccountData(borrower.address); - const daiReserveDataAfter = await pool.getReserveData(dai.address); - const ethReserveDataAfter = await pool.getReserveData(weth.address); + const daiReserveDataAfter = await helpersContract.getReserveData(dai.address); + const ethReserveDataAfter = await helpersContract.getReserveData(weth.address); const collateralPrice = (await oracle.getAssetPrice(weth.address)).toString(); const principalPrice = (await oracle.getAssetPrice(dai.address)).toString(); const collateralDecimals = ( - await pool.getReserveConfigurationData(weth.address) + await helpersContract.getReserveConfigurationData(weth.address) ).decimals.toString(); const principalDecimals = ( - await pool.getReserveConfigurationData(dai.address) + await helpersContract.getReserveConfigurationData(dai.address) ).decimals.toString(); const expectedCollateralLiquidated = new BigNumber(principalPrice) @@ -215,7 +223,7 @@ makeSuite('LendingPool liquidation - liquidator receiving aToken', (testEnv) => }); it('User 3 deposits 1000 USDC, user 4 1 WETH, user 4 borrows - drops HF, liquidates the borrow', async () => { - const {users, pool, usdc, oracle, weth} = testEnv; + const {users, pool, usdc, oracle, weth, helpersContract} = testEnv; const depositor = users[3]; const borrower = users[4]; @@ -278,10 +286,13 @@ makeSuite('LendingPool liquidation - liquidator receiving aToken', (testEnv) => //approve protocol to access depositor wallet await usdc.approve(pool.address, APPROVAL_AMOUNT_LENDING_POOL); - const userReserveDataBefore = await pool.getUserReserveData(usdc.address, borrower.address); + const userReserveDataBefore = await helpersContract.getUserReserveData( + usdc.address, + borrower.address + ); - const usdcReserveDataBefore = await pool.getReserveData(usdc.address); - const ethReserveDataBefore = await pool.getReserveData(weth.address); + const usdcReserveDataBefore = await helpersContract.getReserveData(usdc.address); + const ethReserveDataBefore = await helpersContract.getReserveData(weth.address); const amountToLiquidate = new BigNumber(userReserveDataBefore.currentStableDebt.toString()) .multipliedBy(0.5) @@ -295,21 +306,24 @@ makeSuite('LendingPool liquidation - liquidator receiving aToken', (testEnv) => true ); - const userReserveDataAfter = await pool.getUserReserveData(usdc.address, borrower.address); + const userReserveDataAfter = await helpersContract.getUserReserveData( + usdc.address, + borrower.address + ); const userGlobalDataAfter = await pool.getUserAccountData(borrower.address); - const usdcReserveDataAfter = await pool.getReserveData(usdc.address); - const ethReserveDataAfter = await pool.getReserveData(weth.address); + const usdcReserveDataAfter = await helpersContract.getReserveData(usdc.address); + const ethReserveDataAfter = await helpersContract.getReserveData(weth.address); const collateralPrice = (await oracle.getAssetPrice(weth.address)).toString(); const principalPrice = (await oracle.getAssetPrice(usdc.address)).toString(); const collateralDecimals = ( - await pool.getReserveConfigurationData(weth.address) + await helpersContract.getReserveConfigurationData(weth.address) ).decimals.toString(); const principalDecimals = ( - await pool.getReserveConfigurationData(usdc.address) + await helpersContract.getReserveConfigurationData(usdc.address) ).decimals.toString(); const expectedCollateralLiquidated = new BigNumber(principalPrice) diff --git a/test/liquidation-underlying.spec.ts b/test/liquidation-underlying.spec.ts index df1e9404..bef20fda 100644 --- a/test/liquidation-underlying.spec.ts +++ b/test/liquidation-underlying.spec.ts @@ -119,7 +119,7 @@ makeSuite('LendingPool liquidation - liquidator receiving the underlying asset', }); it('LIQUIDATION - Liquidates the borrow', async () => { - const {dai, weth, users, pool, oracle} = testEnv; + const {dai, weth, users, pool, oracle, helpersContract} = testEnv; const liquidator = users[3]; const borrower = users[1]; @@ -129,10 +129,15 @@ makeSuite('LendingPool liquidation - liquidator receiving the underlying asset', //approve protocol to access the liquidator wallet await dai.connect(liquidator.signer).approve(pool.address, APPROVAL_AMOUNT_LENDING_POOL); - const daiReserveDataBefore = await pool.getReserveData(dai.address); - const ethReserveDataBefore = await pool.getReserveData(weth.address); + const daiReserveDataBefore = await helpersContract.getReserveData(dai.address); + const ethReserveDataBefore = await helpersContract.getReserveData(weth.address); - const userReserveDataBefore = await getUserData(pool, dai.address, borrower.address); + const userReserveDataBefore = await getUserData( + pool, + helpersContract, + dai.address, + borrower.address + ); const amountToLiquidate = userReserveDataBefore.currentStableDebt.div(2).toFixed(0); @@ -142,19 +147,24 @@ makeSuite('LendingPool liquidation - liquidator receiving the underlying asset', .connect(liquidator.signer) .liquidationCall(weth.address, dai.address, borrower.address, amountToLiquidate, false); - const userReserveDataAfter = await getUserData(pool, dai.address, borrower.address); + const userReserveDataAfter = await getUserData( + pool, + helpersContract, + dai.address, + borrower.address + ); - const daiReserveDataAfter = await pool.getReserveData(dai.address); - const ethReserveDataAfter = await pool.getReserveData(weth.address); + const daiReserveDataAfter = await helpersContract.getReserveData(dai.address); + const ethReserveDataAfter = await helpersContract.getReserveData(weth.address); const collateralPrice = await oracle.getAssetPrice(weth.address); const principalPrice = await oracle.getAssetPrice(dai.address); const collateralDecimals = ( - await pool.getReserveConfigurationData(weth.address) + await helpersContract.getReserveConfigurationData(weth.address) ).decimals.toString(); const principalDecimals = ( - await pool.getReserveConfigurationData(dai.address) + await helpersContract.getReserveConfigurationData(dai.address) ).decimals.toString(); const expectedCollateralLiquidated = new BigNumber(principalPrice.toString()) @@ -214,7 +224,7 @@ makeSuite('LendingPool liquidation - liquidator receiving the underlying asset', }); it('User 3 deposits 1000 USDC, user 4 1 WETH, user 4 borrows - drops HF, liquidates the borrow', async () => { - const {usdc, users, pool, oracle, weth} = testEnv; + const {usdc, users, pool, oracle, weth, helpersContract} = testEnv; const depositor = users[3]; const borrower = users[4]; @@ -280,10 +290,13 @@ makeSuite('LendingPool liquidation - liquidator receiving the underlying asset', //approve protocol to access depositor wallet await usdc.connect(liquidator.signer).approve(pool.address, APPROVAL_AMOUNT_LENDING_POOL); - const userReserveDataBefore = await pool.getUserReserveData(usdc.address, borrower.address); + const userReserveDataBefore = await helpersContract.getUserReserveData( + usdc.address, + borrower.address + ); - const usdcReserveDataBefore = await pool.getReserveData(usdc.address); - const ethReserveDataBefore = await pool.getReserveData(weth.address); + const usdcReserveDataBefore = await helpersContract.getReserveData(usdc.address); + const ethReserveDataBefore = await helpersContract.getReserveData(weth.address); const amountToLiquidate = BRE.ethers.BigNumber.from( userReserveDataBefore.currentStableDebt.toString() @@ -295,21 +308,24 @@ makeSuite('LendingPool liquidation - liquidator receiving the underlying asset', .connect(liquidator.signer) .liquidationCall(weth.address, usdc.address, borrower.address, amountToLiquidate, false); - const userReserveDataAfter = await pool.getUserReserveData(usdc.address, borrower.address); + const userReserveDataAfter = await helpersContract.getUserReserveData( + usdc.address, + borrower.address + ); const userGlobalDataAfter = await pool.getUserAccountData(borrower.address); - const usdcReserveDataAfter = await pool.getReserveData(usdc.address); - const ethReserveDataAfter = await pool.getReserveData(weth.address); + const usdcReserveDataAfter = await helpersContract.getReserveData(usdc.address); + const ethReserveDataAfter = await helpersContract.getReserveData(weth.address); const collateralPrice = await oracle.getAssetPrice(weth.address); const principalPrice = await oracle.getAssetPrice(usdc.address); const collateralDecimals = ( - await pool.getReserveConfigurationData(weth.address) + await helpersContract.getReserveConfigurationData(weth.address) ).decimals.toString(); const principalDecimals = ( - await pool.getReserveConfigurationData(usdc.address) + await helpersContract.getReserveConfigurationData(usdc.address) ).decimals.toString(); const expectedCollateralLiquidated = new BigNumber(principalPrice.toString()) @@ -361,7 +377,7 @@ makeSuite('LendingPool liquidation - liquidator receiving the underlying asset', }); it('User 4 deposits 1000 LEND - drops HF, liquidates the LEND, which results on a lower amount being liquidated', async () => { - const {lend, usdc, users, pool, oracle} = testEnv; + const {lend, usdc, users, pool, oracle, helpersContract} = testEnv; const depositor = users[3]; const borrower = users[4]; @@ -395,10 +411,13 @@ makeSuite('LendingPool liquidation - liquidator receiving the underlying asset', //approve protocol to access depositor wallet await usdc.connect(liquidator.signer).approve(pool.address, APPROVAL_AMOUNT_LENDING_POOL); - const userReserveDataBefore = await pool.getUserReserveData(usdc.address, borrower.address); + const userReserveDataBefore = await helpersContract.getUserReserveData( + usdc.address, + borrower.address + ); - const usdcReserveDataBefore = await pool.getReserveData(usdc.address); - const lendReserveDataBefore = await pool.getReserveData(lend.address); + const usdcReserveDataBefore = await helpersContract.getReserveData(usdc.address); + const lendReserveDataBefore = await helpersContract.getReserveData(lend.address); const amountToLiquidate = new BigNumber(userReserveDataBefore.currentStableDebt.toString()) .div(2) @@ -412,26 +431,26 @@ makeSuite('LendingPool liquidation - liquidator receiving the underlying asset', .connect(liquidator.signer) .liquidationCall(lend.address, usdc.address, borrower.address, amountToLiquidate, false); - const userReserveDataAfter = await pool.getUserReserveData(usdc.address, borrower.address); + const userReserveDataAfter = await helpersContract.getUserReserveData( + usdc.address, + borrower.address + ); const userGlobalDataAfter = await pool.getUserAccountData(borrower.address); - const usdcReserveDataAfter = await pool.getReserveData(usdc.address); - const lendReserveDataAfter = await pool.getReserveData(lend.address); + const usdcReserveDataAfter = await helpersContract.getReserveData(usdc.address); + const lendReserveDataAfter = await helpersContract.getReserveData(lend.address); + + const lendConfiguration = await helpersContract.getReserveConfigurationData(lend.address); + const collateralDecimals = lendConfiguration.decimals.toString(); + const liquidationBonus = lendConfiguration.liquidationBonus.toString(); - const collateralDecimals = ( - await pool.getReserveConfigurationData(lend.address) - ).decimals.toString(); const principalDecimals = ( - await pool.getReserveConfigurationData(usdc.address) + await helpersContract.getReserveConfigurationData(usdc.address) ).decimals.toString(); const expectedCollateralLiquidated = oneEther.multipliedBy('1000'); - const liquidationBonus = ( - await pool.getReserveConfigurationData(lend.address) - ).liquidationBonus.toString(); - const expectedPrincipal = new BigNumber(collateralPrice.toString()) .times(expectedCollateralLiquidated) .times(new BigNumber(10).pow(principalDecimals)) diff --git a/test/pausable-functions.spec.ts b/test/pausable-functions.spec.ts index 3403491c..d5e321e3 100644 --- a/test/pausable-functions.spec.ts +++ b/test/pausable-functions.spec.ts @@ -236,7 +236,7 @@ makeSuite('Pausable Pool', (testEnv: TestEnv) => { }); it('Liquidation call', async () => { - const {users, pool, usdc, oracle, weth, configurator} = testEnv; + const {users, pool, usdc, oracle, weth, configurator, helpersContract} = testEnv; const depositor = users[3]; const borrower = users[4]; @@ -295,7 +295,10 @@ makeSuite('Pausable Pool', (testEnv: TestEnv) => { await usdc.mint(await convertToCurrencyDecimals(usdc.address, '1000')); await usdc.approve(pool.address, APPROVAL_AMOUNT_LENDING_POOL); - const userReserveDataBefore = await pool.getUserReserveData(usdc.address, borrower.address); + const userReserveDataBefore = await helpersContract.getUserReserveData( + usdc.address, + borrower.address + ); const amountToLiquidate = new BigNumber(userReserveDataBefore.currentStableDebt.toString()) .multipliedBy(0.5) diff --git a/test/repay-with-collateral.spec.ts b/test/repay-with-collateral.spec.ts index 7fe7d714..46625397 100644 --- a/test/repay-with-collateral.spec.ts +++ b/test/repay-with-collateral.spec.ts @@ -131,7 +131,7 @@ makeSuite('LendingPool. repayWithCollateral()', (testEnv: TestEnv) => { }); it('User 2 tries to repay his DAI Variable loan using his WETH collateral. First half the amount, after that, the rest', async () => { - const {pool, weth, dai, users, mockSwapAdapter, oracle} = testEnv; + const {pool, weth, dai, users, mockSwapAdapter, oracle, helpersContract} = testEnv; const user = users[1]; const amountToRepay = parseEther('10'); @@ -177,10 +177,10 @@ makeSuite('LendingPool. repayWithCollateral()', (testEnv: TestEnv) => { const principalPrice = await oracle.getAssetPrice(dai.address); const collateralDecimals = ( - await pool.getReserveConfigurationData(weth.address) + await helpersContract.getReserveConfigurationData(weth.address) ).decimals.toString(); const principalDecimals = ( - await pool.getReserveConfigurationData(dai.address) + await helpersContract.getReserveConfigurationData(dai.address) ).decimals.toString(); const expectedCollateralLiquidated = new BigNumber(principalPrice.toString()) @@ -230,7 +230,7 @@ makeSuite('LendingPool. repayWithCollateral()', (testEnv: TestEnv) => { }); it('User 3 repays completely his USDC loan by swapping his WETH collateral', async () => { - const {pool, weth, usdc, users, mockSwapAdapter, oracle} = testEnv; + const {pool, weth, usdc, users, mockSwapAdapter, oracle, helpersContract} = testEnv; const user = users[2]; const amountToRepay = parseUnits('10', 6); @@ -277,10 +277,10 @@ makeSuite('LendingPool. repayWithCollateral()', (testEnv: TestEnv) => { const principalPrice = await oracle.getAssetPrice(usdc.address); const collateralDecimals = ( - await pool.getReserveConfigurationData(weth.address) + await helpersContract.getReserveConfigurationData(weth.address) ).decimals.toString(); const principalDecimals = ( - await pool.getReserveConfigurationData(usdc.address) + await helpersContract.getReserveConfigurationData(usdc.address) ).decimals.toString(); const expectedCollateralLiquidated = new BigNumber(principalPrice.toString()) @@ -337,7 +337,7 @@ makeSuite('LendingPool. repayWithCollateral()', (testEnv: TestEnv) => { }); it('User 3 tries to repay with his collateral all his variable debt and part of the stable', async () => { - const {pool, weth, usdc, users, mockSwapAdapter, oracle} = testEnv; + const {pool, weth, usdc, users, mockSwapAdapter, oracle, helpersContract} = testEnv; const user = users[2]; const amountToDeposit = parseEther('20'); @@ -398,10 +398,10 @@ makeSuite('LendingPool. repayWithCollateral()', (testEnv: TestEnv) => { const principalPrice = await oracle.getAssetPrice(usdc.address); const collateralDecimals = ( - await pool.getReserveConfigurationData(weth.address) + await helpersContract.getReserveConfigurationData(weth.address) ).decimals.toString(); const principalDecimals = ( - await pool.getReserveConfigurationData(usdc.address) + await helpersContract.getReserveConfigurationData(usdc.address) ).decimals.toString(); const expectedCollateralLiquidated = new BigNumber(principalPrice.toString()) @@ -478,7 +478,7 @@ makeSuite('LendingPool. repayWithCollateral()', (testEnv: TestEnv) => { }); it('User 4 tries to repay a bigger amount that what can be swapped of a particular collateral, repaying only the maximum allowed by that collateral', async () => { - const {pool, weth, dai, users, mockSwapAdapter, oracle} = testEnv; + const {pool, weth, dai, users, mockSwapAdapter, oracle, helpersContract} = testEnv; const user = users[3]; const amountToDepositWeth = parseEther('0.1'); @@ -535,14 +535,15 @@ makeSuite('LendingPool. repayWithCollateral()', (testEnv: TestEnv) => { const collateralPrice = await oracle.getAssetPrice(weth.address); const principalPrice = await oracle.getAssetPrice(dai.address); - const collateralConfig = await pool.getReserveConfigurationData(weth.address); + const collateralConfig = await helpersContract.getReserveConfigurationData(weth.address); const collateralDecimals = collateralConfig.decimals.toString(); - const principalDecimals = ( - await pool.getReserveConfigurationData(dai.address) - ).decimals.toString(); const collateralLiquidationBonus = collateralConfig.liquidationBonus.toString(); + const principalDecimals = ( + await helpersContract.getReserveConfigurationData(dai.address) + ).decimals.toString(); + const expectedDebtCovered = new BigNumber(collateralPrice.toString()) .times(new BigNumber(wethUserDataBefore.currentATokenBalance.toString())) .times(new BigNumber(10).pow(principalDecimals)) @@ -589,7 +590,7 @@ makeSuite('LendingPool. repayWithCollateral()', (testEnv: TestEnv) => { }); it('User 5 tries to repay his USDC loan by swapping his WETH collateral, should not revert even with WETH collateral disabled', async () => { - const {pool, weth, usdc, users, mockSwapAdapter, oracle} = testEnv; + const {pool, weth, usdc, users, mockSwapAdapter, oracle, helpersContract} = testEnv; const user = users[4]; const amountToRepay = parseUnits('65', 6); @@ -642,10 +643,10 @@ makeSuite('LendingPool. repayWithCollateral()', (testEnv: TestEnv) => { const principalPrice = await oracle.getAssetPrice(usdc.address); const collateralDecimals = ( - await pool.getReserveConfigurationData(weth.address) + await helpersContract.getReserveConfigurationData(weth.address) ).decimals.toString(); const principalDecimals = ( - await pool.getReserveConfigurationData(usdc.address) + await helpersContract.getReserveConfigurationData(usdc.address) ).decimals.toString(); const expectedCollateralLiquidated = new BigNumber(principalPrice.toString()) diff --git a/test/stable-token.spec.ts b/test/stable-token.spec.ts index 1d6adcdb..422cb352 100644 --- a/test/stable-token.spec.ts +++ b/test/stable-token.spec.ts @@ -8,9 +8,9 @@ makeSuite('Stable debt token tests', (testEnv: TestEnv) => { const {CALLER_MUST_BE_LENDING_POOL} = ProtocolErrors; it('Tries to invoke mint not being the LendingPool', async () => { - const {deployer, pool, dai} = testEnv; + const {deployer, pool, dai, helpersContract} = testEnv; - const daiStableDebtTokenAddress = (await pool.getReserveTokensAddresses(dai.address)) + const daiStableDebtTokenAddress = (await helpersContract.getReserveTokensAddresses(dai.address)) .stableDebtTokenAddress; const stableDebtContract = await getContract( @@ -24,9 +24,9 @@ makeSuite('Stable debt token tests', (testEnv: TestEnv) => { }); it('Tries to invoke burn not being the LendingPool', async () => { - const {deployer, pool, dai} = testEnv; + const {deployer, dai, helpersContract} = testEnv; - const daiStableDebtTokenAddress = (await pool.getReserveTokensAddresses(dai.address)) + const daiStableDebtTokenAddress = (await helpersContract.getReserveTokensAddresses(dai.address)) .stableDebtTokenAddress; const stableDebtContract = await getContract( diff --git a/test/upgradeability.spec.ts b/test/upgradeability.spec.ts index 29f2da40..45beb11c 100644 --- a/test/upgradeability.spec.ts +++ b/test/upgradeability.spec.ts @@ -26,7 +26,7 @@ makeSuite('Upgradeability', (testEnv: TestEnv) => { ZERO_ADDRESS, 'Aave Interest bearing DAI updated', 'aDAI', - ZERO_ADDRESS + ZERO_ADDRESS, ]); const stableDebtTokenInstance = await deployContract( @@ -87,13 +87,13 @@ makeSuite('Upgradeability', (testEnv: TestEnv) => { }); it('Upgrades the DAI stable debt token implementation ', async () => { - const {dai, configurator, pool} = testEnv; + const {dai, configurator, pool, helpersContract} = testEnv; const name = await (await getAToken(newATokenAddress)).name(); await configurator.updateStableDebtToken(dai.address, newStableTokenAddress); - const {stableDebtTokenAddress} = await pool.getReserveTokensAddresses(dai.address); + const {stableDebtTokenAddress} = await helpersContract.getReserveTokensAddresses(dai.address); const debtToken = await getContract( eContractid.MockStableDebtToken, @@ -116,13 +116,13 @@ makeSuite('Upgradeability', (testEnv: TestEnv) => { }); it('Upgrades the DAI variable debt token implementation ', async () => { - const {dai, configurator, pool} = testEnv; + const {dai, configurator, pool, helpersContract} = testEnv; const name = await (await getAToken(newATokenAddress)).name(); await configurator.updateVariableDebtToken(dai.address, newVariableTokenAddress); - const {variableDebtTokenAddress} = await pool.getReserveTokensAddresses(dai.address); + const {variableDebtTokenAddress} = await helpersContract.getReserveTokensAddresses(dai.address); const debtToken = await getContract( eContractid.MockStableDebtToken, diff --git a/test/variable-debt-token.spec.ts b/test/variable-debt-token.spec.ts index a79bdde2..e92c6d12 100644 --- a/test/variable-debt-token.spec.ts +++ b/test/variable-debt-token.spec.ts @@ -8,10 +8,11 @@ makeSuite('Variable debt token tests', (testEnv: TestEnv) => { const {CALLER_MUST_BE_LENDING_POOL} = ProtocolErrors; it('Tries to invoke mint not being the LendingPool', async () => { - const {deployer, pool, dai} = testEnv; + const {deployer, pool, dai, helpersContract} = testEnv; - const daiVariableDebtTokenAddress = (await pool.getReserveTokensAddresses(dai.address)) - .variableDebtTokenAddress; + const daiVariableDebtTokenAddress = ( + await helpersContract.getReserveTokensAddresses(dai.address) + ).variableDebtTokenAddress; const variableDebtContract = await getContract( eContractid.VariableDebtToken, @@ -24,10 +25,11 @@ makeSuite('Variable debt token tests', (testEnv: TestEnv) => { }); it('Tries to invoke burn not being the LendingPool', async () => { - const {deployer, pool, dai} = testEnv; + const {deployer, pool, dai, helpersContract} = testEnv; - const daiVariableDebtTokenAddress = (await pool.getReserveTokensAddresses(dai.address)) - .variableDebtTokenAddress; + const daiVariableDebtTokenAddress = ( + await helpersContract.getReserveTokensAddresses(dai.address) + ).variableDebtTokenAddress; const variableDebtContract = await getContract( eContractid.VariableDebtToken, From c181ed02e46fbf43678521ef7ccc5d9dec196cfc Mon Sep 17 00:00:00 2001 From: The3D Date: Wed, 14 Oct 2020 14:24:01 +0200 Subject: [PATCH 09/10] Fixed configurator --- contracts/lendingpool/LendingPoolConfigurator.sol | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/contracts/lendingpool/LendingPoolConfigurator.sol b/contracts/lendingpool/LendingPoolConfigurator.sol index c122730d..2da31b29 100644 --- a/contracts/lendingpool/LendingPoolConfigurator.sol +++ b/contracts/lendingpool/LendingPoolConfigurator.sol @@ -413,12 +413,10 @@ contract LendingPoolConfigurator is VersionedInitializable { function deactivateReserve(address asset) external onlyAaveAdmin { ReserveLogic.ReserveData memory reserveData = pool.getReserveData(asset); - uint256 availableLiquidity = IERC20Detailed(reserveData.aTokenAddress).totalSupply(); - uint256 totalStableDebt = IERC20Detailed(reserveData.stableDebtTokenAddress).totalSupply(); - uint256 totalVariableDebt = IERC20Detailed(reserveData.variableDebtTokenAddress).totalSupply(); + uint256 availableLiquidity = IERC20Detailed(asset).balanceOf(reserveData.aTokenAddress); require( - availableLiquidity == 0 && totalStableDebt == 0 && totalVariableDebt == 0, + availableLiquidity == 0 && reserveData.currentLiquidityRate == 0, Errors.RESERVE_LIQUIDITY_NOT_0 ); From 1ca88ec0ae7232abdac8bd596732f07054b23ce9 Mon Sep 17 00:00:00 2001 From: The3D Date: Wed, 14 Oct 2020 14:34:17 +0200 Subject: [PATCH 10/10] Fixed comment on getUserConfiguration --- contracts/lendingpool/LendingPool.sol | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/contracts/lendingpool/LendingPool.sol b/contracts/lendingpool/LendingPool.sol index 688f3eb3..ab07c5ce 100644 --- a/contracts/lendingpool/LendingPool.sol +++ b/contracts/lendingpool/LendingPool.sol @@ -724,7 +724,7 @@ contract LendingPool is VersionedInitializable, ILendingPool, LendingPoolStorage } /** - * @dev returns the configuration of the user for the specific reserve + * @dev returns the configuration of the user across all the reserves * @param user the user * @return the configuration of the user **/