Merge pull request #111 from aave/feat/2.5-risk-admin

Feat/2.5 risk admin
This commit is contained in:
The-3D 2021-05-31 17:24:50 +02:00 committed by GitHub
commit 6b24f7dc9d
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
9 changed files with 535 additions and 99 deletions

View File

@ -203,6 +203,18 @@ interface ILendingPoolConfigurator {
address indexed implementation
);
/**
* @dev Emitted when a new risk admin is registered
* @param admin the newly registered admin
**/
event RiskAdminRegistered(address indexed admin);
/**
* @dev Emitted when a risk admin is unregistered
* @param admin the unregistered admin
**/
event RiskAdminUnregistered(address indexed admin);
/**
* @dev Initializes reserves in batch
* @param input The array of reserves initialization parameters
@ -344,4 +356,22 @@ interface ILendingPoolConfigurator {
* @param supplyCap The new supply of the reserve
**/
function setSupplyCap(address asset, uint256 supplyCap) external;
/**
* @dev Registers a new admin with rights on risk related configurations
* @param admin The address of the admin to register
**/
function registerRiskAdmin(address admin) external;
/**
* @dev Unegisters a risk admin
* @param admin The address of the admin to unregister
**/
function unregisterRiskAdmin(address admin) external;
/**
* @dev Returns wether an address in a risk admin or not
* @param admin The address of the potential admin
**/
function isRiskAdmin(address admin) external view returns (bool);
}

View File

