import rawBRE from 'hardhat'; import {MockContract} from 'ethereum-waffle'; import { insertContractAddressInDb, getEthersSigners, registerContractInJsonDb, } from '../helpers/contracts-helpers'; import { deployLendingPoolAddressesProvider, deployMintableERC20, deployLendingPoolAddressesProviderRegistry, deployLendingPoolConfigurator, deployLendingPool, deployPriceOracle, deployChainlinkProxyPriceProvider, deployLendingPoolCollateralManager, deployMockFlashLoanReceiver, deployWalletBalancerProvider, deployAaveProtocolDataProvider, deployLendingRateOracle, deployStableAndVariableTokensHelper, deployATokensAndRatesHelper, deployWETHGateway, deployWETHMocked, deployMockUniswapRouter, deployUniswapLiquiditySwapAdapter, deployUniswapRepayAdapter, } from '../helpers/contracts-deployments'; import {Signer} from 'ethers'; import {TokenContractId, eContractid, tEthereumAddress, AavePools} from '../helpers/types'; import {MintableErc20 as MintableERC20} from '../types/MintableErc20'; import {getEmergencyAdmin, getReservesConfigByPool} from '../helpers/configuration'; import {initializeMakeSuite} from './helpers/make-suite'; import { setInitialAssetPricesInOracle, deployAllMockAggregators, setInitialMarketRatesInRatesOracleByHelper, } from '../helpers/oracles-helpers'; import {DRE, waitForTx} from '../helpers/misc-utils'; import { initReservesByHelper, enableReservesToBorrowByHelper, enableReservesAsCollateralByHelper, } from '../helpers/init-helpers'; import {AaveConfig} from '../config/aave'; import {ZERO_ADDRESS} from '../helpers/constants'; import { getLendingPool, getLendingPoolConfiguratorProxy, getPairsTokenAggregator, } from '../helpers/contracts-getters'; import {Weth9Mocked} from '../types/Weth9Mocked'; const MOCK_USD_PRICE_IN_WEI = AaveConfig.ProtocolGlobalParams.MockUsdPriceInWei; const ALL_ASSETS_INITIAL_PRICES = AaveConfig.Mocks.AllAssetsInitialPrices; const USD_ADDRESS = AaveConfig.ProtocolGlobalParams.UsdAddress; const MOCK_CHAINLINK_AGGREGATORS_PRICES = AaveConfig.Mocks.ChainlinkAggregatorPrices; const LENDING_RATE_ORACLE_RATES_COMMON = AaveConfig.LendingRateOracleRatesCommon; const deployAllMockTokens = async (deployer: Signer) => { const tokens: {[symbol: string]: MockContract | MintableERC20 | Weth9Mocked} = {}; const protoConfigData = getReservesConfigByPool(AavePools.proto); const secondaryConfigData = getReservesConfigByPool(AavePools.secondary); for (const tokenSymbol of Object.keys(TokenContractId)) { if (tokenSymbol === 'WETH') { tokens[tokenSymbol] = await deployWETHMocked(); await registerContractInJsonDb(tokenSymbol.toUpperCase(), tokens[tokenSymbol]); continue; } let decimals = 18; let configData = (protoConfigData)[tokenSymbol]; if (!configData) { configData = (secondaryConfigData)[tokenSymbol]; } if (!configData) { decimals = 18; } tokens[tokenSymbol] = await deployMintableERC20([ tokenSymbol, tokenSymbol, configData ? configData.reserveDecimals : 18, ]); await registerContractInJsonDb(tokenSymbol.toUpperCase(), tokens[tokenSymbol]); } return tokens; }; const buildTestEnv = async (deployer: Signer, secondaryWallet: Signer) => { console.time('setup'); const aaveAdmin = await deployer.getAddress(); const mockTokens = await deployAllMockTokens(deployer); const mockTokenAddress = Object.keys(mockTokens).reduce<{[key: string]: string}>((acc, key) => { acc[key] = mockTokens[key].address; return acc; }, {}); const addressesProvider = await deployLendingPoolAddressesProvider(); await waitForTx(await addressesProvider.setPoolAdmin(aaveAdmin)); //setting users[1] as emergency admin, which is in position 2 in the DRE addresses list const addressList = await Promise.all( (await DRE.ethers.getSigners()).map((signer) => signer.getAddress()) ); await waitForTx(await addressesProvider.setEmergencyAdmin(addressList[2])); const addressesProviderRegistry = await deployLendingPoolAddressesProviderRegistry(); await waitForTx( await addressesProviderRegistry.registerAddressesProvider(addressesProvider.address, 1) ); const lendingPoolImpl = await deployLendingPool(); await waitForTx(await addressesProvider.setLendingPoolImpl(lendingPoolImpl.address)); const lendingPoolAddress = await addressesProvider.getLendingPool(); const lendingPoolProxy = await getLendingPool(lendingPoolAddress); await insertContractAddressInDb(eContractid.LendingPool, lendingPoolProxy.address); const lendingPoolConfiguratorImpl = await deployLendingPoolConfigurator(); await waitForTx( await addressesProvider.setLendingPoolConfiguratorImpl(lendingPoolConfiguratorImpl.address) ); const lendingPoolConfiguratorProxy = await getLendingPoolConfiguratorProxy( await addressesProvider.getLendingPoolConfigurator() ); await insertContractAddressInDb( eContractid.LendingPoolConfigurator, lendingPoolConfiguratorProxy.address ); // Deploy deployment helpers await deployStableAndVariableTokensHelper([lendingPoolProxy.address, addressesProvider.address]); await deployATokensAndRatesHelper([ lendingPoolProxy.address, addressesProvider.address, lendingPoolConfiguratorProxy.address, ]); const fallbackOracle = await deployPriceOracle(); await waitForTx(await fallbackOracle.setEthUsdPrice(MOCK_USD_PRICE_IN_WEI)); await setInitialAssetPricesInOracle( ALL_ASSETS_INITIAL_PRICES, { WETH: mockTokens.WETH.address, DAI: mockTokens.DAI.address, TUSD: mockTokens.TUSD.address, USDC: mockTokens.USDC.address, USDT: mockTokens.USDT.address, SUSD: mockTokens.SUSD.address, AAVE: mockTokens.AAVE.address, BAT: mockTokens.BAT.address, REP: mockTokens.REP.address, MKR: mockTokens.MKR.address, LINK: mockTokens.LINK.address, KNC: mockTokens.KNC.address, WBTC: mockTokens.WBTC.address, MANA: mockTokens.MANA.address, ZRX: mockTokens.ZRX.address, SNX: mockTokens.SNX.address, BUSD: mockTokens.BUSD.address, YFI: mockTokens.BUSD.address, REN: mockTokens.REN.address, UNI: mockTokens.UNI.address, ENJ: mockTokens.ENJ.address, USD: USD_ADDRESS, UNI_DAI_ETH: mockTokens.UNI_DAI_ETH.address, UNI_USDC_ETH: mockTokens.UNI_USDC_ETH.address, UNI_SETH_ETH: mockTokens.UNI_SETH_ETH.address, UNI_LEND_ETH: mockTokens.UNI_LEND_ETH.address, UNI_MKR_ETH: mockTokens.UNI_MKR_ETH.address, UNI_LINK_ETH: mockTokens.UNI_LINK_ETH.address, }, fallbackOracle ); const mockAggregators = await deployAllMockAggregators(MOCK_CHAINLINK_AGGREGATORS_PRICES); const allTokenAddresses = Object.entries(mockTokens).reduce( (accum: {[tokenSymbol: string]: tEthereumAddress}, [tokenSymbol, tokenContract]) => ({ ...accum, [tokenSymbol]: tokenContract.address, }), {} ); const allAggregatorsAddresses = Object.entries(mockAggregators).reduce( (accum: {[tokenSymbol: string]: tEthereumAddress}, [tokenSymbol, aggregator]) => ({ ...accum, [tokenSymbol]: aggregator.address, }), {} ); const [tokens, aggregators] = getPairsTokenAggregator(allTokenAddresses, allAggregatorsAddresses); const chainlinkProxyPriceProvider = await deployChainlinkProxyPriceProvider([ tokens, aggregators, fallbackOracle.address, mockTokens.WETH.address, ]); await waitForTx(await addressesProvider.setPriceOracle(fallbackOracle.address)); const lendingRateOracle = await deployLendingRateOracle(); await waitForTx(await addressesProvider.setLendingRateOracle(lendingRateOracle.address)); const {USD, ...tokensAddressesWithoutUsd} = allTokenAddresses; const allReservesAddresses = { ...tokensAddressesWithoutUsd, }; await setInitialMarketRatesInRatesOracleByHelper( LENDING_RATE_ORACLE_RATES_COMMON, allReservesAddresses, lendingRateOracle, aaveAdmin ); const { UNI_DAI_ETH, UNI_USDC_ETH, UNI_SETH_ETH, UNI_LINK_ETH, UNI_MKR_ETH, UNI_LEND_ETH, ...protoPoolReservesAddresses } = <{[symbol: string]: tEthereumAddress}>allReservesAddresses; const reservesParams = getReservesConfigByPool(AavePools.proto); const testHelpers = await deployAaveProtocolDataProvider(addressesProvider.address); await insertContractAddressInDb(eContractid.AaveProtocolDataProvider, testHelpers.address); const admin = await deployer.getAddress(); console.log('Initialize configuration'); await initReservesByHelper(reservesParams, protoPoolReservesAddresses, admin, ZERO_ADDRESS); await enableReservesToBorrowByHelper( reservesParams, protoPoolReservesAddresses, testHelpers, admin ); await enableReservesAsCollateralByHelper( reservesParams, protoPoolReservesAddresses, testHelpers, admin ); const collateralManager = await deployLendingPoolCollateralManager(); await waitForTx( await addressesProvider.setLendingPoolCollateralManager(collateralManager.address) ); const mockFlashLoanReceiver = await deployMockFlashLoanReceiver(addressesProvider.address); await insertContractAddressInDb(eContractid.MockFlashLoanReceiver, mockFlashLoanReceiver.address); const mockUniswapRouter = await deployMockUniswapRouter(); await insertContractAddressInDb(eContractid.MockUniswapV2Router02, mockUniswapRouter.address); const UniswapLiquiditySwapAdapter = await deployUniswapLiquiditySwapAdapter([ addressesProvider.address, mockUniswapRouter.address, ]); await insertContractAddressInDb( eContractid.UniswapLiquiditySwapAdapter, UniswapLiquiditySwapAdapter.address ); const UniswapRepayAdapter = await deployUniswapRepayAdapter([ addressesProvider.address, mockUniswapRouter.address, ]); await insertContractAddressInDb(eContractid.UniswapRepayAdapter, UniswapRepayAdapter.address); await deployWalletBalancerProvider(addressesProvider.address); await deployWETHGateway([mockTokens.WETH.address, lendingPoolAddress]); console.timeEnd('setup'); }; before(async () => { await rawBRE.run('set-DRE'); const [deployer, secondaryWallet] = await getEthersSigners(); console.log('-> Deploying test environment...'); await buildTestEnv(deployer, secondaryWallet); await initializeMakeSuite(); console.log('\n***************'); console.log('Setup and snapshot finished'); console.log('***************\n'); });