From 5532ebdc8a8540cb0ad4354847dfdf0ade74377f Mon Sep 17 00:00:00 2001 From: eboado Date: Tue, 24 Nov 2020 14:53:34 +0100 Subject: [PATCH 01/12] - Moved data types (structs and enum) to a DataTypes library, to simplify interfaces --- contracts/interfaces/ILendingPool.sol | 10 ++- .../ILendingPoolCollateralManager.sol | 2 +- contracts/misc/AaveProtocolDataProvider.sol | 18 +++--- contracts/misc/UiPoolDataProvider.sol | 10 +-- contracts/misc/WETHGateway.sol | 7 ++- contracts/misc/WalletBalanceProvider.sol | 5 +- .../misc/interfaces/IUiPoolDataProvider.sol | 1 - .../protocol/lendingpool/LendingPool.sol | 45 ++++++------- .../LendingPoolCollateralManager.sol | 21 ++++--- .../lendingpool/LendingPoolConfigurator.sol | 36 +++++------ .../lendingpool/LendingPoolStorage.sol | 11 ++-- .../configuration/ReserveConfiguration.sol | 59 +++++++---------- .../configuration/UserConfiguration.sol | 19 +++--- .../protocol/libraries/helpers/Helpers.sol | 16 ++--- .../protocol/libraries/logic/GenericLogic.sol | 17 ++--- .../protocol/libraries/logic/ReserveLogic.sol | 56 ++++++----------- .../libraries/logic/ValidationLogic.sol | 63 ++++++++++--------- ...LendingPoolHarnessForVariableDebtToken.sol | 30 ++++----- specs/harness/UserConfigurationHarness.sol | 2 +- 19 files changed, 198 insertions(+), 230 deletions(-) diff --git a/contracts/interfaces/ILendingPool.sol b/contracts/interfaces/ILendingPool.sol index 1f4104dd..8ff3408f 100644 --- a/contracts/interfaces/ILendingPool.sol +++ b/contracts/interfaces/ILendingPool.sol @@ -2,10 +2,8 @@ pragma solidity 0.6.12; pragma experimental ABIEncoderV2; -import {ReserveConfiguration} from '../protocol/libraries/configuration/ReserveConfiguration.sol'; -import {UserConfiguration} from '../protocol/libraries/configuration/UserConfiguration.sol'; -import {ReserveLogic} from '../protocol/libraries/logic/ReserveLogic.sol'; import {ILendingPoolAddressesProvider} from './ILendingPoolAddressesProvider.sol'; +import {DataTypes} from '../protocol/libraries/types/DataTypes.sol'; interface ILendingPool { /** @@ -355,14 +353,14 @@ interface ILendingPool { * @param asset The address of the underlying asset of the reserve * @return The configuration of the reserve **/ - function getConfiguration(address asset) external view returns (ReserveConfiguration.Map memory); + function getConfiguration(address asset) external view returns (DataTypes.ReserveBitmap memory); /** * @dev Returns the configuration of the user across all the reserves * @param user The user address * @return The configuration of the user **/ - function getUserConfiguration(address user) external view returns (UserConfiguration.Map memory); + function getUserConfiguration(address user) external view returns (DataTypes.UserBitmap memory); /** * @dev Returns the normalized income normalized income of the reserve @@ -383,7 +381,7 @@ interface ILendingPool { * @param asset The address of the underlying asset of the reserve * @return The state of the reserve **/ - function getReserveData(address asset) external view returns (ReserveLogic.ReserveData memory); + function getReserveData(address asset) external view returns (DataTypes.ReserveData memory); function finalizeTransfer( address asset, diff --git a/contracts/interfaces/ILendingPoolCollateralManager.sol b/contracts/interfaces/ILendingPoolCollateralManager.sol index 39244896..785fb68b 100644 --- a/contracts/interfaces/ILendingPoolCollateralManager.sol +++ b/contracts/interfaces/ILendingPoolCollateralManager.sol @@ -49,5 +49,5 @@ interface ILendingPoolCollateralManager { address user, uint256 debtToCover, bool receiveAToken - ) external virtual returns (uint256, string memory); + ) external returns (uint256, string memory); } diff --git a/contracts/misc/AaveProtocolDataProvider.sol b/contracts/misc/AaveProtocolDataProvider.sol index 1be4f326..27cf68f3 100644 --- a/contracts/misc/AaveProtocolDataProvider.sol +++ b/contracts/misc/AaveProtocolDataProvider.sol @@ -5,15 +5,15 @@ pragma experimental ABIEncoderV2; import {ILendingPoolAddressesProvider} from '../interfaces/ILendingPoolAddressesProvider.sol'; import {IERC20Detailed} from '../dependencies/openzeppelin/contracts/IERC20Detailed.sol'; import {ILendingPool} from '../interfaces/ILendingPool.sol'; -import {ReserveLogic} from '../protocol/libraries/logic/ReserveLogic.sol'; import {ReserveConfiguration} from '../protocol/libraries/configuration/ReserveConfiguration.sol'; import {UserConfiguration} from '../protocol/libraries/configuration/UserConfiguration.sol'; import {IStableDebtToken} from '../protocol/tokenization/interfaces/IStableDebtToken.sol'; import {IVariableDebtToken} from '../protocol/tokenization/interfaces/IVariableDebtToken.sol'; +import {DataTypes} from '../protocol/libraries/types/DataTypes.sol'; contract AaveProtocolDataProvider { - using ReserveConfiguration for ReserveConfiguration.Map; - using UserConfiguration for UserConfiguration.Map; + using ReserveConfiguration for DataTypes.ReserveBitmap; + using UserConfiguration for DataTypes.UserBitmap; address constant MKR = 0x9f8F72aA9304c8B593d555F12eF6589cC3A579A2; address constant ETH = 0xEeeeeEeeeEeEeeEeEeEeeEEEeeeeEeeeeeeeEEeE; @@ -55,7 +55,7 @@ contract AaveProtocolDataProvider { address[] memory reserves = pool.getReservesList(); TokenData[] memory aTokens = new TokenData[](reserves.length); for (uint256 i = 0; i < reserves.length; i++) { - ReserveLogic.ReserveData memory reserveData = pool.getReserveData(reserves[i]); + DataTypes.ReserveData memory reserveData = pool.getReserveData(reserves[i]); aTokens[i] = TokenData({ symbol: IERC20Detailed(reserveData.aTokenAddress).symbol(), tokenAddress: reserveData.aTokenAddress @@ -80,7 +80,7 @@ contract AaveProtocolDataProvider { bool isFrozen ) { - ReserveConfiguration.Map memory configuration = + DataTypes.ReserveBitmap memory configuration = ILendingPool(ADDRESSES_PROVIDER.getLendingPool()).getConfiguration(asset); (ltv, liquidationThreshold, liquidationBonus, decimals, reserveFactor) = configuration @@ -108,7 +108,7 @@ contract AaveProtocolDataProvider { uint40 lastUpdateTimestamp ) { - ReserveLogic.ReserveData memory reserve = + DataTypes.ReserveData memory reserve = ILendingPool(ADDRESSES_PROVIDER.getLendingPool()).getReserveData(asset); return ( @@ -140,10 +140,10 @@ contract AaveProtocolDataProvider { bool usageAsCollateralEnabled ) { - ReserveLogic.ReserveData memory reserve = + DataTypes.ReserveData memory reserve = ILendingPool(ADDRESSES_PROVIDER.getLendingPool()).getReserveData(asset); - UserConfiguration.Map memory userConfig = + DataTypes.UserBitmap memory userConfig = ILendingPool(ADDRESSES_PROVIDER.getLendingPool()).getUserConfiguration(user); currentATokenBalance = IERC20Detailed(reserve.aTokenAddress).balanceOf(user); @@ -168,7 +168,7 @@ contract AaveProtocolDataProvider { address variableDebtTokenAddress ) { - ReserveLogic.ReserveData memory reserve = + DataTypes.ReserveData memory reserve = ILendingPool(ADDRESSES_PROVIDER.getLendingPool()).getReserveData(asset); return ( diff --git a/contracts/misc/UiPoolDataProvider.sol b/contracts/misc/UiPoolDataProvider.sol index fef40724..a4cc3feb 100644 --- a/contracts/misc/UiPoolDataProvider.sol +++ b/contracts/misc/UiPoolDataProvider.sol @@ -12,17 +12,17 @@ import {IVariableDebtToken} from '../protocol/tokenization/interfaces/IVariableD import {IStableDebtToken} from '../protocol/tokenization/interfaces/IStableDebtToken.sol'; import {WadRayMath} from '../protocol/libraries/math/WadRayMath.sol'; -import {ReserveLogic} from '../protocol/libraries/logic/ReserveLogic.sol'; import {ReserveConfiguration} from '../protocol/libraries/configuration/ReserveConfiguration.sol'; import {UserConfiguration} from '../protocol/libraries/configuration/UserConfiguration.sol'; import { DefaultReserveInterestRateStrategy } from '../protocol/lendingpool/DefaultReserveInterestRateStrategy.sol'; +import {DataTypes} from '../protocol/libraries/types/DataTypes.sol'; contract UiPoolDataProvider is IUiPoolDataProvider { using WadRayMath for uint256; - using ReserveConfiguration for ReserveConfiguration.Map; - using UserConfiguration for UserConfiguration.Map; + using ReserveConfiguration for DataTypes.ReserveBitmap; + using UserConfiguration for DataTypes.UserBitmap; address public constant MOCK_USD_ADDRESS = 0x10F7Fc1F91Ba351f9C629c5947AD69bD03C05b96; @@ -57,7 +57,7 @@ contract UiPoolDataProvider is IUiPoolDataProvider { ILendingPool lendingPool = ILendingPool(provider.getLendingPool()); IPriceOracleGetter oracle = IPriceOracleGetter(provider.getPriceOracle()); address[] memory reserves = lendingPool.getReservesList(); - UserConfiguration.Map memory userConfig = lendingPool.getUserConfiguration(user); + DataTypes.UserBitmap memory userConfig = lendingPool.getUserConfiguration(user); AggregatedReserveData[] memory reservesData = new AggregatedReserveData[](reserves.length); UserReserveData[] memory userReservesData = @@ -68,7 +68,7 @@ contract UiPoolDataProvider is IUiPoolDataProvider { reserveData.underlyingAsset = reserves[i]; // reserve current state - ReserveLogic.ReserveData memory baseData = + DataTypes.ReserveData memory baseData = lendingPool.getReserveData(reserveData.underlyingAsset); reserveData.liquidityIndex = baseData.liquidityIndex; reserveData.variableBorrowIndex = baseData.variableBorrowIndex; diff --git a/contracts/misc/WETHGateway.sol b/contracts/misc/WETHGateway.sol index 9acd066e..d2745179 100644 --- a/contracts/misc/WETHGateway.sol +++ b/contracts/misc/WETHGateway.sol @@ -12,10 +12,11 @@ import {UserConfiguration} from '../protocol/libraries/configuration/UserConfigu import {Helpers} from '../protocol/libraries/helpers/Helpers.sol'; import {Ownable} from '../dependencies/openzeppelin/contracts/Ownable.sol'; import {IERC20} from '../dependencies/openzeppelin/contracts/IERC20.sol'; +import {DataTypes} from '../protocol/libraries/types/DataTypes.sol'; contract WETHGateway is IWETHGateway, Ownable { - using ReserveConfiguration for ReserveConfiguration.Map; - using UserConfiguration for UserConfiguration.Map; + using ReserveConfiguration for DataTypes.ReserveBitmap; + using UserConfiguration for DataTypes.UserBitmap; IWETH internal immutable WETH; ILendingPool internal immutable POOL; @@ -79,7 +80,7 @@ contract WETHGateway is IWETHGateway, Ownable { Helpers.getUserCurrentDebtMemory(onBehalfOf, POOL.getReserveData(address(WETH))); uint256 paybackAmount = - ReserveLogic.InterestRateMode(rateMode) == ReserveLogic.InterestRateMode.STABLE + DataTypes.InterestRateMode(rateMode) == DataTypes.InterestRateMode.STABLE ? stableDebt : variableDebt; diff --git a/contracts/misc/WalletBalanceProvider.sol b/contracts/misc/WalletBalanceProvider.sol index d7c2aff5..c6519ee2 100644 --- a/contracts/misc/WalletBalanceProvider.sol +++ b/contracts/misc/WalletBalanceProvider.sol @@ -10,6 +10,7 @@ import {ILendingPoolAddressesProvider} from '../interfaces/ILendingPoolAddresses import {ILendingPool} from '../interfaces/ILendingPool.sol'; import {SafeERC20} from '../dependencies/openzeppelin/contracts/SafeERC20.sol'; import {ReserveConfiguration} from '../protocol/libraries/configuration/ReserveConfiguration.sol'; +import {DataTypes} from '../protocol/libraries/types/DataTypes.sol'; /** * @title WalletBalanceProvider contract @@ -22,7 +23,7 @@ contract WalletBalanceProvider { using Address for address payable; using Address for address; using SafeERC20 for IERC20; - using ReserveConfiguration for ReserveConfiguration.Map; + using ReserveConfiguration for DataTypes.ReserveBitmap; address constant MOCK_ETH_ADDRESS = 0xEeeeeEeeeEeEeeEeEeEeeEEEeeeeEeeeeeeeEEeE; @@ -92,7 +93,7 @@ contract WalletBalanceProvider { uint256[] memory balances = new uint256[](reservesWithEth.length); for (uint256 j = 0; j < reserves.length; j++) { - ReserveConfiguration.Map memory configuration = pool.getConfiguration(reservesWithEth[j]); + DataTypes.ReserveBitmap memory configuration = pool.getConfiguration(reservesWithEth[j]); (bool isActive, , , ) = configuration.getFlagsMemory(); diff --git a/contracts/misc/interfaces/IUiPoolDataProvider.sol b/contracts/misc/interfaces/IUiPoolDataProvider.sol index 28a7d984..81a553e8 100644 --- a/contracts/misc/interfaces/IUiPoolDataProvider.sol +++ b/contracts/misc/interfaces/IUiPoolDataProvider.sol @@ -3,7 +3,6 @@ pragma solidity 0.6.12; pragma experimental ABIEncoderV2; import {ILendingPoolAddressesProvider} from '../../interfaces/ILendingPoolAddressesProvider.sol'; -import {ReserveLogic} from '../../protocol/libraries/logic/ReserveLogic.sol'; interface IUiPoolDataProvider { struct AggregatedReserveData { diff --git a/contracts/protocol/lendingpool/LendingPool.sol b/contracts/protocol/lendingpool/LendingPool.sol index 3c4fc341..495cd7aa 100644 --- a/contracts/protocol/lendingpool/LendingPool.sol +++ b/contracts/protocol/lendingpool/LendingPool.sol @@ -24,6 +24,7 @@ import {SafeERC20} from '../../dependencies/openzeppelin/contracts/SafeERC20.sol import {ILendingPool} from '../../interfaces/ILendingPool.sol'; import {LendingPoolStorage} from './LendingPoolStorage.sol'; import {Address} from '../../dependencies/openzeppelin/contracts/Address.sol'; +import {DataTypes} from '../libraries/types/DataTypes.sol'; /** * @title LendingPool contract @@ -107,7 +108,7 @@ contract LendingPool is VersionedInitializable, ILendingPool, LendingPoolStorage address onBehalfOf, uint16 referralCode ) external override whenNotPaused { - ReserveLogic.ReserveData storage reserve = _reserves[asset]; + DataTypes.ReserveData storage reserve = _reserves[asset]; ValidationLogic.validateDeposit(reserve, amount); @@ -143,7 +144,7 @@ contract LendingPool is VersionedInitializable, ILendingPool, LendingPoolStorage uint256 amount, address to ) external override whenNotPaused { - ReserveLogic.ReserveData storage reserve = _reserves[asset]; + DataTypes.ReserveData storage reserve = _reserves[asset]; address aToken = reserve.aTokenAddress; @@ -202,7 +203,7 @@ contract LendingPool is VersionedInitializable, ILendingPool, LendingPoolStorage uint16 referralCode, address onBehalfOf ) external override whenNotPaused { - ReserveLogic.ReserveData storage reserve = _reserves[asset]; + DataTypes.ReserveData storage reserve = _reserves[asset]; _executeBorrow( ExecuteBorrowParams( @@ -235,11 +236,11 @@ contract LendingPool is VersionedInitializable, ILendingPool, LendingPoolStorage uint256 rateMode, address onBehalfOf ) external override whenNotPaused { - ReserveLogic.ReserveData storage reserve = _reserves[asset]; + DataTypes.ReserveData storage reserve = _reserves[asset]; (uint256 stableDebt, uint256 variableDebt) = Helpers.getUserCurrentDebt(onBehalfOf, reserve); - ReserveLogic.InterestRateMode interestRateMode = ReserveLogic.InterestRateMode(rateMode); + DataTypes.InterestRateMode interestRateMode = DataTypes.InterestRateMode(rateMode); ValidationLogic.validateRepay( reserve, @@ -250,7 +251,7 @@ contract LendingPool is VersionedInitializable, ILendingPool, LendingPoolStorage variableDebt ); - uint256 paybackAmount = interestRateMode == ReserveLogic.InterestRateMode.STABLE + uint256 paybackAmount = interestRateMode == DataTypes.InterestRateMode.STABLE ? stableDebt : variableDebt; @@ -260,7 +261,7 @@ contract LendingPool is VersionedInitializable, ILendingPool, LendingPoolStorage reserve.updateState(); - if (interestRateMode == ReserveLogic.InterestRateMode.STABLE) { + if (interestRateMode == DataTypes.InterestRateMode.STABLE) { IStableDebtToken(reserve.stableDebtTokenAddress).burn(onBehalfOf, paybackAmount); } else { IVariableDebtToken(reserve.variableDebtTokenAddress).burn( @@ -288,11 +289,11 @@ contract LendingPool is VersionedInitializable, ILendingPool, LendingPoolStorage * @param rateMode The rate mode that the user wants to swap to **/ function swapBorrowRateMode(address asset, uint256 rateMode) external override whenNotPaused { - ReserveLogic.ReserveData storage reserve = _reserves[asset]; + DataTypes.ReserveData storage reserve = _reserves[asset]; (uint256 stableDebt, uint256 variableDebt) = Helpers.getUserCurrentDebt(msg.sender, reserve); - ReserveLogic.InterestRateMode interestRateMode = ReserveLogic.InterestRateMode(rateMode); + DataTypes.InterestRateMode interestRateMode = DataTypes.InterestRateMode(rateMode); ValidationLogic.validateSwapRateMode( reserve, @@ -304,7 +305,7 @@ contract LendingPool is VersionedInitializable, ILendingPool, LendingPoolStorage reserve.updateState(); - if (interestRateMode == ReserveLogic.InterestRateMode.STABLE) { + if (interestRateMode == DataTypes.InterestRateMode.STABLE) { IStableDebtToken(reserve.stableDebtTokenAddress).burn(msg.sender, stableDebt); IVariableDebtToken(reserve.variableDebtTokenAddress).mint( msg.sender, @@ -341,7 +342,7 @@ 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]; + DataTypes.ReserveData storage reserve = _reserves[asset]; IERC20 stableDebtToken = IERC20(reserve.stableDebtTokenAddress); IERC20 variableDebtToken = IERC20(reserve.variableDebtTokenAddress); @@ -382,7 +383,7 @@ contract LendingPool is VersionedInitializable, ILendingPool, LendingPoolStorage override whenNotPaused { - ReserveLogic.ReserveData storage reserve = _reserves[asset]; + DataTypes.ReserveData storage reserve = _reserves[asset]; ValidationLogic.validateSetUseReserveAsCollateral( reserve, @@ -509,7 +510,7 @@ contract LendingPool is VersionedInitializable, ILendingPool, LendingPoolStorage vars.currentATokenAddress = aTokenAddresses[vars.i]; vars.currentAmountPlusPremium = vars.currentAmount.add(vars.currentPremium); - if (ReserveLogic.InterestRateMode(modes[vars.i]) == ReserveLogic.InterestRateMode.NONE) { + if (DataTypes.InterestRateMode(modes[vars.i]) == DataTypes.InterestRateMode.NONE) { _reserves[vars.currentAsset].updateState(); _reserves[vars.currentAsset].cumulateToLiquidityIndex( IERC20(vars.currentATokenAddress).totalSupply(), @@ -563,7 +564,7 @@ contract LendingPool is VersionedInitializable, ILendingPool, LendingPoolStorage external view override - returns (ReserveLogic.ReserveData memory) + returns (DataTypes.ReserveData memory) { return _reserves[asset]; } @@ -622,7 +623,7 @@ contract LendingPool is VersionedInitializable, ILendingPool, LendingPoolStorage external view override - returns (ReserveConfiguration.Map memory) + returns (DataTypes.ReserveBitmap memory) { return _reserves[asset].configuration; } @@ -636,7 +637,7 @@ contract LendingPool is VersionedInitializable, ILendingPool, LendingPoolStorage external view override - returns (UserConfiguration.Map memory) + returns (DataTypes.UserBitmap memory) { return _usersConfig[user]; } @@ -729,13 +730,13 @@ contract LendingPool is VersionedInitializable, ILendingPool, LendingPoolStorage if (from != to) { if (balanceFromBefore.sub(amount) == 0) { - UserConfiguration.Map storage fromConfig = _usersConfig[from]; + DataTypes.UserBitmap storage fromConfig = _usersConfig[from]; fromConfig.setUsingAsCollateral(reserveId, false); emit ReserveUsedAsCollateralDisabled(asset, from); } if (balanceToBefore == 0 && amount != 0) { - UserConfiguration.Map storage toConfig = _usersConfig[to]; + DataTypes.UserBitmap storage toConfig = _usersConfig[to]; toConfig.setUsingAsCollateral(reserveId, true); emit ReserveUsedAsCollateralEnabled(asset, to); } @@ -823,8 +824,8 @@ contract LendingPool is VersionedInitializable, ILendingPool, LendingPoolStorage } function _executeBorrow(ExecuteBorrowParams memory vars) internal { - ReserveLogic.ReserveData storage reserve = _reserves[vars.asset]; - UserConfiguration.Map storage userConfig = _usersConfig[vars.onBehalfOf]; + DataTypes.ReserveData storage reserve = _reserves[vars.asset]; + DataTypes.UserBitmap storage userConfig = _usersConfig[vars.onBehalfOf]; address oracle = _addressesProvider.getPriceOracle(); @@ -854,7 +855,7 @@ contract LendingPool is VersionedInitializable, ILendingPool, LendingPoolStorage bool isFirstBorrowing = false; if ( - ReserveLogic.InterestRateMode(vars.interestRateMode) == ReserveLogic.InterestRateMode.STABLE + DataTypes.InterestRateMode(vars.interestRateMode) == DataTypes.InterestRateMode.STABLE ) { currentStableRate = reserve.currentStableBorrowRate; @@ -894,7 +895,7 @@ contract LendingPool is VersionedInitializable, ILendingPool, LendingPoolStorage vars.onBehalfOf, vars.amount, vars.interestRateMode, - ReserveLogic.InterestRateMode(vars.interestRateMode) == ReserveLogic.InterestRateMode.STABLE + DataTypes.InterestRateMode(vars.interestRateMode) == DataTypes.InterestRateMode.STABLE ? currentStableRate : reserve.currentVariableBorrowRate, vars.referralCode diff --git a/contracts/protocol/lendingpool/LendingPoolCollateralManager.sol b/contracts/protocol/lendingpool/LendingPoolCollateralManager.sol index 5e9d16ba..30c9268b 100644 --- a/contracts/protocol/lendingpool/LendingPoolCollateralManager.sol +++ b/contracts/protocol/lendingpool/LendingPoolCollateralManager.sol @@ -10,8 +10,6 @@ import {IVariableDebtToken} from '../tokenization/interfaces/IVariableDebtToken. import {IPriceOracleGetter} from '../../interfaces/IPriceOracleGetter.sol'; import {ILendingPoolCollateralManager} from '../../interfaces/ILendingPoolCollateralManager.sol'; import {GenericLogic} from '../libraries/logic/GenericLogic.sol'; -import {ReserveLogic} from '../libraries/logic/ReserveLogic.sol'; -import {UserConfiguration} from '../libraries/configuration/UserConfiguration.sol'; import {Helpers} from '../libraries/helpers/Helpers.sol'; import {WadRayMath} from '../libraries/math/WadRayMath.sol'; import {PercentageMath} from '../libraries/math/PercentageMath.sol'; @@ -19,6 +17,7 @@ import {SafeERC20} from '../../dependencies/openzeppelin/contracts/SafeERC20.sol import {Errors} from '../libraries/helpers/Errors.sol'; import {ValidationLogic} from '../libraries/logic/ValidationLogic.sol'; import {LendingPoolStorage} from './LendingPoolStorage.sol'; +import {DataTypes} from '../libraries/types/DataTypes.sol'; /** * @title LendingPoolCollateralManager contract @@ -27,7 +26,11 @@ import {LendingPoolStorage} from './LendingPoolStorage.sol'; * @notice this contract will be ran always through delegatecall * @dev LendingPoolCollateralManager inherits VersionedInitializable from OpenZeppelin to have the same storage layout as LendingPool **/ -contract LendingPoolCollateralManager is ILendingPoolCollateralManager, VersionedInitializable, LendingPoolStorage { +contract LendingPoolCollateralManager is + ILendingPoolCollateralManager, + VersionedInitializable, + LendingPoolStorage +{ using SafeERC20 for IERC20; using SafeMath for uint256; using WadRayMath for uint256; @@ -52,7 +55,7 @@ contract LendingPoolCollateralManager is ILendingPoolCollateralManager, Versione uint256 healthFactor; IAToken collateralAtoken; bool isCollateralEnabled; - ReserveLogic.InterestRateMode borrowRateMode; + DataTypes.InterestRateMode borrowRateMode; address principalAToken; uint256 errorCode; string errorMsg; @@ -92,9 +95,9 @@ contract LendingPoolCollateralManager is ILendingPoolCollateralManager, Versione uint256 debtToCover, bool receiveAToken ) external override returns (uint256, string memory) { - ReserveLogic.ReserveData storage collateralReserve = _reserves[collateral]; - ReserveLogic.ReserveData storage principalReserve = _reserves[principal]; - UserConfiguration.Map storage userConfig = _usersConfig[user]; + DataTypes.ReserveData storage collateralReserve = _reserves[collateral]; + DataTypes.ReserveData storage principalReserve = _reserves[principal]; + DataTypes.UserBitmap storage userConfig = _usersConfig[user]; LiquidationCallLocalVars memory vars; @@ -266,8 +269,8 @@ contract LendingPoolCollateralManager is ILendingPoolCollateralManager, Versione * @return principalAmountNeeded the purchase amount **/ function _calculateAvailableCollateralToLiquidate( - ReserveLogic.ReserveData storage collateralReserve, - ReserveLogic.ReserveData storage principalReserve, + DataTypes.ReserveData storage collateralReserve, + DataTypes.ReserveData storage principalReserve, address collateralAddress, address principalAddress, uint256 debtToCover, diff --git a/contracts/protocol/lendingpool/LendingPoolConfigurator.sol b/contracts/protocol/lendingpool/LendingPoolConfigurator.sol index ad70947c..e44f241a 100644 --- a/contracts/protocol/lendingpool/LendingPoolConfigurator.sol +++ b/contracts/protocol/lendingpool/LendingPoolConfigurator.sol @@ -14,7 +14,7 @@ import {ITokenConfiguration} from '../tokenization/interfaces/ITokenConfiguratio import {IERC20Detailed} from '../../dependencies/openzeppelin/contracts/IERC20Detailed.sol'; import {Errors} from '../libraries/helpers/Errors.sol'; import {PercentageMath} from '../libraries/math/PercentageMath.sol'; -import {ReserveLogic} from '../libraries/logic/ReserveLogic.sol'; +import {DataTypes} from '../libraries/types/DataTypes.sol'; /** * @title LendingPoolConfigurator contract @@ -25,7 +25,7 @@ import {ReserveLogic} from '../libraries/logic/ReserveLogic.sol'; contract LendingPoolConfigurator is VersionedInitializable { using SafeMath for uint256; - using ReserveConfiguration for ReserveConfiguration.Map; + using ReserveConfiguration for DataTypes.ReserveBitmap; /** * @dev emitted when a reserve is initialized. @@ -250,7 +250,7 @@ contract LendingPoolConfigurator is VersionedInitializable { interestRateStrategyAddress ); - ReserveConfiguration.Map memory currentConfig = pool.getConfiguration(asset); + DataTypes.ReserveBitmap memory currentConfig = pool.getConfiguration(asset); currentConfig.setDecimals(underlyingAssetDecimals); @@ -274,7 +274,7 @@ contract LendingPoolConfigurator is VersionedInitializable { * @param implementation the address of the new aToken implementation **/ function updateAToken(address asset, address implementation) external onlyPoolAdmin { - ReserveLogic.ReserveData memory reserveData = pool.getReserveData(asset); + DataTypes.ReserveData memory reserveData = pool.getReserveData(asset); _upgradeTokenImplementation(asset, reserveData.aTokenAddress, implementation); @@ -287,7 +287,7 @@ contract LendingPoolConfigurator is VersionedInitializable { * @param implementation the address of the new aToken implementation **/ function updateStableDebtToken(address asset, address implementation) external onlyPoolAdmin { - ReserveLogic.ReserveData memory reserveData = pool.getReserveData(asset); + DataTypes.ReserveData memory reserveData = pool.getReserveData(asset); _upgradeTokenImplementation(asset, reserveData.stableDebtTokenAddress, implementation); @@ -300,7 +300,7 @@ contract LendingPoolConfigurator is VersionedInitializable { * @param implementation the address of the new aToken implementation **/ function updateVariableDebtToken(address asset, address implementation) external onlyPoolAdmin { - ReserveLogic.ReserveData memory reserveData = pool.getReserveData(asset); + DataTypes.ReserveData memory reserveData = pool.getReserveData(asset); _upgradeTokenImplementation(asset, reserveData.variableDebtTokenAddress, implementation); @@ -316,7 +316,7 @@ contract LendingPoolConfigurator is VersionedInitializable { external onlyPoolAdmin { - ReserveConfiguration.Map memory currentConfig = pool.getConfiguration(asset); + DataTypes.ReserveBitmap memory currentConfig = pool.getConfiguration(asset); currentConfig.setBorrowingEnabled(true); currentConfig.setStableRateBorrowingEnabled(stableBorrowRateEnabled); @@ -331,7 +331,7 @@ contract LendingPoolConfigurator is VersionedInitializable { * @param asset the address of the reserve **/ function disableBorrowingOnReserve(address asset) external onlyPoolAdmin { - ReserveConfiguration.Map memory currentConfig = pool.getConfiguration(asset); + DataTypes.ReserveBitmap memory currentConfig = pool.getConfiguration(asset); currentConfig.setBorrowingEnabled(false); @@ -354,7 +354,7 @@ contract LendingPoolConfigurator is VersionedInitializable { uint256 liquidationThreshold, uint256 liquidationBonus ) external onlyPoolAdmin { - ReserveConfiguration.Map memory currentConfig = pool.getConfiguration(asset); + DataTypes.ReserveBitmap memory currentConfig = pool.getConfiguration(asset); //validation of the parameters: the LTV can //only be lower or equal than the liquidation threshold @@ -396,7 +396,7 @@ contract LendingPoolConfigurator is VersionedInitializable { * @param asset the address of the reserve **/ function enableReserveStableRate(address asset) external onlyPoolAdmin { - ReserveConfiguration.Map memory currentConfig = pool.getConfiguration(asset); + DataTypes.ReserveBitmap memory currentConfig = pool.getConfiguration(asset); currentConfig.setStableRateBorrowingEnabled(true); @@ -410,7 +410,7 @@ contract LendingPoolConfigurator is VersionedInitializable { * @param asset the address of the reserve **/ function disableReserveStableRate(address asset) external onlyPoolAdmin { - ReserveConfiguration.Map memory currentConfig = pool.getConfiguration(asset); + DataTypes.ReserveBitmap memory currentConfig = pool.getConfiguration(asset); currentConfig.setStableRateBorrowingEnabled(false); @@ -424,7 +424,7 @@ contract LendingPoolConfigurator is VersionedInitializable { * @param asset the address of the reserve **/ function activateReserve(address asset) external onlyPoolAdmin { - ReserveConfiguration.Map memory currentConfig = pool.getConfiguration(asset); + DataTypes.ReserveBitmap memory currentConfig = pool.getConfiguration(asset); currentConfig.setActive(true); @@ -440,7 +440,7 @@ contract LendingPoolConfigurator is VersionedInitializable { function deactivateReserve(address asset) external onlyPoolAdmin { _checkNoLiquidity(asset); - ReserveConfiguration.Map memory currentConfig = pool.getConfiguration(asset); + DataTypes.ReserveBitmap memory currentConfig = pool.getConfiguration(asset); currentConfig.setActive(false); @@ -454,7 +454,7 @@ contract LendingPoolConfigurator is VersionedInitializable { * @param asset the address of the reserve **/ function freezeReserve(address asset) external onlyPoolAdmin { - ReserveConfiguration.Map memory currentConfig = pool.getConfiguration(asset); + DataTypes.ReserveBitmap memory currentConfig = pool.getConfiguration(asset); currentConfig.setFrozen(true); @@ -468,7 +468,7 @@ contract LendingPoolConfigurator is VersionedInitializable { * @param asset the address of the reserve **/ function unfreezeReserve(address asset) external onlyPoolAdmin { - ReserveConfiguration.Map memory currentConfig = pool.getConfiguration(asset); + DataTypes.ReserveBitmap memory currentConfig = pool.getConfiguration(asset); currentConfig.setFrozen(false); @@ -483,7 +483,7 @@ contract LendingPoolConfigurator is VersionedInitializable { * @param reserveFactor the new reserve factor of the reserve **/ function setReserveFactor(address asset, uint256 reserveFactor) external onlyPoolAdmin { - ReserveConfiguration.Map memory currentConfig = pool.getConfiguration(asset); + DataTypes.ReserveBitmap memory currentConfig = pool.getConfiguration(asset); currentConfig.setReserveFactor(reserveFactor); @@ -535,7 +535,7 @@ contract LendingPoolConfigurator is VersionedInitializable { InitializableImmutableAdminUpgradeabilityProxy proxy = InitializableImmutableAdminUpgradeabilityProxy(payable(proxyAddress)); - ReserveConfiguration.Map memory configuration = pool.getConfiguration(asset); + DataTypes.ReserveBitmap memory configuration = pool.getConfiguration(asset); (, , , uint256 decimals, ) = configuration.getParamsMemory(); @@ -559,7 +559,7 @@ contract LendingPoolConfigurator is VersionedInitializable { } function _checkNoLiquidity(address asset) internal view { - ReserveLogic.ReserveData memory reserveData = pool.getReserveData(asset); + DataTypes.ReserveData memory reserveData = pool.getReserveData(asset); uint256 availableLiquidity = IERC20Detailed(asset).balanceOf(reserveData.aTokenAddress); diff --git a/contracts/protocol/lendingpool/LendingPoolStorage.sol b/contracts/protocol/lendingpool/LendingPoolStorage.sol index 721a4f0a..0508ce84 100644 --- a/contracts/protocol/lendingpool/LendingPoolStorage.sol +++ b/contracts/protocol/lendingpool/LendingPoolStorage.sol @@ -5,16 +5,17 @@ import {UserConfiguration} from '../libraries/configuration/UserConfiguration.so import {ReserveConfiguration} from '../libraries/configuration/ReserveConfiguration.sol'; import {ReserveLogic} from '../libraries/logic/ReserveLogic.sol'; import {ILendingPoolAddressesProvider} from '../../interfaces/ILendingPoolAddressesProvider.sol'; +import {DataTypes} from '../libraries/types/DataTypes.sol'; contract LendingPoolStorage { - using ReserveLogic for ReserveLogic.ReserveData; - using ReserveConfiguration for ReserveConfiguration.Map; - using UserConfiguration for UserConfiguration.Map; + using ReserveLogic for DataTypes.ReserveData; + using ReserveConfiguration for DataTypes.ReserveBitmap; + using UserConfiguration for DataTypes.UserBitmap; ILendingPoolAddressesProvider internal _addressesProvider; - mapping(address => ReserveLogic.ReserveData) internal _reserves; - mapping(address => UserConfiguration.Map) internal _usersConfig; + mapping(address => DataTypes.ReserveData) internal _reserves; + mapping(address => DataTypes.UserBitmap) internal _usersConfig; // the list of the available reserves, structured as a mapping for gas savings reasons mapping(uint256 => address) internal _reservesList; diff --git a/contracts/protocol/libraries/configuration/ReserveConfiguration.sol b/contracts/protocol/libraries/configuration/ReserveConfiguration.sol index 3f7a8bf6..f2bce45a 100644 --- a/contracts/protocol/libraries/configuration/ReserveConfiguration.sol +++ b/contracts/protocol/libraries/configuration/ReserveConfiguration.sol @@ -2,6 +2,7 @@ pragma solidity 0.6.12; import {Errors} from '../helpers/Errors.sol'; +import {DataTypes} from '../types/DataTypes.sol'; /** * @title ReserveConfiguration library @@ -35,26 +36,12 @@ library ReserveConfiguration { uint256 constant MAX_VALID_DECIMALS = 255; uint256 constant MAX_VALID_RESERVE_FACTOR = 65535; - struct Map { - //bit 0-15: LTV - //bit 16-31: Liq. threshold - //bit 32-47: Liq. bonus - //bit 48-55: Decimals - //bit 56: Reserve is active - //bit 57: reserve is frozen - //bit 58: borrowing is enabled - //bit 59: stable rate borrowing enabled - //bit 60-63: reserved - //bit 64-79: reserve factor - uint256 data; - } - /** * @dev sets the Loan to Value of the reserve * @param self the reserve configuration * @param ltv the new ltv **/ - function setLtv(ReserveConfiguration.Map memory self, uint256 ltv) internal pure { + function setLtv(DataTypes.ReserveBitmap memory self, uint256 ltv) internal pure { require(ltv <= MAX_VALID_LTV, Errors.RC_INVALID_LTV); self.data = (self.data & LTV_MASK) | ltv; @@ -65,7 +52,7 @@ library ReserveConfiguration { * @param self the reserve configuration * @return the loan to value **/ - function getLtv(ReserveConfiguration.Map storage self) internal view returns (uint256) { + function getLtv(DataTypes.ReserveBitmap storage self) internal view returns (uint256) { return self.data & ~LTV_MASK; } @@ -74,7 +61,7 @@ library ReserveConfiguration { * @param self the reserve configuration * @param threshold the new liquidation threshold **/ - function setLiquidationThreshold(ReserveConfiguration.Map memory self, uint256 threshold) + function setLiquidationThreshold(DataTypes.ReserveBitmap memory self, uint256 threshold) internal pure { @@ -90,7 +77,7 @@ library ReserveConfiguration { * @param self the reserve configuration * @return the liquidation threshold **/ - function getLiquidationThreshold(ReserveConfiguration.Map storage self) + function getLiquidationThreshold(DataTypes.ReserveBitmap storage self) internal view returns (uint256) @@ -103,7 +90,7 @@ library ReserveConfiguration { * @param self the reserve configuration * @param bonus the new liquidation bonus **/ - function setLiquidationBonus(ReserveConfiguration.Map memory self, uint256 bonus) internal pure { + function setLiquidationBonus(DataTypes.ReserveBitmap memory self, uint256 bonus) internal pure { require(bonus <= MAX_VALID_LIQUIDATION_BONUS, Errors.RC_INVALID_LIQ_BONUS); self.data = @@ -116,7 +103,7 @@ library ReserveConfiguration { * @param self the reserve configuration * @return the liquidation bonus **/ - function getLiquidationBonus(ReserveConfiguration.Map storage self) + function getLiquidationBonus(DataTypes.ReserveBitmap storage self) internal view returns (uint256) @@ -129,7 +116,7 @@ library ReserveConfiguration { * @param self the reserve configuration * @param decimals the decimals **/ - function setDecimals(ReserveConfiguration.Map memory self, uint256 decimals) internal pure { + function setDecimals(DataTypes.ReserveBitmap memory self, uint256 decimals) internal pure { require(decimals <= MAX_VALID_DECIMALS, Errors.RC_INVALID_DECIMALS); self.data = (self.data & DECIMALS_MASK) | (decimals << RESERVE_DECIMALS_START_BIT_POSITION); @@ -140,7 +127,7 @@ library ReserveConfiguration { * @param self the reserve configuration * @return the decimals of the asset **/ - function getDecimals(ReserveConfiguration.Map storage self) internal view returns (uint256) { + function getDecimals(DataTypes.ReserveBitmap storage self) internal view returns (uint256) { return (self.data & ~DECIMALS_MASK) >> RESERVE_DECIMALS_START_BIT_POSITION; } @@ -149,7 +136,7 @@ library ReserveConfiguration { * @param self the reserve configuration * @param active the active state **/ - function setActive(ReserveConfiguration.Map memory self, bool active) internal pure { + function setActive(DataTypes.ReserveBitmap memory self, bool active) internal pure { self.data = (self.data & ACTIVE_MASK) | (uint256(active ? 1 : 0) << IS_ACTIVE_START_BIT_POSITION); @@ -160,7 +147,7 @@ library ReserveConfiguration { * @param self the reserve configuration * @return the active state **/ - function getActive(ReserveConfiguration.Map storage self) internal view returns (bool) { + function getActive(DataTypes.ReserveBitmap storage self) internal view returns (bool) { return (self.data & ~ACTIVE_MASK) != 0; } @@ -169,7 +156,7 @@ library ReserveConfiguration { * @param self the reserve configuration * @param frozen the frozen state **/ - function setFrozen(ReserveConfiguration.Map memory self, bool frozen) internal pure { + function setFrozen(DataTypes.ReserveBitmap memory self, bool frozen) internal pure { self.data = (self.data & FROZEN_MASK) | (uint256(frozen ? 1 : 0) << IS_FROZEN_START_BIT_POSITION); @@ -180,7 +167,7 @@ library ReserveConfiguration { * @param self the reserve configuration * @return the frozen state **/ - function getFrozen(ReserveConfiguration.Map storage self) internal view returns (bool) { + function getFrozen(DataTypes.ReserveBitmap storage self) internal view returns (bool) { return (self.data & ~FROZEN_MASK) != 0; } @@ -189,7 +176,7 @@ library ReserveConfiguration { * @param self the reserve configuration * @param enabled true if the borrowing needs to be enabled, false otherwise **/ - function setBorrowingEnabled(ReserveConfiguration.Map memory self, bool enabled) internal pure { + function setBorrowingEnabled(DataTypes.ReserveBitmap memory self, bool enabled) internal pure { self.data = (self.data & BORROWING_MASK) | (uint256(enabled ? 1 : 0) << BORROWING_ENABLED_START_BIT_POSITION); @@ -200,7 +187,7 @@ library ReserveConfiguration { * @param self the reserve configuration * @return the borrowing state **/ - function getBorrowingEnabled(ReserveConfiguration.Map storage self) internal view returns (bool) { + function getBorrowingEnabled(DataTypes.ReserveBitmap storage self) internal view returns (bool) { return (self.data & ~BORROWING_MASK) != 0; } @@ -209,7 +196,7 @@ library ReserveConfiguration { * @param self the reserve configuration * @param enabled true if the stable rate borrowing needs to be enabled, false otherwise **/ - function setStableRateBorrowingEnabled(ReserveConfiguration.Map memory self, bool enabled) + function setStableRateBorrowingEnabled(DataTypes.ReserveBitmap memory self, bool enabled) internal pure { @@ -223,7 +210,7 @@ library ReserveConfiguration { * @param self the reserve configuration * @return the stable rate borrowing state **/ - function getStableRateBorrowingEnabled(ReserveConfiguration.Map storage self) + function getStableRateBorrowingEnabled(DataTypes.ReserveBitmap storage self) internal view returns (bool) @@ -236,7 +223,7 @@ library ReserveConfiguration { * @param self the reserve configuration * @param reserveFactor the reserve factor **/ - function setReserveFactor(ReserveConfiguration.Map memory self, uint256 reserveFactor) + function setReserveFactor(DataTypes.ReserveBitmap memory self, uint256 reserveFactor) internal pure { @@ -252,7 +239,7 @@ library ReserveConfiguration { * @param self the reserve configuration * @return the reserve factor **/ - function getReserveFactor(ReserveConfiguration.Map storage self) internal view returns (uint256) { + function getReserveFactor(DataTypes.ReserveBitmap storage self) internal view returns (uint256) { return (self.data & ~RESERVE_FACTOR_MASK) >> RESERVE_FACTOR_START_BIT_POSITION; } @@ -261,7 +248,7 @@ library ReserveConfiguration { * @param self the reserve configuration * @return the state flags representing active, frozen, borrowing enabled, stableRateBorrowing enabled **/ - function getFlags(ReserveConfiguration.Map storage self) + function getFlags(DataTypes.ReserveBitmap storage self) internal view returns ( @@ -286,7 +273,7 @@ library ReserveConfiguration { * @param self the reserve configuration * @return the state params representing ltv, liquidation threshold, liquidation bonus, the reserve decimals **/ - function getParams(ReserveConfiguration.Map storage self) + function getParams(DataTypes.ReserveBitmap storage self) internal view returns ( @@ -313,7 +300,7 @@ library ReserveConfiguration { * @param self the reserve configuration * @return the state params representing ltv, liquidation threshold, liquidation bonus, the reserve decimals **/ - function getParamsMemory(ReserveConfiguration.Map memory self) + function getParamsMemory(DataTypes.ReserveBitmap memory self) internal pure returns ( @@ -338,7 +325,7 @@ library ReserveConfiguration { * @param self the reserve configuration * @return the state flags representing active, frozen, borrowing enabled, stableRateBorrowing enabled **/ - function getFlagsMemory(ReserveConfiguration.Map memory self) + function getFlagsMemory(DataTypes.ReserveBitmap memory self) internal pure returns ( diff --git a/contracts/protocol/libraries/configuration/UserConfiguration.sol b/contracts/protocol/libraries/configuration/UserConfiguration.sol index 665b019a..e7067d2b 100644 --- a/contracts/protocol/libraries/configuration/UserConfiguration.sol +++ b/contracts/protocol/libraries/configuration/UserConfiguration.sol @@ -2,6 +2,7 @@ pragma solidity 0.6.12; import {Errors} from '../helpers/Errors.sol'; +import {DataTypes} from '../types/DataTypes.sol'; /** * @title UserConfiguration library @@ -12,10 +13,6 @@ library UserConfiguration { uint256 internal constant BORROWING_MASK = 0x5555555555555555555555555555555555555555555555555555555555555555; - struct Map { - uint256 data; - } - /** * @dev sets if the user is borrowing the reserve identified by reserveIndex * @param self the configuration object @@ -23,7 +20,7 @@ library UserConfiguration { * @param borrowing true if the user is borrowing the reserve, false otherwise **/ function setBorrowing( - UserConfiguration.Map storage self, + DataTypes.UserBitmap storage self, uint256 reserveIndex, bool borrowing ) internal { @@ -40,7 +37,7 @@ library UserConfiguration { * @param _usingAsCollateral true if the user is usin the reserve as collateral, false otherwise **/ function setUsingAsCollateral( - UserConfiguration.Map storage self, + DataTypes.UserBitmap storage self, uint256 reserveIndex, bool _usingAsCollateral ) internal { @@ -56,7 +53,7 @@ library UserConfiguration { * @param reserveIndex the index of the reserve in the bitmap * @return true if the user has been using a reserve for borrowing or as collateral, false otherwise **/ - function isUsingAsCollateralOrBorrowing(UserConfiguration.Map memory self, uint256 reserveIndex) + function isUsingAsCollateralOrBorrowing(DataTypes.UserBitmap memory self, uint256 reserveIndex) internal pure returns (bool) @@ -71,7 +68,7 @@ library UserConfiguration { * @param reserveIndex the index of the reserve in the bitmap * @return true if the user has been using a reserve for borrowing, false otherwise **/ - function isBorrowing(UserConfiguration.Map memory self, uint256 reserveIndex) + function isBorrowing(DataTypes.UserBitmap memory self, uint256 reserveIndex) internal pure returns (bool) @@ -86,7 +83,7 @@ library UserConfiguration { * @param reserveIndex the index of the reserve in the bitmap * @return true if the user has been using a reserve as collateral, false otherwise **/ - function isUsingAsCollateral(UserConfiguration.Map memory self, uint256 reserveIndex) + function isUsingAsCollateral(DataTypes.UserBitmap memory self, uint256 reserveIndex) internal pure returns (bool) @@ -100,7 +97,7 @@ library UserConfiguration { * @param self the configuration object * @return true if the user has been borrowing any reserve, false otherwise **/ - function isBorrowingAny(UserConfiguration.Map memory self) internal pure returns (bool) { + function isBorrowingAny(DataTypes.UserBitmap memory self) internal pure returns (bool) { return self.data & BORROWING_MASK != 0; } @@ -109,7 +106,7 @@ library UserConfiguration { * @param self the configuration object * @return true if the user has been borrowing any reserve, false otherwise **/ - function isEmpty(UserConfiguration.Map memory self) internal pure returns (bool) { + function isEmpty(DataTypes.UserBitmap memory self) internal pure returns (bool) { return self.data == 0; } } diff --git a/contracts/protocol/libraries/helpers/Helpers.sol b/contracts/protocol/libraries/helpers/Helpers.sol index b0d8731c..b21249e2 100644 --- a/contracts/protocol/libraries/helpers/Helpers.sol +++ b/contracts/protocol/libraries/helpers/Helpers.sol @@ -1,8 +1,8 @@ // SPDX-License-Identifier: agpl-3.0 pragma solidity 0.6.12; -import {DebtTokenBase} from '../../tokenization/base/DebtTokenBase.sol'; -import {ReserveLogic} from '../logic/ReserveLogic.sol'; +import {IERC20} from '../../../dependencies/openzeppelin/contracts/IERC20.sol'; +import {DataTypes} from '../types/DataTypes.sol'; /** * @title Helpers library @@ -16,25 +16,25 @@ library Helpers { * @param reserve the reserve object * @return the stable and variable debt balance **/ - function getUserCurrentDebt(address user, ReserveLogic.ReserveData storage reserve) + function getUserCurrentDebt(address user, DataTypes.ReserveData storage reserve) internal view returns (uint256, uint256) { return ( - DebtTokenBase(reserve.stableDebtTokenAddress).balanceOf(user), - DebtTokenBase(reserve.variableDebtTokenAddress).balanceOf(user) + IERC20(reserve.stableDebtTokenAddress).balanceOf(user), + IERC20(reserve.variableDebtTokenAddress).balanceOf(user) ); } - function getUserCurrentDebtMemory(address user, ReserveLogic.ReserveData memory reserve) + function getUserCurrentDebtMemory(address user, DataTypes.ReserveData memory reserve) internal view returns (uint256, uint256) { return ( - DebtTokenBase(reserve.stableDebtTokenAddress).balanceOf(user), - DebtTokenBase(reserve.variableDebtTokenAddress).balanceOf(user) + IERC20(reserve.stableDebtTokenAddress).balanceOf(user), + IERC20(reserve.variableDebtTokenAddress).balanceOf(user) ); } } diff --git a/contracts/protocol/libraries/logic/GenericLogic.sol b/contracts/protocol/libraries/logic/GenericLogic.sol index 37244dfd..e2b39711 100644 --- a/contracts/protocol/libraries/logic/GenericLogic.sol +++ b/contracts/protocol/libraries/logic/GenericLogic.sol @@ -10,6 +10,7 @@ import {UserConfiguration} from '../configuration/UserConfiguration.sol'; import {WadRayMath} from '../math/WadRayMath.sol'; import {PercentageMath} from '../math/PercentageMath.sol'; import {IPriceOracleGetter} from '../../../interfaces/IPriceOracleGetter.sol'; +import {DataTypes} from '../types/DataTypes.sol'; /** * @title GenericLogic library @@ -17,12 +18,12 @@ import {IPriceOracleGetter} from '../../../interfaces/IPriceOracleGetter.sol'; * @title Implements protocol-level logic to check the status of the user across all the reserves */ library GenericLogic { - using ReserveLogic for ReserveLogic.ReserveData; + using ReserveLogic for DataTypes.ReserveData; using SafeMath for uint256; using WadRayMath for uint256; using PercentageMath for uint256; - using ReserveConfiguration for ReserveConfiguration.Map; - using UserConfiguration for UserConfiguration.Map; + using ReserveConfiguration for DataTypes.ReserveBitmap; + using UserConfiguration for DataTypes.UserBitmap; uint256 public constant HEALTH_FACTOR_LIQUIDATION_THRESHOLD = 1 ether; @@ -55,8 +56,8 @@ library GenericLogic { address asset, address user, uint256 amount, - mapping(address => ReserveLogic.ReserveData) storage reservesData, - UserConfiguration.Map calldata userConfig, + mapping(address => DataTypes.ReserveData) storage reservesData, + DataTypes.UserBitmap calldata userConfig, mapping(uint256 => address) storage reserves, uint256 reservesCount, address oracle @@ -150,8 +151,8 @@ library GenericLogic { **/ function calculateUserAccountData( address user, - mapping(address => ReserveLogic.ReserveData) storage reservesData, - UserConfiguration.Map memory userConfig, + mapping(address => DataTypes.ReserveData) storage reservesData, + DataTypes.UserBitmap memory userConfig, mapping(uint256 => address) storage reserves, uint256 reservesCount, address oracle @@ -177,7 +178,7 @@ library GenericLogic { } vars.currentReserveAddress = reserves[vars.i]; - ReserveLogic.ReserveData storage currentReserve = reservesData[vars.currentReserveAddress]; + DataTypes.ReserveData storage currentReserve = reservesData[vars.currentReserveAddress]; (vars.ltv, vars.liquidationThreshold, , vars.decimals, ) = currentReserve .configuration diff --git a/contracts/protocol/libraries/logic/ReserveLogic.sol b/contracts/protocol/libraries/logic/ReserveLogic.sol index 1e23fa0c..6d794f66 100644 --- a/contracts/protocol/libraries/logic/ReserveLogic.sol +++ b/contracts/protocol/libraries/logic/ReserveLogic.sol @@ -13,6 +13,7 @@ import {IReserveInterestRateStrategy} from '../../../interfaces/IReserveInterest import {WadRayMath} from '../math/WadRayMath.sol'; import {PercentageMath} from '../math/PercentageMath.sol'; import {Errors} from '../helpers/Errors.sol'; +import {DataTypes} from '../types/DataTypes.sol'; /** * @title ReserveLogic library @@ -43,35 +44,8 @@ library ReserveLogic { uint256 variableBorrowIndex ); - using ReserveLogic for ReserveLogic.ReserveData; - using ReserveConfiguration for ReserveConfiguration.Map; - - enum InterestRateMode {NONE, STABLE, VARIABLE} - - // refer to the whitepaper, section 1.1 basic concepts for a formal description of these properties. - struct ReserveData { - //stores the reserve configuration - ReserveConfiguration.Map configuration; - //the liquidity index. Expressed in ray - uint128 liquidityIndex; - //variable borrow index. Expressed in ray - uint128 variableBorrowIndex; - //the current supply rate. Expressed in ray - uint128 currentLiquidityRate; - //the current variable borrow rate. Expressed in ray - uint128 currentVariableBorrowRate; - //the current stable borrow rate. Expressed in ray - uint128 currentStableBorrowRate; - uint40 lastUpdateTimestamp; - //tokens addresses - address aTokenAddress; - address stableDebtTokenAddress; - address variableDebtTokenAddress; - //address of the interest rate strategy - address interestRateStrategyAddress; - //the id of the reserve. Represents the position in the list of the active reserves - uint8 id; - } + using ReserveLogic for DataTypes.ReserveData; + using ReserveConfiguration for DataTypes.ReserveBitmap; /** * @dev returns the ongoing normalized income for the reserve. @@ -80,7 +54,11 @@ library ReserveLogic { * @param reserve the reserve object * @return the normalized income. expressed in ray **/ - function getNormalizedIncome(ReserveData storage reserve) internal view returns (uint256) { + function getNormalizedIncome(DataTypes.ReserveData storage reserve) + internal + view + returns (uint256) + { uint40 timestamp = reserve.lastUpdateTimestamp; //solium-disable-next-line @@ -104,7 +82,11 @@ library ReserveLogic { * @param reserve the reserve object * @return the normalized variable debt. expressed in ray **/ - function getNormalizedDebt(ReserveData storage reserve) internal view returns (uint256) { + function getNormalizedDebt(DataTypes.ReserveData storage reserve) + internal + view + returns (uint256) + { uint40 timestamp = reserve.lastUpdateTimestamp; //solium-disable-next-line @@ -126,7 +108,7 @@ library ReserveLogic { * a formal specification. * @param reserve the reserve object **/ - function updateState(ReserveData storage reserve) internal { + function updateState(DataTypes.ReserveData storage reserve) internal { uint256 scaledVariableDebt = IVariableDebtToken(reserve.variableDebtTokenAddress).scaledTotalSupply(); uint256 previousVariableBorrowIndex = reserve.variableBorrowIndex; @@ -160,7 +142,7 @@ library ReserveLogic { * @param amount the amount to accomulate **/ function cumulateToLiquidityIndex( - ReserveData storage reserve, + DataTypes.ReserveData storage reserve, uint256 totalLiquidity, uint256 amount ) internal { @@ -181,7 +163,7 @@ library ReserveLogic { * @param interestRateStrategyAddress the address of the interest rate strategy contract **/ function init( - ReserveData storage reserve, + DataTypes.ReserveData storage reserve, address aTokenAddress, address stableDebtTokenAddress, address variableDebtTokenAddress, @@ -216,7 +198,7 @@ library ReserveLogic { * @param liquidityTaken the amount of liquidity taken from the protocol (redeem or borrow) **/ function updateInterestRates( - ReserveData storage reserve, + DataTypes.ReserveData storage reserve, address reserveAddress, address aTokenAddress, uint256 liquidityAdded, @@ -292,7 +274,7 @@ library ReserveLogic { * @param newVariableBorrowIndex the variable borrow index after the last accumulation of the interest **/ function _mintToTreasury( - ReserveData storage reserve, + DataTypes.ReserveData storage reserve, uint256 scaledVariableDebt, uint256 previousVariableBorrowIndex, uint256 newLiquidityIndex, @@ -352,7 +334,7 @@ library ReserveLogic { * @param variableBorrowIndex the last stored variable borrow index **/ function _updateIndexes( - ReserveData storage reserve, + DataTypes.ReserveData storage reserve, uint256 scaledVariableDebt, uint256 liquidityIndex, uint256 variableBorrowIndex, diff --git a/contracts/protocol/libraries/logic/ValidationLogic.sol b/contracts/protocol/libraries/logic/ValidationLogic.sol index a966aa3e..1bb03671 100644 --- a/contracts/protocol/libraries/logic/ValidationLogic.sol +++ b/contracts/protocol/libraries/logic/ValidationLogic.sol @@ -14,6 +14,7 @@ import {UserConfiguration} from '../configuration/UserConfiguration.sol'; import {Errors} from '../helpers/Errors.sol'; import {Helpers} from '../helpers/Helpers.sol'; import {IReserveInterestRateStrategy} from '../../../interfaces/IReserveInterestRateStrategy.sol'; +import {DataTypes} from '../types/DataTypes.sol'; /** * @title ReserveLogic library @@ -21,13 +22,13 @@ import {IReserveInterestRateStrategy} from '../../../interfaces/IReserveInterest * @notice Implements functions to validate specific action on the protocol. */ library ValidationLogic { - using ReserveLogic for ReserveLogic.ReserveData; + using ReserveLogic for DataTypes.ReserveData; using SafeMath for uint256; using WadRayMath for uint256; using PercentageMath for uint256; using SafeERC20 for IERC20; - using ReserveConfiguration for ReserveConfiguration.Map; - using UserConfiguration for UserConfiguration.Map; + using ReserveConfiguration for DataTypes.ReserveBitmap; + using UserConfiguration for DataTypes.UserBitmap; uint256 public constant REBALANCE_UP_LIQUIDITY_RATE_THRESHOLD = 4000; uint256 public constant REBALANCE_UP_USAGE_RATIO_THRESHOLD = 0.95 * 1e27; //usage ratio of 95% @@ -37,7 +38,7 @@ library ValidationLogic { * @param reserve the reserve state on which the user is depositing * @param amount the amount to be deposited */ - function validateDeposit(ReserveLogic.ReserveData storage reserve, uint256 amount) external view { + function validateDeposit(DataTypes.ReserveData storage reserve, uint256 amount) external view { (bool isActive, bool isFrozen, , ) = reserve.configuration.getFlags(); require(amount != 0, Errors.VL_INVALID_AMOUNT); @@ -60,8 +61,8 @@ library ValidationLogic { address reserveAddress, uint256 amount, uint256 userBalance, - mapping(address => ReserveLogic.ReserveData) storage reservesData, - UserConfiguration.Map storage userConfig, + mapping(address => DataTypes.ReserveData) storage reservesData, + DataTypes.UserBitmap storage userConfig, mapping(uint256 => address) storage reserves, uint256 reservesCount, address oracle @@ -100,7 +101,7 @@ library ValidationLogic { uint256 availableLiquidity; uint256 finalUserBorrowRate; uint256 healthFactor; - ReserveLogic.InterestRateMode rateMode; + DataTypes.InterestRateMode rateMode; bool healthFactorBelowThreshold; bool isActive; bool isFrozen; @@ -125,14 +126,14 @@ library ValidationLogic { function validateBorrow( address asset, - ReserveLogic.ReserveData storage reserve, + DataTypes.ReserveData storage reserve, address userAddress, uint256 amount, uint256 amountInETH, uint256 interestRateMode, uint256 maxStableLoanPercent, - mapping(address => ReserveLogic.ReserveData) storage reservesData, - UserConfiguration.Map storage userConfig, + mapping(address => DataTypes.ReserveData) storage reservesData, + DataTypes.UserBitmap storage userConfig, mapping(uint256 => address) storage reserves, uint256 reservesCount, address oracle @@ -151,8 +152,8 @@ library ValidationLogic { //validate interest rate mode require( - uint256(ReserveLogic.InterestRateMode.VARIABLE) == interestRateMode || - uint256(ReserveLogic.InterestRateMode.STABLE) == interestRateMode, + uint256(DataTypes.InterestRateMode.VARIABLE) == interestRateMode || + uint256(DataTypes.InterestRateMode.STABLE) == interestRateMode, Errors.VL_INVALID_INTEREST_RATE_MODE_SELECTED ); @@ -197,7 +198,7 @@ library ValidationLogic { * liquidity **/ - if (vars.rateMode == ReserveLogic.InterestRateMode.STABLE) { + if (vars.rateMode == DataTypes.InterestRateMode.STABLE) { //check if the borrow mode is stable and if stable rate borrowing is enabled on this reserve require(vars.stableRateBorrowingEnabled, Errors.VL_STABLE_BORROWING_NOT_ENABLED); @@ -228,9 +229,9 @@ library ValidationLogic { * @param variableDebt the borrow balance of the user */ function validateRepay( - ReserveLogic.ReserveData storage reserve, + DataTypes.ReserveData storage reserve, uint256 amountSent, - ReserveLogic.InterestRateMode rateMode, + DataTypes.InterestRateMode rateMode, address onBehalfOf, uint256 stableDebt, uint256 variableDebt @@ -243,9 +244,9 @@ library ValidationLogic { require( (stableDebt > 0 && - ReserveLogic.InterestRateMode(rateMode) == ReserveLogic.InterestRateMode.STABLE) || + DataTypes.InterestRateMode(rateMode) == DataTypes.InterestRateMode.STABLE) || (variableDebt > 0 && - ReserveLogic.InterestRateMode(rateMode) == ReserveLogic.InterestRateMode.VARIABLE), + DataTypes.InterestRateMode(rateMode) == DataTypes.InterestRateMode.VARIABLE), Errors.VL_NO_DEBT_OF_SELECTED_TYPE ); @@ -264,20 +265,20 @@ library ValidationLogic { * @param currentRateMode the rate mode of the borrow */ function validateSwapRateMode( - ReserveLogic.ReserveData storage reserve, - UserConfiguration.Map storage userConfig, + DataTypes.ReserveData storage reserve, + DataTypes.UserBitmap storage userConfig, uint256 stableDebt, uint256 variableDebt, - ReserveLogic.InterestRateMode currentRateMode + DataTypes.InterestRateMode currentRateMode ) external view { (bool isActive, bool isFrozen, , bool stableRateEnabled) = reserve.configuration.getFlags(); require(isActive, Errors.VL_NO_ACTIVE_RESERVE); require(!isFrozen, Errors.VL_RESERVE_FROZEN); - if (currentRateMode == ReserveLogic.InterestRateMode.STABLE) { + if (currentRateMode == DataTypes.InterestRateMode.STABLE) { require(stableDebt > 0, Errors.VL_NO_STABLE_RATE_LOAN_IN_RESERVE); - } else if (currentRateMode == ReserveLogic.InterestRateMode.VARIABLE) { + } else if (currentRateMode == DataTypes.InterestRateMode.VARIABLE) { require(variableDebt > 0, Errors.VL_NO_VARIABLE_RATE_LOAN_IN_RESERVE); /** * user wants to swap to stable, before swapping we need to ensure that @@ -308,7 +309,7 @@ library ValidationLogic { * @param aTokenAddress the address of the aToken contract */ function validateRebalanceStableBorrowRate( - ReserveLogic.ReserveData storage reserve, + DataTypes.ReserveData storage reserve, address reserveAddress, IERC20 stableDebtToken, IERC20 variableDebtToken, @@ -349,11 +350,11 @@ library ValidationLogic { * @param oracle the price oracle */ function validateSetUseReserveAsCollateral( - ReserveLogic.ReserveData storage reserve, + DataTypes.ReserveData storage reserve, address reserveAddress, bool useAsCollateral, - mapping(address => ReserveLogic.ReserveData) storage reservesData, - UserConfiguration.Map storage userConfig, + mapping(address => DataTypes.ReserveData) storage reservesData, + DataTypes.UserBitmap storage userConfig, mapping(uint256 => address) storage reserves, uint256 reservesCount, address oracle @@ -397,9 +398,9 @@ library ValidationLogic { * @param userVariableDebt Total variable debt balance of the user **/ function validateLiquidationCall( - ReserveLogic.ReserveData storage collateralReserve, - ReserveLogic.ReserveData storage principalReserve, - UserConfiguration.Map storage userConfig, + DataTypes.ReserveData storage collateralReserve, + DataTypes.ReserveData storage principalReserve, + DataTypes.UserBitmap storage userConfig, uint256 userHealthFactor, uint256 userStableDebt, uint256 userVariableDebt @@ -452,8 +453,8 @@ library ValidationLogic { */ function validateTransfer( address from, - mapping(address => ReserveLogic.ReserveData) storage reservesData, - UserConfiguration.Map storage userConfig, + mapping(address => DataTypes.ReserveData) storage reservesData, + DataTypes.UserBitmap storage userConfig, mapping(uint256 => address) storage reserves, uint256 reservesCount, address oracle diff --git a/specs/harness/LendingPoolHarnessForVariableDebtToken.sol b/specs/harness/LendingPoolHarnessForVariableDebtToken.sol index 065a18d0..9d4dabb6 100644 --- a/specs/harness/LendingPoolHarnessForVariableDebtToken.sol +++ b/specs/harness/LendingPoolHarnessForVariableDebtToken.sol @@ -1,16 +1,12 @@ pragma solidity 0.6.12; pragma experimental ABIEncoderV2; -import { - ReserveConfiguration -} from '../../contracts/libraries/configuration/ReserveConfiguration.sol'; -import {UserConfiguration} from '../../contracts/libraries/configuration/UserConfiguration.sol'; -import {ReserveLogic} from '../../contracts/libraries/logic/ReserveLogic.sol'; import {ILendingPool} from '../../contracts/interfaces/ILendingPool.sol'; import {LendingPool} from '../../contracts/lendingpool/LendingPool.sol'; import { ILendingPoolAddressesProvider } from '../../contracts/interfaces/ILendingPoolAddressesProvider.sol'; +import {DataTypes} from '../protocol/libraries/types/DataTypes.sol'; /* Certora: Harness that delegates calls to the original LendingPool. @@ -77,32 +73,32 @@ contract LendingPoolHarnessForVariableDebtToken is ILendingPool { originalPool.liquidationCall(collateral, asset, user, debtToCover, receiveAToken); } - function getReservesList() external override view returns (address[] memory) { + function getReservesList() external view override returns (address[] memory) { return originalPool.getReservesList(); } function getReserveData(address asset) external - override view - returns (ReserveLogic.ReserveData memory) + override + returns (DataTypes.ReserveData memory) { return originalPool.getReserveData(asset); } function getUserConfiguration(address user) external - override view - returns (UserConfiguration.Map memory) + override + returns (DataTypes.UserBitmap memory) { return originalPool.getUserConfiguration(user); } function getUserAccountData(address user) external - override view + override returns ( uint256 totalCollateralETH, uint256 totalBorrowsETH, @@ -144,16 +140,16 @@ contract LendingPoolHarnessForVariableDebtToken is ILendingPool { function getConfiguration(address asset) external - override view - returns (ReserveConfiguration.Map memory) + override + returns (DataTypes.ReserveBitmap memory) { return originalPool.getConfiguration(asset); } mapping(uint256 => uint256) private reserveNormalizedIncome; - function getReserveNormalizedIncome(address asset) external override view returns (uint256) { + function getReserveNormalizedIncome(address asset) external view override returns (uint256) { require(reserveNormalizedIncome[block.timestamp] == 1e27); return reserveNormalizedIncome[block.timestamp]; } @@ -162,8 +158,8 @@ contract LendingPoolHarnessForVariableDebtToken is ILendingPool { function getReserveNormalizedVariableDebt(address asset) external - override view + override returns (uint256) { require(reserveNormalizedVariableDebt[block.timestamp] == 1e27); @@ -174,7 +170,7 @@ contract LendingPoolHarnessForVariableDebtToken is ILendingPool { originalPool.setPause(val); } - function paused() external override view returns (bool) { + function paused() external view override returns (bool) { return originalPool.paused(); } @@ -201,7 +197,7 @@ contract LendingPoolHarnessForVariableDebtToken is ILendingPool { originalPool.finalizeTransfer(asset, from, to, amount, balanceFromAfter, balanceToBefore); } - function getAddressesProvider() external override view returns (ILendingPoolAddressesProvider) { + function getAddressesProvider() external view override returns (ILendingPoolAddressesProvider) { return originalPool.getAddressesProvider(); } } diff --git a/specs/harness/UserConfigurationHarness.sol b/specs/harness/UserConfigurationHarness.sol index 0780c222..1238175f 100644 --- a/specs/harness/UserConfigurationHarness.sol +++ b/specs/harness/UserConfigurationHarness.sol @@ -7,7 +7,7 @@ import {UserConfiguration} from '../../contracts/libraries/configuration/UserCon A wrapper contract for calling functions from the library UserConfiguration. */ contract UserConfigurationHarness { - UserConfiguration.Map internal usersConfig; + DataTypes.UserBitmap internal usersConfig; function setBorrowing( address user, From 093e6925733b62b4ae4ae7fad528d15b6c9779af Mon Sep 17 00:00:00 2001 From: eboado Date: Tue, 24 Nov 2020 15:11:02 +0100 Subject: [PATCH 02/12] - Unexcluded types/ on contracts libraries --- .gitignore | 2 +- .../protocol/libraries/types/DataTypes.sol | 49 +++++++++++++++++++ 2 files changed, 50 insertions(+), 1 deletion(-) create mode 100644 contracts/protocol/libraries/types/DataTypes.sol diff --git a/.gitignore b/.gitignore index 626ee868..e6704cbb 100644 --- a/.gitignore +++ b/.gitignore @@ -7,7 +7,7 @@ dist/ build/ .vscode .idea -types +/types deployed-contracts.json diff --git a/contracts/protocol/libraries/types/DataTypes.sol b/contracts/protocol/libraries/types/DataTypes.sol new file mode 100644 index 00000000..a0498f51 --- /dev/null +++ b/contracts/protocol/libraries/types/DataTypes.sol @@ -0,0 +1,49 @@ +// SPDX-License-Identifier: agpl-3.0 +pragma solidity 0.6.12; + +library DataTypes { + // refer to the whitepaper, section 1.1 basic concepts for a formal description of these properties. + struct ReserveData { + //stores the reserve configuration + ReserveBitmap configuration; + //the liquidity index. Expressed in ray + uint128 liquidityIndex; + //variable borrow index. Expressed in ray + uint128 variableBorrowIndex; + //the current supply rate. Expressed in ray + uint128 currentLiquidityRate; + //the current variable borrow rate. Expressed in ray + uint128 currentVariableBorrowRate; + //the current stable borrow rate. Expressed in ray + uint128 currentStableBorrowRate; + uint40 lastUpdateTimestamp; + //tokens addresses + address aTokenAddress; + address stableDebtTokenAddress; + address variableDebtTokenAddress; + //address of the interest rate strategy + address interestRateStrategyAddress; + //the id of the reserve. Represents the position in the list of the active reserves + uint8 id; + } + + struct ReserveBitmap { + //bit 0-15: LTV + //bit 16-31: Liq. threshold + //bit 32-47: Liq. bonus + //bit 48-55: Decimals + //bit 56: Reserve is active + //bit 57: reserve is frozen + //bit 58: borrowing is enabled + //bit 59: stable rate borrowing enabled + //bit 60-63: reserved + //bit 64-79: reserve factor + uint256 data; + } + + struct UserBitmap { + uint256 data; + } + + enum InterestRateMode {NONE, STABLE, VARIABLE} +} From 126458c7aa5839e49fecc8545e25bb0a848ae11b Mon Sep 17 00:00:00 2001 From: The3D Date: Tue, 24 Nov 2020 16:17:27 +0100 Subject: [PATCH 03/12] Updated ReserveMap and UserMap --- contracts/interfaces/ILendingPool.sol | 4 +- contracts/misc/AaveProtocolDataProvider.sol | 8 ++-- contracts/misc/UiPoolDataProvider.sol | 6 +-- contracts/misc/WETHGateway.sol | 4 +- contracts/misc/WalletBalanceProvider.sol | 4 +- .../protocol/lendingpool/LendingPool.sol | 10 ++--- .../LendingPoolCollateralManager.sol | 2 +- .../lendingpool/LendingPoolConfigurator.sol | 26 +++++------ .../lendingpool/LendingPoolStorage.sol | 6 +-- .../configuration/ReserveConfiguration.sol | 44 +++++++++---------- .../configuration/UserConfiguration.sol | 14 +++--- .../protocol/libraries/logic/GenericLogic.sol | 8 ++-- .../protocol/libraries/logic/ReserveLogic.sol | 2 +- .../libraries/logic/ValidationLogic.sol | 16 +++---- .../protocol/libraries/types/DataTypes.sol | 6 +-- ...LendingPoolHarnessForVariableDebtToken.sol | 4 +- specs/harness/UserConfigurationHarness.sol | 2 +- 17 files changed, 83 insertions(+), 83 deletions(-) diff --git a/contracts/interfaces/ILendingPool.sol b/contracts/interfaces/ILendingPool.sol index 8ff3408f..74a3b7a6 100644 --- a/contracts/interfaces/ILendingPool.sol +++ b/contracts/interfaces/ILendingPool.sol @@ -353,14 +353,14 @@ interface ILendingPool { * @param asset The address of the underlying asset of the reserve * @return The configuration of the reserve **/ - function getConfiguration(address asset) external view returns (DataTypes.ReserveBitmap memory); + function getConfiguration(address asset) external view returns (DataTypes.ReserveConfigurationMap memory); /** * @dev Returns the configuration of the user across all the reserves * @param user The user address * @return The configuration of the user **/ - function getUserConfiguration(address user) external view returns (DataTypes.UserBitmap memory); + function getUserConfiguration(address user) external view returns (DataTypes.UserConfigurationMap memory); /** * @dev Returns the normalized income normalized income of the reserve diff --git a/contracts/misc/AaveProtocolDataProvider.sol b/contracts/misc/AaveProtocolDataProvider.sol index 27cf68f3..d9b476af 100644 --- a/contracts/misc/AaveProtocolDataProvider.sol +++ b/contracts/misc/AaveProtocolDataProvider.sol @@ -12,8 +12,8 @@ import {IVariableDebtToken} from '../protocol/tokenization/interfaces/IVariableD import {DataTypes} from '../protocol/libraries/types/DataTypes.sol'; contract AaveProtocolDataProvider { - using ReserveConfiguration for DataTypes.ReserveBitmap; - using UserConfiguration for DataTypes.UserBitmap; + using ReserveConfiguration for DataTypes.ReserveConfigurationMap; + using UserConfiguration for DataTypes.UserConfigurationMap; address constant MKR = 0x9f8F72aA9304c8B593d555F12eF6589cC3A579A2; address constant ETH = 0xEeeeeEeeeEeEeeEeEeEeeEEEeeeeEeeeeeeeEEeE; @@ -80,7 +80,7 @@ contract AaveProtocolDataProvider { bool isFrozen ) { - DataTypes.ReserveBitmap memory configuration = + DataTypes.ReserveConfigurationMap memory configuration = ILendingPool(ADDRESSES_PROVIDER.getLendingPool()).getConfiguration(asset); (ltv, liquidationThreshold, liquidationBonus, decimals, reserveFactor) = configuration @@ -143,7 +143,7 @@ contract AaveProtocolDataProvider { DataTypes.ReserveData memory reserve = ILendingPool(ADDRESSES_PROVIDER.getLendingPool()).getReserveData(asset); - DataTypes.UserBitmap memory userConfig = + DataTypes.UserConfigurationMap memory userConfig = ILendingPool(ADDRESSES_PROVIDER.getLendingPool()).getUserConfiguration(user); currentATokenBalance = IERC20Detailed(reserve.aTokenAddress).balanceOf(user); diff --git a/contracts/misc/UiPoolDataProvider.sol b/contracts/misc/UiPoolDataProvider.sol index a4cc3feb..f0e2c2d5 100644 --- a/contracts/misc/UiPoolDataProvider.sol +++ b/contracts/misc/UiPoolDataProvider.sol @@ -21,8 +21,8 @@ import {DataTypes} from '../protocol/libraries/types/DataTypes.sol'; contract UiPoolDataProvider is IUiPoolDataProvider { using WadRayMath for uint256; - using ReserveConfiguration for DataTypes.ReserveBitmap; - using UserConfiguration for DataTypes.UserBitmap; + using ReserveConfiguration for DataTypes.ReserveConfigurationMap; + using UserConfiguration for DataTypes.UserConfigurationMap; address public constant MOCK_USD_ADDRESS = 0x10F7Fc1F91Ba351f9C629c5947AD69bD03C05b96; @@ -57,7 +57,7 @@ contract UiPoolDataProvider is IUiPoolDataProvider { ILendingPool lendingPool = ILendingPool(provider.getLendingPool()); IPriceOracleGetter oracle = IPriceOracleGetter(provider.getPriceOracle()); address[] memory reserves = lendingPool.getReservesList(); - DataTypes.UserBitmap memory userConfig = lendingPool.getUserConfiguration(user); + DataTypes.UserConfigurationMap memory userConfig = lendingPool.getUserConfiguration(user); AggregatedReserveData[] memory reservesData = new AggregatedReserveData[](reserves.length); UserReserveData[] memory userReservesData = diff --git a/contracts/misc/WETHGateway.sol b/contracts/misc/WETHGateway.sol index d2745179..4111abe5 100644 --- a/contracts/misc/WETHGateway.sol +++ b/contracts/misc/WETHGateway.sol @@ -15,8 +15,8 @@ import {IERC20} from '../dependencies/openzeppelin/contracts/IERC20.sol'; import {DataTypes} from '../protocol/libraries/types/DataTypes.sol'; contract WETHGateway is IWETHGateway, Ownable { - using ReserveConfiguration for DataTypes.ReserveBitmap; - using UserConfiguration for DataTypes.UserBitmap; + using ReserveConfiguration for DataTypes.ReserveConfigurationMap; + using UserConfiguration for DataTypes.UserConfigurationMap; IWETH internal immutable WETH; ILendingPool internal immutable POOL; diff --git a/contracts/misc/WalletBalanceProvider.sol b/contracts/misc/WalletBalanceProvider.sol index c6519ee2..cd4a81ce 100644 --- a/contracts/misc/WalletBalanceProvider.sol +++ b/contracts/misc/WalletBalanceProvider.sol @@ -23,7 +23,7 @@ contract WalletBalanceProvider { using Address for address payable; using Address for address; using SafeERC20 for IERC20; - using ReserveConfiguration for DataTypes.ReserveBitmap; + using ReserveConfiguration for DataTypes.ReserveConfigurationMap; address constant MOCK_ETH_ADDRESS = 0xEeeeeEeeeEeEeeEeEeEeeEEEeeeeEeeeeeeeEEeE; @@ -93,7 +93,7 @@ contract WalletBalanceProvider { uint256[] memory balances = new uint256[](reservesWithEth.length); for (uint256 j = 0; j < reserves.length; j++) { - DataTypes.ReserveBitmap memory configuration = pool.getConfiguration(reservesWithEth[j]); + DataTypes.ReserveConfigurationMap memory configuration = pool.getConfiguration(reservesWithEth[j]); (bool isActive, , , ) = configuration.getFlagsMemory(); diff --git a/contracts/protocol/lendingpool/LendingPool.sol b/contracts/protocol/lendingpool/LendingPool.sol index 495cd7aa..525141a6 100644 --- a/contracts/protocol/lendingpool/LendingPool.sol +++ b/contracts/protocol/lendingpool/LendingPool.sol @@ -623,7 +623,7 @@ contract LendingPool is VersionedInitializable, ILendingPool, LendingPoolStorage external view override - returns (DataTypes.ReserveBitmap memory) + returns (DataTypes.ReserveConfigurationMap memory) { return _reserves[asset].configuration; } @@ -637,7 +637,7 @@ contract LendingPool is VersionedInitializable, ILendingPool, LendingPoolStorage external view override - returns (DataTypes.UserBitmap memory) + returns (DataTypes.UserConfigurationMap memory) { return _usersConfig[user]; } @@ -730,13 +730,13 @@ contract LendingPool is VersionedInitializable, ILendingPool, LendingPoolStorage if (from != to) { if (balanceFromBefore.sub(amount) == 0) { - DataTypes.UserBitmap storage fromConfig = _usersConfig[from]; + DataTypes.UserConfigurationMap storage fromConfig = _usersConfig[from]; fromConfig.setUsingAsCollateral(reserveId, false); emit ReserveUsedAsCollateralDisabled(asset, from); } if (balanceToBefore == 0 && amount != 0) { - DataTypes.UserBitmap storage toConfig = _usersConfig[to]; + DataTypes.UserConfigurationMap storage toConfig = _usersConfig[to]; toConfig.setUsingAsCollateral(reserveId, true); emit ReserveUsedAsCollateralEnabled(asset, to); } @@ -825,7 +825,7 @@ contract LendingPool is VersionedInitializable, ILendingPool, LendingPoolStorage function _executeBorrow(ExecuteBorrowParams memory vars) internal { DataTypes.ReserveData storage reserve = _reserves[vars.asset]; - DataTypes.UserBitmap storage userConfig = _usersConfig[vars.onBehalfOf]; + DataTypes.UserConfigurationMap storage userConfig = _usersConfig[vars.onBehalfOf]; address oracle = _addressesProvider.getPriceOracle(); diff --git a/contracts/protocol/lendingpool/LendingPoolCollateralManager.sol b/contracts/protocol/lendingpool/LendingPoolCollateralManager.sol index 30c9268b..8aef4190 100644 --- a/contracts/protocol/lendingpool/LendingPoolCollateralManager.sol +++ b/contracts/protocol/lendingpool/LendingPoolCollateralManager.sol @@ -97,7 +97,7 @@ contract LendingPoolCollateralManager is ) external override returns (uint256, string memory) { DataTypes.ReserveData storage collateralReserve = _reserves[collateral]; DataTypes.ReserveData storage principalReserve = _reserves[principal]; - DataTypes.UserBitmap storage userConfig = _usersConfig[user]; + DataTypes.UserConfigurationMap storage userConfig = _usersConfig[user]; LiquidationCallLocalVars memory vars; diff --git a/contracts/protocol/lendingpool/LendingPoolConfigurator.sol b/contracts/protocol/lendingpool/LendingPoolConfigurator.sol index e44f241a..b31b067f 100644 --- a/contracts/protocol/lendingpool/LendingPoolConfigurator.sol +++ b/contracts/protocol/lendingpool/LendingPoolConfigurator.sol @@ -25,7 +25,7 @@ import {DataTypes} from '../libraries/types/DataTypes.sol'; contract LendingPoolConfigurator is VersionedInitializable { using SafeMath for uint256; - using ReserveConfiguration for DataTypes.ReserveBitmap; + using ReserveConfiguration for DataTypes.ReserveConfigurationMap; /** * @dev emitted when a reserve is initialized. @@ -250,7 +250,7 @@ contract LendingPoolConfigurator is VersionedInitializable { interestRateStrategyAddress ); - DataTypes.ReserveBitmap memory currentConfig = pool.getConfiguration(asset); + DataTypes.ReserveConfigurationMap memory currentConfig = pool.getConfiguration(asset); currentConfig.setDecimals(underlyingAssetDecimals); @@ -316,7 +316,7 @@ contract LendingPoolConfigurator is VersionedInitializable { external onlyPoolAdmin { - DataTypes.ReserveBitmap memory currentConfig = pool.getConfiguration(asset); + DataTypes.ReserveConfigurationMap memory currentConfig = pool.getConfiguration(asset); currentConfig.setBorrowingEnabled(true); currentConfig.setStableRateBorrowingEnabled(stableBorrowRateEnabled); @@ -331,7 +331,7 @@ contract LendingPoolConfigurator is VersionedInitializable { * @param asset the address of the reserve **/ function disableBorrowingOnReserve(address asset) external onlyPoolAdmin { - DataTypes.ReserveBitmap memory currentConfig = pool.getConfiguration(asset); + DataTypes.ReserveConfigurationMap memory currentConfig = pool.getConfiguration(asset); currentConfig.setBorrowingEnabled(false); @@ -354,7 +354,7 @@ contract LendingPoolConfigurator is VersionedInitializable { uint256 liquidationThreshold, uint256 liquidationBonus ) external onlyPoolAdmin { - DataTypes.ReserveBitmap memory currentConfig = pool.getConfiguration(asset); + DataTypes.ReserveConfigurationMap memory currentConfig = pool.getConfiguration(asset); //validation of the parameters: the LTV can //only be lower or equal than the liquidation threshold @@ -396,7 +396,7 @@ contract LendingPoolConfigurator is VersionedInitializable { * @param asset the address of the reserve **/ function enableReserveStableRate(address asset) external onlyPoolAdmin { - DataTypes.ReserveBitmap memory currentConfig = pool.getConfiguration(asset); + DataTypes.ReserveConfigurationMap memory currentConfig = pool.getConfiguration(asset); currentConfig.setStableRateBorrowingEnabled(true); @@ -410,7 +410,7 @@ contract LendingPoolConfigurator is VersionedInitializable { * @param asset the address of the reserve **/ function disableReserveStableRate(address asset) external onlyPoolAdmin { - DataTypes.ReserveBitmap memory currentConfig = pool.getConfiguration(asset); + DataTypes.ReserveConfigurationMap memory currentConfig = pool.getConfiguration(asset); currentConfig.setStableRateBorrowingEnabled(false); @@ -424,7 +424,7 @@ contract LendingPoolConfigurator is VersionedInitializable { * @param asset the address of the reserve **/ function activateReserve(address asset) external onlyPoolAdmin { - DataTypes.ReserveBitmap memory currentConfig = pool.getConfiguration(asset); + DataTypes.ReserveConfigurationMap memory currentConfig = pool.getConfiguration(asset); currentConfig.setActive(true); @@ -440,7 +440,7 @@ contract LendingPoolConfigurator is VersionedInitializable { function deactivateReserve(address asset) external onlyPoolAdmin { _checkNoLiquidity(asset); - DataTypes.ReserveBitmap memory currentConfig = pool.getConfiguration(asset); + DataTypes.ReserveConfigurationMap memory currentConfig = pool.getConfiguration(asset); currentConfig.setActive(false); @@ -454,7 +454,7 @@ contract LendingPoolConfigurator is VersionedInitializable { * @param asset the address of the reserve **/ function freezeReserve(address asset) external onlyPoolAdmin { - DataTypes.ReserveBitmap memory currentConfig = pool.getConfiguration(asset); + DataTypes.ReserveConfigurationMap memory currentConfig = pool.getConfiguration(asset); currentConfig.setFrozen(true); @@ -468,7 +468,7 @@ contract LendingPoolConfigurator is VersionedInitializable { * @param asset the address of the reserve **/ function unfreezeReserve(address asset) external onlyPoolAdmin { - DataTypes.ReserveBitmap memory currentConfig = pool.getConfiguration(asset); + DataTypes.ReserveConfigurationMap memory currentConfig = pool.getConfiguration(asset); currentConfig.setFrozen(false); @@ -483,7 +483,7 @@ contract LendingPoolConfigurator is VersionedInitializable { * @param reserveFactor the new reserve factor of the reserve **/ function setReserveFactor(address asset, uint256 reserveFactor) external onlyPoolAdmin { - DataTypes.ReserveBitmap memory currentConfig = pool.getConfiguration(asset); + DataTypes.ReserveConfigurationMap memory currentConfig = pool.getConfiguration(asset); currentConfig.setReserveFactor(reserveFactor); @@ -535,7 +535,7 @@ contract LendingPoolConfigurator is VersionedInitializable { InitializableImmutableAdminUpgradeabilityProxy proxy = InitializableImmutableAdminUpgradeabilityProxy(payable(proxyAddress)); - DataTypes.ReserveBitmap memory configuration = pool.getConfiguration(asset); + DataTypes.ReserveConfigurationMap memory configuration = pool.getConfiguration(asset); (, , , uint256 decimals, ) = configuration.getParamsMemory(); diff --git a/contracts/protocol/lendingpool/LendingPoolStorage.sol b/contracts/protocol/lendingpool/LendingPoolStorage.sol index 0508ce84..4edff4a3 100644 --- a/contracts/protocol/lendingpool/LendingPoolStorage.sol +++ b/contracts/protocol/lendingpool/LendingPoolStorage.sol @@ -9,13 +9,13 @@ import {DataTypes} from '../libraries/types/DataTypes.sol'; contract LendingPoolStorage { using ReserveLogic for DataTypes.ReserveData; - using ReserveConfiguration for DataTypes.ReserveBitmap; - using UserConfiguration for DataTypes.UserBitmap; + using ReserveConfiguration for DataTypes.ReserveConfigurationMap; + using UserConfiguration for DataTypes.UserConfigurationMap; ILendingPoolAddressesProvider internal _addressesProvider; mapping(address => DataTypes.ReserveData) internal _reserves; - mapping(address => DataTypes.UserBitmap) internal _usersConfig; + mapping(address => DataTypes.UserConfigurationMap) internal _usersConfig; // the list of the available reserves, structured as a mapping for gas savings reasons mapping(uint256 => address) internal _reservesList; diff --git a/contracts/protocol/libraries/configuration/ReserveConfiguration.sol b/contracts/protocol/libraries/configuration/ReserveConfiguration.sol index f2bce45a..39df878b 100644 --- a/contracts/protocol/libraries/configuration/ReserveConfiguration.sol +++ b/contracts/protocol/libraries/configuration/ReserveConfiguration.sol @@ -41,7 +41,7 @@ library ReserveConfiguration { * @param self the reserve configuration * @param ltv the new ltv **/ - function setLtv(DataTypes.ReserveBitmap memory self, uint256 ltv) internal pure { + function setLtv(DataTypes.ReserveConfigurationMap memory self, uint256 ltv) internal pure { require(ltv <= MAX_VALID_LTV, Errors.RC_INVALID_LTV); self.data = (self.data & LTV_MASK) | ltv; @@ -52,7 +52,7 @@ library ReserveConfiguration { * @param self the reserve configuration * @return the loan to value **/ - function getLtv(DataTypes.ReserveBitmap storage self) internal view returns (uint256) { + function getLtv(DataTypes.ReserveConfigurationMap storage self) internal view returns (uint256) { return self.data & ~LTV_MASK; } @@ -61,7 +61,7 @@ library ReserveConfiguration { * @param self the reserve configuration * @param threshold the new liquidation threshold **/ - function setLiquidationThreshold(DataTypes.ReserveBitmap memory self, uint256 threshold) + function setLiquidationThreshold(DataTypes.ReserveConfigurationMap memory self, uint256 threshold) internal pure { @@ -77,7 +77,7 @@ library ReserveConfiguration { * @param self the reserve configuration * @return the liquidation threshold **/ - function getLiquidationThreshold(DataTypes.ReserveBitmap storage self) + function getLiquidationThreshold(DataTypes.ReserveConfigurationMap storage self) internal view returns (uint256) @@ -90,7 +90,7 @@ library ReserveConfiguration { * @param self the reserve configuration * @param bonus the new liquidation bonus **/ - function setLiquidationBonus(DataTypes.ReserveBitmap memory self, uint256 bonus) internal pure { + function setLiquidationBonus(DataTypes.ReserveConfigurationMap memory self, uint256 bonus) internal pure { require(bonus <= MAX_VALID_LIQUIDATION_BONUS, Errors.RC_INVALID_LIQ_BONUS); self.data = @@ -103,7 +103,7 @@ library ReserveConfiguration { * @param self the reserve configuration * @return the liquidation bonus **/ - function getLiquidationBonus(DataTypes.ReserveBitmap storage self) + function getLiquidationBonus(DataTypes.ReserveConfigurationMap storage self) internal view returns (uint256) @@ -116,7 +116,7 @@ library ReserveConfiguration { * @param self the reserve configuration * @param decimals the decimals **/ - function setDecimals(DataTypes.ReserveBitmap memory self, uint256 decimals) internal pure { + function setDecimals(DataTypes.ReserveConfigurationMap memory self, uint256 decimals) internal pure { require(decimals <= MAX_VALID_DECIMALS, Errors.RC_INVALID_DECIMALS); self.data = (self.data & DECIMALS_MASK) | (decimals << RESERVE_DECIMALS_START_BIT_POSITION); @@ -127,7 +127,7 @@ library ReserveConfiguration { * @param self the reserve configuration * @return the decimals of the asset **/ - function getDecimals(DataTypes.ReserveBitmap storage self) internal view returns (uint256) { + function getDecimals(DataTypes.ReserveConfigurationMap storage self) internal view returns (uint256) { return (self.data & ~DECIMALS_MASK) >> RESERVE_DECIMALS_START_BIT_POSITION; } @@ -136,7 +136,7 @@ library ReserveConfiguration { * @param self the reserve configuration * @param active the active state **/ - function setActive(DataTypes.ReserveBitmap memory self, bool active) internal pure { + function setActive(DataTypes.ReserveConfigurationMap memory self, bool active) internal pure { self.data = (self.data & ACTIVE_MASK) | (uint256(active ? 1 : 0) << IS_ACTIVE_START_BIT_POSITION); @@ -147,7 +147,7 @@ library ReserveConfiguration { * @param self the reserve configuration * @return the active state **/ - function getActive(DataTypes.ReserveBitmap storage self) internal view returns (bool) { + function getActive(DataTypes.ReserveConfigurationMap storage self) internal view returns (bool) { return (self.data & ~ACTIVE_MASK) != 0; } @@ -156,7 +156,7 @@ library ReserveConfiguration { * @param self the reserve configuration * @param frozen the frozen state **/ - function setFrozen(DataTypes.ReserveBitmap memory self, bool frozen) internal pure { + function setFrozen(DataTypes.ReserveConfigurationMap memory self, bool frozen) internal pure { self.data = (self.data & FROZEN_MASK) | (uint256(frozen ? 1 : 0) << IS_FROZEN_START_BIT_POSITION); @@ -167,7 +167,7 @@ library ReserveConfiguration { * @param self the reserve configuration * @return the frozen state **/ - function getFrozen(DataTypes.ReserveBitmap storage self) internal view returns (bool) { + function getFrozen(DataTypes.ReserveConfigurationMap storage self) internal view returns (bool) { return (self.data & ~FROZEN_MASK) != 0; } @@ -176,7 +176,7 @@ library ReserveConfiguration { * @param self the reserve configuration * @param enabled true if the borrowing needs to be enabled, false otherwise **/ - function setBorrowingEnabled(DataTypes.ReserveBitmap memory self, bool enabled) internal pure { + function setBorrowingEnabled(DataTypes.ReserveConfigurationMap memory self, bool enabled) internal pure { self.data = (self.data & BORROWING_MASK) | (uint256(enabled ? 1 : 0) << BORROWING_ENABLED_START_BIT_POSITION); @@ -187,7 +187,7 @@ library ReserveConfiguration { * @param self the reserve configuration * @return the borrowing state **/ - function getBorrowingEnabled(DataTypes.ReserveBitmap storage self) internal view returns (bool) { + function getBorrowingEnabled(DataTypes.ReserveConfigurationMap storage self) internal view returns (bool) { return (self.data & ~BORROWING_MASK) != 0; } @@ -196,7 +196,7 @@ library ReserveConfiguration { * @param self the reserve configuration * @param enabled true if the stable rate borrowing needs to be enabled, false otherwise **/ - function setStableRateBorrowingEnabled(DataTypes.ReserveBitmap memory self, bool enabled) + function setStableRateBorrowingEnabled(DataTypes.ReserveConfigurationMap memory self, bool enabled) internal pure { @@ -210,7 +210,7 @@ library ReserveConfiguration { * @param self the reserve configuration * @return the stable rate borrowing state **/ - function getStableRateBorrowingEnabled(DataTypes.ReserveBitmap storage self) + function getStableRateBorrowingEnabled(DataTypes.ReserveConfigurationMap storage self) internal view returns (bool) @@ -223,7 +223,7 @@ library ReserveConfiguration { * @param self the reserve configuration * @param reserveFactor the reserve factor **/ - function setReserveFactor(DataTypes.ReserveBitmap memory self, uint256 reserveFactor) + function setReserveFactor(DataTypes.ReserveConfigurationMap memory self, uint256 reserveFactor) internal pure { @@ -239,7 +239,7 @@ library ReserveConfiguration { * @param self the reserve configuration * @return the reserve factor **/ - function getReserveFactor(DataTypes.ReserveBitmap storage self) internal view returns (uint256) { + function getReserveFactor(DataTypes.ReserveConfigurationMap storage self) internal view returns (uint256) { return (self.data & ~RESERVE_FACTOR_MASK) >> RESERVE_FACTOR_START_BIT_POSITION; } @@ -248,7 +248,7 @@ library ReserveConfiguration { * @param self the reserve configuration * @return the state flags representing active, frozen, borrowing enabled, stableRateBorrowing enabled **/ - function getFlags(DataTypes.ReserveBitmap storage self) + function getFlags(DataTypes.ReserveConfigurationMap storage self) internal view returns ( @@ -273,7 +273,7 @@ library ReserveConfiguration { * @param self the reserve configuration * @return the state params representing ltv, liquidation threshold, liquidation bonus, the reserve decimals **/ - function getParams(DataTypes.ReserveBitmap storage self) + function getParams(DataTypes.ReserveConfigurationMap storage self) internal view returns ( @@ -300,7 +300,7 @@ library ReserveConfiguration { * @param self the reserve configuration * @return the state params representing ltv, liquidation threshold, liquidation bonus, the reserve decimals **/ - function getParamsMemory(DataTypes.ReserveBitmap memory self) + function getParamsMemory(DataTypes.ReserveConfigurationMap memory self) internal pure returns ( @@ -325,7 +325,7 @@ library ReserveConfiguration { * @param self the reserve configuration * @return the state flags representing active, frozen, borrowing enabled, stableRateBorrowing enabled **/ - function getFlagsMemory(DataTypes.ReserveBitmap memory self) + function getFlagsMemory(DataTypes.ReserveConfigurationMap memory self) internal pure returns ( diff --git a/contracts/protocol/libraries/configuration/UserConfiguration.sol b/contracts/protocol/libraries/configuration/UserConfiguration.sol index e7067d2b..b4af79ad 100644 --- a/contracts/protocol/libraries/configuration/UserConfiguration.sol +++ b/contracts/protocol/libraries/configuration/UserConfiguration.sol @@ -20,7 +20,7 @@ library UserConfiguration { * @param borrowing true if the user is borrowing the reserve, false otherwise **/ function setBorrowing( - DataTypes.UserBitmap storage self, + DataTypes.UserConfigurationMap storage self, uint256 reserveIndex, bool borrowing ) internal { @@ -37,7 +37,7 @@ library UserConfiguration { * @param _usingAsCollateral true if the user is usin the reserve as collateral, false otherwise **/ function setUsingAsCollateral( - DataTypes.UserBitmap storage self, + DataTypes.UserConfigurationMap storage self, uint256 reserveIndex, bool _usingAsCollateral ) internal { @@ -53,7 +53,7 @@ library UserConfiguration { * @param reserveIndex the index of the reserve in the bitmap * @return true if the user has been using a reserve for borrowing or as collateral, false otherwise **/ - function isUsingAsCollateralOrBorrowing(DataTypes.UserBitmap memory self, uint256 reserveIndex) + function isUsingAsCollateralOrBorrowing(DataTypes.UserConfigurationMap memory self, uint256 reserveIndex) internal pure returns (bool) @@ -68,7 +68,7 @@ library UserConfiguration { * @param reserveIndex the index of the reserve in the bitmap * @return true if the user has been using a reserve for borrowing, false otherwise **/ - function isBorrowing(DataTypes.UserBitmap memory self, uint256 reserveIndex) + function isBorrowing(DataTypes.UserConfigurationMap memory self, uint256 reserveIndex) internal pure returns (bool) @@ -83,7 +83,7 @@ library UserConfiguration { * @param reserveIndex the index of the reserve in the bitmap * @return true if the user has been using a reserve as collateral, false otherwise **/ - function isUsingAsCollateral(DataTypes.UserBitmap memory self, uint256 reserveIndex) + function isUsingAsCollateral(DataTypes.UserConfigurationMap memory self, uint256 reserveIndex) internal pure returns (bool) @@ -97,7 +97,7 @@ library UserConfiguration { * @param self the configuration object * @return true if the user has been borrowing any reserve, false otherwise **/ - function isBorrowingAny(DataTypes.UserBitmap memory self) internal pure returns (bool) { + function isBorrowingAny(DataTypes.UserConfigurationMap memory self) internal pure returns (bool) { return self.data & BORROWING_MASK != 0; } @@ -106,7 +106,7 @@ library UserConfiguration { * @param self the configuration object * @return true if the user has been borrowing any reserve, false otherwise **/ - function isEmpty(DataTypes.UserBitmap memory self) internal pure returns (bool) { + function isEmpty(DataTypes.UserConfigurationMap memory self) internal pure returns (bool) { return self.data == 0; } } diff --git a/contracts/protocol/libraries/logic/GenericLogic.sol b/contracts/protocol/libraries/logic/GenericLogic.sol index e2b39711..e8ee263f 100644 --- a/contracts/protocol/libraries/logic/GenericLogic.sol +++ b/contracts/protocol/libraries/logic/GenericLogic.sol @@ -22,8 +22,8 @@ library GenericLogic { using SafeMath for uint256; using WadRayMath for uint256; using PercentageMath for uint256; - using ReserveConfiguration for DataTypes.ReserveBitmap; - using UserConfiguration for DataTypes.UserBitmap; + using ReserveConfiguration for DataTypes.ReserveConfigurationMap; + using UserConfiguration for DataTypes.UserConfigurationMap; uint256 public constant HEALTH_FACTOR_LIQUIDATION_THRESHOLD = 1 ether; @@ -57,7 +57,7 @@ library GenericLogic { address user, uint256 amount, mapping(address => DataTypes.ReserveData) storage reservesData, - DataTypes.UserBitmap calldata userConfig, + DataTypes.UserConfigurationMap calldata userConfig, mapping(uint256 => address) storage reserves, uint256 reservesCount, address oracle @@ -152,7 +152,7 @@ library GenericLogic { function calculateUserAccountData( address user, mapping(address => DataTypes.ReserveData) storage reservesData, - DataTypes.UserBitmap memory userConfig, + DataTypes.UserConfigurationMap memory userConfig, mapping(uint256 => address) storage reserves, uint256 reservesCount, address oracle diff --git a/contracts/protocol/libraries/logic/ReserveLogic.sol b/contracts/protocol/libraries/logic/ReserveLogic.sol index 6d794f66..7a73be5b 100644 --- a/contracts/protocol/libraries/logic/ReserveLogic.sol +++ b/contracts/protocol/libraries/logic/ReserveLogic.sol @@ -45,7 +45,7 @@ library ReserveLogic { ); using ReserveLogic for DataTypes.ReserveData; - using ReserveConfiguration for DataTypes.ReserveBitmap; + using ReserveConfiguration for DataTypes.ReserveConfigurationMap; /** * @dev returns the ongoing normalized income for the reserve. diff --git a/contracts/protocol/libraries/logic/ValidationLogic.sol b/contracts/protocol/libraries/logic/ValidationLogic.sol index 1bb03671..7df21875 100644 --- a/contracts/protocol/libraries/logic/ValidationLogic.sol +++ b/contracts/protocol/libraries/logic/ValidationLogic.sol @@ -27,8 +27,8 @@ library ValidationLogic { using WadRayMath for uint256; using PercentageMath for uint256; using SafeERC20 for IERC20; - using ReserveConfiguration for DataTypes.ReserveBitmap; - using UserConfiguration for DataTypes.UserBitmap; + using ReserveConfiguration for DataTypes.ReserveConfigurationMap; + using UserConfiguration for DataTypes.UserConfigurationMap; uint256 public constant REBALANCE_UP_LIQUIDITY_RATE_THRESHOLD = 4000; uint256 public constant REBALANCE_UP_USAGE_RATIO_THRESHOLD = 0.95 * 1e27; //usage ratio of 95% @@ -62,7 +62,7 @@ library ValidationLogic { uint256 amount, uint256 userBalance, mapping(address => DataTypes.ReserveData) storage reservesData, - DataTypes.UserBitmap storage userConfig, + DataTypes.UserConfigurationMap storage userConfig, mapping(uint256 => address) storage reserves, uint256 reservesCount, address oracle @@ -133,7 +133,7 @@ library ValidationLogic { uint256 interestRateMode, uint256 maxStableLoanPercent, mapping(address => DataTypes.ReserveData) storage reservesData, - DataTypes.UserBitmap storage userConfig, + DataTypes.UserConfigurationMap storage userConfig, mapping(uint256 => address) storage reserves, uint256 reservesCount, address oracle @@ -266,7 +266,7 @@ library ValidationLogic { */ function validateSwapRateMode( DataTypes.ReserveData storage reserve, - DataTypes.UserBitmap storage userConfig, + DataTypes.UserConfigurationMap storage userConfig, uint256 stableDebt, uint256 variableDebt, DataTypes.InterestRateMode currentRateMode @@ -354,7 +354,7 @@ library ValidationLogic { address reserveAddress, bool useAsCollateral, mapping(address => DataTypes.ReserveData) storage reservesData, - DataTypes.UserBitmap storage userConfig, + DataTypes.UserConfigurationMap storage userConfig, mapping(uint256 => address) storage reserves, uint256 reservesCount, address oracle @@ -400,7 +400,7 @@ library ValidationLogic { function validateLiquidationCall( DataTypes.ReserveData storage collateralReserve, DataTypes.ReserveData storage principalReserve, - DataTypes.UserBitmap storage userConfig, + DataTypes.UserConfigurationMap storage userConfig, uint256 userHealthFactor, uint256 userStableDebt, uint256 userVariableDebt @@ -454,7 +454,7 @@ library ValidationLogic { function validateTransfer( address from, mapping(address => DataTypes.ReserveData) storage reservesData, - DataTypes.UserBitmap storage userConfig, + DataTypes.UserConfigurationMap storage userConfig, mapping(uint256 => address) storage reserves, uint256 reservesCount, address oracle diff --git a/contracts/protocol/libraries/types/DataTypes.sol b/contracts/protocol/libraries/types/DataTypes.sol index a0498f51..a19e5efc 100644 --- a/contracts/protocol/libraries/types/DataTypes.sol +++ b/contracts/protocol/libraries/types/DataTypes.sol @@ -5,7 +5,7 @@ library DataTypes { // refer to the whitepaper, section 1.1 basic concepts for a formal description of these properties. struct ReserveData { //stores the reserve configuration - ReserveBitmap configuration; + ReserveConfigurationMap configuration; //the liquidity index. Expressed in ray uint128 liquidityIndex; //variable borrow index. Expressed in ray @@ -27,7 +27,7 @@ library DataTypes { uint8 id; } - struct ReserveBitmap { + struct ReserveConfigurationMap { //bit 0-15: LTV //bit 16-31: Liq. threshold //bit 32-47: Liq. bonus @@ -41,7 +41,7 @@ library DataTypes { uint256 data; } - struct UserBitmap { + struct UserConfigurationMap { uint256 data; } diff --git a/specs/harness/LendingPoolHarnessForVariableDebtToken.sol b/specs/harness/LendingPoolHarnessForVariableDebtToken.sol index 9d4dabb6..b366d22a 100644 --- a/specs/harness/LendingPoolHarnessForVariableDebtToken.sol +++ b/specs/harness/LendingPoolHarnessForVariableDebtToken.sol @@ -90,7 +90,7 @@ contract LendingPoolHarnessForVariableDebtToken is ILendingPool { external view override - returns (DataTypes.UserBitmap memory) + returns (DataTypes.UserConfigurationMap memory) { return originalPool.getUserConfiguration(user); } @@ -142,7 +142,7 @@ contract LendingPoolHarnessForVariableDebtToken is ILendingPool { external view override - returns (DataTypes.ReserveBitmap memory) + returns (DataTypes.ReserveConfigurationMap memory) { return originalPool.getConfiguration(asset); } diff --git a/specs/harness/UserConfigurationHarness.sol b/specs/harness/UserConfigurationHarness.sol index 1238175f..38ca2686 100644 --- a/specs/harness/UserConfigurationHarness.sol +++ b/specs/harness/UserConfigurationHarness.sol @@ -7,7 +7,7 @@ import {UserConfiguration} from '../../contracts/libraries/configuration/UserCon A wrapper contract for calling functions from the library UserConfiguration. */ contract UserConfigurationHarness { - DataTypes.UserBitmap internal usersConfig; + DataTypes.UserConfigurationMap internal usersConfig; function setBorrowing( address user, From 1054dea632f758ac8c57d8f6c97f68d2ba751b0f Mon Sep 17 00:00:00 2001 From: The3D Date: Tue, 24 Nov 2020 17:07:47 +0100 Subject: [PATCH 04/12] Removed reserveLogic import from WETHGateway --- contracts/interfaces/ILendingPool.sol | 101 +++++++++++++++++++++++++- contracts/misc/WETHGateway.sol | 1 - 2 files changed, 99 insertions(+), 3 deletions(-) diff --git a/contracts/interfaces/ILendingPool.sol b/contracts/interfaces/ILendingPool.sol index 74a3b7a6..9f0769dd 100644 --- a/contracts/interfaces/ILendingPool.sol +++ b/contracts/interfaces/ILendingPool.sol @@ -2,8 +2,105 @@ pragma solidity 0.6.12; pragma experimental ABIEncoderV2; -import {ILendingPoolAddressesProvider} from './ILendingPoolAddressesProvider.sol'; -import {DataTypes} from '../protocol/libraries/types/DataTypes.sol'; +/** + * @title LendingPoolAddressesProvider contract + * @dev Main registry of addresses part of or connected to the protocol, including permissioned roles + * - Acting also as factory of proxies and admin of those, so with right to change its implementations + * - Owned by the Aave Governance + * @author Aave + **/ +interface ILendingPoolAddressesProvider { + event LendingPoolUpdated(address indexed newAddress); + event ConfigurationAdminUpdated(address indexed newAddress); + event EmergencyAdminUpdated(address indexed newAddress); + event LendingPoolConfiguratorUpdated(address indexed newAddress); + event LendingPoolCollateralManagerUpdated(address indexed newAddress); + event PriceOracleUpdated(address indexed newAddress); + event LendingRateOracleUpdated(address indexed newAddress); + event ProxyCreated(bytes32 id, address indexed newAddress); + event AddressSet(bytes32 id, address indexed newAddress, bool hasProxy); + + function setAddress(bytes32 id, address newAddress) external; + + function setAddressAsProxy(bytes32 id, address impl) external; + + function getAddress(bytes32 id) external view returns (address); + + function getLendingPool() external view returns (address); + + function setLendingPoolImpl(address pool) external; + + function getLendingPoolConfigurator() external view returns (address); + + function setLendingPoolConfiguratorImpl(address configurator) external; + + function getLendingPoolCollateralManager() external view returns (address); + + function setLendingPoolCollateralManager(address manager) external; + + function getPoolAdmin() external view returns (address); + + function setPoolAdmin(address admin) external; + + function getEmergencyAdmin() external view returns (address); + + function setEmergencyAdmin(address admin) external; + + function getPriceOracle() external view returns (address); + + function setPriceOracle(address priceOracle) external; + + function getLendingRateOracle() external view returns (address); + + function setLendingRateOracle(address lendingRateOracle) external; +} + +library DataTypes { + // refer to the whitepaper, section 1.1 basic concepts for a formal description of these properties. + struct ReserveData { + //stores the reserve configuration + ReserveConfigurationMap configuration; + //the liquidity index. Expressed in ray + uint128 liquidityIndex; + //variable borrow index. Expressed in ray + uint128 variableBorrowIndex; + //the current supply rate. Expressed in ray + uint128 currentLiquidityRate; + //the current variable borrow rate. Expressed in ray + uint128 currentVariableBorrowRate; + //the current stable borrow rate. Expressed in ray + uint128 currentStableBorrowRate; + uint40 lastUpdateTimestamp; + //tokens addresses + address aTokenAddress; + address stableDebtTokenAddress; + address variableDebtTokenAddress; + //address of the interest rate strategy + address interestRateStrategyAddress; + //the id of the reserve. Represents the position in the list of the active reserves + uint8 id; + } + + struct ReserveConfigurationMap { + //bit 0-15: LTV + //bit 16-31: Liq. threshold + //bit 32-47: Liq. bonus + //bit 48-55: Decimals + //bit 56: Reserve is active + //bit 57: reserve is frozen + //bit 58: borrowing is enabled + //bit 59: stable rate borrowing enabled + //bit 60-63: reserved + //bit 64-79: reserve factor + uint256 data; + } + + struct UserConfigurationMap { + uint256 data; + } + + enum InterestRateMode {NONE, STABLE, VARIABLE} +} interface ILendingPool { /** diff --git a/contracts/misc/WETHGateway.sol b/contracts/misc/WETHGateway.sol index 4111abe5..ee8261b0 100644 --- a/contracts/misc/WETHGateway.sol +++ b/contracts/misc/WETHGateway.sol @@ -6,7 +6,6 @@ import {IWETH} from './interfaces/IWETH.sol'; import {IWETHGateway} from './interfaces/IWETHGateway.sol'; import {ILendingPool} from '../interfaces/ILendingPool.sol'; import {IAToken} from '../protocol/tokenization/interfaces/IAToken.sol'; -import {ReserveLogic} from '../protocol/libraries/logic/ReserveLogic.sol'; import {ReserveConfiguration} from '../protocol/libraries/configuration/ReserveConfiguration.sol'; import {UserConfiguration} from '../protocol/libraries/configuration/UserConfiguration.sol'; import {Helpers} from '../protocol/libraries/helpers/Helpers.sol'; From e4bccaed917ba80c54f56a8d0cacff2ca03a4406 Mon Sep 17 00:00:00 2001 From: The3D Date: Wed, 25 Nov 2020 11:40:55 +0100 Subject: [PATCH 05/12] Fixed ILendingPool interface --- contracts/interfaces/ILendingPool.sol | 110 +++----------------------- 1 file changed, 10 insertions(+), 100 deletions(-) diff --git a/contracts/interfaces/ILendingPool.sol b/contracts/interfaces/ILendingPool.sol index 9f0769dd..d445579a 100644 --- a/contracts/interfaces/ILendingPool.sol +++ b/contracts/interfaces/ILendingPool.sol @@ -2,105 +2,9 @@ pragma solidity 0.6.12; pragma experimental ABIEncoderV2; -/** - * @title LendingPoolAddressesProvider contract - * @dev Main registry of addresses part of or connected to the protocol, including permissioned roles - * - Acting also as factory of proxies and admin of those, so with right to change its implementations - * - Owned by the Aave Governance - * @author Aave - **/ -interface ILendingPoolAddressesProvider { - event LendingPoolUpdated(address indexed newAddress); - event ConfigurationAdminUpdated(address indexed newAddress); - event EmergencyAdminUpdated(address indexed newAddress); - event LendingPoolConfiguratorUpdated(address indexed newAddress); - event LendingPoolCollateralManagerUpdated(address indexed newAddress); - event PriceOracleUpdated(address indexed newAddress); - event LendingRateOracleUpdated(address indexed newAddress); - event ProxyCreated(bytes32 id, address indexed newAddress); - event AddressSet(bytes32 id, address indexed newAddress, bool hasProxy); +import {ILendingPoolAddressesProvider} from './ILendingPoolAddressesProvider.sol'; +import {DataTypes} from '../protocol/libraries/types/DataTypes.sol'; - function setAddress(bytes32 id, address newAddress) external; - - function setAddressAsProxy(bytes32 id, address impl) external; - - function getAddress(bytes32 id) external view returns (address); - - function getLendingPool() external view returns (address); - - function setLendingPoolImpl(address pool) external; - - function getLendingPoolConfigurator() external view returns (address); - - function setLendingPoolConfiguratorImpl(address configurator) external; - - function getLendingPoolCollateralManager() external view returns (address); - - function setLendingPoolCollateralManager(address manager) external; - - function getPoolAdmin() external view returns (address); - - function setPoolAdmin(address admin) external; - - function getEmergencyAdmin() external view returns (address); - - function setEmergencyAdmin(address admin) external; - - function getPriceOracle() external view returns (address); - - function setPriceOracle(address priceOracle) external; - - function getLendingRateOracle() external view returns (address); - - function setLendingRateOracle(address lendingRateOracle) external; -} - -library DataTypes { - // refer to the whitepaper, section 1.1 basic concepts for a formal description of these properties. - struct ReserveData { - //stores the reserve configuration - ReserveConfigurationMap configuration; - //the liquidity index. Expressed in ray - uint128 liquidityIndex; - //variable borrow index. Expressed in ray - uint128 variableBorrowIndex; - //the current supply rate. Expressed in ray - uint128 currentLiquidityRate; - //the current variable borrow rate. Expressed in ray - uint128 currentVariableBorrowRate; - //the current stable borrow rate. Expressed in ray - uint128 currentStableBorrowRate; - uint40 lastUpdateTimestamp; - //tokens addresses - address aTokenAddress; - address stableDebtTokenAddress; - address variableDebtTokenAddress; - //address of the interest rate strategy - address interestRateStrategyAddress; - //the id of the reserve. Represents the position in the list of the active reserves - uint8 id; - } - - struct ReserveConfigurationMap { - //bit 0-15: LTV - //bit 16-31: Liq. threshold - //bit 32-47: Liq. bonus - //bit 48-55: Decimals - //bit 56: Reserve is active - //bit 57: reserve is frozen - //bit 58: borrowing is enabled - //bit 59: stable rate borrowing enabled - //bit 60-63: reserved - //bit 64-79: reserve factor - uint256 data; - } - - struct UserConfigurationMap { - uint256 data; - } - - enum InterestRateMode {NONE, STABLE, VARIABLE} -} interface ILendingPool { /** @@ -450,14 +354,20 @@ interface ILendingPool { * @param asset The address of the underlying asset of the reserve * @return The configuration of the reserve **/ - function getConfiguration(address asset) external view returns (DataTypes.ReserveConfigurationMap memory); + function getConfiguration(address asset) + external + view + returns (DataTypes.ReserveConfigurationMap memory); /** * @dev Returns the configuration of the user across all the reserves * @param user The user address * @return The configuration of the user **/ - function getUserConfiguration(address user) external view returns (DataTypes.UserConfigurationMap memory); + function getUserConfiguration(address user) + external + view + returns (DataTypes.UserConfigurationMap memory); /** * @dev Returns the normalized income normalized income of the reserve From ba516a10d0c931035a2eb5bc9318ce4e42f445cb Mon Sep 17 00:00:00 2001 From: eboado Date: Wed, 25 Nov 2020 12:03:11 +0100 Subject: [PATCH 06/12] - Improved docs and naming on LendingPoolCollateralManager --- .../LendingPoolCollateralManager.sol | 201 +++++++++--------- 1 file changed, 97 insertions(+), 104 deletions(-) diff --git a/contracts/protocol/lendingpool/LendingPoolCollateralManager.sol b/contracts/protocol/lendingpool/LendingPoolCollateralManager.sol index 8aef4190..adf36486 100644 --- a/contracts/protocol/lendingpool/LendingPoolCollateralManager.sol +++ b/contracts/protocol/lendingpool/LendingPoolCollateralManager.sol @@ -22,9 +22,9 @@ import {DataTypes} from '../libraries/types/DataTypes.sol'; /** * @title LendingPoolCollateralManager contract * @author Aave - * @notice Implements actions involving management of collateral in the protocol. - * @notice this contract will be ran always through delegatecall - * @dev LendingPoolCollateralManager inherits VersionedInitializable from OpenZeppelin to have the same storage layout as LendingPool + * @dev Implements actions involving management of collateral in the protocol, the main one being the liquidations + * IMPORTANT This contract will run always via DELEGATECALL, through the LendingPool, so the chain of inheritance + * is the same as the LendingPool, to have compatible storage layouts **/ contract LendingPoolCollateralManager is ILendingPoolCollateralManager, @@ -36,67 +36,56 @@ contract LendingPoolCollateralManager is using WadRayMath for uint256; using PercentageMath for uint256; - // IMPORTANT The storage layout of the LendingPool is reproduced here because this contract - // is gonna be used through DELEGATECALL - uint256 internal constant LIQUIDATION_CLOSE_FACTOR_PERCENT = 5000; struct LiquidationCallLocalVars { uint256 userCollateralBalance; uint256 userStableDebt; uint256 userVariableDebt; - uint256 maxPrincipalAmountToLiquidate; + uint256 maxDebtToLiquidate; uint256 actualAmountToLiquidate; uint256 liquidationRatio; uint256 maxAmountCollateralToLiquidate; uint256 userStableRate; uint256 maxCollateralToLiquidate; - uint256 principalAmountNeeded; + uint256 debtAmountNeeded; uint256 healthFactor; IAToken collateralAtoken; bool isCollateralEnabled; DataTypes.InterestRateMode borrowRateMode; - address principalAToken; uint256 errorCode; string errorMsg; } - struct AvailableCollateralToLiquidateLocalVars { - uint256 userCompoundedBorrowBalance; - uint256 liquidationBonus; - uint256 collateralPrice; - uint256 principalCurrencyPrice; - uint256 maxAmountCollateralToLiquidate; - uint256 principalDecimals; - uint256 collateralDecimals; - } - /** - * @dev as the contract extends the VersionedInitializable contract to match the state - * of the LendingPool contract, the getRevision() function is needed. + * @dev As thIS contract extends the VersionedInitializable contract to match the state + * of the LendingPool contract, the getRevision() function is needed, but the value is not + * important, as the initialize() function will never be called here */ function getRevision() internal pure override returns (uint256) { return 0; } /** - * @dev users can invoke this function to liquidate an undercollateralized position. - * @param collateral the address of the collateral to liquidated - * @param principal the address of the principal reserve - * @param user the address of the borrower - * @param debtToCover the amount of principal that the liquidator wants to repay - * @param receiveAToken true if the liquidators wants to receive the aTokens, false if - * he wants to receive the underlying asset directly + * @dev Function to liquidate a non-healthy position collateral-wise, with Health Factor below 1 + * - The caller (liquidator) covers `debtToCover` amount of debt of the user getting liquidated, and receives + * a proportionally amount of the `collateralAsset` plus a bonus to cover market risk + * @param collateralAsset The address of the underlying asset used as collateral, to receive as result of the liquidation + * @param debtAsset The address of the underlying borrowed asset to be repaid with the liquidation + * @param user The address of the borrower getting liquidated + * @param debtToCover The debt amount of borrowed `asset` the liquidator wants to cover + * @param receiveAToken `true` if the liquidators wants to receive the collateral aTokens, `false` if he wants + * to receive the underlying collateral asset directly **/ function liquidationCall( - address collateral, - address principal, + address collateralAsset, + address debtAsset, address user, uint256 debtToCover, bool receiveAToken ) external override returns (uint256, string memory) { - DataTypes.ReserveData storage collateralReserve = _reserves[collateral]; - DataTypes.ReserveData storage principalReserve = _reserves[principal]; + DataTypes.ReserveData storage collateralReserve = _reserves[collateralAsset]; + DataTypes.ReserveData storage debtReserve = _reserves[debtAsset]; DataTypes.UserConfigurationMap storage userConfig = _usersConfig[user]; LiquidationCallLocalVars memory vars; @@ -110,15 +99,11 @@ contract LendingPoolCollateralManager is _addressesProvider.getPriceOracle() ); - //if the user hasn't borrowed the specific currency defined by asset, it cannot be liquidated - (vars.userStableDebt, vars.userVariableDebt) = Helpers.getUserCurrentDebt( - user, - principalReserve - ); + (vars.userStableDebt, vars.userVariableDebt) = Helpers.getUserCurrentDebt(user, debtReserve); (vars.errorCode, vars.errorMsg) = ValidationLogic.validateLiquidationCall( collateralReserve, - principalReserve, + debtReserve, userConfig, vars.healthFactor, vars.userStableDebt, @@ -133,38 +118,39 @@ contract LendingPoolCollateralManager is vars.userCollateralBalance = vars.collateralAtoken.balanceOf(user); - vars.maxPrincipalAmountToLiquidate = vars.userStableDebt.add(vars.userVariableDebt).percentMul( + vars.maxDebtToLiquidate = vars.userStableDebt.add(vars.userVariableDebt).percentMul( LIQUIDATION_CLOSE_FACTOR_PERCENT ); - vars.actualAmountToLiquidate = debtToCover > vars.maxPrincipalAmountToLiquidate - ? vars.maxPrincipalAmountToLiquidate + vars.actualAmountToLiquidate = debtToCover > vars.maxDebtToLiquidate + ? vars.maxDebtToLiquidate : debtToCover; ( vars.maxCollateralToLiquidate, - vars.principalAmountNeeded + vars.debtAmountNeeded ) = _calculateAvailableCollateralToLiquidate( collateralReserve, - principalReserve, - collateral, - principal, + debtReserve, + collateralAsset, + debtAsset, vars.actualAmountToLiquidate, vars.userCollateralBalance ); - //if principalAmountNeeded < vars.ActualAmountToLiquidate, there isn't enough - //of collateral to cover the actual amount that is being liquidated, hence we liquidate - //a smaller amount + // If debtAmountNeeded < vars.actualAmountToLiquidate, there isn't enough + // collateral to cover the actual amount that is being liquidated, hence we liquidate + // a smaller amount - if (vars.principalAmountNeeded < vars.actualAmountToLiquidate) { - vars.actualAmountToLiquidate = vars.principalAmountNeeded; + if (vars.debtAmountNeeded < vars.actualAmountToLiquidate) { + vars.actualAmountToLiquidate = vars.debtAmountNeeded; } - //if liquidator reclaims the underlying asset, we make sure there is enough available collateral in the reserve + // If the liquidator reclaims the underlying asset, we make sure there is enough available liquidity in the + // collateral reserve if (!receiveAToken) { uint256 currentAvailableCollateral = - IERC20(collateral).balanceOf(address(vars.collateralAtoken)); + IERC20(collateralAsset).balanceOf(address(vars.collateralAtoken)); if (currentAvailableCollateral < vars.maxCollateralToLiquidate) { return ( uint256(Errors.CollateralManagerErrors.NOT_ENOUGH_LIQUIDITY), @@ -173,54 +159,48 @@ contract LendingPoolCollateralManager is } } - //update the principal reserve - principalReserve.updateState(); + debtReserve.updateState(); if (vars.userVariableDebt >= vars.actualAmountToLiquidate) { - IVariableDebtToken(principalReserve.variableDebtTokenAddress).burn( + IVariableDebtToken(debtReserve.variableDebtTokenAddress).burn( user, vars.actualAmountToLiquidate, - principalReserve.variableBorrowIndex + debtReserve.variableBorrowIndex ); } else { - //if the user does not have variable debt, no need to try to burn variable - //debt tokens + // If the user doesn't have variable debt, no need to try to burn variable debt tokens if (vars.userVariableDebt > 0) { - IVariableDebtToken(principalReserve.variableDebtTokenAddress).burn( + IVariableDebtToken(debtReserve.variableDebtTokenAddress).burn( user, vars.userVariableDebt, - principalReserve.variableBorrowIndex + debtReserve.variableBorrowIndex ); } - IStableDebtToken(principalReserve.stableDebtTokenAddress).burn( + IStableDebtToken(debtReserve.stableDebtTokenAddress).burn( user, vars.actualAmountToLiquidate.sub(vars.userVariableDebt) ); } - principalReserve.updateInterestRates( - principal, - principalReserve.aTokenAddress, + debtReserve.updateInterestRates( + debtAsset, + debtReserve.aTokenAddress, vars.actualAmountToLiquidate, 0 ); - //if liquidator reclaims the aToken, he receives the equivalent atoken amount if (receiveAToken) { vars.collateralAtoken.transferOnLiquidation(user, msg.sender, vars.maxCollateralToLiquidate); } else { - //otherwise receives the underlying asset - - //updating collateral reserve collateralReserve.updateState(); collateralReserve.updateInterestRates( - collateral, + collateralAsset, address(vars.collateralAtoken), 0, vars.maxCollateralToLiquidate ); - //burn the equivalent amount of atoken + // Burn the equivalent amount of aToken, sending the underlying to the liquidator vars.collateralAtoken.burn( user, msg.sender, @@ -229,24 +209,23 @@ contract LendingPoolCollateralManager is ); } - //if the collateral being liquidated is equal to the user balance, - //we set the currency as not being used as collateral anymore - + // If the collateral being liquidated is equal to the user balance, + // we set the currency as not being used as collateral anymore if (vars.maxCollateralToLiquidate == vars.userCollateralBalance) { userConfig.setUsingAsCollateral(collateralReserve.id, false); - emit ReserveUsedAsCollateralDisabled(collateral, user); + emit ReserveUsedAsCollateralDisabled(collateralAsset, user); } - //transfers the principal currency to the aToken - IERC20(principal).safeTransferFrom( + // Transfers the debt asset being repaid to the aToken, where the liquidity is kept + IERC20(debtAsset).safeTransferFrom( msg.sender, - principalReserve.aTokenAddress, + debtReserve.aTokenAddress, vars.actualAmountToLiquidate ); emit LiquidationCall( - collateral, - principal, + collateralAsset, + debtAsset, user, vars.actualAmountToLiquidate, vars.maxCollateralToLiquidate, @@ -257,60 +236,74 @@ contract LendingPoolCollateralManager is return (uint256(Errors.CollateralManagerErrors.NO_ERROR), Errors.LPCM_NO_ERRORS); } + struct AvailableCollateralToLiquidateLocalVars { + uint256 userCompoundedBorrowBalance; + uint256 liquidationBonus; + uint256 collateralPrice; + uint256 debtAssetPrice; + uint256 maxAmountCollateralToLiquidate; + uint256 debtAssetDecimals; + uint256 collateralDecimals; + } + /** - * @dev calculates how much of a specific collateral can be liquidated, given - * a certain amount of principal currency. This function needs to be called after - * all the checks to validate the liquidation have been performed, otherwise it might fail. - * @param collateralAddress the collateral to be liquidated - * @param principalAddress the principal currency to be liquidated - * @param debtToCover the amount of principal being liquidated - * @param userCollateralBalance the collatera balance for the specific collateral asset of the user being liquidated - * @return collateralAmount the maximum amount that is possible to liquidated given all the liquidation constraints (user balance, close factor) - * @return principalAmountNeeded the purchase amount + * @dev Calculates how much of a specific collateral can be liquidated, given + * a certain amount of debt asset. + * - This function needs to be called after all the checks to validate the liquidation have been performed, + * otherwise it might fail. + * @param collateralReserve The data of the collateral reserve + * @param debtReserve The data of the debt reserve + * @param collateralAsset The address of the underlying asset used as collateral, to receive as result of the liquidation + * @param debtAsset The address of the underlying borrowed asset to be repaid with the liquidation + * @param debtToCover The debt amount of borrowed `asset` the liquidator wants to cover + * @param userCollateralBalance The collateral balance for the specific `collateralAsset` of the user being liquidated + * @return collateralAmount: The maximum amount that is possible to liquidate given all the liquidation constraints + * (user balance, close factor) + * debtAmountNeeded: The amount to repay with the liquidation **/ function _calculateAvailableCollateralToLiquidate( DataTypes.ReserveData storage collateralReserve, - DataTypes.ReserveData storage principalReserve, - address collateralAddress, - address principalAddress, + DataTypes.ReserveData storage debtReserve, + address collateralAsset, + address debtAsset, uint256 debtToCover, uint256 userCollateralBalance ) internal view returns (uint256, uint256) { uint256 collateralAmount = 0; - uint256 principalAmountNeeded = 0; + uint256 debtAmountNeeded = 0; IPriceOracleGetter oracle = IPriceOracleGetter(_addressesProvider.getPriceOracle()); AvailableCollateralToLiquidateLocalVars memory vars; - vars.collateralPrice = oracle.getAssetPrice(collateralAddress); - vars.principalCurrencyPrice = oracle.getAssetPrice(principalAddress); + vars.collateralPrice = oracle.getAssetPrice(collateralAsset); + vars.debtAssetPrice = oracle.getAssetPrice(debtAsset); (, , vars.liquidationBonus, vars.collateralDecimals, ) = collateralReserve .configuration .getParams(); - vars.principalDecimals = principalReserve.configuration.getDecimals(); + vars.debtAssetDecimals = debtReserve.configuration.getDecimals(); - //this is the maximum possible amount of the selected collateral that can be liquidated, given the - //max amount of principal currency that is available for liquidation. + // This is the maximum possible amount of the selected collateral that can be liquidated, given the + // max amount of debt that is available for liquidation vars.maxAmountCollateralToLiquidate = vars - .principalCurrencyPrice + .debtAssetPrice .mul(debtToCover) .mul(10**vars.collateralDecimals) .percentMul(vars.liquidationBonus) - .div(vars.collateralPrice.mul(10**vars.principalDecimals)); + .div(vars.collateralPrice.mul(10**vars.debtAssetDecimals)); if (vars.maxAmountCollateralToLiquidate > userCollateralBalance) { collateralAmount = userCollateralBalance; - principalAmountNeeded = vars + debtAmountNeeded = vars .collateralPrice .mul(collateralAmount) - .mul(10**vars.principalDecimals) - .div(vars.principalCurrencyPrice.mul(10**vars.collateralDecimals)) + .mul(10**vars.debtAssetDecimals) + .div(vars.debtAssetPrice.mul(10**vars.collateralDecimals)) .percentDiv(vars.liquidationBonus); } else { collateralAmount = vars.maxAmountCollateralToLiquidate; - principalAmountNeeded = debtToCover; + debtAmountNeeded = debtToCover; } - return (collateralAmount, principalAmountNeeded); + return (collateralAmount, debtAmountNeeded); } } From ee11faa573ffa63ce55ea408e8e3c86d217c64f5 Mon Sep 17 00:00:00 2001 From: The3D Date: Wed, 25 Nov 2020 13:41:09 +0100 Subject: [PATCH 07/12] Updated comments, renamed variales --- .../LendingPoolCollateralManager.sol | 34 +++++++++---------- 1 file changed, 17 insertions(+), 17 deletions(-) diff --git a/contracts/protocol/lendingpool/LendingPoolCollateralManager.sol b/contracts/protocol/lendingpool/LendingPoolCollateralManager.sol index adf36486..5c39ae47 100644 --- a/contracts/protocol/lendingpool/LendingPoolCollateralManager.sol +++ b/contracts/protocol/lendingpool/LendingPoolCollateralManager.sol @@ -42,8 +42,8 @@ contract LendingPoolCollateralManager is uint256 userCollateralBalance; uint256 userStableDebt; uint256 userVariableDebt; - uint256 maxDebtToLiquidate; - uint256 actualAmountToLiquidate; + uint256 maxLiquidatableDebt; + uint256 actualDebtToLiquidate; uint256 liquidationRatio; uint256 maxAmountCollateralToLiquidate; uint256 userStableRate; @@ -67,7 +67,7 @@ contract LendingPoolCollateralManager is } /** - * @dev Function to liquidate a non-healthy position collateral-wise, with Health Factor below 1 + * @dev Function to liquidate a position if its Health Factor drops below 1 * - The caller (liquidator) covers `debtToCover` amount of debt of the user getting liquidated, and receives * a proportionally amount of the `collateralAsset` plus a bonus to cover market risk * @param collateralAsset The address of the underlying asset used as collateral, to receive as result of the liquidation @@ -118,12 +118,12 @@ contract LendingPoolCollateralManager is vars.userCollateralBalance = vars.collateralAtoken.balanceOf(user); - vars.maxDebtToLiquidate = vars.userStableDebt.add(vars.userVariableDebt).percentMul( + vars.maxLiquidatableDebt = vars.userStableDebt.add(vars.userVariableDebt).percentMul( LIQUIDATION_CLOSE_FACTOR_PERCENT ); - vars.actualAmountToLiquidate = debtToCover > vars.maxDebtToLiquidate - ? vars.maxDebtToLiquidate + vars.actualDebtToLiquidate = debtToCover > vars.maxLiquidatableDebt + ? vars.maxLiquidatableDebt : debtToCover; ( @@ -134,16 +134,16 @@ contract LendingPoolCollateralManager is debtReserve, collateralAsset, debtAsset, - vars.actualAmountToLiquidate, + vars.actualDebtToLiquidate, vars.userCollateralBalance ); - // If debtAmountNeeded < vars.actualAmountToLiquidate, there isn't enough + // If debtAmountNeeded < actualDebtToLiquidate, there isn't enough // collateral to cover the actual amount that is being liquidated, hence we liquidate // a smaller amount - if (vars.debtAmountNeeded < vars.actualAmountToLiquidate) { - vars.actualAmountToLiquidate = vars.debtAmountNeeded; + if (vars.debtAmountNeeded < vars.actualDebtToLiquidate) { + vars.actualDebtToLiquidate = vars.debtAmountNeeded; } // If the liquidator reclaims the underlying asset, we make sure there is enough available liquidity in the @@ -161,10 +161,10 @@ contract LendingPoolCollateralManager is debtReserve.updateState(); - if (vars.userVariableDebt >= vars.actualAmountToLiquidate) { + if (vars.userVariableDebt >= vars.actualDebtToLiquidate) { IVariableDebtToken(debtReserve.variableDebtTokenAddress).burn( user, - vars.actualAmountToLiquidate, + vars.actualDebtToLiquidate, debtReserve.variableBorrowIndex ); } else { @@ -178,14 +178,14 @@ contract LendingPoolCollateralManager is } IStableDebtToken(debtReserve.stableDebtTokenAddress).burn( user, - vars.actualAmountToLiquidate.sub(vars.userVariableDebt) + vars.actualDebtToLiquidate.sub(vars.userVariableDebt) ); } debtReserve.updateInterestRates( debtAsset, debtReserve.aTokenAddress, - vars.actualAmountToLiquidate, + vars.actualDebtToLiquidate, 0 ); @@ -220,14 +220,14 @@ contract LendingPoolCollateralManager is IERC20(debtAsset).safeTransferFrom( msg.sender, debtReserve.aTokenAddress, - vars.actualAmountToLiquidate + vars.actualDebtToLiquidate ); emit LiquidationCall( collateralAsset, debtAsset, user, - vars.actualAmountToLiquidate, + vars.actualDebtToLiquidate, vars.maxCollateralToLiquidate, msg.sender, receiveAToken @@ -284,7 +284,7 @@ contract LendingPoolCollateralManager is vars.debtAssetDecimals = debtReserve.configuration.getDecimals(); // This is the maximum possible amount of the selected collateral that can be liquidated, given the - // max amount of debt that is available for liquidation + // max amount of liquidatable debt vars.maxAmountCollateralToLiquidate = vars .debtAssetPrice .mul(debtToCover) From f9290705a00180ecf09744fbdea015af7fedddb8 Mon Sep 17 00:00:00 2001 From: The3D Date: Wed, 25 Nov 2020 13:45:52 +0100 Subject: [PATCH 08/12] Removed space in comments --- contracts/protocol/lendingpool/LendingPoolCollateralManager.sol | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/contracts/protocol/lendingpool/LendingPoolCollateralManager.sol b/contracts/protocol/lendingpool/LendingPoolCollateralManager.sol index 5c39ae47..9606bb39 100644 --- a/contracts/protocol/lendingpool/LendingPoolCollateralManager.sol +++ b/contracts/protocol/lendingpool/LendingPoolCollateralManager.sol @@ -284,7 +284,7 @@ contract LendingPoolCollateralManager is vars.debtAssetDecimals = debtReserve.configuration.getDecimals(); // This is the maximum possible amount of the selected collateral that can be liquidated, given the - // max amount of liquidatable debt + // max amount of liquidatable debt vars.maxAmountCollateralToLiquidate = vars .debtAssetPrice .mul(debtToCover) From 43d64c4509b2a9dff8fc2fa9186f245e6c9fd76e Mon Sep 17 00:00:00 2001 From: The3D Date: Wed, 25 Nov 2020 15:27:17 +0100 Subject: [PATCH 09/12] Updated LendingPoolConfigurator --- .../lendingpool/LendingPoolConfigurator.sol | 231 +++++++++--------- 1 file changed, 111 insertions(+), 120 deletions(-) diff --git a/contracts/protocol/lendingpool/LendingPoolConfigurator.sol b/contracts/protocol/lendingpool/LendingPoolConfigurator.sol index b31b067f..20933644 100644 --- a/contracts/protocol/lendingpool/LendingPoolConfigurator.sol +++ b/contracts/protocol/lendingpool/LendingPoolConfigurator.sol @@ -19,8 +19,8 @@ import {DataTypes} from '../libraries/types/DataTypes.sol'; /** * @title LendingPoolConfigurator contract * @author Aave - * @notice Executes configuration methods on the LendingPoolCore contract. Allows to enable/disable reserves - * and set different protocol parameters. + * @dev Implements the configuration methods for the Aave protocol. Interacts directly with the LendingPool contract + * All the functions can be invoked by either the PoolAdmin or the EmergencyAdmin. **/ contract LendingPoolConfigurator is VersionedInitializable { @@ -28,12 +28,12 @@ contract LendingPoolConfigurator is VersionedInitializable { using ReserveConfiguration for DataTypes.ReserveConfigurationMap; /** - * @dev emitted when a reserve is initialized. - * @param asset the address of the reserve - * @param aToken the address of the overlying aToken contract - * @param stableDebtToken the address of the associated stable rate debt token - * @param variableDebtToken the address of the associated variable rate debt token - * @param interestRateStrategyAddress the address of the interest rate strategy for the reserve + * @dev Emitted when a reserve is initialized. + * @param asset The address of the underlying asset of the reserve + * @param aToken The address of the associated aToken contract + * @param stableDebtToken The address of the associated stable rate debt token + * @param variableDebtToken The address of the associated variable rate debt token + * @param interestRateStrategyAddress The address of the interest rate strategy for the reserve **/ event ReserveInitialized( address indexed asset, @@ -44,24 +44,24 @@ contract LendingPoolConfigurator is VersionedInitializable { ); /** - * @dev emitted when borrowing is enabled on a reserve - * @param asset the address of the reserve - * @param stableRateEnabled true if stable rate borrowing is enabled, false otherwise + * @dev Emitted when borrowing is enabled on a reserve + * @param asset The address of the underlying asset of the reserve + * @param stableRateEnabled True if stable rate borrowing is enabled, false otherwise **/ event BorrowingEnabledOnReserve(address indexed asset, bool stableRateEnabled); /** - * @dev emitted when borrowing is disabled on a reserve - * @param asset the address of the reserve + * @dev Emitted when borrowing is disabled on a reserve + * @param asset The address of the underlying asset of the reserve **/ event BorrowingDisabledOnReserve(address indexed asset); /** - * @dev emitted when a a reserve collateralization risk parameters are updated. - * @param asset the address of the reserve - * @param ltv the loan to value of the asset when used as collateral - * @param liquidationThreshold the threshold at which loans using this asset as collateral will be considered undercollateralized - * @param liquidationBonus the bonus liquidators receive to liquidate this asset + * @dev Emitted when the collateralization risk parameters for the specified asset are updated. + * @param asset The address of the underlying asset of the reserve + * @param ltv The loan to value of the asset when used as collateral + * @param liquidationThreshold The threshold at which loans using this asset as collateral will be considered undercollateralized + * @param liquidationBonus The bonus liquidators receive to liquidate this asset **/ event CollateralConfigurationChanged( address indexed asset, @@ -71,67 +71,67 @@ contract LendingPoolConfigurator is VersionedInitializable { ); /** - * @dev emitted when stable rate borrowing is enabled on a reserve - * @param asset the address of the reserve + * @dev Emitted when stable rate borrowing is enabled on a reserve + * @param asset The address of the underlying asset of the reserve **/ event StableRateEnabledOnReserve(address indexed asset); /** - * @dev emitted when stable rate borrowing is disabled on a reserve - * @param asset the address of the reserve + * @dev Emitted when stable rate borrowing is disabled on a reserve + * @param asset The address of the underlying asset of the reserve **/ event StableRateDisabledOnReserve(address indexed asset); /** - * @dev emitted when a reserve is activated - * @param asset the address of the reserve + * @dev Emitted when a reserve is activated + * @param asset The address of the underlying asset of the reserve **/ event ReserveActivated(address indexed asset); /** - * @dev emitted when a reserve is deactivated - * @param asset the address of the reserve + * @dev Emitted when a reserve is deactivated + * @param asset The address of the underlying asset of the reserve **/ event ReserveDeactivated(address indexed asset); /** - * @dev emitted when a reserve is frozen - * @param asset the address of the reserve + * @dev Emitted when a reserve is frozen + * @param asset The address of the underlying asset of the reserve **/ event ReserveFrozen(address indexed asset); /** - * @dev emitted when a reserve is unfrozen - * @param asset the address of the reserve + * @dev Emitted when a reserve is unfrozen + * @param asset The address of the underlying asset of the reserve **/ event ReserveUnfrozen(address indexed asset); /** - * @dev emitted when a reserve factor is updated - * @param asset the address of the reserve - * @param factor the new reserve factor + * @dev Emitted when a reserve factor is updated + * @param asset The address of the underlying asset of the reserve + * @param factor The new reserve factor **/ event ReserveFactorChanged(address indexed asset, uint256 factor); /** - * @dev emitted when the reserve decimals are updated - * @param asset the address of the reserve - * @param decimals the new decimals + * @dev Emitted when the reserve decimals are updated + * @param asset The address of the underlying asset of the reserve + * @param decimals The new decimals **/ event ReserveDecimalsChanged(address indexed asset, uint256 decimals); /** - * @dev emitted when a reserve interest strategy contract is updated - * @param asset the address of the reserve - * @param strategy the new address of the interest strategy contract + * @dev Emitted when a reserve interest strategy contract is updated + * @param asset The address of the underlying asset of the reserve + * @param strategy The new address of the interest strategy contract **/ event ReserveInterestRateStrategyChanged(address indexed asset, address strategy); /** - * @dev emitted when an aToken implementation is upgraded - * @param asset the address of the reserve - * @param proxy the aToken proxy address - * @param implementation the new aToken implementation + * @dev Emitted when an aToken implementation is upgraded + * @param asset The address of the underlying asset of the reserve + * @param proxy The aToken proxy address + * @param implementation The new aToken implementation **/ event ATokenUpgraded( address indexed asset, @@ -140,10 +140,10 @@ contract LendingPoolConfigurator is VersionedInitializable { ); /** - * @dev emitted when the implementation of a stable debt token is upgraded - * @param asset the address of the reserve - * @param proxy the stable debt token proxy address - * @param implementation the new aToken implementation + * @dev Emitted when the implementation of a stable debt token is upgraded + * @param asset The address of the underlying asset of the reserve + * @param proxy The stable debt token proxy address + * @param implementation The new aToken implementation **/ event StableDebtTokenUpgraded( address indexed asset, @@ -152,10 +152,10 @@ contract LendingPoolConfigurator is VersionedInitializable { ); /** - * @dev emitted when the implementation of a variable debt token is upgraded - * @param asset the address of the reserve - * @param proxy the variable debt token proxy address - * @param implementation the new aToken implementation + * @dev Emitted when the implementation of a variable debt token is upgraded + * @param asset The address of the underlying asset of the reserve + * @param proxy The variable debt token proxy address + * @param implementation The new aToken implementation **/ event VariableDebtTokenUpgraded( address indexed asset, @@ -166,17 +166,11 @@ contract LendingPoolConfigurator is VersionedInitializable { ILendingPoolAddressesProvider internal addressesProvider; ILendingPool internal pool; - /** - * @dev only the pool admin can call functions affected by this modifier - **/ modifier onlyPoolAdmin { require(addressesProvider.getPoolAdmin() == msg.sender, Errors.CALLER_NOT_POOL_ADMIN); _; } - /** - * @dev only the emergency admin can call functions affected by this modifier - **/ modifier onlyEmergencyAdmin { require( addressesProvider.getEmergencyAdmin() == msg.sender, @@ -185,7 +179,7 @@ contract LendingPoolConfigurator is VersionedInitializable { _; } - uint256 internal constant CONFIGURATOR_REVISION = 0x3; + uint256 internal constant CONFIGURATOR_REVISION = 0x1; function getRevision() internal pure override returns (uint256) { return CONFIGURATOR_REVISION; @@ -197,12 +191,12 @@ contract LendingPoolConfigurator is VersionedInitializable { } /** - * @dev initializes a reserve - * @param aTokenImpl the address of the aToken contract implementation - * @param stableDebtTokenImpl the address of the stable debt token contract - * @param variableDebtTokenImpl the address of the variable debt token contract - * @param underlyingAssetDecimals the decimals of the reserve underlying asset - * @param interestRateStrategyAddress the address of the interest rate strategy contract for this reserve + * @dev Initializes a reserve + * @param aTokenImpl The address of the aToken contract implementation + * @param stableDebtTokenImpl The address of the stable debt token contract + * @param variableDebtTokenImpl The address of the variable debt token contract + * @param underlyingAssetDecimals The decimals of the reserve underlying asset + * @param interestRateStrategyAddress The address of the interest rate strategy contract for this reserve **/ function initReserve( address aTokenImpl, @@ -269,9 +263,9 @@ contract LendingPoolConfigurator is VersionedInitializable { } /** - * @dev updates the aToken implementation for the asset - * @param asset the address of the reserve to be updated - * @param implementation the address of the new aToken implementation + * @dev Updates the aToken implementation for the reserve + * @param asset The address of the underlying asset of the reserve to be updated + * @param implementation The address of the new aToken implementation **/ function updateAToken(address asset, address implementation) external onlyPoolAdmin { DataTypes.ReserveData memory reserveData = pool.getReserveData(asset); @@ -282,9 +276,9 @@ contract LendingPoolConfigurator is VersionedInitializable { } /** - * @dev updates the stable debt token implementation for the asset - * @param asset the address of the reserve to be updated - * @param implementation the address of the new aToken implementation + * @dev Updates the stable debt token implementation for the reserve + * @param asset The address of the underlying asset of the reserve to be updated + * @param implementation The address of the new aToken implementation **/ function updateStableDebtToken(address asset, address implementation) external onlyPoolAdmin { DataTypes.ReserveData memory reserveData = pool.getReserveData(asset); @@ -295,9 +289,9 @@ contract LendingPoolConfigurator is VersionedInitializable { } /** - * @dev updates the variable debt token implementation for the asset - * @param asset the address of the reserve to be updated - * @param implementation the address of the new aToken implementation + * @dev Updates the variable debt token implementation for the asset + * @param asset The address of the underlying asset of the reserve to be updated + * @param implementation The address of the new aToken implementation **/ function updateVariableDebtToken(address asset, address implementation) external onlyPoolAdmin { DataTypes.ReserveData memory reserveData = pool.getReserveData(asset); @@ -308,9 +302,9 @@ contract LendingPoolConfigurator is VersionedInitializable { } /** - * @dev enables borrowing on a reserve - * @param asset the address of the reserve - * @param stableBorrowRateEnabled true if stable borrow rate needs to be enabled by default on this reserve + * @dev Enables borrowing on a reserve + * @param asset The address of the underlying asset of the reserve + * @param stableBorrowRateEnabled True if stable borrow rate needs to be enabled by default on this reserve **/ function enableBorrowingOnReserve(address asset, bool stableBorrowRateEnabled) external @@ -327,8 +321,8 @@ contract LendingPoolConfigurator is VersionedInitializable { } /** - * @dev disables borrowing on a reserve - * @param asset the address of the reserve + * @dev Disables borrowing on a reserve + * @param asset The address of the underlying asset of the reserve **/ function disableBorrowingOnReserve(address asset) external onlyPoolAdmin { DataTypes.ReserveConfigurationMap memory currentConfig = pool.getConfiguration(asset); @@ -340,12 +334,12 @@ contract LendingPoolConfigurator is VersionedInitializable { } /** - * @dev configures the reserve collateralization parameters. + * @dev Configures the reserve collateralization parameters * all the values are expressed in percentages with two decimals of precision. A valid value is 10000, which means 100.00% - * @param asset the address of the reserve - * @param ltv the loan to value of the asset when used as collateral - * @param liquidationThreshold the threshold at which loans using this asset as collateral will be considered undercollateralized - * @param liquidationBonus the bonus liquidators receive to liquidate this asset. The values is always above 100%. A value of 105% + * @param asset The address of the underlying asset of the reserve + * @param ltv The loan to value of the asset when used as collateral + * @param liquidationThreshold The threshold at which loans using this asset as collateral will be considered undercollateralized + * @param liquidationBonus The bonus liquidators receive to liquidate this asset. The values is always above 100%. A value of 105% * means the liquidator will receive a 5% bonus **/ function configureReserveAsCollateral( @@ -363,15 +357,16 @@ contract LendingPoolConfigurator is VersionedInitializable { if (liquidationThreshold != 0) { //liquidation bonus must be bigger than 100.00%, otherwise the liquidator would receive less - //collateral than needed to cover the debt. - uint256 absoluteBonus = - liquidationBonus.sub(PercentageMath.PERCENTAGE_FACTOR, Errors.LPC_INVALID_CONFIGURATION); - require(absoluteBonus > 0, Errors.LPC_INVALID_CONFIGURATION); - - //we also need to require that the liq threshold is lower or equal than the liquidation bonus, to ensure that - //there is always enough margin for liquidators to receive the bonus. + //collateral than needed to cover the debt require( - liquidationThreshold.add(absoluteBonus) <= PercentageMath.PERCENTAGE_FACTOR, + liquidationBonus > PercentageMath.PERCENTAGE_FACTOR, + Errors.LPC_INVALID_CONFIGURATION + ); + + //if threshold * bonus is less than PERCENTAGE_FACTOR, it's guaranteed that at the moment + //a loan is taken there is enough collateral available to cover the liquidation bonus + require( + liquidationThreshold.percentMul(liquidationBonus) <= PercentageMath.PERCENTAGE_FACTOR, Errors.LPC_INVALID_CONFIGURATION ); } else { @@ -392,8 +387,8 @@ contract LendingPoolConfigurator is VersionedInitializable { } /** - * @dev enable stable rate borrowing on a reserve - * @param asset the address of the reserve + * @dev Enable stable rate borrowing on a reserve + * @param asset The address of the underlying asset of the reserve **/ function enableReserveStableRate(address asset) external onlyPoolAdmin { DataTypes.ReserveConfigurationMap memory currentConfig = pool.getConfiguration(asset); @@ -406,8 +401,8 @@ contract LendingPoolConfigurator is VersionedInitializable { } /** - * @dev disable stable rate borrowing on a reserve - * @param asset the address of the reserve + * @dev Disable stable rate borrowing on a reserve + * @param asset The address of the underlying asset of the reserve **/ function disableReserveStableRate(address asset) external onlyPoolAdmin { DataTypes.ReserveConfigurationMap memory currentConfig = pool.getConfiguration(asset); @@ -420,8 +415,8 @@ contract LendingPoolConfigurator is VersionedInitializable { } /** - * @dev activates a reserve - * @param asset the address of the reserve + * @dev Activates a reserve + * @param asset The address of the underlying asset of the reserve **/ function activateReserve(address asset) external onlyPoolAdmin { DataTypes.ReserveConfigurationMap memory currentConfig = pool.getConfiguration(asset); @@ -434,8 +429,8 @@ contract LendingPoolConfigurator is VersionedInitializable { } /** - * @dev deactivates a reserve - * @param asset the address of the reserve + * @dev Deactivates a reserve + * @param asset The address of the underlying asset of the reserve **/ function deactivateReserve(address asset) external onlyPoolAdmin { _checkNoLiquidity(asset); @@ -450,8 +445,9 @@ contract LendingPoolConfigurator is VersionedInitializable { } /** - * @dev freezes a reserve. A frozen reserve doesn't accept any new deposit, borrow or rate swap, but can accept repayments, liquidations, rate rebalances and redeems - * @param asset the address of the reserve + * @dev Freezes a reserve. A frozen reserve doesn't allow any new deposit, borrow or rate swap + * but allows repayments, liquidations, rate rebalances and withdrawals + * @param asset The address of the underlying asset of the reserve **/ function freezeReserve(address asset) external onlyPoolAdmin { DataTypes.ReserveConfigurationMap memory currentConfig = pool.getConfiguration(asset); @@ -464,8 +460,8 @@ contract LendingPoolConfigurator is VersionedInitializable { } /** - * @dev unfreezes a reserve - * @param asset the address of the reserve + * @dev Unfreezes a reserve + * @param asset The address of the underlying asset of the reserve **/ function unfreezeReserve(address asset) external onlyPoolAdmin { DataTypes.ReserveConfigurationMap memory currentConfig = pool.getConfiguration(asset); @@ -478,9 +474,9 @@ contract LendingPoolConfigurator is VersionedInitializable { } /** - * @dev updates the reserve factor of a reserve - * @param asset the address of the reserve - * @param reserveFactor the new reserve factor of the reserve + * @dev Updates the reserve factor of a reserve + * @param asset The address of the underlying asset of the reserve + * @param reserveFactor The new reserve factor of the reserve **/ function setReserveFactor(address asset, uint256 reserveFactor) external onlyPoolAdmin { DataTypes.ReserveConfigurationMap memory currentConfig = pool.getConfiguration(asset); @@ -493,9 +489,9 @@ contract LendingPoolConfigurator is VersionedInitializable { } /** - * @dev sets the interest rate strategy of a reserve - * @param asset the address of the reserve - * @param rateStrategyAddress the new address of the interest strategy contract + * @dev Sets the interest rate strategy of a reserve + * @param asset The address of the underlying asset of the reserve + * @param rateStrategyAddress The new address of the interest strategy contract **/ function setReserveInterestRateStrategyAddress(address asset, address rateStrategyAddress) external @@ -506,10 +502,13 @@ contract LendingPoolConfigurator is VersionedInitializable { } /** - * @dev initializes a token with a proxy and a specific implementation - * @param implementation the address of the implementation - * @param decimals the decimals of the token + * @dev pauses or unpauses all the actions of the protocol, including aToken transfers + * @param val true if protocol needs to be paused, false otherwise **/ + function setPoolPause(bool val) external onlyEmergencyAdmin { + pool.setPause(val); + } + function _initTokenWithProxy(address implementation, uint8 decimals) internal returns (address) { InitializableImmutableAdminUpgradeabilityProxy proxy = new InitializableImmutableAdminUpgradeabilityProxy(address(this)); @@ -550,14 +549,6 @@ contract LendingPoolConfigurator is VersionedInitializable { proxy.upgradeToAndCall(implementation, params); } - /** - * @dev pauses or unpauses LendingPool actions - * @param val the boolean value to set the current pause state of LendingPool - **/ - function setPoolPause(bool val) external onlyEmergencyAdmin { - pool.setPause(val); - } - function _checkNoLiquidity(address asset) internal view { DataTypes.ReserveData memory reserveData = pool.getReserveData(asset); From c997a910c80772a2cd28129e87c7b4e6d260d8fd Mon Sep 17 00:00:00 2001 From: The3D Date: Wed, 25 Nov 2020 15:31:03 +0100 Subject: [PATCH 10/12] Updated comment --- contracts/protocol/lendingpool/LendingPoolConfigurator.sol | 1 - 1 file changed, 1 deletion(-) diff --git a/contracts/protocol/lendingpool/LendingPoolConfigurator.sol b/contracts/protocol/lendingpool/LendingPoolConfigurator.sol index 20933644..a4bbede3 100644 --- a/contracts/protocol/lendingpool/LendingPoolConfigurator.sol +++ b/contracts/protocol/lendingpool/LendingPoolConfigurator.sol @@ -20,7 +20,6 @@ import {DataTypes} from '../libraries/types/DataTypes.sol'; * @title LendingPoolConfigurator contract * @author Aave * @dev Implements the configuration methods for the Aave protocol. Interacts directly with the LendingPool contract - * All the functions can be invoked by either the PoolAdmin or the EmergencyAdmin. **/ contract LendingPoolConfigurator is VersionedInitializable { From 7d96451ced33496d0f79d6c128d96d99ad38d214 Mon Sep 17 00:00:00 2001 From: The3D Date: Wed, 25 Nov 2020 15:31:27 +0100 Subject: [PATCH 11/12] Updated comment --- contracts/protocol/lendingpool/LendingPoolConfigurator.sol | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/contracts/protocol/lendingpool/LendingPoolConfigurator.sol b/contracts/protocol/lendingpool/LendingPoolConfigurator.sol index a4bbede3..17265a14 100644 --- a/contracts/protocol/lendingpool/LendingPoolConfigurator.sol +++ b/contracts/protocol/lendingpool/LendingPoolConfigurator.sol @@ -19,7 +19,7 @@ import {DataTypes} from '../libraries/types/DataTypes.sol'; /** * @title LendingPoolConfigurator contract * @author Aave - * @dev Implements the configuration methods for the Aave protocol. Interacts directly with the LendingPool contract + * @dev Implements the configuration methods for the Aave protocol **/ contract LendingPoolConfigurator is VersionedInitializable { From 00477d9334b28c3d7a11709772270d6f82a7589e Mon Sep 17 00:00:00 2001 From: eboado Date: Wed, 25 Nov 2020 16:17:08 +0100 Subject: [PATCH 12/12] - Added `using` to LendingPoolConfigurator --- contracts/protocol/lendingpool/LendingPoolConfigurator.sol | 1 + 1 file changed, 1 insertion(+) diff --git a/contracts/protocol/lendingpool/LendingPoolConfigurator.sol b/contracts/protocol/lendingpool/LendingPoolConfigurator.sol index 17265a14..2e08d70c 100644 --- a/contracts/protocol/lendingpool/LendingPoolConfigurator.sol +++ b/contracts/protocol/lendingpool/LendingPoolConfigurator.sol @@ -24,6 +24,7 @@ import {DataTypes} from '../libraries/types/DataTypes.sol'; contract LendingPoolConfigurator is VersionedInitializable { using SafeMath for uint256; + using PercentageMath for uint256; using ReserveConfiguration for DataTypes.ReserveConfigurationMap; /**