import rawBRE from 'hardhat'; import { MockContract } from 'ethereum-waffle'; import { insertContractAddressInDb, getEthersSigners, registerContractInJsonDb, getEthersSignersAddresses, } from '../../helpers/contracts-helpers'; import { deployLendingPoolAddressesProvider, deployMintableERC20, deployLendingPoolAddressesProviderRegistry, deployLendingPoolConfigurator, deployLendingPool, deployPriceOracle, deployLendingPoolCollateralManager, deployMockFlashLoanReceiver, deployWalletBalancerProvider, deployAaveProtocolDataProvider, deployLendingRateOracle, deployStableAndVariableTokensHelper, deployATokensAndRatesHelper, deployWETHGateway, deployWETHMocked, deployMockUniswapRouter, deployUniswapLiquiditySwapAdapter, deployUniswapRepayAdapter, deployFlashLiquidationAdapter, authorizeWETHGateway, deployATokenImplementations, deployAaveOracle, } from '../../helpers/contracts-deployments'; import { Signer } from 'ethers'; import { TokenContractId, eContractid, tEthereumAddress, AavePools } from '../../helpers/types'; import { MintableERC20 } from '../../types/MintableERC20'; import { ConfigNames, getReservesConfigByPool, getTreasuryAddress, loadPoolConfig, } 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, configureReservesByHelper } from '../../helpers/init-helpers'; import AmmConfig from '../../markets/amm'; import { oneEther, ZERO_ADDRESS } from '../../helpers/constants'; import { getLendingPool, getLendingPoolConfiguratorProxy, getPairsTokenAggregator, } from '../../helpers/contracts-getters'; import { WETH9Mocked } from '../../types/WETH9Mocked'; const MOCK_USD_PRICE_IN_WEI = AmmConfig.ProtocolGlobalParams.MockUsdPriceInWei; const ALL_ASSETS_INITIAL_PRICES = AmmConfig.Mocks.AllAssetsInitialPrices; const USD_ADDRESS = AmmConfig.ProtocolGlobalParams.UsdAddress; const MOCK_CHAINLINK_AGGREGATORS_PRICES = AmmConfig.Mocks.AllAssetsInitialPrices; const LENDING_RATE_ORACLE_RATES_COMMON = AmmConfig.LendingRateOracleRatesCommon; const deployAllMockTokens = async (deployer: Signer) => { const tokens: { [symbol: string]: MockContract | MintableERC20 | WETH9Mocked } = {}; const ammConfigData = getReservesConfigByPool(AavePools.amm); for (const tokenSymbol of Object.keys(TokenContractId)) { if (tokenSymbol === 'WETH') { tokens[tokenSymbol] = await deployWETHMocked(); await registerContractInJsonDb('WETH', tokens[tokenSymbol]); continue; } let decimals = 18; let configData = (ammConfigData)[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 config = loadPoolConfig(ConfigNames.Amm); const { ATokenNamePrefix, StableDebtTokenNamePrefix, VariableDebtTokenNamePrefix, SymbolPrefix, ReservesConfig, } = config; const mockTokens = await deployAllMockTokens(deployer); const addressesProvider = await deployLendingPoolAddressesProvider(AmmConfig.MarketId); 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 getEthersSignersAddresses(); 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, 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, // DAI: mockTokens.LpDAI.address, // USDC: mockTokens.LpUSDC.address, // USDT: mockTokens.LpUSDT.address, // WBTC: mockTokens.LpWBTC.address, // WETH: mockTokens.LpWETH.address, UniDAIWETH: mockTokens.UniDAIWETH.address, UniWBTCWETH: mockTokens.UniWBTCWETH.address, UniAAVEWETH: mockTokens.UniAAVEWETH.address, UniBATWETH: mockTokens.UniBATWETH.address, UniDAIUSDC: mockTokens.UniDAIUSDC.address, UniCRVWETH: mockTokens.UniCRVWETH.address, UniLINKWETH: mockTokens.UniLINKWETH.address, UniMKRWETH: mockTokens.UniMKRWETH.address, UniRENWETH: mockTokens.UniRENWETH.address, UniSNXWETH: mockTokens.UniSNXWETH.address, UniUNIWETH: mockTokens.UniUNIWETH.address, UniUSDCWETH: mockTokens.UniUSDCWETH.address, UniWBTCUSDC: mockTokens.UniWBTCUSDC.address, UniYFIWETH: mockTokens.UniYFIWETH.address, BptWBTCWETH: mockTokens.BptWBTCWETH.address, BptBALWETH: mockTokens.BptBALWETH.address, WMATIC: mockTokens.WMATIC.address, USD: USD_ADDRESS, STAKE: mockTokens.STAKE.address, xSUSHI: ZERO_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, config.OracleQuoteCurrency ); await deployAaveOracle([ tokens, aggregators, fallbackOracle.address, mockTokens.WETH.address, oneEther.toString(), ]); 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 ); await deployATokenImplementations(ConfigNames.Amm, ReservesConfig); const testHelpers = await deployAaveProtocolDataProvider(addressesProvider.address); await insertContractAddressInDb(eContractid.AaveProtocolDataProvider, testHelpers.address); const admin = await deployer.getAddress(); console.log('Initialize configuration'); const treasuryAddress = await getTreasuryAddress(config); await initReservesByHelper( ReservesConfig, allReservesAddresses, ATokenNamePrefix, StableDebtTokenNamePrefix, VariableDebtTokenNamePrefix, SymbolPrefix, admin, treasuryAddress, ZERO_ADDRESS, ConfigNames.Amm, false ); await configureReservesByHelper(ReservesConfig, allReservesAddresses, testHelpers, admin); const collateralManager = await deployLendingPoolCollateralManager(); await waitForTx( await addressesProvider.setLendingPoolCollateralManager(collateralManager.address) ); await deployMockFlashLoanReceiver(addressesProvider.address); const mockUniswapRouter = await deployMockUniswapRouter(); const adapterParams: [string, string, string] = [ addressesProvider.address, mockUniswapRouter.address, mockTokens.WETH.address, ]; await deployUniswapLiquiditySwapAdapter(adapterParams); await deployUniswapRepayAdapter(adapterParams); await deployFlashLiquidationAdapter(adapterParams); await deployWalletBalancerProvider(); const gateWay = await deployWETHGateway([mockTokens.WETH.address]); await authorizeWETHGateway(gateWay.address, lendingPoolAddress); console.timeEnd('setup'); }; before(async () => { await rawBRE.run('set-DRE'); const [deployer, secondaryWallet] = await getEthersSigners(); const FORK = process.env.FORK; if (FORK) { await rawBRE.run('amm:mainnet', { skipRegistry: true }); } else { console.log('-> Deploying test environment...'); await buildTestEnv(deployer, secondaryWallet); } await initializeMakeSuite(); console.log('\n***************'); console.log('Setup and snapshot finished'); console.log('***************\n'); });