Merge branch 'protocol-2.5' into feat/2.5-remove-global-pause

This commit is contained in:
emilio 2021-07-11 19:30:32 +02:00
commit 92e4cf1013
5 changed files with 52 additions and 34 deletions

View File

@ -350,7 +350,7 @@ interface ILendingPoolConfigurator {
function unfreezeReserve(address asset) external; function unfreezeReserve(address asset) external;
/** /**
* @dev Pauses/Unpauses a reserve. A paused reserve allow now user moves such as deposit, borrow, repay, swap interestrate, liquidate * @dev Pauses a reserve. A paused reserve does not allow any interaction (deposit, borrow, repay, swap interestrate, liquidate, atoken transfers)
* @param asset The address of the underlying asset of the reserve * @param asset The address of the underlying asset of the reserve
* @param val true = pausing, false = unpausing * @param val true = pausing, false = unpausing
**/ **/

View File

@ -269,7 +269,9 @@ contract LendingPool is VersionedInitializable, ILendingPool, LendingPoolStorage
DataTypes.ReserveData storage reserve = _reserves[asset]; DataTypes.ReserveData storage reserve = _reserves[asset];
DataTypes.ReserveCache memory reserveCache = reserve.cache(); DataTypes.ReserveCache memory reserveCache = reserve.cache();
ValidationLogic.validateSetUseReserveAsCollateral(reserveCache); uint256 userBalance = IERC20(reserveCache.aTokenAddress).balanceOf(msg.sender);
ValidationLogic.validateSetUseReserveAsCollateral(reserveCache, userBalance);
_usersConfig[msg.sender].setUsingAsCollateral(reserve.id, useAsCollateral); _usersConfig[msg.sender].setUsingAsCollateral(reserve.id, useAsCollateral);
@ -278,6 +280,7 @@ contract LendingPool is VersionedInitializable, ILendingPool, LendingPoolStorage
} else { } else {
ValidationLogic.validateHFAndExposureCap( ValidationLogic.validateHFAndExposureCap(
asset, asset,
userBalance,
msg.sender, msg.sender,
_reserves, _reserves,
_usersConfig[msg.sender], _usersConfig[msg.sender],
@ -614,6 +617,7 @@ contract LendingPool is VersionedInitializable, ILendingPool, LendingPoolStorage
if (fromConfig.isBorrowingAny()) { if (fromConfig.isBorrowingAny()) {
ValidationLogic.validateHFAndExposureCap( ValidationLogic.validateHFAndExposureCap(
asset, asset,
amount,
from, from,
_reserves, _reserves,
_usersConfig[from], _usersConfig[from],
@ -852,6 +856,7 @@ contract LendingPool is VersionedInitializable, ILendingPool, LendingPoolStorage
if (userConfig.isBorrowingAny()) { if (userConfig.isBorrowingAny()) {
ValidationLogic.validateHFAndExposureCap( ValidationLogic.validateHFAndExposureCap(
asset, asset,
0,
msg.sender, msg.sender,
_reserves, _reserves,
userConfig, userConfig,

View File

@ -407,14 +407,14 @@ contract LendingPoolConfigurator is VersionedInitializable, ILendingPoolConfigur
} }
/// @inheritdoc ILendingPoolConfigurator /// @inheritdoc ILendingPoolConfigurator
function setReservePause(address asset, bool val) public override onlyEmergencyOrPoolAdmin { function setReservePause(address asset, bool paused) public override onlyEmergencyOrPoolAdmin {
DataTypes.ReserveConfigurationMap memory currentConfig = _pool.getConfiguration(asset); DataTypes.ReserveConfigurationMap memory currentConfig = _pool.getConfiguration(asset);
currentConfig.setPaused(val); currentConfig.setPaused(paused);
_pool.setConfiguration(asset, currentConfig.data); _pool.setConfiguration(asset, currentConfig.data);
if (val) { if (paused) {
emit ReservePaused(asset); emit ReservePaused(asset);
} else { } else {
emit ReserveUnpaused(asset); emit ReserveUnpaused(asset);
@ -484,11 +484,13 @@ contract LendingPoolConfigurator is VersionedInitializable, ILendingPoolConfigur
} }
/// @inheritdoc ILendingPoolConfigurator /// @inheritdoc ILendingPoolConfigurator
function setPoolPause(bool val) external override onlyEmergencyAdmin { function setPoolPause(bool paused) external override onlyEmergencyAdmin {
address[] memory reserves = _pool.getReservesList(); address[] memory reserves = _pool.getReservesList();
for (uint256 i = 0; i < reserves.length; i++) { for (uint256 i = 0; i < reserves.length; i++) {
setReservePause(reserves[i], val); if (reserves[i] != address(0)) { //might happen is a reserve was dropped
setReservePause(reserves[i], paused);
}
} }
} }

View File

@ -186,6 +186,7 @@ library ValidationLogic {
vars.currentLtv, vars.currentLtv,
vars.currentLiquidationThreshold, vars.currentLiquidationThreshold,
vars.healthFactor, vars.healthFactor,
) = GenericLogic.calculateUserAccountData( ) = GenericLogic.calculateUserAccountData(
userAddress, userAddress,
reservesData, reservesData,
@ -387,17 +388,16 @@ library ValidationLogic {
* @dev Validates the action of setting an asset as collateral * @dev Validates the action of setting an asset as collateral
* @param reserveCache The cached data of the reserve * @param reserveCache The cached data of the reserve
*/ */
function validateSetUseReserveAsCollateral(DataTypes.ReserveCache memory reserveCache) function validateSetUseReserveAsCollateral(
external DataTypes.ReserveCache memory reserveCache,
view uint256 userBalance
{ ) external pure {
uint256 underlyingBalance = IERC20(reserveCache.aTokenAddress).balanceOf(msg.sender);
(bool isActive, , , , bool isPaused) = reserveCache.reserveConfiguration.getFlagsMemory(); (bool isActive, , , , bool isPaused) = reserveCache.reserveConfiguration.getFlagsMemory();
require(isActive, Errors.VL_NO_ACTIVE_RESERVE); require(isActive, Errors.VL_NO_ACTIVE_RESERVE);
require(!isPaused, Errors.VL_RESERVE_PAUSED); require(!isPaused, Errors.VL_RESERVE_PAUSED);
require(underlyingBalance > 0, Errors.VL_UNDERLYING_BALANCE_NOT_GREATER_THAN_0); require(userBalance > 0, Errors.VL_UNDERLYING_BALANCE_NOT_GREATER_THAN_0);
} }
/** /**
@ -507,8 +507,19 @@ library ValidationLogic {
return (uint256(Errors.CollateralManagerErrors.NO_ERROR), Errors.LPCM_NO_ERRORS); return (uint256(Errors.CollateralManagerErrors.NO_ERROR), Errors.LPCM_NO_ERRORS);
} }
struct validateHFAndExposureCapLocalVars {
uint256 healthFactor;
uint256 ltv;
uint256 uncappedLtv;
uint256 exposureCap;
uint256 reserveDecimals;
uint256 totalSupplyAtoken;
}
/** /**
* @dev Validates the health factor of a user and the exposure cap for the asset being withdrawn * @dev Validates the health factor of a user and the exposure cap for the asset being withdrawn
* @param asset The asset for which the exposure cap will be validated
* @param expCapOffset The offset to consider on the total atoken supply of asset when validating the exposure cap
* @param from The user from which the aTokens are being transferred * @param from The user from which the aTokens are being transferred
* @param reservesData The state of all the reserves * @param reservesData The state of all the reserves
* @param userConfig The state of the user for the specific reserve * @param userConfig The state of the user for the specific reserve
@ -517,7 +528,8 @@ library ValidationLogic {
* @param oracle The price oracle * @param oracle The price oracle
*/ */
function validateHFAndExposureCap( function validateHFAndExposureCap(
address collateral, address asset,
uint256 expCapOffset,
address from, address from,
mapping(address => DataTypes.ReserveData) storage reservesData, mapping(address => DataTypes.ReserveData) storage reservesData,
DataTypes.UserConfigurationMap storage userConfig, DataTypes.UserConfigurationMap storage userConfig,
@ -525,30 +537,31 @@ library ValidationLogic {
uint256 reservesCount, uint256 reservesCount,
address oracle address oracle
) external view { ) external view {
DataTypes.ReserveData memory reserve = reservesData[collateral]; validateHFAndExposureCapLocalVars memory vars;
(, , uint256 ltv, uint256 liquidationThreshold, uint256 healthFactor, uint256 uncappedLtv) = DataTypes.ReserveData memory reserve = reservesData[asset];
GenericLogic.calculateUserAccountData( (, , vars.ltv, , vars.healthFactor, vars.uncappedLtv) = GenericLogic.calculateUserAccountData(
from, from,
reservesData, reservesData,
userConfig, userConfig,
reserves, reserves,
reservesCount, reservesCount,
oracle oracle
); );
require( require(
healthFactor >= GenericLogic.HEALTH_FACTOR_LIQUIDATION_THRESHOLD, vars.healthFactor >= GenericLogic.HEALTH_FACTOR_LIQUIDATION_THRESHOLD,
Errors.VL_HEALTH_FACTOR_LOWER_THAN_LIQUIDATION_THRESHOLD Errors.VL_HEALTH_FACTOR_LOWER_THAN_LIQUIDATION_THRESHOLD
); );
uint256 exposureCap = reserve.configuration.getExposureCapMemory(); vars.exposureCap = reserve.configuration.getExposureCapMemory();
if (exposureCap != 0) { if (vars.exposureCap != 0) {
if (ltv < uncappedLtv) { if (vars.ltv < vars.uncappedLtv) {
uint256 totalSupplyAtoken = IERC20(reserve.aTokenAddress).totalSupply(); vars.totalSupplyAtoken = IERC20(reserve.aTokenAddress).totalSupply();
(, , , uint256 reserveDecimals, ) = reserve.configuration.getParamsMemory(); (, , , vars.reserveDecimals, ) = reserve.configuration.getParamsMemory();
bool isAssetCapped = totalSupplyAtoken.div(10**reserveDecimals) >= exposureCap; bool isAssetCapped =
vars.totalSupplyAtoken.sub(expCapOffset).div(10**vars.reserveDecimals) >=
vars.exposureCap;
require(isAssetCapped, Errors.VL_COLLATERAL_EXPOSURE_CAP_EXCEEDED); require(isAssetCapped, Errors.VL_COLLATERAL_EXPOSURE_CAP_EXCEEDED);
} }
} }

View File

@ -61,8 +61,6 @@ makeSuite('Mint to treasury', (testEnv: TestEnv) => {
const { accruedToTreasury } = await pool.getReserveData(dai.address); const { accruedToTreasury } = await pool.getReserveData(dai.address);
console.log("Accrued to treasury ", accruedToTreasury.toString());
expect(accruedToTreasury.toString()).to.be.bignumber.almostEqual( expect(accruedToTreasury.toString()).to.be.bignumber.almostEqual(
expectedAccruedToTreasury, expectedAccruedToTreasury,
'Invalid amount accrued to the treasury' 'Invalid amount accrued to the treasury'