@ -33,6 +33,8 @@ contract LendingPoolConfigurator is VersionedInitializable, ILendingPoolConfigur
ILendingPoolAddressesProvider internal _addressesProvider;
ILendingPool internal _pool;
mapping(address => bool) private _riskAdmins;
modifier onlyPoolAdmin {
require(_addressesProvider.getPoolAdmin() == msg.sender, Errors.CALLER_NOT_POOL_ADMIN);
_;
@ -55,6 +57,14 @@ contract LendingPoolConfigurator is VersionedInitializable, ILendingPoolConfigur
_;
}
modifier onlyRiskOrPoolAdmins {
require(
_riskAdmins[msg.sender] || _addressesProvider.getPoolAdmin() == msg.sender,
Errors.LPC_CALLER_NOT_RISK_OR_POOL_ADMIN
);
_;
}
uint256 internal constant CONFIGURATOR_REVISION = 0x1;
function getRevision() internal pure override returns (uint256) {
@ -254,7 +264,7 @@ contract LendingPoolConfigurator is VersionedInitializable, ILendingPoolConfigur
address asset,
uint256 borrowCap,
bool stableBorrowRateEnabled
) external override onlyPoolAdmin {
) external override onlyRiskOrPoolAdmins {
DataTypes.ReserveConfigurationMap memory currentConfig = _pool.getConfiguration(asset);
currentConfig.setBorrowingEnabled(true);
@ -268,7 +278,7 @@ contract LendingPoolConfigurator is VersionedInitializable, ILendingPoolConfigur
}
/// @inheritdoc ILendingPoolConfigurator
function disableBorrowingOnReserve(address asset) external override onlyPoolAdmin {
function disableBorrowingOnReserve(address asset) external override onlyRiskOrPoolAdmins {
DataTypes.ReserveConfigurationMap memory currentConfig = _pool.getConfiguration(asset);
currentConfig.setBorrowingEnabled(false);
@ -283,7 +293,7 @@ contract LendingPoolConfigurator is VersionedInitializable, ILendingPoolConfigur
uint256 ltv,
uint256 liquidationThreshold,
uint256 liquidationBonus
) external override onlyPoolAdmin {
) external override onlyRiskOrPoolAdmins {
DataTypes.ReserveConfigurationMap memory currentConfig = _pool.getConfiguration(asset);
//validation of the parameters: the LTV can
@ -323,7 +333,7 @@ contract LendingPoolConfigurator is VersionedInitializable, ILendingPoolConfigur
}
/// @inheritdoc ILendingPoolConfigurator
function enableReserveStableRate(address asset) external override onlyPoolAdmin {
function enableReserveStableRate(address asset) external override onlyRiskOrPoolAdmins {
DataTypes.ReserveConfigurationMap memory currentConfig = _pool.getConfiguration(asset);
currentConfig.setStableRateBorrowingEnabled(true);
@ -334,7 +344,7 @@ contract LendingPoolConfigurator is VersionedInitializable, ILendingPoolConfigur
}
/// @inheritdoc ILendingPoolConfigurator
function disableReserveStableRate(address asset) external override onlyPoolAdmin {
function disableReserveStableRate(address asset) external override onlyRiskOrPoolAdmins {
DataTypes.ReserveConfigurationMap memory currentConfig = _pool.getConfiguration(asset);
currentConfig.setStableRateBorrowingEnabled(false);
@ -369,7 +379,7 @@ contract LendingPoolConfigurator is VersionedInitializable, ILendingPoolConfigur
}
/// @inheritdoc ILendingPoolConfigurator
function freezeReserve(address asset) external override onlyPoolAdmin {
function freezeReserve(address asset) external override onlyRiskOrPoolAdmins {
DataTypes.ReserveConfigurationMap memory currentConfig = _pool.getConfiguration(asset);
currentConfig.setFrozen(true);
@ -380,7 +390,7 @@ contract LendingPoolConfigurator is VersionedInitializable, ILendingPoolConfigur
}
/// @inheritdoc ILendingPoolConfigurator
function unfreezeReserve(address asset) external override onlyPoolAdmin {
function unfreezeReserve(address asset) external override onlyRiskOrPoolAdmins {
DataTypes.ReserveConfigurationMap memory currentConfig = _pool.getConfiguration(asset);
currentConfig.setFrozen(false);
@ -413,7 +423,11 @@ contract LendingPoolConfigurator is VersionedInitializable, ILendingPoolConfigur
}
/// @inheritdoc ILendingPoolConfigurator
function setReserveFactor(address asset, uint256 reserveFactor) external override onlyPoolAdmin {
function setReserveFactor(address asset, uint256 reserveFactor)
external
override
onlyRiskOrPoolAdmins
{
DataTypes.ReserveConfigurationMap memory currentConfig = _pool.getConfiguration(asset);
currentConfig.setReserveFactor(reserveFactor);
@ -424,7 +438,7 @@ contract LendingPoolConfigurator is VersionedInitializable, ILendingPoolConfigur
}
///@inheritdoc ILendingPoolConfigurator
function setBorrowCap(address asset, uint256 borrowCap) external override onlyPoolAdmin {
function setBorrowCap(address asset, uint256 borrowCap) external override onlyRiskOrPoolAdmins {
DataTypes.ReserveConfigurationMap memory currentConfig = _pool.getConfiguration(asset);
currentConfig.setBorrowCap(borrowCap);
@ -435,7 +449,7 @@ contract LendingPoolConfigurator is VersionedInitializable, ILendingPoolConfigur
}
///@inheritdoc ILendingPoolConfigurator
function setSupplyCap(address asset, uint256 supplyCap) external override onlyPoolAdmin {
function setSupplyCap(address asset, uint256 supplyCap) external override onlyRiskOrPoolAdmins {
DataTypes.ReserveConfigurationMap memory currentConfig = _pool.getConfiguration(asset);
currentConfig.setSupplyCap(supplyCap);
@ -445,15 +459,11 @@ contract LendingPoolConfigurator is VersionedInitializable, ILendingPoolConfigur
emit SupplyCapChanged(asset, supplyCap);
}
/**
* @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
**/
///@inheritdoc ILendingPoolConfigurator
function setReserveInterestRateStrategyAddress(address asset, address rateStrategyAddress)
external
override
onlyPoolAdmin
onlyRiskOrPoolAdmins
{
_pool.setReserveInterestRateStrategyAddress(asset, rateStrategyAddress);
emit ReserveInterestRateStrategyChanged(asset, rateStrategyAddress);
@ -464,6 +474,23 @@ contract LendingPoolConfigurator is VersionedInitializable, ILendingPoolConfigur
_pool.setPause(val);
}
/// @inheritdoc ILendingPoolConfigurator
function registerRiskAdmin(address admin) external override onlyPoolAdmin {
_riskAdmins[admin] = true;
emit RiskAdminRegistered(admin);
}
/// @inheritdoc ILendingPoolConfigurator
function unregisterRiskAdmin(address admin) external override onlyPoolAdmin {
_riskAdmins[admin] = false;
emit RiskAdminUnregistered(admin);
}
/// @inheritdoc ILendingPoolConfigurator
function isRiskAdmin(address admin) external view override onlyPoolAdmin returns (bool) {
return _riskAdmins[admin];
}
function _initTokenWithProxy(address implementation, bytes memory initParams)
internal
returns (address)

View File

@ -108,6 +108,7 @@ library Errors {
string public constant RC_INVALID_SUPPLY_CAP = '84';
string public constant LPC_CALLER_NOT_EMERGENCY_OR_POOL_ADMIN = '85';
string public constant VL_RESERVE_PAUSED = '86';
string public constant LPC_CALLER_NOT_RISK_OR_POOL_ADMIN = '87';
enum CollateralManagerErrors {
NO_ERROR,

View File

@ -183,6 +183,7 @@ export enum ProtocolErrors {
RC_INVALID_SUPPLY_CAP = '84',
LPC_CALLER_NOT_EMERGENCY_OR_POOL_ADMIN = '85',
VL_RESERVE_PAUSED = '86',
LPC_CALLER_NOT_RISK_OR_POOL_ADMIN = '87',
// old

View File

@ -92,8 +92,6 @@ export const strategyMATIC: IReserveParams = {
borrowCap: '0',
supplyCap: '0',
reserveFactor: '2000',
borrowCap: '0',
supplyCap: '0',
};
export const strategyAAVE: IReserveParams = {

View File

@ -128,6 +128,7 @@ const buildTestEnv = async (deployer: Signer, secondaryWallet: Signer) => {
const lendingPoolConfiguratorProxy = await getLendingPoolConfiguratorProxy(
await addressesProvider.getLendingPoolConfigurator()
);
await waitForTx(await lendingPoolConfiguratorProxy.registerRiskAdmin(addressList[3]));
await insertContractAddressInDb(
eContractid.LendingPoolConfigurator,
lendingPoolConfiguratorProxy.address

View File

@ -24,6 +24,7 @@ makeSuite('LendingPoolConfigurator', (testEnv: TestEnv) => {
RC_INVALID_BORROW_CAP,
RC_INVALID_SUPPLY_CAP,
LPC_CALLER_NOT_EMERGENCY_OR_POOL_ADMIN,
LPC_CALLER_NOT_RISK_OR_POOL_ADMIN,
VL_RESERVE_PAUSED,
} = ProtocolErrors;
@ -134,10 +135,9 @@ makeSuite('LendingPoolConfigurator', (testEnv: TestEnv) => {
expect(supplyCap).to.be.equal(strategyWETH.supplyCap);
});
it('Pauses the ETH reserve by emergency admin', async () => {
const { configurator, weth, helpersContract, addressesProvider, users } = testEnv;
expect(users[1].address).to.be.equal(await addressesProvider.getEmergencyAdmin());
await configurator.connect(users[1].signer).pauseReserve(weth.address);
const { configurator, weth, helpersContract, addressesProvider, users, emergencyAdmin } =
testEnv;
await configurator.connect(emergencyAdmin.signer).pauseReserve(weth.address);
const {
decimals,
ltv,
@ -167,8 +167,8 @@ makeSuite('LendingPoolConfigurator', (testEnv: TestEnv) => {
});
it('Unpauses the ETH reserve by emergency admin ', async () => {
const { configurator, helpersContract, weth, users } = testEnv;
await configurator.connect(users[1].signer).unpauseReserve(weth.address);
const { configurator, helpersContract, weth, users, emergencyAdmin } = testEnv;
await configurator.connect(emergencyAdmin.signer).unpauseReserve(weth.address);
const {
decimals,
@ -199,22 +199,22 @@ makeSuite('LendingPoolConfigurator', (testEnv: TestEnv) => {
});
it('Check the only admin or emergency admin can pauseReserve ', async () => {
const { configurator, users, weth } = testEnv;
const { configurator, users, weth, riskAdmin } = testEnv;
await expect(
configurator.connect(users[2].signer).pauseReserve(weth.address),
configurator.connect(riskAdmin.signer).pauseReserve(weth.address),
CALLER_NOT_POOL_ADMIN
).to.be.revertedWith(LPC_CALLER_NOT_EMERGENCY_OR_POOL_ADMIN);
});
it('Check the only admin or emergency admin can unpauseReserve ', async () => {
const { configurator, users, weth } = testEnv;
const { configurator, users, weth, riskAdmin } = testEnv;
await expect(
configurator.connect(users[2].signer).unpauseReserve(weth.address),
configurator.connect(riskAdmin.signer).unpauseReserve(weth.address),
CALLER_NOT_POOL_ADMIN
).to.be.revertedWith(LPC_CALLER_NOT_EMERGENCY_OR_POOL_ADMIN);
});
it('Freezes the ETH reserve', async () => {
it('Freezes the ETH reserve by pool Admin', async () => {
const { configurator, weth, helpersContract } = testEnv;
await configurator.freezeReserve(weth.address);
@ -246,7 +246,7 @@ makeSuite('LendingPoolConfigurator', (testEnv: TestEnv) => {
expect(supplyCap).to.be.equal(strategyWETH.supplyCap);
});
it('Unfreezes the ETH reserve', async () => {
it('Unfreezes the ETH reserve by Pool admin', async () => {
const { configurator, helpersContract, weth } = testEnv;
await configurator.unfreezeReserve(weth.address);
@ -277,24 +277,87 @@ makeSuite('LendingPoolConfigurator', (testEnv: TestEnv) => {
expect(borrowCap).to.be.equal(strategyWETH.borrowCap);
expect(supplyCap).to.be.equal(strategyWETH.supplyCap);
});
it('Freezes the ETH reserve by Risk Admin', async () => {
const { configurator, weth, helpersContract, riskAdmin } = testEnv;
it('Check the onlyAaveAdmin on freezeReserve ', async () => {
const { configurator, users, weth } = testEnv;
await expect(
configurator.connect(users[2].signer).freezeReserve(weth.address),
CALLER_NOT_POOL_ADMIN
).to.be.revertedWith(CALLER_NOT_POOL_ADMIN);
await configurator.connect(riskAdmin.signer).freezeReserve(weth.address);
const {
decimals,
ltv,
liquidationBonus,
liquidationThreshold,
reserveFactor,
stableBorrowRateEnabled,
borrowingEnabled,
isActive,
isFrozen,
} = await helpersContract.getReserveConfigurationData(weth.address);
const { borrowCap, supplyCap } = await helpersContract.getReserveCaps(weth.address);
const isPaused = await helpersContract.getPaused(weth.address);
expect(borrowingEnabled).to.be.equal(true);
expect(isActive).to.be.equal(true);
expect(isPaused).to.be.equal(false);
expect(isFrozen).to.be.equal(true);
expect(decimals).to.be.equal(strategyWETH.reserveDecimals);
expect(ltv).to.be.equal(strategyWETH.baseLTVAsCollateral);
expect(liquidationThreshold).to.be.equal(strategyWETH.liquidationThreshold);
expect(liquidationBonus).to.be.equal(strategyWETH.liquidationBonus);
expect(stableBorrowRateEnabled).to.be.equal(strategyWETH.stableBorrowRateEnabled);
expect(reserveFactor).to.be.equal(strategyWETH.reserveFactor);
expect(borrowCap).to.be.equal(strategyWETH.borrowCap);
expect(supplyCap).to.be.equal(strategyWETH.supplyCap);
});
it('Check the onlyAaveAdmin on unfreezeReserve ', async () => {
const { configurator, users, weth } = testEnv;
await expect(
configurator.connect(users[2].signer).unfreezeReserve(weth.address),
CALLER_NOT_POOL_ADMIN
).to.be.revertedWith(CALLER_NOT_POOL_ADMIN);
it('Unfreezes the ETH reserve by Risk admin', async () => {
const { configurator, helpersContract, weth, riskAdmin } = testEnv;
await configurator.connect(riskAdmin.signer).unfreezeReserve(weth.address);
const {
decimals,
ltv,
liquidationBonus,
liquidationThreshold,
reserveFactor,
stableBorrowRateEnabled,
borrowingEnabled,
isActive,
isFrozen,
} = await helpersContract.getReserveConfigurationData(weth.address);
const { borrowCap, supplyCap } = await helpersContract.getReserveCaps(weth.address);
const isPaused = await helpersContract.getPaused(weth.address);
expect(borrowingEnabled).to.be.equal(true);
expect(isActive).to.be.equal(true);
expect(isPaused).to.be.equal(false);
expect(isFrozen).to.be.equal(false);
expect(decimals).to.be.equal(strategyWETH.reserveDecimals);
expect(ltv).to.be.equal(strategyWETH.baseLTVAsCollateral);
expect(liquidationThreshold).to.be.equal(strategyWETH.liquidationThreshold);
expect(liquidationBonus).to.be.equal(strategyWETH.liquidationBonus);
expect(stableBorrowRateEnabled).to.be.equal(strategyWETH.stableBorrowRateEnabled);
expect(reserveFactor).to.be.equal(strategyWETH.reserveFactor);
expect(borrowCap).to.be.equal(strategyWETH.borrowCap);
expect(supplyCap).to.be.equal(strategyWETH.supplyCap);
});
it('Deactivates the ETH reserve for borrowing', async () => {
it('Check the onlyRiskOrPoolAdmins on freezeReserve ', async () => {
const { configurator, users, weth, emergencyAdmin } = testEnv;
await expect(
configurator.connect(emergencyAdmin.signer).freezeReserve(weth.address),
LPC_CALLER_NOT_RISK_OR_POOL_ADMIN
).to.be.revertedWith(LPC_CALLER_NOT_RISK_OR_POOL_ADMIN);
});
it('Check the onlyRiskOrPoolAdmins on unfreezeReserve ', async () => {
const { configurator, users, weth, emergencyAdmin } = testEnv;
await expect(
configurator.connect(emergencyAdmin.signer).unfreezeReserve(weth.address),
LPC_CALLER_NOT_RISK_OR_POOL_ADMIN
).to.be.revertedWith(LPC_CALLER_NOT_RISK_OR_POOL_ADMIN);
});
it('Deactivates the ETH reserve for borrowing via pool admin', async () => {
const { configurator, helpersContract, weth } = testEnv;
await configurator.disableBorrowingOnReserve(weth.address);
const {
@ -325,7 +388,7 @@ makeSuite('LendingPoolConfigurator', (testEnv: TestEnv) => {
expect(supplyCap).to.be.equal(strategyWETH.supplyCap);
});
it('Activates the ETH reserve for borrowing', async () => {
it('Activates the ETH reserve for borrowing via pool admin', async () => {
const { configurator, weth, helpersContract } = testEnv;
await configurator.enableBorrowingOnReserve(weth.address, '0', true);
const { variableBorrowIndex } = await helpersContract.getReserveData(weth.address);
@ -360,23 +423,92 @@ makeSuite('LendingPoolConfigurator', (testEnv: TestEnv) => {
expect(variableBorrowIndex.toString()).to.be.equal(RAY);
});
it('Check the onlyAaveAdmin on disableBorrowingOnReserve ', async () => {
const { configurator, users, weth } = testEnv;
await expect(
configurator.connect(users[2].signer).disableBorrowingOnReserve(weth.address),
CALLER_NOT_POOL_ADMIN
).to.be.revertedWith(CALLER_NOT_POOL_ADMIN);
it('Deactivates the ETH reserve for borrowing via risk admin', async () => {
const { configurator, helpersContract, weth, riskAdmin } = testEnv;
await configurator.connect(riskAdmin.signer).disableBorrowingOnReserve(weth.address);
const {
decimals,
ltv,
liquidationBonus,
liquidationThreshold,
reserveFactor,
stableBorrowRateEnabled,
borrowingEnabled,
isActive,
isFrozen,
} = await helpersContract.getReserveConfigurationData(weth.address);
const { borrowCap, supplyCap } = await helpersContract.getReserveCaps(weth.address);
const isPaused = await helpersContract.getPaused(weth.address);
expect(borrowingEnabled).to.be.equal(false);
expect(isActive).to.be.equal(true);
expect(isPaused).to.be.equal(false);
expect(isFrozen).to.be.equal(false);
expect(decimals).to.be.equal(strategyWETH.reserveDecimals);
expect(ltv).to.be.equal(strategyWETH.baseLTVAsCollateral);
expect(liquidationThreshold).to.be.equal(strategyWETH.liquidationThreshold);
expect(liquidationBonus).to.be.equal(strategyWETH.liquidationBonus);
expect(stableBorrowRateEnabled).to.be.equal(strategyWETH.stableBorrowRateEnabled);
expect(reserveFactor).to.be.equal(strategyWETH.reserveFactor);
expect(borrowCap).to.be.equal(strategyWETH.borrowCap);
expect(supplyCap).to.be.equal(strategyWETH.supplyCap);
});
it('Check the onlyAaveAdmin on enableBorrowingOnReserve ', async () => {
const { configurator, users, weth } = testEnv;
await expect(
configurator.connect(users[2].signer).enableBorrowingOnReserve(weth.address, '0', true),
CALLER_NOT_POOL_ADMIN
).to.be.revertedWith(CALLER_NOT_POOL_ADMIN);
it('Activates the ETH reserve for borrowing via risk admin', async () => {
const { configurator, weth, helpersContract, riskAdmin } = testEnv;
await configurator.connect(riskAdmin.signer).enableBorrowingOnReserve(weth.address, '0', true);
const { variableBorrowIndex } = await helpersContract.getReserveData(weth.address);
const {
decimals,
ltv,
liquidationBonus,
liquidationThreshold,
reserveFactor,
stableBorrowRateEnabled,
borrowingEnabled,
isActive,
isFrozen,
} = await helpersContract.getReserveConfigurationData(weth.address);
const { borrowCap, supplyCap } = await helpersContract.getReserveCaps(weth.address);
const isPaused = await helpersContract.getPaused(weth.address);
expect(borrowingEnabled).to.be.equal(true);
expect(isActive).to.be.equal(true);
expect(isPaused).to.be.equal(false);
expect(isFrozen).to.be.equal(false);
expect(decimals).to.be.equal(strategyWETH.reserveDecimals);
expect(ltv).to.be.equal(strategyWETH.baseLTVAsCollateral);
expect(liquidationThreshold).to.be.equal(strategyWETH.liquidationThreshold);
expect(liquidationBonus).to.be.equal(strategyWETH.liquidationBonus);
expect(stableBorrowRateEnabled).to.be.equal(strategyWETH.stableBorrowRateEnabled);
expect(reserveFactor).to.be.equal(strategyWETH.reserveFactor);
expect(borrowCap).to.be.equal(strategyWETH.borrowCap);
expect(supplyCap).to.be.equal(strategyWETH.supplyCap);
expect(variableBorrowIndex.toString()).to.be.equal(RAY);
});
it('Deactivates the ETH reserve as collateral', async () => {
it('Check the onlyAaveAdmin or Risk admin on disableBorrowingOnReserve ', async () => {
const { configurator, users, weth, emergencyAdmin } = testEnv;
await expect(
configurator.connect(emergencyAdmin.signer).disableBorrowingOnReserve(weth.address),
CALLER_NOT_POOL_ADMIN
).to.be.revertedWith(LPC_CALLER_NOT_RISK_OR_POOL_ADMIN);
});
it('Check the onlyAaveAdmin or Risk admin on enableBorrowingOnReserve ', async () => {
const { configurator, users, weth, emergencyAdmin } = testEnv;
await expect(
configurator
.connect(emergencyAdmin.signer)
.enableBorrowingOnReserve(weth.address, MAX_BORROW_CAP, true),
CALLER_NOT_POOL_ADMIN
).to.be.revertedWith(LPC_CALLER_NOT_RISK_OR_POOL_ADMIN);
});
it('Deactivates the ETH reserve as collateral via pool admin', async () => {
const { configurator, helpersContract, weth } = testEnv;
await configurator.configureReserveAsCollateral(weth.address, 0, 0, 0);
@ -408,7 +540,7 @@ makeSuite('LendingPoolConfigurator', (testEnv: TestEnv) => {
expect(supplyCap).to.be.equal(strategyWETH.supplyCap);
});
it('Activates the ETH reserve as collateral', async () => {
it('Activates the ETH reserve as collateral via pool admin', async () => {
const { configurator, helpersContract, weth } = testEnv;
await configurator.configureReserveAsCollateral(weth.address, '8000', '8250', '10500');
@ -439,18 +571,85 @@ makeSuite('LendingPoolConfigurator', (testEnv: TestEnv) => {
expect(borrowCap).to.be.equal(strategyWETH.borrowCap);
expect(supplyCap).to.be.equal(strategyWETH.supplyCap);
});
it('Deactivates the ETH reserve as collateral via risk admin', async () => {
const { configurator, helpersContract, weth, riskAdmin } = testEnv;
await configurator
.connect(riskAdmin.signer)
.configureReserveAsCollateral(weth.address, 0, 0, 0);
it('Check the onlyAaveAdmin on configureReserveAsCollateral ', async () => {
const { configurator, users, weth } = testEnv;
await expect(
configurator
.connect(users[2].signer)
.configureReserveAsCollateral(weth.address, '7500', '8000', '10500'),
CALLER_NOT_POOL_ADMIN
).to.be.revertedWith(CALLER_NOT_POOL_ADMIN);
const {
decimals,
ltv,
liquidationBonus,
liquidationThreshold,
reserveFactor,
stableBorrowRateEnabled,
borrowingEnabled,
isActive,
isFrozen,
} = await helpersContract.getReserveConfigurationData(weth.address);
const { borrowCap, supplyCap } = await helpersContract.getReserveCaps(weth.address);
const isPaused = await helpersContract.getPaused(weth.address);
expect(borrowingEnabled).to.be.equal(true);
expect(isActive).to.be.equal(true);
expect(isPaused).to.be.equal(false);
expect(isFrozen).to.be.equal(false);
expect(decimals).to.be.equal(18);
expect(ltv).to.be.equal(0);
expect(liquidationThreshold).to.be.equal(0);
expect(liquidationBonus).to.be.equal(0);
expect(stableBorrowRateEnabled).to.be.equal(true);
expect(reserveFactor).to.be.equal(strategyWETH.reserveFactor);
expect(borrowCap).to.be.equal(strategyWETH.borrowCap);
expect(supplyCap).to.be.equal(strategyWETH.supplyCap);
});
it('Disable stable borrow rate on the ETH reserve', async () => {
it('Activates the ETH reserve as collateral via risk admin', async () => {
const { configurator, helpersContract, weth, riskAdmin } = testEnv;
await configurator
.connect(riskAdmin.signer)
.configureReserveAsCollateral(weth.address, '8000', '8250', '10500');
const {
decimals,
ltv,
liquidationBonus,
liquidationThreshold,
reserveFactor,
stableBorrowRateEnabled,
borrowingEnabled,
isActive,
isFrozen,
} = await helpersContract.getReserveConfigurationData(weth.address);
const { borrowCap, supplyCap } = await helpersContract.getReserveCaps(weth.address);
const isPaused = await helpersContract.getPaused(weth.address);
expect(borrowingEnabled).to.be.equal(true);
expect(isActive).to.be.equal(true);
expect(isPaused).to.be.equal(false);
expect(isFrozen).to.be.equal(false);
expect(decimals).to.be.equal(strategyWETH.reserveDecimals);
expect(ltv).to.be.equal(strategyWETH.baseLTVAsCollateral);
expect(liquidationThreshold).to.be.equal(strategyWETH.liquidationThreshold);
expect(liquidationBonus).to.be.equal(strategyWETH.liquidationBonus);
expect(stableBorrowRateEnabled).to.be.equal(strategyWETH.stableBorrowRateEnabled);
expect(reserveFactor).to.be.equal(strategyWETH.reserveFactor);
expect(borrowCap).to.be.equal(strategyWETH.borrowCap);
expect(supplyCap).to.be.equal(strategyWETH.supplyCap);
});
it('Check the onlyRiskOrPoolAdmin on configureReserveAsCollateral ', async () => {
const { configurator, users, weth, emergencyAdmin } = testEnv;
await expect(
configurator
.connect(emergencyAdmin.signer)
.configureReserveAsCollateral(weth.address, '7500', '8000', '10500'),
CALLER_NOT_POOL_ADMIN
).to.be.revertedWith(LPC_CALLER_NOT_RISK_OR_POOL_ADMIN);
});
it('Disable stable borrow rate on the ETH reserve via pool admin', async () => {
const { configurator, helpersContract, weth } = testEnv;
await configurator.disableReserveStableRate(weth.address);
const {
@ -481,7 +680,7 @@ makeSuite('LendingPoolConfigurator', (testEnv: TestEnv) => {
expect(supplyCap).to.be.equal(strategyWETH.supplyCap);
});
it('Enables stable borrow rate on the ETH reserve', async () => {
it('Enables stable borrow rate on the ETH reserve via pool admin', async () => {
const { configurator, helpersContract, weth } = testEnv;
await configurator.enableReserveStableRate(weth.address);
const {
@ -511,47 +710,108 @@ makeSuite('LendingPoolConfigurator', (testEnv: TestEnv) => {
expect(borrowCap).to.be.equal(strategyWETH.borrowCap);
expect(supplyCap).to.be.equal(strategyWETH.supplyCap);
});
it('Disable stable borrow rate on the ETH reserve risk admin', async () => {
const { configurator, helpersContract, weth, riskAdmin } = testEnv;
await configurator.connect(riskAdmin.signer).disableReserveStableRate(weth.address);
const {
decimals,
ltv,
liquidationBonus,
liquidationThreshold,
reserveFactor,
stableBorrowRateEnabled,
borrowingEnabled,
isActive,
isFrozen,
} = await helpersContract.getReserveConfigurationData(weth.address);
const { borrowCap, supplyCap } = await helpersContract.getReserveCaps(weth.address);
const isPaused = await helpersContract.getPaused(weth.address);
it('Check the onlyAaveAdmin on disableReserveStableRate', async () => {
const { configurator, users, weth } = testEnv;
await expect(
configurator.connect(users[2].signer).disableReserveStableRate(weth.address),
CALLER_NOT_POOL_ADMIN
).to.be.revertedWith(CALLER_NOT_POOL_ADMIN);
expect(borrowingEnabled).to.be.equal(true);
expect(isActive).to.be.equal(true);
expect(isPaused).to.be.equal(false);
expect(isFrozen).to.be.equal(false);
expect(decimals).to.be.equal(strategyWETH.reserveDecimals);
expect(ltv).to.be.equal(strategyWETH.baseLTVAsCollateral);
expect(liquidationThreshold).to.be.equal(strategyWETH.liquidationThreshold);
expect(liquidationBonus).to.be.equal(strategyWETH.liquidationBonus);
expect(stableBorrowRateEnabled).to.be.equal(false);
expect(reserveFactor).to.be.equal(strategyWETH.reserveFactor);
expect(borrowCap).to.be.equal(strategyWETH.borrowCap);
expect(supplyCap).to.be.equal(strategyWETH.supplyCap);
});
it('Check the onlyAaveAdmin on enableReserveStableRate', async () => {
const { configurator, users, weth } = testEnv;
await expect(
configurator.connect(users[2].signer).enableReserveStableRate(weth.address),
CALLER_NOT_POOL_ADMIN
).to.be.revertedWith(CALLER_NOT_POOL_ADMIN);
it('Enables stable borrow rate on the ETH reserve risk admin', async () => {
const { configurator, helpersContract, weth, riskAdmin } = testEnv;
await configurator.connect(riskAdmin.signer).enableReserveStableRate(weth.address);
const {
decimals,
ltv,
liquidationBonus,
liquidationThreshold,
reserveFactor,
stableBorrowRateEnabled,
borrowingEnabled,
isActive,
isFrozen,
} = await helpersContract.getReserveConfigurationData(weth.address);
const { borrowCap, supplyCap } = await helpersContract.getReserveCaps(weth.address);
const isPaused = await helpersContract.getPaused(weth.address);
expect(borrowingEnabled).to.be.equal(true);
expect(isActive).to.be.equal(true);
expect(isPaused).to.be.equal(false);
expect(isFrozen).to.be.equal(false);
expect(decimals).to.be.equal(strategyWETH.reserveDecimals);
expect(ltv).to.be.equal(strategyWETH.baseLTVAsCollateral);
expect(liquidationThreshold).to.be.equal(strategyWETH.liquidationThreshold);
expect(liquidationBonus).to.be.equal(strategyWETH.liquidationBonus);
expect(stableBorrowRateEnabled).to.be.equal(true);
expect(reserveFactor).to.be.equal(strategyWETH.reserveFactor);
expect(borrowCap).to.be.equal(strategyWETH.borrowCap);
expect(supplyCap).to.be.equal(strategyWETH.supplyCap);
});
it('Check the onlyAaveAdmin on setReserveFactor', async () => {
const { configurator, users, weth } = testEnv;
it('Check the onlyRiskOrPoolAdmin on disableReserveStableRate', async () => {
const { configurator, users, weth, emergencyAdmin } = testEnv;
await expect(
configurator.connect(users[2].signer).setReserveFactor(weth.address, '1000'),
configurator.connect(emergencyAdmin.signer).disableReserveStableRate(weth.address),
CALLER_NOT_POOL_ADMIN
).to.be.revertedWith(CALLER_NOT_POOL_ADMIN);
).to.be.revertedWith(LPC_CALLER_NOT_RISK_OR_POOL_ADMIN);
});
it('Check the onlyAaveAdmin on setBorrowCap', async () => {
const { configurator, users, weth } = testEnv;
it('Check the onlyRiskOrPoolAdmin on enableReserveStableRate', async () => {
const { configurator, users, weth, emergencyAdmin } = testEnv;
await expect(
configurator.connect(users[2].signer).setBorrowCap(weth.address, '3000000000'),
configurator.connect(emergencyAdmin.signer).enableReserveStableRate(weth.address),
CALLER_NOT_POOL_ADMIN
).to.be.revertedWith(CALLER_NOT_POOL_ADMIN);
});
it('Check the onlyAaveAdmin on setSupplyCap', async () => {
const { configurator, users, weth } = testEnv;
await expect(
configurator.connect(users[2].signer).setSupplyCap(weth.address, '3000000000'),
CALLER_NOT_POOL_ADMIN
).to.be.revertedWith(CALLER_NOT_POOL_ADMIN);
).to.be.revertedWith(LPC_CALLER_NOT_RISK_OR_POOL_ADMIN);
});
it('Changes the reserve factor of WETH', async () => {
it('Check the onlyRiskOrPoolAdmin on setReserveFactor', async () => {
const { configurator, users, weth, emergencyAdmin } = testEnv;
await expect(
configurator.connect(emergencyAdmin.signer).setReserveFactor(weth.address, '1000'),
CALLER_NOT_POOL_ADMIN
).to.be.revertedWith(LPC_CALLER_NOT_RISK_OR_POOL_ADMIN);
});
it('Check the onlyRiskOrPoolAdmin on setBorrowCap', async () => {
const { configurator, users, weth, emergencyAdmin } = testEnv;
await expect(
configurator.connect(emergencyAdmin.signer).setBorrowCap(weth.address, '3000000000'),
CALLER_NOT_POOL_ADMIN
).to.be.revertedWith(LPC_CALLER_NOT_RISK_OR_POOL_ADMIN);
});
it('Check the onlyRiskOrPoolAdmin on setSupplyCap', async () => {
const { configurator, users, weth, emergencyAdmin } = testEnv;
await expect(
configurator.connect(emergencyAdmin.signer).setSupplyCap(weth.address, '3000000000'),
CALLER_NOT_POOL_ADMIN
).to.be.revertedWith(LPC_CALLER_NOT_RISK_OR_POOL_ADMIN);
});
it('Changes the reserve factor of WETH via pool admin', async () => {
const { configurator, helpersContract, weth } = testEnv;
await configurator.setReserveFactor(weth.address, '1000');
const {
@ -581,6 +841,36 @@ makeSuite('LendingPoolConfigurator', (testEnv: TestEnv) => {
expect(supplyCap).to.be.equal(strategyWETH.supplyCap);
expect(reserveFactor).to.be.equal(1000);
});
it('Changes the reserve factor of WETH risk admin', async () => {
const { configurator, helpersContract, weth, riskAdmin } = testEnv;
await configurator.connect(riskAdmin.signer).setReserveFactor(weth.address, '1000');
const {
decimals,
ltv,
liquidationBonus,
liquidationThreshold,
reserveFactor,
stableBorrowRateEnabled,
borrowingEnabled,
isActive,
isFrozen,
} = await helpersContract.getReserveConfigurationData(weth.address);
const { borrowCap, supplyCap } = await helpersContract.getReserveCaps(weth.address);
const isPaused = await helpersContract.getPaused(weth.address);
expect(borrowingEnabled).to.be.equal(true);
expect(isActive).to.be.equal(true);
expect(isPaused).to.be.equal(false);
expect(isFrozen).to.be.equal(false);
expect(decimals).to.be.equal(strategyWETH.reserveDecimals);
expect(ltv).to.be.equal(strategyWETH.baseLTVAsCollateral);
expect(liquidationThreshold).to.be.equal(strategyWETH.liquidationThreshold);
expect(liquidationBonus).to.be.equal(strategyWETH.liquidationBonus);
expect(stableBorrowRateEnabled).to.be.equal(strategyWETH.stableBorrowRateEnabled);
expect(borrowCap).to.be.equal(strategyWETH.borrowCap);
expect(supplyCap).to.be.equal(strategyWETH.supplyCap);
expect(reserveFactor).to.be.equal(1000);
});
it('Check that borrowCap cannot be set to value that exceeds the MAX_BORROW_CAP', async () => {
const { configurator, users, weth } = testEnv;
@ -597,7 +887,7 @@ makeSuite('LendingPoolConfigurator', (testEnv: TestEnv) => {
).to.be.revertedWith(RC_INVALID_SUPPLY_CAP);
});
it('Changes the borrow Cap of WETH', async () => {
it('Changes the borrow Cap of WETH via pool admin', async () => {
const { configurator, helpersContract, weth } = testEnv;
await configurator.setBorrowCap(weth.address, '3000000');
const {
@ -627,8 +917,38 @@ makeSuite('LendingPoolConfigurator', (testEnv: TestEnv) => {
expect(borrowCap).to.be.equal('3000000');
expect(supplyCap).to.be.equal(strategyWETH.supplyCap);
});
it('Changes the borrow Cap of WETH risk admin', async () => {
const { configurator, helpersContract, weth, riskAdmin } = testEnv;
await configurator.connect(riskAdmin.signer).setBorrowCap(weth.address, '3000000');
const {
decimals,
ltv,
liquidationBonus,
liquidationThreshold,
reserveFactor,
stableBorrowRateEnabled,
borrowingEnabled,
isActive,
isFrozen,
} = await helpersContract.getReserveConfigurationData(weth.address);
const { borrowCap, supplyCap } = await helpersContract.getReserveCaps(weth.address);
const isPaused = await helpersContract.getPaused(weth.address);
it('Changes the supply Cap of WETH', async () => {
expect(borrowingEnabled).to.be.equal(true);
expect(isActive).to.be.equal(true);
expect(isPaused).to.be.equal(false);
expect(isFrozen).to.be.equal(false);
expect(decimals).to.be.equal(strategyWETH.reserveDecimals);
expect(ltv).to.be.equal(strategyWETH.baseLTVAsCollateral);
expect(liquidationThreshold).to.be.equal(strategyWETH.liquidationThreshold);
expect(liquidationBonus).to.be.equal(strategyWETH.liquidationBonus);
expect(stableBorrowRateEnabled).to.be.equal(strategyWETH.stableBorrowRateEnabled);
expect(reserveFactor).to.be.equal(1000);
expect(borrowCap).to.be.equal('3000000');
expect(supplyCap).to.be.equal(strategyWETH.supplyCap);
});
it('Changes the supply Cap of WETH via pool admin', async () => {
const { configurator, helpersContract, weth } = testEnv;
await configurator.setSupplyCap(weth.address, '3000000');
const {
@ -658,6 +978,36 @@ makeSuite('LendingPoolConfigurator', (testEnv: TestEnv) => {
expect(borrowCap).to.be.equal('3000000');
expect(supplyCap).to.be.equal('3000000');
});
it('Changes the supply Cap of WETH via risk admin', async () => {
const { configurator, helpersContract, weth, riskAdmin } = testEnv;
await configurator.connect(riskAdmin.signer).setSupplyCap(weth.address, '3000000');
const {
decimals,
ltv,
liquidationBonus,
liquidationThreshold,
reserveFactor,
stableBorrowRateEnabled,
borrowingEnabled,
isActive,
isFrozen,
} = await helpersContract.getReserveConfigurationData(weth.address);
const { borrowCap, supplyCap } = await helpersContract.getReserveCaps(weth.address);
const isPaused = await helpersContract.getPaused(weth.address);
expect(borrowingEnabled).to.be.equal(true);
expect(isActive).to.be.equal(true);
expect(isPaused).to.be.equal(false);
expect(isFrozen).to.be.equal(false);
expect(decimals).to.be.equal(strategyWETH.reserveDecimals);
expect(ltv).to.be.equal(strategyWETH.baseLTVAsCollateral);
expect(liquidationThreshold).to.be.equal(strategyWETH.liquidationThreshold);
expect(liquidationBonus).to.be.equal(strategyWETH.liquidationBonus);
expect(stableBorrowRateEnabled).to.be.equal(strategyWETH.stableBorrowRateEnabled);
expect(reserveFactor).to.be.equal(1000);
expect(borrowCap).to.be.equal('3000000');
expect(supplyCap).to.be.equal('3000000');
});
it('Reverts when trying to disable the DAI reserve with liquidity on it', async () => {
const { dai, pool, configurator } = testEnv;
@ -676,4 +1026,23 @@ makeSuite('LendingPoolConfigurator', (testEnv: TestEnv) => {
LPC_RESERVE_LIQUIDITY_NOT_0
).to.be.revertedWith(LPC_RESERVE_LIQUIDITY_NOT_0);
});
it('Register a new risk Admin', async () => {
const { dai, pool, configurator, users, riskAdmin } = testEnv;
await configurator.registerRiskAdmin(users[3].address);
const isRiskAdminRegistered = await configurator.isRiskAdmin(riskAdmin.address);
const isNewRegistered = await configurator.isRiskAdmin(users[3].address);
expect(isNewRegistered).to.be.true;
expect(isRiskAdminRegistered).to.be.true;
});
it('Unregister a risk Admins', async () => {
const { dai, pool, configurator, users, riskAdmin } = testEnv;
await configurator.unregisterRiskAdmin(users[3].address);
await configurator.unregisterRiskAdmin(riskAdmin.address);
const isRiskAdminRegistered = await configurator.isRiskAdmin(riskAdmin.address);
const isNewRegistered = await configurator.isRiskAdmin(users[3].address);
expect(isNewRegistered).to.be.false;
expect(isRiskAdminRegistered).to.be.false;
});
});

View File

@ -51,6 +51,9 @@ export interface SignerWithAddress {
}
export interface TestEnv {
deployer: SignerWithAddress;
poolAdmin: SignerWithAddress;
emergencyAdmin: SignerWithAddress;
riskAdmin: SignerWithAddress;
users: SignerWithAddress[];
pool: LendingPool;
configurator: LendingPoolConfigurator;
@ -77,6 +80,9 @@ const setBuidlerevmSnapshotId = (id: string) => {
const testEnv: TestEnv = {
deployer: {} as SignerWithAddress,
poolAdmin: {} as SignerWithAddress,
emergencyAdmin: {} as SignerWithAddress,
riskAdmin: {} as SignerWithAddress,
users: [] as SignerWithAddress[],
pool: {} as LendingPool,
configurator: {} as LendingPoolConfigurator,
@ -110,6 +116,9 @@ export async function initializeMakeSuite() {
});
}
testEnv.deployer = deployer;
testEnv.poolAdmin = deployer;
testEnv.emergencyAdmin = testEnv.users[1];
testEnv.riskAdmin = testEnv.users[2];
testEnv.pool = await getLendingPool();
testEnv.configurator = await getLendingPoolConfiguratorProxy();

View File

@ -156,7 +156,7 @@ makeSuite('LendingPoolConfigurator', (testEnv: TestEnv) => {
it('Activates the ETH reserve for borrowing', async () => {
const { configurator, weth, helpersContract } = testEnv;
await configurator.enableBorrowingOnReserve(weth.address, MAX_BORROW_CAP, true);
await configurator.enableBorrowingOnReserve(weth.address, '0', true);
const { variableBorrowIndex } = await helpersContract.getReserveData(weth.address);
const {