From 9f110e1d19766c23383318b0f94808631d1c35c3 Mon Sep 17 00:00:00 2001 From: Hadrien Charlanes Date: Wed, 30 Jun 2021 18:31:43 +0200 Subject: [PATCH 1/9] fix: protected against disable as collateral + withdraw --- contracts/protocol/lendingpool/LendingPool.sol | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/contracts/protocol/lendingpool/LendingPool.sol b/contracts/protocol/lendingpool/LendingPool.sol index 1bb6b684..57a60d8a 100644 --- a/contracts/protocol/lendingpool/LendingPool.sol +++ b/contracts/protocol/lendingpool/LendingPool.sol @@ -498,6 +498,7 @@ contract LendingPool is VersionedInitializable, ILendingPool, LendingPoolStorage ltv, currentLiquidationThreshold, healthFactor, + ) = GenericLogic.getUserAccountData( user, _reserves, @@ -875,7 +876,7 @@ contract LendingPool is VersionedInitializable, ILendingPool, LendingPoolStorage reserveCache.nextLiquidityIndex ); - if (userConfig.isUsingAsCollateral(reserve.id)) { + if (reserve.configuration.getLtv() > 0) { if (userConfig.isBorrowingAny()) { ValidationLogic.validateHFAndExposureCap( asset, From 716d1ce68d14f5665d1388a63c3617bd8b0474bc Mon Sep 17 00:00:00 2001 From: Hadrien Charlanes Date: Thu, 1 Jul 2021 10:29:40 +0200 Subject: [PATCH 2/9] fix: protected against disable as collateral + withdraw/transfer --- .../protocol/lendingpool/LendingPool.sol | 5 +- .../libraries/logic/ValidationLogic.sol | 46 ++++++++++++------- 2 files changed, 33 insertions(+), 18 deletions(-) diff --git a/contracts/protocol/lendingpool/LendingPool.sol b/contracts/protocol/lendingpool/LendingPool.sol index 57a60d8a..cb4bf47e 100644 --- a/contracts/protocol/lendingpool/LendingPool.sol +++ b/contracts/protocol/lendingpool/LendingPool.sol @@ -291,6 +291,7 @@ contract LendingPool is VersionedInitializable, ILendingPool, LendingPoolStorage } else { ValidationLogic.validateHFAndExposureCap( asset, + IERC20(reserveCache.aTokenAddress).balanceOf(msg.sender), msg.sender, _reserves, _usersConfig[msg.sender], @@ -632,6 +633,7 @@ contract LendingPool is VersionedInitializable, ILendingPool, LendingPoolStorage if (fromConfig.isBorrowingAny()) { ValidationLogic.validateHFAndExposureCap( asset, + 0, from, _reserves, _usersConfig[from], @@ -876,10 +878,11 @@ contract LendingPool is VersionedInitializable, ILendingPool, LendingPoolStorage reserveCache.nextLiquidityIndex ); - if (reserve.configuration.getLtv() > 0) { + if (userConfig.isUsingAsCollateral(reserve.id)) { if (userConfig.isBorrowingAny()) { ValidationLogic.validateHFAndExposureCap( asset, + 0, msg.sender, _reserves, userConfig, diff --git a/contracts/protocol/libraries/logic/ValidationLogic.sol b/contracts/protocol/libraries/logic/ValidationLogic.sol index 42fee42a..f653ad23 100644 --- a/contracts/protocol/libraries/logic/ValidationLogic.sol +++ b/contracts/protocol/libraries/logic/ValidationLogic.sol @@ -186,6 +186,7 @@ library ValidationLogic { vars.currentLtv, vars.currentLiquidationThreshold, vars.healthFactor, + ) = GenericLogic.calculateUserAccountData( userAddress, reservesData, @@ -507,6 +508,15 @@ library ValidationLogic { 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 * @param from The user from which the aTokens are being transferred @@ -518,6 +528,7 @@ library ValidationLogic { */ function validateHFAndExposureCap( address collateral, + uint256 collateralToBeWithdrawn, address from, mapping(address => DataTypes.ReserveData) storage reservesData, DataTypes.UserConfigurationMap storage userConfig, @@ -525,30 +536,31 @@ library ValidationLogic { uint256 reservesCount, address oracle ) external view { + validateHFAndExposureCapLocalVars memory vars; DataTypes.ReserveData memory reserve = reservesData[collateral]; - (, , uint256 ltv, uint256 liquidationThreshold, uint256 healthFactor, uint256 uncappedLtv) = - GenericLogic.calculateUserAccountData( - from, - reservesData, - userConfig, - reserves, - reservesCount, - oracle - ); - + (, , vars.ltv, , vars.healthFactor, vars.uncappedLtv) = GenericLogic.calculateUserAccountData( + from, + reservesData, + userConfig, + reserves, + reservesCount, + oracle + ); require( - healthFactor >= GenericLogic.HEALTH_FACTOR_LIQUIDATION_THRESHOLD, + vars.healthFactor >= GenericLogic.HEALTH_FACTOR_LIQUIDATION_THRESHOLD, Errors.VL_HEALTH_FACTOR_LOWER_THAN_LIQUIDATION_THRESHOLD ); - uint256 exposureCap = reserve.configuration.getExposureCapMemory(); + vars.exposureCap = reserve.configuration.getExposureCapMemory(); - if (exposureCap != 0) { - if (ltv < uncappedLtv) { - uint256 totalSupplyAtoken = IERC20(reserve.aTokenAddress).totalSupply(); - (, , , uint256 reserveDecimals, ) = reserve.configuration.getParamsMemory(); - bool isAssetCapped = totalSupplyAtoken.div(10**reserveDecimals) >= exposureCap; + if (vars.exposureCap != 0) { + if (vars.ltv < vars.uncappedLtv) { + vars.totalSupplyAtoken = IERC20(reserve.aTokenAddress).totalSupply(); + (, , , vars.reserveDecimals, ) = reserve.configuration.getParamsMemory(); + bool isAssetCapped = + vars.totalSupplyAtoken.sub(collateralToBeWithdrawn).div(10**vars.reserveDecimals) >= + vars.exposureCap; require(isAssetCapped, Errors.VL_COLLATERAL_EXPOSURE_CAP_EXCEEDED); } } From 66165c4fdd90a571602a75ac8d2d5189dcd8fbb9 Mon Sep 17 00:00:00 2001 From: Hadrien Charlanes Date: Thu, 1 Jul 2021 14:15:40 +0200 Subject: [PATCH 3/9] refactor: refactored the pause pool funciton. From global pause to reserve local pauses --- .../interfaces/ILendingPoolConfigurator.sol | 12 +++---- .../protocol/lendingpool/LendingPool.sol | 34 ++++++------------- .../lendingpool/LendingPoolConfigurator.sol | 27 +++++++-------- .../lendingpool/LendingPoolStorage.sol | 2 ++ test-suites/test-aave/configurator.spec.ts | 24 ++++++------- 5 files changed, 41 insertions(+), 58 deletions(-) diff --git a/contracts/interfaces/ILendingPoolConfigurator.sol b/contracts/interfaces/ILendingPoolConfigurator.sol index e3803ae6..0526a4f2 100644 --- a/contracts/interfaces/ILendingPoolConfigurator.sol +++ b/contracts/interfaces/ILendingPoolConfigurator.sol @@ -350,16 +350,11 @@ interface ILendingPoolConfigurator { function unfreezeReserve(address asset) external; /** - * @dev Pauses a reserve. A paused reserve allow now user moves such as deposit, borrow, repay, swap interestrate, liquidate + * @dev Pauses/Unpauses a reserve. A paused reserve allow now user moves such as deposit, borrow, repay, swap interestrate, liquidate * @param asset The address of the underlying asset of the reserve + * @param val true = pausing, false = unpausing **/ - function pauseReserve(address asset) external; - - /** - * @dev Unpauses a reserve - * @param asset The address of the underlying asset of the reserve - **/ - function unpauseReserve(address asset) external; + function setReservePause(address asset, bool val) external; /** * @dev Updates the reserve factor of a reserve @@ -378,6 +373,7 @@ interface ILendingPoolConfigurator { /** * @dev pauses or unpauses all the actions of the protocol, including aToken transfers + * Effectively it pauses every reserve * @param val true if protocol needs to be paused, false otherwise **/ function setPoolPause(bool val) external; diff --git a/contracts/protocol/lendingpool/LendingPool.sol b/contracts/protocol/lendingpool/LendingPool.sol index 1bb6b684..6355d01e 100644 --- a/contracts/protocol/lendingpool/LendingPool.sol +++ b/contracts/protocol/lendingpool/LendingPool.sol @@ -53,20 +53,11 @@ contract LendingPool is VersionedInitializable, ILendingPool, LendingPoolStorage uint256 public constant LENDINGPOOL_REVISION = 0x2; - modifier whenNotPaused() { - _whenNotPaused(); - _; - } - modifier onlyLendingPoolConfigurator() { _onlyLendingPoolConfigurator(); _; } - function _whenNotPaused() internal view { - require(!_paused, Errors.LP_IS_PAUSED); - } - function _onlyLendingPoolConfigurator() internal view { require( _addressesProvider.getLendingPoolConfigurator() == msg.sender, @@ -99,7 +90,7 @@ contract LendingPool is VersionedInitializable, ILendingPool, LendingPoolStorage uint256 amount, address onBehalfOf, uint16 referralCode - ) external override whenNotPaused { + ) external override { _executeDeposit(asset, amount, onBehalfOf, referralCode); } @@ -131,7 +122,7 @@ contract LendingPool is VersionedInitializable, ILendingPool, LendingPoolStorage address asset, uint256 amount, address to - ) external override whenNotPaused returns (uint256) { + ) external override returns (uint256) { return _executeWithdraw(asset, amount, to); } @@ -142,7 +133,7 @@ contract LendingPool is VersionedInitializable, ILendingPool, LendingPoolStorage uint256 interestRateMode, uint16 referralCode, address onBehalfOf - ) external override whenNotPaused { + ) external override { _executeBorrow( ExecuteBorrowParams( asset, @@ -162,7 +153,7 @@ contract LendingPool is VersionedInitializable, ILendingPool, LendingPoolStorage uint256 amount, uint256 rateMode, address onBehalfOf - ) external override whenNotPaused returns (uint256) { + ) external override returns (uint256) { return _executeRepay(asset, amount, rateMode, onBehalfOf); } @@ -190,7 +181,7 @@ contract LendingPool is VersionedInitializable, ILendingPool, LendingPoolStorage } ///@inheritdoc ILendingPool - function swapBorrowRateMode(address asset, uint256 rateMode) external override whenNotPaused { + function swapBorrowRateMode(address asset, uint256 rateMode) external override { DataTypes.ReserveData storage reserve = _reserves[asset]; DataTypes.ReserveCache memory reserveCache = reserve.cache(); @@ -239,7 +230,7 @@ contract LendingPool is VersionedInitializable, ILendingPool, LendingPoolStorage } ///@inheritdoc ILendingPool - function rebalanceStableBorrowRate(address asset, address user) external override whenNotPaused { + function rebalanceStableBorrowRate(address asset, address user) external override { DataTypes.ReserveData storage reserve = _reserves[asset]; DataTypes.ReserveCache memory reserveCache = reserve.cache(); @@ -274,11 +265,7 @@ contract LendingPool is VersionedInitializable, ILendingPool, LendingPoolStorage } ///@inheritdoc ILendingPool - function setUserUseReserveAsCollateral(address asset, bool useAsCollateral) - external - override - whenNotPaused - { + function setUserUseReserveAsCollateral(address asset, bool useAsCollateral) external override { DataTypes.ReserveData storage reserve = _reserves[asset]; DataTypes.ReserveCache memory reserveCache = reserve.cache(); @@ -310,7 +297,7 @@ contract LendingPool is VersionedInitializable, ILendingPool, LendingPoolStorage address user, uint256 debtToCover, bool receiveAToken - ) external override whenNotPaused { + ) external override { address collateralManager = _addressesProvider.getLendingPoolCollateralManager(); //solium-disable-next-line @@ -359,7 +346,7 @@ contract LendingPool is VersionedInitializable, ILendingPool, LendingPoolStorage address onBehalfOf, bytes calldata params, uint16 referralCode - ) external override whenNotPaused { + ) external override { FlashLoanLocalVars memory vars; vars.aTokenAddresses = new address[](assets.length); @@ -498,6 +485,7 @@ contract LendingPool is VersionedInitializable, ILendingPool, LendingPoolStorage ltv, currentLiquidationThreshold, healthFactor, + ) = GenericLogic.getUserAccountData( user, _reserves, @@ -617,7 +605,7 @@ contract LendingPool is VersionedInitializable, ILendingPool, LendingPoolStorage uint256 amount, uint256 balanceFromBefore, uint256 balanceToBefore - ) external override whenNotPaused { + ) external override { require(msg.sender == _reserves[asset].aTokenAddress, Errors.LP_CALLER_MUST_BE_AN_ATOKEN); ValidationLogic.validateTransfer(_reserves[asset]); diff --git a/contracts/protocol/lendingpool/LendingPoolConfigurator.sol b/contracts/protocol/lendingpool/LendingPoolConfigurator.sol index 6cbfc0f3..4affa47a 100644 --- a/contracts/protocol/lendingpool/LendingPoolConfigurator.sol +++ b/contracts/protocol/lendingpool/LendingPoolConfigurator.sol @@ -407,25 +407,18 @@ contract LendingPoolConfigurator is VersionedInitializable, ILendingPoolConfigur } /// @inheritdoc ILendingPoolConfigurator - function pauseReserve(address asset) external override onlyEmergencyOrPoolAdmin { + function setReservePause(address asset, bool val) public override onlyEmergencyOrPoolAdmin { DataTypes.ReserveConfigurationMap memory currentConfig = _pool.getConfiguration(asset); - currentConfig.setPaused(true); + currentConfig.setPaused(val); _pool.setConfiguration(asset, currentConfig.data); - emit ReservePaused(asset); - } - - /// @inheritdoc ILendingPoolConfigurator - function unpauseReserve(address asset) external override onlyEmergencyOrPoolAdmin { - DataTypes.ReserveConfigurationMap memory currentConfig = _pool.getConfiguration(asset); - - currentConfig.setPaused(false); - - _pool.setConfiguration(asset, currentConfig.data); - - emit ReserveUnpaused(asset); + if (val) { + emit ReservePaused(asset); + } else { + emit ReserveUnpaused(asset); + } } /// @inheritdoc ILendingPoolConfigurator @@ -492,7 +485,11 @@ contract LendingPoolConfigurator is VersionedInitializable, ILendingPoolConfigur /// @inheritdoc ILendingPoolConfigurator function setPoolPause(bool val) external override onlyEmergencyAdmin { - _pool.setPause(val); + address[] memory reserves = _pool.getReservesList(); + + for (uint256 i = 0; i < reserves.length; i++) { + setReservePause(reserves[i], val); + } } /// @inheritdoc ILendingPoolConfigurator diff --git a/contracts/protocol/lendingpool/LendingPoolStorage.sol b/contracts/protocol/lendingpool/LendingPoolStorage.sol index 6289e008..c791e3cf 100644 --- a/contracts/protocol/lendingpool/LendingPoolStorage.sol +++ b/contracts/protocol/lendingpool/LendingPoolStorage.sol @@ -22,6 +22,8 @@ contract LendingPoolStorage { uint256 internal _reservesCount; + // Deprecated: global LendingPool pause state, no longer used + // Replaced by pause states for each reserve bool internal _paused; uint256 internal _maxStableRateBorrowSizePercent; diff --git a/test-suites/test-aave/configurator.spec.ts b/test-suites/test-aave/configurator.spec.ts index c3eb05d0..4eeab7bc 100644 --- a/test-suites/test-aave/configurator.spec.ts +++ b/test-suites/test-aave/configurator.spec.ts @@ -75,7 +75,7 @@ makeSuite('LendingPoolConfigurator', (testEnv: TestEnv) => { expect(await configurator.signer.getAddress()).to.be.equal( await addressesProvider.getPoolAdmin() ); - await configurator.pauseReserve(weth.address); + await configurator.setReservePause(weth.address, true); const { decimals, ltv, @@ -106,7 +106,7 @@ makeSuite('LendingPoolConfigurator', (testEnv: TestEnv) => { it('Unpauses the ETH reserve by pool admin ', async () => { const { configurator, helpersContract, weth } = testEnv; - await configurator.unpauseReserve(weth.address); + await configurator.setReservePause(weth.address, false); const { decimals, @@ -138,7 +138,7 @@ makeSuite('LendingPoolConfigurator', (testEnv: TestEnv) => { it('Pauses the ETH reserve by emergency admin', async () => { const { configurator, weth, helpersContract, addressesProvider, users, emergencyAdmin } = testEnv; - await configurator.connect(emergencyAdmin.signer).pauseReserve(weth.address); + await configurator.connect(emergencyAdmin.signer).setReservePause(weth.address, true); const { decimals, ltv, @@ -169,7 +169,7 @@ makeSuite('LendingPoolConfigurator', (testEnv: TestEnv) => { it('Unpauses the ETH reserve by emergency admin ', async () => { const { configurator, helpersContract, weth, users, emergencyAdmin } = testEnv; - await configurator.connect(emergencyAdmin.signer).unpauseReserve(weth.address); + await configurator.connect(emergencyAdmin.signer).setReservePause(weth.address, false); const { decimals, @@ -202,7 +202,7 @@ makeSuite('LendingPoolConfigurator', (testEnv: TestEnv) => { it('Check the only admin or emergency admin can pauseReserve ', async () => { const { configurator, users, weth, riskAdmin } = testEnv; await expect( - configurator.connect(riskAdmin.signer).pauseReserve(weth.address), + configurator.connect(riskAdmin.signer).setReservePause(weth.address, true), CALLER_NOT_POOL_ADMIN ).to.be.revertedWith(LPC_CALLER_NOT_EMERGENCY_OR_POOL_ADMIN); }); @@ -210,14 +210,14 @@ makeSuite('LendingPoolConfigurator', (testEnv: TestEnv) => { it('Check the only admin or emergency admin can unpauseReserve ', async () => { const { configurator, users, weth, riskAdmin } = testEnv; await expect( - configurator.connect(riskAdmin.signer).unpauseReserve(weth.address), + configurator.connect(riskAdmin.signer).setReservePause(weth.address, false), CALLER_NOT_POOL_ADMIN ).to.be.revertedWith(LPC_CALLER_NOT_EMERGENCY_OR_POOL_ADMIN); }); it('Pauses the ETH reserve by the pool admin', async () => { const { configurator, weth, helpersContract, addressesProvider, users, emergencyAdmin } = testEnv; - await configurator.pauseReserve(weth.address); + await configurator.setReservePause(weth.address, true); const { decimals, ltv, @@ -251,7 +251,7 @@ makeSuite('LendingPoolConfigurator', (testEnv: TestEnv) => { it('Unpauses the ETH reserve by pool admin ', async () => { const { configurator, helpersContract, weth } = testEnv; - await configurator.unpauseReserve(weth.address); + await configurator.setReservePause(weth.address, false); const { decimals, @@ -286,7 +286,7 @@ makeSuite('LendingPoolConfigurator', (testEnv: TestEnv) => { it('Pauses the ETH reserve by emergency admin', async () => { const { configurator, weth, helpersContract, addressesProvider, users, emergencyAdmin } = testEnv; - await configurator.connect(emergencyAdmin.signer).pauseReserve(weth.address); + await configurator.connect(emergencyAdmin.signer).setReservePause(weth.address, true); const { decimals, ltv, @@ -320,7 +320,7 @@ makeSuite('LendingPoolConfigurator', (testEnv: TestEnv) => { it('Unpauses the ETH reserve by emergency admin ', async () => { const { configurator, helpersContract, weth, users, emergencyAdmin } = testEnv; - await configurator.connect(emergencyAdmin.signer).unpauseReserve(weth.address); + await configurator.connect(emergencyAdmin.signer).setReservePause(weth.address, false); const { decimals, @@ -356,7 +356,7 @@ makeSuite('LendingPoolConfigurator', (testEnv: TestEnv) => { it('Check the only admin or emergency admin can pauseReserve ', async () => { const { configurator, users, weth, riskAdmin } = testEnv; await expect( - configurator.connect(riskAdmin.signer).pauseReserve(weth.address), + configurator.connect(riskAdmin.signer).setReservePause(weth.address, true), CALLER_NOT_POOL_ADMIN ).to.be.revertedWith(LPC_CALLER_NOT_EMERGENCY_OR_POOL_ADMIN); }); @@ -364,7 +364,7 @@ makeSuite('LendingPoolConfigurator', (testEnv: TestEnv) => { it('Check the only admin or emergency admin can unpauseReserve ', async () => { const { configurator, users, weth, riskAdmin } = testEnv; await expect( - configurator.connect(riskAdmin.signer).unpauseReserve(weth.address), + configurator.connect(riskAdmin.signer).setReservePause(weth.address, false), CALLER_NOT_POOL_ADMIN ).to.be.revertedWith(LPC_CALLER_NOT_EMERGENCY_OR_POOL_ADMIN); }); From 79a8d2bba646e83724657742ca14596df83b3dfa Mon Sep 17 00:00:00 2001 From: Hadrien Charlanes Date: Thu, 1 Jul 2021 16:50:17 +0200 Subject: [PATCH 4/9] doc: added deprecated notice --- contracts/protocol/libraries/helpers/Errors.sol | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/contracts/protocol/libraries/helpers/Errors.sol b/contracts/protocol/libraries/helpers/Errors.sol index 6f4fdb4d..53e966c3 100644 --- a/contracts/protocol/libraries/helpers/Errors.sol +++ b/contracts/protocol/libraries/helpers/Errors.sol @@ -87,7 +87,7 @@ library Errors { string public constant LP_INVALID_EQUAL_ASSETS_TO_SWAP = '61'; string public constant LP_REENTRANCY_NOT_ALLOWED = '62'; string public constant LP_CALLER_MUST_BE_AN_ATOKEN = '63'; - string public constant LP_IS_PAUSED = '64'; // 'Pool is paused' + string public constant LP_IS_PAUSED = '64'; // Deprecated 'Pool is paused' string public constant LP_NO_MORE_RESERVES_ALLOWED = '65'; string public constant LP_INVALID_FLASH_LOAN_EXECUTOR_RETURN = '66'; string public constant RC_INVALID_LTV = '67'; From 8d020df60c52bdaecd9dd54f460d9d3ac2f8f7b8 Mon Sep 17 00:00:00 2001 From: Hadrien Charlanes Date: Thu, 1 Jul 2021 16:53:06 +0200 Subject: [PATCH 5/9] refactor: adapted tests to new way of pausing LendingPool through pausing all reserves --- .../test-aave/liquidation-atoken.spec.ts | 1 - .../test-aave/pausable-functions.spec.ts | 27 ++++++++++--------- .../test-amm/liquidation-atoken.spec.ts | 1 - .../test-amm/pausable-functions.spec.ts | 22 +++++++-------- 4 files changed, 26 insertions(+), 25 deletions(-) diff --git a/test-suites/test-aave/liquidation-atoken.spec.ts b/test-suites/test-aave/liquidation-atoken.spec.ts index 1b6f9911..00ad07be 100644 --- a/test-suites/test-aave/liquidation-atoken.spec.ts +++ b/test-suites/test-aave/liquidation-atoken.spec.ts @@ -17,7 +17,6 @@ makeSuite('LendingPool liquidation - liquidator receiving aToken', (testEnv) => INVALID_HF, LPCM_SPECIFIED_CURRENCY_NOT_BORROWED_BY_USER, LPCM_COLLATERAL_CANNOT_BE_LIQUIDATED, - LP_IS_PAUSED, } = ProtocolErrors; it('Deposits WETH, borrows DAI/Check liquidation fails because health factor is above 1', async () => { diff --git a/test-suites/test-aave/pausable-functions.spec.ts b/test-suites/test-aave/pausable-functions.spec.ts index 24bedb69..54b318e7 100644 --- a/test-suites/test-aave/pausable-functions.spec.ts +++ b/test-suites/test-aave/pausable-functions.spec.ts @@ -12,8 +12,11 @@ const { expect } = require('chai'); makeSuite('Pausable Pool', (testEnv: TestEnv) => { let _mockFlashLoanReceiver = {} as MockFlashLoanReceiver; - const { LP_IS_PAUSED, INVALID_FROM_BALANCE_AFTER_TRANSFER, INVALID_TO_BALANCE_AFTER_TRANSFER } = - ProtocolErrors; + const { + VL_RESERVE_PAUSED, + INVALID_FROM_BALANCE_AFTER_TRANSFER, + INVALID_TO_BALANCE_AFTER_TRANSFER, + } = ProtocolErrors; before(async () => { _mockFlashLoanReceiver = await getMockFlashLoanReceiver(); @@ -41,7 +44,7 @@ makeSuite('Pausable Pool', (testEnv: TestEnv) => { // User 0 tries the transfer to User 1 await expect( aDai.connect(users[0].signer).transfer(users[1].address, amountDAItoDeposit) - ).to.revertedWith(LP_IS_PAUSED); + ).to.revertedWith(VL_RESERVE_PAUSED); const pausedFromBalance = await aDai.balanceOf(users[0].address); const pausedToBalance = await aDai.balanceOf(users[1].address); @@ -88,7 +91,7 @@ makeSuite('Pausable Pool', (testEnv: TestEnv) => { await configurator.connect(users[1].signer).setPoolPause(true); await expect( pool.connect(users[0].signer).deposit(dai.address, amountDAItoDeposit, users[0].address, '0') - ).to.revertedWith(LP_IS_PAUSED); + ).to.revertedWith(VL_RESERVE_PAUSED); // Configurator unpauses the pool await configurator.connect(users[1].signer).setPoolPause(false); @@ -113,7 +116,7 @@ makeSuite('Pausable Pool', (testEnv: TestEnv) => { // user tries to burn await expect( pool.connect(users[0].signer).withdraw(dai.address, amountDAItoDeposit, users[0].address) - ).to.revertedWith(LP_IS_PAUSED); + ).to.revertedWith(VL_RESERVE_PAUSED); // Configurator unpauses the pool await configurator.connect(users[1].signer).setPoolPause(false); @@ -129,7 +132,7 @@ makeSuite('Pausable Pool', (testEnv: TestEnv) => { // Try to execute liquidation await expect( pool.connect(user.signer).borrow(dai.address, '1', '1', '0', user.address) - ).revertedWith(LP_IS_PAUSED); + ).revertedWith(VL_RESERVE_PAUSED); // Unpause the pool await configurator.connect(users[1].signer).setPoolPause(false); @@ -144,7 +147,7 @@ makeSuite('Pausable Pool', (testEnv: TestEnv) => { // Try to execute liquidation await expect(pool.connect(user.signer).repay(dai.address, '1', '1', user.address)).revertedWith( - LP_IS_PAUSED + VL_RESERVE_PAUSED ); // Unpause the pool @@ -175,7 +178,7 @@ makeSuite('Pausable Pool', (testEnv: TestEnv) => { '0x10', '0' ) - ).revertedWith(LP_IS_PAUSED); + ).revertedWith(VL_RESERVE_PAUSED); // Unpause pool await configurator.connect(users[1].signer).setPoolPause(false); @@ -256,7 +259,7 @@ makeSuite('Pausable Pool', (testEnv: TestEnv) => { // Do liquidation await expect( pool.liquidationCall(weth.address, usdc.address, borrower.address, amountToLiquidate, true) - ).revertedWith(LP_IS_PAUSED); + ).revertedWith(VL_RESERVE_PAUSED); // Unpause pool await configurator.connect(users[1].signer).setPoolPause(false); @@ -285,7 +288,7 @@ makeSuite('Pausable Pool', (testEnv: TestEnv) => { // Try to repay await expect( pool.connect(user.signer).swapBorrowRateMode(usdc.address, RateMode.Stable) - ).revertedWith(LP_IS_PAUSED); + ).revertedWith(VL_RESERVE_PAUSED); // Unpause pool await configurator.connect(users[1].signer).setPoolPause(false); @@ -299,7 +302,7 @@ makeSuite('Pausable Pool', (testEnv: TestEnv) => { await expect( pool.connect(user.signer).rebalanceStableBorrowRate(dai.address, user.address) - ).revertedWith(LP_IS_PAUSED); + ).revertedWith(VL_RESERVE_PAUSED); // Unpause pool await configurator.connect(users[1].signer).setPoolPause(false); @@ -319,7 +322,7 @@ makeSuite('Pausable Pool', (testEnv: TestEnv) => { await expect( pool.connect(user.signer).setUserUseReserveAsCollateral(weth.address, false) - ).revertedWith(LP_IS_PAUSED); + ).revertedWith(VL_RESERVE_PAUSED); // Unpause pool await configurator.connect(users[1].signer).setPoolPause(false); diff --git a/test-suites/test-amm/liquidation-atoken.spec.ts b/test-suites/test-amm/liquidation-atoken.spec.ts index 90296edb..775fe769 100644 --- a/test-suites/test-amm/liquidation-atoken.spec.ts +++ b/test-suites/test-amm/liquidation-atoken.spec.ts @@ -17,7 +17,6 @@ makeSuite('LendingPool liquidation - liquidator receiving aToken', (testEnv) => INVALID_HF, LPCM_SPECIFIED_CURRENCY_NOT_BORROWED_BY_USER, LPCM_COLLATERAL_CANNOT_BE_LIQUIDATED, - LP_IS_PAUSED, } = ProtocolErrors; it('Deposits WETH, borrows DAI/Check liquidation fails because health factor is above 1', async () => { diff --git a/test-suites/test-amm/pausable-functions.spec.ts b/test-suites/test-amm/pausable-functions.spec.ts index f42388a8..e5bd4637 100644 --- a/test-suites/test-amm/pausable-functions.spec.ts +++ b/test-suites/test-amm/pausable-functions.spec.ts @@ -13,7 +13,7 @@ makeSuite('Pausable Pool', (testEnv: TestEnv) => { let _mockFlashLoanReceiver = {} as MockFlashLoanReceiver; const { - LP_IS_PAUSED, + VL_RESERVE_PAUSED, INVALID_FROM_BALANCE_AFTER_TRANSFER, INVALID_TO_BALANCE_AFTER_TRANSFER, } = ProtocolErrors; @@ -44,7 +44,7 @@ makeSuite('Pausable Pool', (testEnv: TestEnv) => { // User 0 tries the transfer to User 1 await expect( aDai.connect(users[0].signer).transfer(users[1].address, amountDAItoDeposit) - ).to.revertedWith(LP_IS_PAUSED); + ).to.revertedWith(VL_RESERVE_PAUSED); const pausedFromBalance = await aDai.balanceOf(users[0].address); const pausedToBalance = await aDai.balanceOf(users[1].address); @@ -91,7 +91,7 @@ makeSuite('Pausable Pool', (testEnv: TestEnv) => { await configurator.connect(users[1].signer).setPoolPause(true); await expect( pool.connect(users[0].signer).deposit(dai.address, amountDAItoDeposit, users[0].address, '0') - ).to.revertedWith(LP_IS_PAUSED); + ).to.revertedWith(VL_RESERVE_PAUSED); // Configurator unpauses the pool await configurator.connect(users[1].signer).setPoolPause(false); @@ -116,7 +116,7 @@ makeSuite('Pausable Pool', (testEnv: TestEnv) => { // user tries to burn await expect( pool.connect(users[0].signer).withdraw(dai.address, amountDAItoDeposit, users[0].address) - ).to.revertedWith(LP_IS_PAUSED); + ).to.revertedWith(VL_RESERVE_PAUSED); // Configurator unpauses the pool await configurator.connect(users[1].signer).setPoolPause(false); @@ -132,7 +132,7 @@ makeSuite('Pausable Pool', (testEnv: TestEnv) => { // Try to execute liquidation await expect( pool.connect(user.signer).borrow(dai.address, '1', '2', '0', user.address) - ).revertedWith(LP_IS_PAUSED); + ).revertedWith(VL_RESERVE_PAUSED); // Unpause the pool await configurator.connect(users[1].signer).setPoolPause(false); @@ -147,7 +147,7 @@ makeSuite('Pausable Pool', (testEnv: TestEnv) => { // Try to execute liquidation await expect(pool.connect(user.signer).repay(dai.address, '1', '2', user.address)).revertedWith( - LP_IS_PAUSED + VL_RESERVE_PAUSED ); // Unpause the pool @@ -178,7 +178,7 @@ makeSuite('Pausable Pool', (testEnv: TestEnv) => { '0x10', '0' ) - ).revertedWith(LP_IS_PAUSED); + ).revertedWith(VL_RESERVE_PAUSED); // Unpause pool await configurator.connect(users[1].signer).setPoolPause(false); @@ -259,7 +259,7 @@ makeSuite('Pausable Pool', (testEnv: TestEnv) => { // Do liquidation await expect( pool.liquidationCall(weth.address, usdc.address, borrower.address, amountToLiquidate, true) - ).revertedWith(LP_IS_PAUSED); + ).revertedWith(VL_RESERVE_PAUSED); // Unpause pool await configurator.connect(users[1].signer).setPoolPause(false); @@ -288,7 +288,7 @@ makeSuite('Pausable Pool', (testEnv: TestEnv) => { // Try to repay await expect( pool.connect(user.signer).swapBorrowRateMode(usdc.address, RateMode.Stable) - ).revertedWith(LP_IS_PAUSED); + ).revertedWith(VL_RESERVE_PAUSED); // Unpause pool await configurator.connect(users[1].signer).setPoolPause(false); @@ -302,7 +302,7 @@ makeSuite('Pausable Pool', (testEnv: TestEnv) => { await expect( pool.connect(user.signer).rebalanceStableBorrowRate(dai.address, user.address) - ).revertedWith(LP_IS_PAUSED); + ).revertedWith(VL_RESERVE_PAUSED); // Unpause pool await configurator.connect(users[1].signer).setPoolPause(false); @@ -322,7 +322,7 @@ makeSuite('Pausable Pool', (testEnv: TestEnv) => { await expect( pool.connect(user.signer).setUserUseReserveAsCollateral(weth.address, false) - ).revertedWith(LP_IS_PAUSED); + ).revertedWith(VL_RESERVE_PAUSED); // Unpause pool await configurator.connect(users[1].signer).setPoolPause(false); From 0fe470656e1f5acc7f19ce5f817d6e1c8b1cd4d5 Mon Sep 17 00:00:00 2001 From: The3D Date: Thu, 1 Jul 2021 16:59:14 +0200 Subject: [PATCH 6/9] fix: various fixes and refactorings on the implementation --- .../protocol/lendingpool/LendingPool.sol | 8 ++++--- .../libraries/logic/ValidationLogic.sol | 21 ++++++++++--------- 2 files changed, 16 insertions(+), 13 deletions(-) diff --git a/contracts/protocol/lendingpool/LendingPool.sol b/contracts/protocol/lendingpool/LendingPool.sol index cb4bf47e..47f1359a 100644 --- a/contracts/protocol/lendingpool/LendingPool.sol +++ b/contracts/protocol/lendingpool/LendingPool.sol @@ -282,7 +282,9 @@ contract LendingPool is VersionedInitializable, ILendingPool, LendingPoolStorage DataTypes.ReserveData storage reserve = _reserves[asset]; 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); @@ -291,7 +293,7 @@ contract LendingPool is VersionedInitializable, ILendingPool, LendingPoolStorage } else { ValidationLogic.validateHFAndExposureCap( asset, - IERC20(reserveCache.aTokenAddress).balanceOf(msg.sender), + userBalance, msg.sender, _reserves, _usersConfig[msg.sender], @@ -633,7 +635,7 @@ contract LendingPool is VersionedInitializable, ILendingPool, LendingPoolStorage if (fromConfig.isBorrowingAny()) { ValidationLogic.validateHFAndExposureCap( asset, - 0, + amount, from, _reserves, _usersConfig[from], diff --git a/contracts/protocol/libraries/logic/ValidationLogic.sol b/contracts/protocol/libraries/logic/ValidationLogic.sol index f653ad23..10b7a4f5 100644 --- a/contracts/protocol/libraries/logic/ValidationLogic.sol +++ b/contracts/protocol/libraries/logic/ValidationLogic.sol @@ -388,17 +388,16 @@ library ValidationLogic { * @dev Validates the action of setting an asset as collateral * @param reserveCache The cached data of the reserve */ - function validateSetUseReserveAsCollateral(DataTypes.ReserveCache memory reserveCache) - external - view - { - uint256 underlyingBalance = IERC20(reserveCache.aTokenAddress).balanceOf(msg.sender); + function validateSetUseReserveAsCollateral( + DataTypes.ReserveCache memory reserveCache, + uint256 userBalance + ) external pure { (bool isActive, , , , bool isPaused) = reserveCache.reserveConfiguration.getFlagsMemory(); require(isActive, Errors.VL_NO_ACTIVE_RESERVE); 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); } /** @@ -519,6 +518,8 @@ library ValidationLogic { /** * @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 reservesData The state of all the reserves * @param userConfig The state of the user for the specific reserve @@ -527,8 +528,8 @@ library ValidationLogic { * @param oracle The price oracle */ function validateHFAndExposureCap( - address collateral, - uint256 collateralToBeWithdrawn, + address asset, + uint256 expCapOffset, address from, mapping(address => DataTypes.ReserveData) storage reservesData, DataTypes.UserConfigurationMap storage userConfig, @@ -537,7 +538,7 @@ library ValidationLogic { address oracle ) external view { validateHFAndExposureCapLocalVars memory vars; - DataTypes.ReserveData memory reserve = reservesData[collateral]; + DataTypes.ReserveData memory reserve = reservesData[asset]; (, , vars.ltv, , vars.healthFactor, vars.uncappedLtv) = GenericLogic.calculateUserAccountData( from, reservesData, @@ -559,7 +560,7 @@ library ValidationLogic { vars.totalSupplyAtoken = IERC20(reserve.aTokenAddress).totalSupply(); (, , , vars.reserveDecimals, ) = reserve.configuration.getParamsMemory(); bool isAssetCapped = - vars.totalSupplyAtoken.sub(collateralToBeWithdrawn).div(10**vars.reserveDecimals) >= + vars.totalSupplyAtoken.sub(expCapOffset).div(10**vars.reserveDecimals) >= vars.exposureCap; require(isAssetCapped, Errors.VL_COLLATERAL_EXPOSURE_CAP_EXCEEDED); } From 93d3e9de866222f081c604ca344687179139adf6 Mon Sep 17 00:00:00 2001 From: Hadrien Charlanes Date: Thu, 1 Jul 2021 17:05:05 +0200 Subject: [PATCH 7/9] test: adapted test for new setReservePause function (replacing pause/unpause) --- test-suites/test-aave/reserve-pause.spec.ts | 43 ++++++++++----------- 1 file changed, 21 insertions(+), 22 deletions(-) diff --git a/test-suites/test-aave/reserve-pause.spec.ts b/test-suites/test-aave/reserve-pause.spec.ts index b9686b48..771fd0fd 100644 --- a/test-suites/test-aave/reserve-pause.spec.ts +++ b/test-suites/test-aave/reserve-pause.spec.ts @@ -9,7 +9,7 @@ import { getMockFlashLoanReceiver } from '../../helpers/contracts-getters'; const { expect } = require('chai'); -makeSuite('Pause Reserve', (testEnv: TestEnv) => { +makeSuite('Pause One Reserve', (testEnv: TestEnv) => { let _mockFlashLoanReceiver = {} as MockFlashLoanReceiver; const { @@ -22,7 +22,6 @@ makeSuite('Pause Reserve', (testEnv: TestEnv) => { _mockFlashLoanReceiver = await getMockFlashLoanReceiver(); }); - it('User 0 deposits 1000 DAI. Configurator pauses pool. Transfers to user 1 reverts. Configurator unpauses the network and next transfer succeeds', async () => { const { users, pool, dai, aDai, configurator } = testEnv; @@ -40,7 +39,7 @@ makeSuite('Pause Reserve', (testEnv: TestEnv) => { const user1Balance = await aDai.balanceOf(users[1].address); // Configurator pauses the pool - await configurator.connect(users[1].signer).pauseReserve(dai.address); + await configurator.connect(users[1].signer).setReservePause(dai.address, true); // User 0 tries the transfer to User 1 await expect( @@ -60,7 +59,7 @@ makeSuite('Pause Reserve', (testEnv: TestEnv) => { ); // Configurator unpauses the pool - await configurator.connect(users[1].signer).unpauseReserve(dai.address); + await configurator.connect(users[1].signer).setReservePause(dai.address, false); // User 0 succeeds transfer to User 1 await aDai.connect(users[0].signer).transfer(users[1].address, amountDAItoDeposit); @@ -89,13 +88,13 @@ makeSuite('Pause Reserve', (testEnv: TestEnv) => { await dai.connect(users[0].signer).approve(pool.address, APPROVAL_AMOUNT_LENDING_POOL); // Configurator pauses the pool - await configurator.connect(users[1].signer).pauseReserve(dai.address); + await configurator.connect(users[1].signer).setReservePause(dai.address, true); await expect( pool.connect(users[0].signer).deposit(dai.address, amountDAItoDeposit, users[0].address, '0') ).to.revertedWith(VL_RESERVE_PAUSED); // Configurator unpauses the pool - await configurator.connect(users[1].signer).unpauseReserve(dai.address); + await configurator.connect(users[1].signer).setReservePause(dai.address, false); }); it('Withdraw', async () => { @@ -112,7 +111,7 @@ makeSuite('Pause Reserve', (testEnv: TestEnv) => { .deposit(dai.address, amountDAItoDeposit, users[0].address, '0'); // Configurator pauses the pool - await configurator.connect(users[1].signer).pauseReserve(dai.address); + await configurator.connect(users[1].signer).setReservePause(dai.address, true); // user tries to burn await expect( @@ -120,7 +119,7 @@ makeSuite('Pause Reserve', (testEnv: TestEnv) => { ).to.revertedWith(VL_RESERVE_PAUSED); // Configurator unpauses the pool - await configurator.connect(users[1].signer).unpauseReserve(dai.address); + await configurator.connect(users[1].signer).setReservePause(dai.address, false); }); it('Borrow', async () => { @@ -128,7 +127,7 @@ makeSuite('Pause Reserve', (testEnv: TestEnv) => { const user = users[1]; // Pause the pool - await configurator.connect(users[1].signer).pauseReserve(dai.address); + await configurator.connect(users[1].signer).setReservePause(dai.address, true); // Try to execute liquidation await expect( @@ -136,7 +135,7 @@ makeSuite('Pause Reserve', (testEnv: TestEnv) => { ).revertedWith(VL_RESERVE_PAUSED); // Unpause the pool - await configurator.connect(users[1].signer).unpauseReserve(dai.address); + await configurator.connect(users[1].signer).setReservePause(dai.address, false); }); it('Repay', async () => { @@ -144,7 +143,7 @@ makeSuite('Pause Reserve', (testEnv: TestEnv) => { const user = users[1]; // Pause the pool - await configurator.connect(users[1].signer).pauseReserve(dai.address); + await configurator.connect(users[1].signer).setReservePause(dai.address, true); // Try to execute liquidation await expect(pool.connect(user.signer).repay(dai.address, '1', '1', user.address)).revertedWith( @@ -152,7 +151,7 @@ makeSuite('Pause Reserve', (testEnv: TestEnv) => { ); // Unpause the pool - await configurator.connect(users[1].signer).unpauseReserve(dai.address); + await configurator.connect(users[1].signer).setReservePause(dai.address, false); }); it('Flash loan', async () => { @@ -165,7 +164,7 @@ makeSuite('Pause Reserve', (testEnv: TestEnv) => { await _mockFlashLoanReceiver.setFailExecutionTransfer(true); // Pause pool - await configurator.connect(users[1].signer).pauseReserve(weth.address); + await configurator.connect(users[1].signer).setReservePause(weth.address, true); await expect( pool @@ -182,7 +181,7 @@ makeSuite('Pause Reserve', (testEnv: TestEnv) => { ).revertedWith(VL_RESERVE_PAUSED); // Unpause pool - await configurator.connect(users[1].signer).unpauseReserve(weth.address); + await configurator.connect(users[1].signer).setReservePause(weth.address, false); }); it('Liquidation call', async () => { @@ -255,7 +254,7 @@ makeSuite('Pause Reserve', (testEnv: TestEnv) => { .toFixed(0); // Pause pool - await configurator.connect(users[1].signer).pauseReserve(usdc.address); + await configurator.connect(users[1].signer).setReservePause(usdc.address, true); // Do liquidation await expect( @@ -263,7 +262,7 @@ makeSuite('Pause Reserve', (testEnv: TestEnv) => { ).revertedWith(VL_RESERVE_PAUSED); // Unpause pool - await configurator.connect(users[1].signer).unpauseReserve(usdc.address); + await configurator.connect(users[1].signer).setReservePause(usdc.address, false); }); it('SwapBorrowRateMode', async () => { @@ -284,7 +283,7 @@ makeSuite('Pause Reserve', (testEnv: TestEnv) => { await pool.connect(user.signer).borrow(usdc.address, amountToBorrow, 2, 0, user.address); // Pause pool - await configurator.connect(users[1].signer).pauseReserve(usdc.address); + await configurator.connect(users[1].signer).setReservePause(usdc.address, true); // Try to repay await expect( @@ -292,21 +291,21 @@ makeSuite('Pause Reserve', (testEnv: TestEnv) => { ).revertedWith(VL_RESERVE_PAUSED); // Unpause pool - await configurator.connect(users[1].signer).unpauseReserve(usdc.address); + await configurator.connect(users[1].signer).setReservePause(usdc.address, false); }); it('RebalanceStableBorrowRate', async () => { const { pool, dai, users, configurator } = testEnv; const user = users[1]; // Pause pool - await configurator.connect(users[1].signer).pauseReserve(dai.address); + await configurator.connect(users[1].signer).setReservePause(dai.address, true); await expect( pool.connect(user.signer).rebalanceStableBorrowRate(dai.address, user.address) ).revertedWith(VL_RESERVE_PAUSED); // Unpause pool - await configurator.connect(users[1].signer).unpauseReserve(dai.address); + await configurator.connect(users[1].signer).setReservePause(dai.address, false); }); it('setUserUseReserveAsCollateral', async () => { @@ -319,13 +318,13 @@ makeSuite('Pause Reserve', (testEnv: TestEnv) => { await pool.connect(user.signer).deposit(weth.address, amountWETHToDeposit, user.address, '0'); // Pause pool - await configurator.connect(users[1].signer).pauseReserve(weth.address); + await configurator.connect(users[1].signer).setReservePause(weth.address, true); await expect( pool.connect(user.signer).setUserUseReserveAsCollateral(weth.address, false) ).revertedWith(VL_RESERVE_PAUSED); // Unpause pool - await configurator.connect(users[1].signer).unpauseReserve(weth.address); + await configurator.connect(users[1].signer).setReservePause(weth.address, false); }); }); From 7acbd2925b3b789c34d87ebf04c8f48141bf41e4 Mon Sep 17 00:00:00 2001 From: The3D Date: Thu, 1 Jul 2021 19:55:30 +0200 Subject: [PATCH 8/9] refactor: changed params names, removed redundant event --- contracts/interfaces/ILendingPool.sol | 10 ---------- contracts/protocol/lendingpool/LendingPool.sol | 9 ++------- .../protocol/lendingpool/LendingPoolConfigurator.sol | 10 +++++----- test-suites/test-aave/mint-to-treasury.spec.ts | 2 -- 4 files changed, 7 insertions(+), 24 deletions(-) diff --git a/contracts/interfaces/ILendingPool.sol b/contracts/interfaces/ILendingPool.sol index 6e3befe8..b5753258 100644 --- a/contracts/interfaces/ILendingPool.sol +++ b/contracts/interfaces/ILendingPool.sol @@ -113,16 +113,6 @@ interface ILendingPool { uint16 referralCode ); - /** - * @dev Emitted when the pause is triggered. - */ - event Paused(); - - /** - * @dev Emitted when the pause is lifted. - */ - event Unpaused(); - /** * @dev Emitted when a borrower is liquidated. This event is emitted by the LendingPool via * LendingPoolCollateral manager using a DELEGATECALL diff --git a/contracts/protocol/lendingpool/LendingPool.sol b/contracts/protocol/lendingpool/LendingPool.sol index 6355d01e..ad89d14e 100644 --- a/contracts/protocol/lendingpool/LendingPool.sol +++ b/contracts/protocol/lendingpool/LendingPool.sol @@ -685,13 +685,8 @@ contract LendingPool is VersionedInitializable, ILendingPool, LendingPoolStorage } ///@inheritdoc ILendingPool - function setPause(bool val) external override onlyLendingPoolConfigurator { - _paused = val; - if (_paused) { - emit Paused(); - } else { - emit Unpaused(); - } + function setPause(bool paused) external override onlyLendingPoolConfigurator { + _paused = paused; } ///@inheritdoc ILendingPool diff --git a/contracts/protocol/lendingpool/LendingPoolConfigurator.sol b/contracts/protocol/lendingpool/LendingPoolConfigurator.sol index 4affa47a..44735f00 100644 --- a/contracts/protocol/lendingpool/LendingPoolConfigurator.sol +++ b/contracts/protocol/lendingpool/LendingPoolConfigurator.sol @@ -407,14 +407,14 @@ contract LendingPoolConfigurator is VersionedInitializable, ILendingPoolConfigur } /// @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); - currentConfig.setPaused(val); + currentConfig.setPaused(paused); _pool.setConfiguration(asset, currentConfig.data); - if (val) { + if (paused) { emit ReservePaused(asset); } else { emit ReserveUnpaused(asset); @@ -484,11 +484,11 @@ contract LendingPoolConfigurator is VersionedInitializable, ILendingPoolConfigur } /// @inheritdoc ILendingPoolConfigurator - function setPoolPause(bool val) external override onlyEmergencyAdmin { + function setPoolPause(bool paused) external override onlyEmergencyAdmin { address[] memory reserves = _pool.getReservesList(); for (uint256 i = 0; i < reserves.length; i++) { - setReservePause(reserves[i], val); + setReservePause(reserves[i], paused); } } diff --git a/test-suites/test-aave/mint-to-treasury.spec.ts b/test-suites/test-aave/mint-to-treasury.spec.ts index 1ed83274..42cfc50d 100644 --- a/test-suites/test-aave/mint-to-treasury.spec.ts +++ b/test-suites/test-aave/mint-to-treasury.spec.ts @@ -61,8 +61,6 @@ makeSuite('Mint to treasury', (testEnv: TestEnv) => { const { accruedToTreasury } = await pool.getReserveData(dai.address); - console.log("Accrued to treasury ", accruedToTreasury.toString()); - expect(accruedToTreasury.toString()).to.be.bignumber.almostEqual( expectedAccruedToTreasury, 'Invalid amount accrued to the treasury' From 2c19aeb87b9c1edfff4f7ca7cd9ed1a21361136e Mon Sep 17 00:00:00 2001 From: The3D Date: Thu, 1 Jul 2021 20:00:02 +0200 Subject: [PATCH 9/9] fix: added check to skip dropped reserves in setPoolPause() --- contracts/protocol/lendingpool/LendingPoolConfigurator.sol | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/contracts/protocol/lendingpool/LendingPoolConfigurator.sol b/contracts/protocol/lendingpool/LendingPoolConfigurator.sol index 44735f00..4ecc8b2d 100644 --- a/contracts/protocol/lendingpool/LendingPoolConfigurator.sol +++ b/contracts/protocol/lendingpool/LendingPoolConfigurator.sol @@ -488,7 +488,9 @@ contract LendingPoolConfigurator is VersionedInitializable, ILendingPoolConfigur address[] memory reserves = _pool.getReservesList(); for (uint256 i = 0; i < reserves.length; i++) { - setReservePause(reserves[i], paused); + if (reserves[i] != address(0)) { //might happen is a reserve was dropped + setReservePause(reserves[i], paused); + } } }