From 5532ebdc8a8540cb0ad4354847dfdf0ade74377f Mon Sep 17 00:00:00 2001 From: eboado Date: Tue, 24 Nov 2020 14:53:34 +0100 Subject: [PATCH] - 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,