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/interfaces/ILendingPool.sol b/contracts/interfaces/ILendingPool.sol index 1f4104dd..d445579a 100644 --- a/contracts/interfaces/ILendingPool.sol +++ b/contracts/interfaces/ILendingPool.sol @@ -2,10 +2,9 @@ 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 +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 (ReserveConfiguration.Map 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 (UserConfiguration.Map memory); + function getUserConfiguration(address user) + external + view + returns (DataTypes.UserConfigurationMap memory); /** * @dev Returns the normalized income normalized income of the reserve @@ -383,7 +388,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..d9b476af 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.ReserveConfigurationMap; + using UserConfiguration for DataTypes.UserConfigurationMap; 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.ReserveConfigurationMap 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.UserConfigurationMap 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..f0e2c2d5 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.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(); - UserConfiguration.Map memory userConfig = lendingPool.getUserConfiguration(user); + DataTypes.UserConfigurationMap 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..ee8261b0 100644 --- a/contracts/misc/WETHGateway.sol +++ b/contracts/misc/WETHGateway.sol @@ -6,16 +6,16 @@ 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'; 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.ReserveConfigurationMap; + using UserConfiguration for DataTypes.UserConfigurationMap; IWETH internal immutable WETH; ILendingPool internal immutable POOL; @@ -79,7 +79,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..cd4a81ce 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.ReserveConfigurationMap; 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.ReserveConfigurationMap 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..525141a6 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.ReserveConfigurationMap memory) { return _reserves[asset].configuration; } @@ -636,7 +637,7 @@ contract LendingPool is VersionedInitializable, ILendingPool, LendingPoolStorage external view override - returns (UserConfiguration.Map memory) + returns (DataTypes.UserConfigurationMap 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.UserConfigurationMap storage fromConfig = _usersConfig[from]; fromConfig.setUsingAsCollateral(reserveId, false); emit ReserveUsedAsCollateralDisabled(asset, from); } if (balanceToBefore == 0 && amount != 0) { - UserConfiguration.Map storage toConfig = _usersConfig[to]; + DataTypes.UserConfigurationMap 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.UserConfigurationMap 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..9606bb39 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,82 +17,76 @@ 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 * @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, VersionedInitializable, LendingPoolStorage { +contract LendingPoolCollateralManager is + ILendingPoolCollateralManager, + VersionedInitializable, + LendingPoolStorage +{ using SafeERC20 for IERC20; using SafeMath for uint256; 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 actualAmountToLiquidate; + uint256 maxLiquidatableDebt; + uint256 actualDebtToLiquidate; uint256 liquidationRatio; uint256 maxAmountCollateralToLiquidate; uint256 userStableRate; uint256 maxCollateralToLiquidate; - uint256 principalAmountNeeded; + uint256 debtAmountNeeded; uint256 healthFactor; IAToken collateralAtoken; bool isCollateralEnabled; - ReserveLogic.InterestRateMode borrowRateMode; - address principalAToken; + DataTypes.InterestRateMode borrowRateMode; 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 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 + * @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) { - ReserveLogic.ReserveData storage collateralReserve = _reserves[collateral]; - ReserveLogic.ReserveData storage principalReserve = _reserves[principal]; - UserConfiguration.Map storage userConfig = _usersConfig[user]; + DataTypes.ReserveData storage collateralReserve = _reserves[collateralAsset]; + DataTypes.ReserveData storage debtReserve = _reserves[debtAsset]; + DataTypes.UserConfigurationMap storage userConfig = _usersConfig[user]; LiquidationCallLocalVars memory vars; @@ -107,15 +99,11 @@ contract LendingPoolCollateralManager is ILendingPoolCollateralManager, Versione _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, @@ -130,38 +118,39 @@ contract LendingPoolCollateralManager is ILendingPoolCollateralManager, Versione vars.userCollateralBalance = vars.collateralAtoken.balanceOf(user); - vars.maxPrincipalAmountToLiquidate = vars.userStableDebt.add(vars.userVariableDebt).percentMul( + vars.maxLiquidatableDebt = vars.userStableDebt.add(vars.userVariableDebt).percentMul( LIQUIDATION_CLOSE_FACTOR_PERCENT ); - vars.actualAmountToLiquidate = debtToCover > vars.maxPrincipalAmountToLiquidate - ? vars.maxPrincipalAmountToLiquidate + vars.actualDebtToLiquidate = debtToCover > vars.maxLiquidatableDebt + ? vars.maxLiquidatableDebt : debtToCover; ( vars.maxCollateralToLiquidate, - vars.principalAmountNeeded + vars.debtAmountNeeded ) = _calculateAvailableCollateralToLiquidate( collateralReserve, - principalReserve, - collateral, - principal, - vars.actualAmountToLiquidate, + debtReserve, + collateralAsset, + debtAsset, + vars.actualDebtToLiquidate, 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 < actualDebtToLiquidate, 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.actualDebtToLiquidate) { + vars.actualDebtToLiquidate = 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), @@ -170,54 +159,48 @@ contract LendingPoolCollateralManager is ILendingPoolCollateralManager, Versione } } - //update the principal reserve - principalReserve.updateState(); + debtReserve.updateState(); - if (vars.userVariableDebt >= vars.actualAmountToLiquidate) { - IVariableDebtToken(principalReserve.variableDebtTokenAddress).burn( + if (vars.userVariableDebt >= vars.actualDebtToLiquidate) { + IVariableDebtToken(debtReserve.variableDebtTokenAddress).burn( user, - vars.actualAmountToLiquidate, - principalReserve.variableBorrowIndex + vars.actualDebtToLiquidate, + 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) + vars.actualDebtToLiquidate.sub(vars.userVariableDebt) ); } - principalReserve.updateInterestRates( - principal, - principalReserve.aTokenAddress, - vars.actualAmountToLiquidate, + debtReserve.updateInterestRates( + debtAsset, + debtReserve.aTokenAddress, + vars.actualDebtToLiquidate, 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, @@ -226,26 +209,25 @@ contract LendingPoolCollateralManager is ILendingPoolCollateralManager, Versione ); } - //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, - vars.actualAmountToLiquidate + debtReserve.aTokenAddress, + vars.actualDebtToLiquidate ); emit LiquidationCall( - collateral, - principal, + collateralAsset, + debtAsset, user, - vars.actualAmountToLiquidate, + vars.actualDebtToLiquidate, vars.maxCollateralToLiquidate, msg.sender, receiveAToken @@ -254,60 +236,74 @@ contract LendingPoolCollateralManager is ILendingPoolCollateralManager, Versione 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( - ReserveLogic.ReserveData storage collateralReserve, - ReserveLogic.ReserveData storage principalReserve, - address collateralAddress, - address principalAddress, + DataTypes.ReserveData storage collateralReserve, + 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 liquidatable debt 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); } } diff --git a/contracts/protocol/lendingpool/LendingPoolConfigurator.sol b/contracts/protocol/lendingpool/LendingPoolConfigurator.sol index ad70947c..2e08d70c 100644 --- a/contracts/protocol/lendingpool/LendingPoolConfigurator.sol +++ b/contracts/protocol/lendingpool/LendingPoolConfigurator.sol @@ -14,26 +14,26 @@ 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 * @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 **/ contract LendingPoolConfigurator is VersionedInitializable { using SafeMath for uint256; - using ReserveConfiguration for ReserveConfiguration.Map; + using PercentageMath for uint256; + 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, @@ -250,7 +244,7 @@ contract LendingPoolConfigurator is VersionedInitializable { interestRateStrategyAddress ); - ReserveConfiguration.Map memory currentConfig = pool.getConfiguration(asset); + DataTypes.ReserveConfigurationMap memory currentConfig = pool.getConfiguration(asset); currentConfig.setDecimals(underlyingAssetDecimals); @@ -269,12 +263,12 @@ 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 { - ReserveLogic.ReserveData memory reserveData = pool.getReserveData(asset); + DataTypes.ReserveData memory reserveData = pool.getReserveData(asset); _upgradeTokenImplementation(asset, reserveData.aTokenAddress, implementation); @@ -282,12 +276,12 @@ 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 { - ReserveLogic.ReserveData memory reserveData = pool.getReserveData(asset); + DataTypes.ReserveData memory reserveData = pool.getReserveData(asset); _upgradeTokenImplementation(asset, reserveData.stableDebtTokenAddress, implementation); @@ -295,12 +289,12 @@ 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 { - ReserveLogic.ReserveData memory reserveData = pool.getReserveData(asset); + DataTypes.ReserveData memory reserveData = pool.getReserveData(asset); _upgradeTokenImplementation(asset, reserveData.variableDebtTokenAddress, implementation); @@ -308,15 +302,15 @@ 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 onlyPoolAdmin { - ReserveConfiguration.Map memory currentConfig = pool.getConfiguration(asset); + DataTypes.ReserveConfigurationMap memory currentConfig = pool.getConfiguration(asset); currentConfig.setBorrowingEnabled(true); currentConfig.setStableRateBorrowingEnabled(stableBorrowRateEnabled); @@ -327,11 +321,11 @@ 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 { - ReserveConfiguration.Map memory currentConfig = pool.getConfiguration(asset); + DataTypes.ReserveConfigurationMap memory currentConfig = pool.getConfiguration(asset); currentConfig.setBorrowingEnabled(false); @@ -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( @@ -354,7 +348,7 @@ contract LendingPoolConfigurator is VersionedInitializable { uint256 liquidationThreshold, uint256 liquidationBonus ) external onlyPoolAdmin { - ReserveConfiguration.Map 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 @@ -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,11 +387,11 @@ 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 { - ReserveConfiguration.Map memory currentConfig = pool.getConfiguration(asset); + DataTypes.ReserveConfigurationMap memory currentConfig = pool.getConfiguration(asset); currentConfig.setStableRateBorrowingEnabled(true); @@ -406,11 +401,11 @@ 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 { - ReserveConfiguration.Map memory currentConfig = pool.getConfiguration(asset); + DataTypes.ReserveConfigurationMap memory currentConfig = pool.getConfiguration(asset); currentConfig.setStableRateBorrowingEnabled(false); @@ -420,11 +415,11 @@ 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 { - ReserveConfiguration.Map memory currentConfig = pool.getConfiguration(asset); + DataTypes.ReserveConfigurationMap memory currentConfig = pool.getConfiguration(asset); currentConfig.setActive(true); @@ -434,13 +429,13 @@ 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); - ReserveConfiguration.Map memory currentConfig = pool.getConfiguration(asset); + DataTypes.ReserveConfigurationMap memory currentConfig = pool.getConfiguration(asset); currentConfig.setActive(false); @@ -450,11 +445,12 @@ 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 { - ReserveConfiguration.Map memory currentConfig = pool.getConfiguration(asset); + DataTypes.ReserveConfigurationMap memory currentConfig = pool.getConfiguration(asset); currentConfig.setFrozen(true); @@ -464,11 +460,11 @@ 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 { - ReserveConfiguration.Map memory currentConfig = pool.getConfiguration(asset); + DataTypes.ReserveConfigurationMap memory currentConfig = pool.getConfiguration(asset); currentConfig.setFrozen(false); @@ -478,12 +474,12 @@ 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 { - ReserveConfiguration.Map memory currentConfig = pool.getConfiguration(asset); + DataTypes.ReserveConfigurationMap memory currentConfig = pool.getConfiguration(asset); currentConfig.setReserveFactor(reserveFactor); @@ -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)); @@ -535,7 +534,7 @@ contract LendingPoolConfigurator is VersionedInitializable { InitializableImmutableAdminUpgradeabilityProxy proxy = InitializableImmutableAdminUpgradeabilityProxy(payable(proxyAddress)); - ReserveConfiguration.Map memory configuration = pool.getConfiguration(asset); + DataTypes.ReserveConfigurationMap memory configuration = pool.getConfiguration(asset); (, , , uint256 decimals, ) = configuration.getParamsMemory(); @@ -550,16 +549,8 @@ 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 { - 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..4edff4a3 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.ReserveConfigurationMap; + using UserConfiguration for DataTypes.UserConfigurationMap; ILendingPoolAddressesProvider internal _addressesProvider; - mapping(address => ReserveLogic.ReserveData) internal _reserves; - mapping(address => UserConfiguration.Map) internal _usersConfig; + mapping(address => DataTypes.ReserveData) internal _reserves; + 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 3f7a8bf6..39df878b 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.ReserveConfigurationMap 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.ReserveConfigurationMap 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.ReserveConfigurationMap 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.ReserveConfigurationMap 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.ReserveConfigurationMap 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.ReserveConfigurationMap 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.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); @@ -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.ReserveConfigurationMap 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.ReserveConfigurationMap 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.ReserveConfigurationMap 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.ReserveConfigurationMap 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.ReserveConfigurationMap 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.ReserveConfigurationMap 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.ReserveConfigurationMap 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.ReserveConfigurationMap 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.ReserveConfigurationMap 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.ReserveConfigurationMap 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.ReserveConfigurationMap 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.ReserveConfigurationMap 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.ReserveConfigurationMap 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.ReserveConfigurationMap 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.ReserveConfigurationMap memory self) internal pure returns ( diff --git a/contracts/protocol/libraries/configuration/UserConfiguration.sol b/contracts/protocol/libraries/configuration/UserConfiguration.sol index 665b019a..b4af79ad 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.UserConfigurationMap 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.UserConfigurationMap 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.UserConfigurationMap 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.UserConfigurationMap 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.UserConfigurationMap 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.UserConfigurationMap 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.UserConfigurationMap 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..e8ee263f 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.ReserveConfigurationMap; + using UserConfiguration for DataTypes.UserConfigurationMap; 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.UserConfigurationMap 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.UserConfigurationMap 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..7a73be5b 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.ReserveConfigurationMap; /** * @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..7df21875 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.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% @@ -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.UserConfigurationMap 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.UserConfigurationMap 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.UserConfigurationMap 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.UserConfigurationMap 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.UserConfigurationMap 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.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 new file mode 100644 index 00000000..a19e5efc --- /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 + 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} +} diff --git a/specs/harness/LendingPoolHarnessForVariableDebtToken.sol b/specs/harness/LendingPoolHarnessForVariableDebtToken.sol index cb699e39..57752c58 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/protocol/libraries/configuration/ReserveConfiguration.sol'; -import {UserConfiguration} from '../../contracts/protocol/libraries/configuration/UserConfiguration.sol'; -import {ReserveLogic} from '../../contracts/protocol/libraries/logic/ReserveLogic.sol'; import {ILendingPool} from '../../contracts/interfaces/ILendingPool.sol'; import {LendingPool} from '../../contracts/protocol/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,24 +73,24 @@ 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.UserConfigurationMap memory) { return originalPool.getUserConfiguration(user); } @@ -144,16 +140,16 @@ contract LendingPoolHarnessForVariableDebtToken is ILendingPool { function getConfiguration(address asset) external - override view - returns (ReserveConfiguration.Map memory) + override + returns (DataTypes.ReserveConfigurationMap 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 1ebd6e34..00a8da90 100644 --- a/specs/harness/UserConfigurationHarness.sol +++ b/specs/harness/UserConfigurationHarness.sol @@ -7,7 +7,7 @@ import {UserConfiguration} from '../../contracts/protocol/libraries/configuratio A wrapper contract for calling functions from the library UserConfiguration. */ contract UserConfigurationHarness { - UserConfiguration.Map internal usersConfig; + DataTypes.UserConfigurationMap internal usersConfig; function setBorrowing( address user,