Trim PausablePool into LendingPool to save code size.

This commit is contained in:
David Racero 2020-09-15 11:56:08 +02:00
parent eea47aedde
commit 83bf3e5677
5 changed files with 68 additions and 105 deletions

View File

@ -25,7 +25,6 @@ import {LendingPoolLiquidationManager} from './LendingPoolLiquidationManager.sol
import {IPriceOracleGetter} from '../interfaces/IPriceOracleGetter.sol'; import {IPriceOracleGetter} from '../interfaces/IPriceOracleGetter.sol';
import {SafeERC20} from '@openzeppelin/contracts/token/ERC20/SafeERC20.sol'; import {SafeERC20} from '@openzeppelin/contracts/token/ERC20/SafeERC20.sol';
import {ILendingPool} from '../interfaces/ILendingPool.sol'; import {ILendingPool} from '../interfaces/ILendingPool.sol';
import {PausablePool} from '../misc/PausablePool.sol';
/** /**
* @title LendingPool contract * @title LendingPool contract
@ -33,7 +32,7 @@ import {PausablePool} from '../misc/PausablePool.sol';
* @author Aave * @author Aave
**/ **/
contract LendingPool is VersionedInitializable, PausablePool, ILendingPool { contract LendingPool is VersionedInitializable, ILendingPool {
using SafeMath for uint256; using SafeMath for uint256;
using WadRayMath for uint256; using WadRayMath for uint256;
using ReserveLogic for ReserveLogic.ReserveData; using ReserveLogic for ReserveLogic.ReserveData;
@ -56,6 +55,7 @@ contract LendingPool is VersionedInitializable, PausablePool, ILendingPool {
address[] internal _reservesList; address[] internal _reservesList;
bool internal _flashLiquidationLocked; bool internal _flashLiquidationLocked;
bool public _paused;
/** /**
* @dev only lending pools configurator can use functions affected by this modifier * @dev only lending pools configurator can use functions affected by this modifier
@ -68,6 +68,17 @@ contract LendingPool is VersionedInitializable, PausablePool, ILendingPool {
_; _;
} }
/**
* @dev Modifier to make a function callable only when the contract is not paused.
*
* Requirements:
*
* - The contract must not be paused.
*/
function whenNotPaused() internal view {
require(!_paused, Errors.IS_PAUSED);
}
uint256 public constant UINT_MAX_VALUE = uint256(-1); uint256 public constant UINT_MAX_VALUE = uint256(-1);
uint256 public constant LENDINGPOOL_REVISION = 0x2; uint256 public constant LENDINGPOOL_REVISION = 0x2;
@ -97,7 +108,8 @@ contract LendingPool is VersionedInitializable, PausablePool, ILendingPool {
uint256 amount, uint256 amount,
address onBehalfOf, address onBehalfOf,
uint16 referralCode uint16 referralCode
) external override whenNotPaused { ) external override {
whenNotPaused();
ReserveLogic.ReserveData storage reserve = _reserves[asset]; ReserveLogic.ReserveData storage reserve = _reserves[asset];
ValidationLogic.validateDeposit(reserve, amount); ValidationLogic.validateDeposit(reserve, amount);
@ -125,7 +137,8 @@ contract LendingPool is VersionedInitializable, PausablePool, ILendingPool {
* @param asset the address of the reserve * @param asset the address of the reserve
* @param amount the underlying amount to be redeemed * @param amount the underlying amount to be redeemed
**/ **/
function withdraw(address asset, uint256 amount) external override whenNotPaused { function withdraw(address asset, uint256 amount) external override {
whenNotPaused();
ReserveLogic.ReserveData storage reserve = _reserves[asset]; ReserveLogic.ReserveData storage reserve = _reserves[asset];
address aToken = reserve.aTokenAddress; address aToken = reserve.aTokenAddress;
@ -186,6 +199,7 @@ contract LendingPool is VersionedInitializable, PausablePool, ILendingPool {
uint256 interestRateMode, uint256 interestRateMode,
uint256 amount uint256 amount
) external override { ) external override {
whenNotPaused();
address debtToken = _reserves[asset].getDebtTokenAddress(interestRateMode); address debtToken = _reserves[asset].getDebtTokenAddress(interestRateMode);
_borrowAllowance[debtToken][msg.sender][user] = amount; _borrowAllowance[debtToken][msg.sender][user] = amount;
@ -207,7 +221,8 @@ contract LendingPool is VersionedInitializable, PausablePool, ILendingPool {
uint256 interestRateMode, uint256 interestRateMode,
uint16 referralCode, uint16 referralCode,
address onBehalfOf address onBehalfOf
) external override whenNotPaused { ) external override {
whenNotPaused();
ReserveLogic.ReserveData storage reserve = _reserves[asset]; ReserveLogic.ReserveData storage reserve = _reserves[asset];
if (onBehalfOf != msg.sender) { if (onBehalfOf != msg.sender) {
@ -246,7 +261,8 @@ contract LendingPool is VersionedInitializable, PausablePool, ILendingPool {
uint256 amount, uint256 amount,
uint256 rateMode, uint256 rateMode,
address onBehalfOf address onBehalfOf
) external override whenNotPaused { ) external override {
whenNotPaused();
_executeRepay(asset, msg.sender, amount, rateMode, onBehalfOf); _executeRepay(asset, msg.sender, amount, rateMode, onBehalfOf);
} }
@ -307,7 +323,8 @@ contract LendingPool is VersionedInitializable, PausablePool, ILendingPool {
* @param asset the address of the reserve on which the user borrowed * @param asset the address of the reserve on which the user borrowed
* @param rateMode the rate mode that the user wants to swap * @param rateMode the rate mode that the user wants to swap
**/ **/
function swapBorrowRateMode(address asset, uint256 rateMode) external override whenNotPaused { function swapBorrowRateMode(address asset, uint256 rateMode) external override {
whenNotPaused();
ReserveLogic.ReserveData storage reserve = _reserves[asset]; ReserveLogic.ReserveData storage reserve = _reserves[asset];
(uint256 stableDebt, uint256 variableDebt) = Helpers.getUserCurrentDebt(msg.sender, reserve); (uint256 stableDebt, uint256 variableDebt) = Helpers.getUserCurrentDebt(msg.sender, reserve);
@ -350,7 +367,8 @@ contract LendingPool is VersionedInitializable, PausablePool, ILendingPool {
* @param asset the address of the reserve * @param asset the address of the reserve
* @param user the address of the user to be rebalanced * @param user the address of the user to be rebalanced
**/ **/
function rebalanceStableBorrowRate(address asset, address user) external override whenNotPaused { function rebalanceStableBorrowRate(address asset, address user) external override {
whenNotPaused();
ReserveLogic.ReserveData storage reserve = _reserves[asset]; ReserveLogic.ReserveData storage reserve = _reserves[asset];
IStableDebtToken stableDebtToken = IStableDebtToken(reserve.stableDebtTokenAddress); IStableDebtToken stableDebtToken = IStableDebtToken(reserve.stableDebtTokenAddress);
@ -395,11 +413,8 @@ contract LendingPool is VersionedInitializable, PausablePool, ILendingPool {
* @param asset the address of the reserve * @param asset the address of the reserve
* @param useAsCollateral true if the user wants to user the deposit as collateral, false otherwise. * @param useAsCollateral true if the user wants to user the deposit as collateral, false otherwise.
**/ **/
function setUserUseReserveAsCollateral(address asset, bool useAsCollateral) function setUserUseReserveAsCollateral(address asset, bool useAsCollateral) external override {
external whenNotPaused();
override
whenNotPaused
{
ReserveLogic.ReserveData storage reserve = _reserves[asset]; ReserveLogic.ReserveData storage reserve = _reserves[asset];
ValidationLogic.validateSetUseReserveAsCollateral( ValidationLogic.validateSetUseReserveAsCollateral(
@ -435,7 +450,8 @@ contract LendingPool is VersionedInitializable, PausablePool, ILendingPool {
address user, address user,
uint256 purchaseAmount, uint256 purchaseAmount,
bool receiveAToken bool receiveAToken
) external override whenNotPaused { ) external override {
whenNotPaused();
address liquidationManager = _addressesProvider.getLendingPoolLiquidationManager(); address liquidationManager = _addressesProvider.getLendingPoolLiquidationManager();
//solium-disable-next-line //solium-disable-next-line
@ -491,7 +507,8 @@ contract LendingPool is VersionedInitializable, PausablePool, ILendingPool {
uint256 principalAmount, uint256 principalAmount,
address receiver, address receiver,
bytes calldata params bytes calldata params
) external override whenNotPaused { ) external override {
whenNotPaused();
require(!_flashLiquidationLocked, Errors.REENTRANCY_NOT_ALLOWED); require(!_flashLiquidationLocked, Errors.REENTRANCY_NOT_ALLOWED);
_flashLiquidationLocked = true; _flashLiquidationLocked = true;
@ -538,7 +555,8 @@ contract LendingPool is VersionedInitializable, PausablePool, ILendingPool {
uint256 mode, uint256 mode,
bytes calldata params, bytes calldata params,
uint16 referralCode uint16 referralCode
) external override whenNotPaused { ) external override {
whenNotPaused();
ReserveLogic.ReserveData storage reserve = _reserves[asset]; ReserveLogic.ReserveData storage reserve = _reserves[asset];
FlashLoanLocalVars memory vars; FlashLoanLocalVars memory vars;
@ -974,7 +992,7 @@ contract LendingPool is VersionedInitializable, PausablePool, ILendingPool {
address user, address user,
uint256 amount uint256 amount
) external override view returns (bool) { ) external override view returns (bool) {
if (PausablePool.paused()) { if (_paused) {
return false; return false;
} }
return return
@ -1004,9 +1022,18 @@ contract LendingPool is VersionedInitializable, PausablePool, ILendingPool {
} }
/** /**
* @dev pause or unpause all the Lending Pool actions and aToken transfers * @dev Returns to normal state.
*
* Requirements:
*
* - The contract must be paused.
*/ */
function setPause(bool val) external override onlyLendingPoolConfigurator { function setPause(bool val) external override onlyLendingPoolConfigurator {
PausablePool._setPause(val); _paused = val;
if (_paused) {
emit Paused();
} else {
emit Unpaused();
}
} }
} }

View File

@ -30,7 +30,7 @@ import {ValidationLogic} from '../libraries/logic/ValidationLogic.sol';
* @notice Implements the liquidation function. * @notice Implements the liquidation function.
* @dev LendingPoolLiquidationManager inherits Pausable from OpenZeppelin to have the same storage layout as LendingPool * @dev LendingPoolLiquidationManager inherits Pausable from OpenZeppelin to have the same storage layout as LendingPool
**/ **/
contract LendingPoolLiquidationManager is VersionedInitializable, Pausable { contract LendingPoolLiquidationManager is VersionedInitializable {
using SafeERC20 for IERC20; using SafeERC20 for IERC20;
using SafeMath for uint256; using SafeMath for uint256;
using WadRayMath for uint256; using WadRayMath for uint256;
@ -51,6 +51,7 @@ contract LendingPoolLiquidationManager is VersionedInitializable, Pausable {
address[] internal reservesList; address[] internal reservesList;
bool internal _flashLiquidationLocked; bool internal _flashLiquidationLocked;
bool public _paused;
uint256 internal constant LIQUIDATION_CLOSE_FACTOR_PERCENT = 5000; uint256 internal constant LIQUIDATION_CLOSE_FACTOR_PERCENT = 5000;

View File

@ -79,7 +79,6 @@ library Errors {
// pausable error message // pausable error message
string public constant IS_PAUSED = '54'; // 'Pool is paused' string public constant IS_PAUSED = '54'; // 'Pool is paused'
string public constant NOT_PAUSED = '55'; // 'Pool is not paused'
enum LiquidationErrors { enum LiquidationErrors {
NO_ERROR, NO_ERROR,
NO_COLLATERAL_AVAILABLE, NO_COLLATERAL_AVAILABLE,

View File

@ -1,64 +0,0 @@
pragma solidity ^0.6.8;
// Comments made with // are due current max code size at LendingPool
// import {Errors} from '../libraries/helpers/Errors.sol';
/**
* @dev Contract module which allows children to implement an emergency stop
* mechanism that can be triggered by an authorized account.
*
* This module is used through inheritance. It will make available the
* modifiers `whenNotPaused` and `whenPaused`, which can be applied to
* the functions of your contract. Note that they will not be pausable by
* simply including this module, only once the modifiers are put in place.
*/
contract PausablePool {
/**
* @dev Emitted when the pause is triggered by `account`.
*/
event Paused();
/**
* @dev Emitted when the pause is lifted by `account`.
*/
event Unpaused();
bool private _paused;
/**
* @dev Returns true if the contract is paused, and false otherwise.
*/
function paused() public virtual view returns (bool) {
return _paused;
}
/**
* @dev Modifier to make a function callable only when the contract is not paused.
*
* Requirements:
*
* - The contract must not be paused.
*/
modifier whenNotPaused() {
// require(!_paused, Errors.IS_PAUSED);
require(!_paused, '54');
_;
}
/**
* @dev Returns to normal state.
*
* Requirements:
*
* - The contract must be paused.
*/
function _setPause(bool val) internal virtual {
_paused = val;
if (_paused) {
emit Paused();
return;
}
emit Unpaused();
}
}

View File

@ -40,7 +40,7 @@ makeSuite('Pausable Pool', (testEnv: TestEnv) => {
const user1Balance = await aDai.balanceOf(users[1].address); const user1Balance = await aDai.balanceOf(users[1].address);
// Configurator pauses the pool // Configurator pauses the pool
await configurator.pausePool(); await configurator.setPoolPause(true);
// User 0 tries the transfer to User 1 // User 0 tries the transfer to User 1
await expect( await expect(
@ -60,7 +60,7 @@ makeSuite('Pausable Pool', (testEnv: TestEnv) => {
); );
// Configurator unpauses the pool // Configurator unpauses the pool
await configurator.unpausePool(); await configurator.setPoolPause(false);
// User 0 succeeds transfer to User 1 // User 0 succeeds transfer to User 1
await aDai.connect(users[0].signer).transfer(users[1].address, amountDAItoDeposit); await aDai.connect(users[0].signer).transfer(users[1].address, amountDAItoDeposit);
@ -89,13 +89,13 @@ makeSuite('Pausable Pool', (testEnv: TestEnv) => {
await dai.connect(users[0].signer).approve(pool.address, APPROVAL_AMOUNT_LENDING_POOL); await dai.connect(users[0].signer).approve(pool.address, APPROVAL_AMOUNT_LENDING_POOL);
// Configurator pauses the pool // Configurator pauses the pool
await configurator.pausePool(); await configurator.setPoolPause(true);
await expect( await expect(
pool.connect(users[0].signer).deposit(dai.address, amountDAItoDeposit, users[0].address, '0') pool.connect(users[0].signer).deposit(dai.address, amountDAItoDeposit, users[0].address, '0')
).to.revertedWith(IS_PAUSED); ).to.revertedWith(IS_PAUSED);
// Configurator unpauses the pool // Configurator unpauses the pool
await configurator.unpausePool(); await configurator.setPoolPause(false);
}); });
it('User 0 burns 1000 aDAI but reverts due pool is paused', async () => { it('User 0 burns 1000 aDAI but reverts due pool is paused', async () => {
@ -112,7 +112,7 @@ makeSuite('Pausable Pool', (testEnv: TestEnv) => {
.deposit(dai.address, amountDAItoDeposit, users[0].address, '0'); .deposit(dai.address, amountDAItoDeposit, users[0].address, '0');
// Configurator pauses the pool // Configurator pauses the pool
await configurator.pausePool(); await configurator.setPoolPause(true);
// user tries to burn // user tries to burn
await expect( await expect(
@ -120,7 +120,7 @@ makeSuite('Pausable Pool', (testEnv: TestEnv) => {
).to.revertedWith(IS_PAUSED); ).to.revertedWith(IS_PAUSED);
// Configurator unpauses the pool // Configurator unpauses the pool
await configurator.unpausePool(); await configurator.setPoolPause(false);
}); });
it('Repay with collateral', async () => { it('Repay with collateral', async () => {
@ -129,7 +129,7 @@ makeSuite('Pausable Pool', (testEnv: TestEnv) => {
const liquidator = users[5]; const liquidator = users[5];
// Pause the pool // Pause the pool
await configurator.pausePool(); await configurator.setPoolPause(true);
// Try to execute liquidation // Try to execute liquidation
await expect( await expect(
@ -146,7 +146,7 @@ makeSuite('Pausable Pool', (testEnv: TestEnv) => {
).revertedWith(IS_PAUSED); ).revertedWith(IS_PAUSED);
// Unpause the pool // Unpause the pool
await configurator.unpausePool(); await configurator.setPoolPause(false);
}); });
it('Flash loan', async () => { it('Flash loan', async () => {
@ -159,7 +159,7 @@ makeSuite('Pausable Pool', (testEnv: TestEnv) => {
await _mockFlashLoanReceiver.setFailExecutionTransfer(true); await _mockFlashLoanReceiver.setFailExecutionTransfer(true);
// Pause pool // Pause pool
await configurator.pausePool(); await configurator.setPoolPause(true);
await expect( await expect(
pool pool
@ -168,7 +168,7 @@ makeSuite('Pausable Pool', (testEnv: TestEnv) => {
).revertedWith(IS_PAUSED); ).revertedWith(IS_PAUSED);
// Unpause pool // Unpause pool
await configurator.unpausePool(); await configurator.setPoolPause(false);
}); });
it('Liquidation call', async () => { it('Liquidation call', async () => {
@ -238,7 +238,7 @@ makeSuite('Pausable Pool', (testEnv: TestEnv) => {
.toFixed(0); .toFixed(0);
// Pause pool // Pause pool
await configurator.pausePool(); await configurator.setPoolPause(true);
// Do liquidation // Do liquidation
expect( expect(
@ -246,7 +246,7 @@ makeSuite('Pausable Pool', (testEnv: TestEnv) => {
).revertedWith(IS_PAUSED); ).revertedWith(IS_PAUSED);
// Unpause pool // Unpause pool
await configurator.unpausePool(); await configurator.setPoolPause(false);
}); });
it('User 6 deposits WETH and DAI, then borrows USDC at Variable', async () => { it('User 6 deposits WETH and DAI, then borrows USDC at Variable', async () => {
@ -271,7 +271,7 @@ makeSuite('Pausable Pool', (testEnv: TestEnv) => {
await mockSwapAdapter.setAmountToReturn(amountToRepay); await mockSwapAdapter.setAmountToReturn(amountToRepay);
// Pause pool // Pause pool
await configurator.pausePool(); await configurator.setPoolPause(true);
// Try to repay // Try to repay
await expect( await expect(
@ -288,7 +288,7 @@ makeSuite('Pausable Pool', (testEnv: TestEnv) => {
).revertedWith(IS_PAUSED); ).revertedWith(IS_PAUSED);
// Unpause pool // Unpause pool
await configurator.unpausePool(); await configurator.setPoolPause(false);
}); });
it('User 2 deposits WETH and DAI, then borrows USDC at Variable, then tries to swap to stable but pool is paused', async () => { it('User 2 deposits WETH and DAI, then borrows USDC at Variable, then tries to swap to stable but pool is paused', async () => {
@ -309,7 +309,7 @@ makeSuite('Pausable Pool', (testEnv: TestEnv) => {
await pool.connect(user.signer).borrow(usdc.address, amountToBorrow, 2, 0, user.address); await pool.connect(user.signer).borrow(usdc.address, amountToBorrow, 2, 0, user.address);
// Pause pool // Pause pool
await configurator.pausePool(); await configurator.setPoolPause(true);
// Try to repay // Try to repay
await expect( await expect(
@ -317,21 +317,21 @@ makeSuite('Pausable Pool', (testEnv: TestEnv) => {
).revertedWith(IS_PAUSED); ).revertedWith(IS_PAUSED);
// Unpause pool // Unpause pool
await configurator.unpausePool(); await configurator.setPoolPause(false);
}); });
it('User 2 tries to rebalance stable borrow rate', async () => { it('User 2 tries to rebalance stable borrow rate', async () => {
const {pool, dai, users, configurator} = testEnv; const {pool, dai, users, configurator} = testEnv;
const user = users[1]; const user = users[1];
// Pause pool // Pause pool
await configurator.pausePool(); await configurator.setPoolPause(true);
await expect( await expect(
pool.connect(user.signer).rebalanceStableBorrowRate(dai.address, user.address) pool.connect(user.signer).rebalanceStableBorrowRate(dai.address, user.address)
).revertedWith(IS_PAUSED); ).revertedWith(IS_PAUSED);
// Unpause pool // Unpause pool
await configurator.unpausePool(); await configurator.setPoolPause(false);
}); });
it('User 2 tries to rebalance stable borrow rate', async () => { it('User 2 tries to rebalance stable borrow rate', async () => {
@ -344,13 +344,13 @@ makeSuite('Pausable Pool', (testEnv: TestEnv) => {
await pool.connect(user.signer).deposit(weth.address, amountWETHToDeposit, user.address, '0'); await pool.connect(user.signer).deposit(weth.address, amountWETHToDeposit, user.address, '0');
// Pause pool // Pause pool
await configurator.pausePool(); await configurator.setPoolPause(true);
await expect( await expect(
pool.connect(user.signer).setUserUseReserveAsCollateral(weth.address, false) pool.connect(user.signer).setUserUseReserveAsCollateral(weth.address, false)
).revertedWith(IS_PAUSED); ).revertedWith(IS_PAUSED);
// Unpause pool // Unpause pool
await configurator.unpausePool(); await configurator.setPoolPause(false);
}); });
}); });