diff --git a/contracts/protocol/lendingpool/LendingPool.sol b/contracts/protocol/lendingpool/LendingPool.sol index f61826f0..ad7f8948 100644 --- a/contracts/protocol/lendingpool/LendingPool.sol +++ b/contracts/protocol/lendingpool/LendingPool.sol @@ -465,7 +465,7 @@ contract LendingPool is VersionedInitializable, ILendingPool, LendingPoolStorage ) external override whenNotPaused { FlashLoanLocalVars memory vars; - ValidationLogic.validateFlashloan(assets, amounts); + ValidationLogic.validateFlashloan(assets, amounts, _reserves); address[] memory aTokenAddresses = new address[](assets.length); uint256[] memory premiums = new uint256[](assets.length); @@ -728,6 +728,7 @@ contract LendingPool is VersionedInitializable, ILendingPool, LendingPoolStorage if (fromConfig.isUsingAsCollateral(reserveId)) { if (fromConfig.isBorrowingAny()) { ValidationLogic.validateHealthFactor( + asset, from, _reserves, _usersConfig[from], diff --git a/contracts/protocol/libraries/helpers/Errors.sol b/contracts/protocol/libraries/helpers/Errors.sol index 9fa7e96e..2b6f015a 100644 --- a/contracts/protocol/libraries/helpers/Errors.sol +++ b/contracts/protocol/libraries/helpers/Errors.sol @@ -119,6 +119,7 @@ library Errors { NO_ACTIVE_RESERVE, HEALTH_FACTOR_LOWER_THAN_LIQUIDATION_THRESHOLD, INVALID_EQUAL_ASSETS_TO_SWAP, - FROZEN_RESERVE + FROZEN_RESERVE, + PAUSED_RESERVE } } diff --git a/contracts/protocol/libraries/logic/ValidationLogic.sol b/contracts/protocol/libraries/logic/ValidationLogic.sol index 8038043e..24915aa5 100644 --- a/contracts/protocol/libraries/logic/ValidationLogic.sol +++ b/contracts/protocol/libraries/logic/ValidationLogic.sol @@ -41,10 +41,11 @@ library ValidationLogic { * @param amount The amount to be deposited */ function validateDeposit(DataTypes.ReserveData storage reserve, uint256 amount) external view { - (bool isActive, bool isFrozen, , , ) = reserve.configuration.getFlags(); + (bool isActive, bool isFrozen, , , bool isPaused) = reserve.configuration.getFlags(); require(amount != 0, Errors.VL_INVALID_AMOUNT); require(isActive, Errors.VL_NO_ACTIVE_RESERVE); + require(!isPaused, Errors.VL_RESERVE_PAUSED); require(!isFrozen, Errors.VL_RESERVE_FROZEN); require( IERC20(reserve.aTokenAddress) @@ -70,8 +71,9 @@ library ValidationLogic { require(amount != 0, Errors.VL_INVALID_AMOUNT); require(amount <= userBalance, Errors.VL_NOT_ENOUGH_AVAILABLE_USER_BALANCE); - (bool isActive, , , , ) = reservesData[reserveAddress].configuration.getFlags(); + (bool isActive, , , , bool isPaused) = reservesData[reserveAddress].configuration.getFlags(); require(isActive, Errors.VL_NO_ACTIVE_RESERVE); + require(!isPaused, Errors.VL_RESERVE_PAUSED); } struct ValidateBorrowLocalVars { @@ -233,10 +235,10 @@ library ValidationLogic { address onBehalfOf, uint256 stableDebt, uint256 variableDebt - ) internal view { - bool isActive = reserve.configuration.getActive(); - + ) external view { + (bool isActive, , , , bool isPaused) = reserve.configuration.getFlags(); require(isActive, Errors.VL_NO_ACTIVE_RESERVE); + require(!isPaused, Errors.VL_RESERVE_PAUSED); require(amountSent > 0, Errors.VL_INVALID_AMOUNT); @@ -348,6 +350,9 @@ library ValidationLogic { DataTypes.ReserveData storage reserve ) external view { uint256 underlyingBalance = IERC20(reserve.aTokenAddress).balanceOf(msg.sender); + bool isPaused = reserve.configuration.getPaused(); + + require(!isPaused, Errors.VL_RESERVE_PAUSED); require(underlyingBalance > 0, Errors.VL_UNDERLYING_BALANCE_NOT_GREATER_THAN_0); } @@ -357,7 +362,17 @@ library ValidationLogic { * @param assets The assets being flashborrowed * @param amounts The amounts for each asset being borrowed **/ - function validateFlashloan(address[] memory assets, uint256[] memory amounts) internal pure { + function validateFlashloan( + address[] memory assets, + uint256[] memory amounts, + mapping(address => DataTypes.ReserveData) storage reservesData + ) internal view { + for (uint i = 0; i < assets.length; i++) { + require( + !reservesData[assets[i]].configuration.getPaused(), + Errors.VL_RESERVE_PAUSED + ); + } require(assets.length == amounts.length, Errors.VL_INCONSISTENT_FLASHLOAN_PARAMS); } @@ -386,6 +401,14 @@ library ValidationLogic { Errors.VL_NO_ACTIVE_RESERVE ); } + if ( + collateralReserve.configuration.getPaused() || principalReserve.configuration.getPaused() + ) { + return ( + uint256(Errors.CollateralManagerErrors.PAUSED_RESERVE), + Errors.VL_RESERVE_PAUSED + ); + } if (userHealthFactor >= GenericLogic.HEALTH_FACTOR_LIQUIDATION_THRESHOLD) { return ( @@ -426,6 +449,7 @@ library ValidationLogic { * @param oracle The price oracle */ function validateHealthFactor( + address reserveAddress, address from, mapping(address => DataTypes.ReserveData) storage reservesData, DataTypes.UserConfigurationMap storage userConfig, @@ -433,6 +457,8 @@ library ValidationLogic { uint256 reservesCount, address oracle ) internal view { + bool isPaused = reservesData[reserveAddress].configuration.getPaused(); + require(!isPaused, Errors.VL_RESERVE_PAUSED); (, , , , uint256 healthFactor) = GenericLogic.calculateUserAccountData( from,