import { TestEnv, makeSuite } from './helpers/make-suite'; import { APPROVAL_AMOUNT_LENDING_POOL, MAX_UINT_AMOUNT, RAY, MAX_BORROW_CAP, } from '../../helpers/constants'; import { convertToCurrencyDecimals } from '../../helpers/contracts-helpers'; import { ProtocolErrors } from '../../helpers/types'; import { strategyWETH } from '../../markets/aave/reservesConfigs'; import { BigNumber } from '@ethersproject/bignumber'; const { expect } = require('chai'); makeSuite('LendingPoolConfigurator', (testEnv: TestEnv) => { const { CALLER_NOT_POOL_ADMIN, LPC_RESERVE_LIQUIDITY_NOT_0, RC_INVALID_LTV, RC_INVALID_LIQ_THRESHOLD, RC_INVALID_LIQ_BONUS, RC_INVALID_DECIMALS, RC_INVALID_RESERVE_FACTOR, RC_INVALID_BORROW_CAP, RC_INVALID_SUPPLY_CAP, } = ProtocolErrors; it('Reverts trying to set an invalid reserve factor', async () => { const { configurator, weth } = testEnv; const invalidReserveFactor = 65536; await expect( configurator.setReserveFactor(weth.address, invalidReserveFactor) ).to.be.revertedWith(RC_INVALID_RESERVE_FACTOR); }); it('Deactivates the ETH reserve', async () => { const { configurator, weth, helpersContract } = testEnv; await configurator.deactivateReserve(weth.address); const { isActive } = await helpersContract.getReserveConfigurationData(weth.address); expect(isActive).to.be.equal(false); }); it('Rectivates the ETH reserve', async () => { const { configurator, weth, helpersContract } = testEnv; await configurator.activateReserve(weth.address); const { isActive } = await helpersContract.getReserveConfigurationData(weth.address); expect(isActive).to.be.equal(true); }); it('Check the onlyAaveAdmin on deactivateReserve ', async () => { const { configurator, users, weth } = testEnv; await expect( configurator.connect(users[2].signer).deactivateReserve(weth.address), CALLER_NOT_POOL_ADMIN ).to.be.revertedWith(CALLER_NOT_POOL_ADMIN); }); it('Check the onlyAaveAdmin on activateReserve ', async () => { const { configurator, users, weth } = testEnv; await expect( configurator.connect(users[2].signer).activateReserve(weth.address), CALLER_NOT_POOL_ADMIN ).to.be.revertedWith(CALLER_NOT_POOL_ADMIN); }); it('Freezes the ETH reserve', async () => { const { configurator, weth, helpersContract } = testEnv; await configurator.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); expect(borrowingEnabled).to.be.equal(true); expect(isActive).to.be.equal(true); 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('Unfreezes the ETH reserve', async () => { const { configurator, helpersContract, weth } = testEnv; await configurator.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); expect(borrowingEnabled).to.be.equal(true); expect(isActive).to.be.equal(true); 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 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); }); 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('Deactivates the ETH reserve for borrowing', async () => { const { configurator, helpersContract, weth } = testEnv; await configurator.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); expect(borrowingEnabled).to.be.equal(false); expect(isActive).to.be.equal(true); 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('Activates the ETH reserve for borrowing', async () => { const { configurator, weth, helpersContract } = testEnv; await configurator.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); expect(borrowingEnabled).to.be.equal(true); expect(isActive).to.be.equal(true); 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('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('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('Deactivates the ETH reserve as collateral', async () => { const { configurator, helpersContract, weth } = testEnv; await configurator.configureReserveAsCollateral(weth.address, 0, 0, 0); const { decimals, ltv, liquidationBonus, liquidationThreshold, reserveFactor, stableBorrowRateEnabled, borrowingEnabled, isActive, isFrozen, } = await helpersContract.getReserveConfigurationData(weth.address); const { borrowCap, supplyCap } = await helpersContract.getReserveCaps(weth.address); expect(borrowingEnabled).to.be.equal(true); expect(isActive).to.be.equal(true); 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('Activates the ETH reserve as collateral', async () => { const { configurator, helpersContract, weth } = testEnv; await configurator.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); expect(borrowingEnabled).to.be.equal(true); expect(isActive).to.be.equal(true); 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 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); }); it('Disable stable borrow rate on the ETH reserve', async () => { const { configurator, helpersContract, weth } = testEnv; await configurator.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); expect(borrowingEnabled).to.be.equal(true); expect(isActive).to.be.equal(true); 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('Enables stable borrow rate on the ETH reserve', async () => { const { configurator, helpersContract, weth } = testEnv; await configurator.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); expect(borrowingEnabled).to.be.equal(true); expect(isActive).to.be.equal(true); 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 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); }); 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('Check the onlyAaveAdmin on setReserveFactor', async () => { const { configurator, users, weth } = testEnv; await expect( configurator.connect(users[2].signer).setReserveFactor(weth.address, '1000'), CALLER_NOT_POOL_ADMIN ).to.be.revertedWith(CALLER_NOT_POOL_ADMIN); }); it('Check the onlyAaveAdmin on setBorrowCap', async () => { const { configurator, users, weth } = testEnv; await expect( configurator.connect(users[2].signer).setBorrowCap(weth.address, '3000000000'), 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); }); it('Changes the reserve factor of WETH', async () => { const { configurator, helpersContract, weth } = testEnv; await configurator.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); expect(borrowingEnabled).to.be.equal(true); expect(isActive).to.be.equal(true); 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; await expect( configurator.setBorrowCap(weth.address, BigNumber.from(MAX_BORROW_CAP).add(1)), CALLER_NOT_POOL_ADMIN ).to.be.revertedWith(RC_INVALID_BORROW_CAP); }); it('Check that supplyCap cannot be set to value that exceeds the MAX_SUPPLY_CAP', async () => { const { configurator, users, weth } = testEnv; await expect( configurator.setSupplyCap(weth.address, BigNumber.from(MAX_BORROW_CAP).add(1)), CALLER_NOT_POOL_ADMIN ).to.be.revertedWith(RC_INVALID_SUPPLY_CAP); }); it('Changes the borrow Cap of WETH', async () => { const { configurator, helpersContract, weth } = testEnv; await configurator.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); expect(borrowingEnabled).to.be.equal(true); expect(isActive).to.be.equal(true); 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', async () => { const { configurator, helpersContract, weth } = testEnv; await configurator.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); expect(borrowingEnabled).to.be.equal(true); expect(isActive).to.be.equal(true); 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; const userAddress = await pool.signer.getAddress(); await dai.mint(await convertToCurrencyDecimals(dai.address, '1000')); //approve protocol to access depositor wallet await dai.approve(pool.address, APPROVAL_AMOUNT_LENDING_POOL); const amountDAItoDeposit = await convertToCurrencyDecimals(dai.address, '1000'); //user 1 deposits 1000 DAI await pool.deposit(dai.address, amountDAItoDeposit, userAddress, '0'); await expect( configurator.deactivateReserve(dai.address), LPC_RESERVE_LIQUIDITY_NOT_0 ).to.be.revertedWith(LPC_RESERVE_LIQUIDITY_NOT_0); }); });