mirror of
				https://github.com/Instadapp/aave-protocol-v2.git
				synced 2024-07-29 21:47:30 +00:00 
			
		
		
		
	Added missing stash work
This commit is contained in:
		
							parent
							
								
									383f7fc3bb
								
							
						
					
					
						commit
						54d9e3a7ee
					
				| 
						 | 
				
			
			@ -1,3 +1,6 @@
 | 
			
		|||
import path from 'path';
 | 
			
		||||
import fs from 'fs';
 | 
			
		||||
 | 
			
		||||
import {usePlugin, BuidlerConfig} from '@nomiclabs/buidler/config';
 | 
			
		||||
// @ts-ignore
 | 
			
		||||
import {accounts} from './test-wallets.js';
 | 
			
		||||
| 
						 | 
				
			
			@ -22,6 +25,13 @@ const MNEMONICS: {[network: string]: string} = {
 | 
			
		|||
  [eEthereumNetwork.main]: '',
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
['misc', 'migrations', 'dev-deployment'].forEach((folder) => {
 | 
			
		||||
  const tasksPath = path.join(__dirname, 'tasks', folder);
 | 
			
		||||
  fs.readdirSync(tasksPath)
 | 
			
		||||
    .filter((pth) => pth.includes('.ts'))
 | 
			
		||||
    .forEach((task) => require(`${tasksPath}/${task}`));
 | 
			
		||||
});
 | 
			
		||||
 | 
			
		||||
const getCommonNetworkConfig = (networkName: eEthereumNetwork, networkId: number) => {
 | 
			
		||||
  return {
 | 
			
		||||
    url: `https://${networkName}.infura.io/v3/${INFURA_KEY}`,
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -9,6 +9,10 @@ import {
 | 
			
		|||
  AavePools,
 | 
			
		||||
  iParamsPerNetwork,
 | 
			
		||||
  iParamsPerPool,
 | 
			
		||||
  TokenContractId,
 | 
			
		||||
  MockTokenMap,
 | 
			
		||||
  iMultiPoolsAssets,
 | 
			
		||||
  IReserveParams,
 | 
			
		||||
} from './types';
 | 
			
		||||
import {LendingPoolAddressesProvider} from '../types/LendingPoolAddressesProvider';
 | 
			
		||||
import {MintableErc20} from '../types/MintableErc20';
 | 
			
		||||
| 
						 | 
				
			
			@ -33,6 +37,9 @@ import BigNumber from 'bignumber.js';
 | 
			
		|||
import {Ierc20Detailed} from '../types/Ierc20Detailed';
 | 
			
		||||
import {StableDebtToken} from '../types/StableDebtToken';
 | 
			
		||||
import {VariableDebtToken} from '../types/VariableDebtToken';
 | 
			
		||||
import {MockContract} from 'ethereum-waffle';
 | 
			
		||||
import {getReservesConfigByPool} from './constants';
 | 
			
		||||
import {verifyContract} from './etherscan-verification';
 | 
			
		||||
 | 
			
		||||
export const registerContractInJsonDb = async (contractId: string, contractInstance: Contract) => {
 | 
			
		||||
  const currentNetwork = BRE.network.name;
 | 
			
		||||
| 
						 | 
				
			
			@ -93,20 +100,47 @@ export const getContract = async <ContractType extends Contract>(
 | 
			
		|||
  address: string
 | 
			
		||||
): Promise<ContractType> => (await BRE.ethers.getContractAt(contractName, address)) as ContractType;
 | 
			
		||||
 | 
			
		||||
export const deployLendingPoolAddressesProvider = async () =>
 | 
			
		||||
  await deployContract<LendingPoolAddressesProvider>(eContractid.LendingPoolAddressesProvider, []);
 | 
			
		||||
export const deployLendingPoolAddressesProvider = async (verify?: boolean) => {
 | 
			
		||||
  const instance = await deployContract<LendingPoolAddressesProvider>(
 | 
			
		||||
    eContractid.LendingPoolAddressesProvider,
 | 
			
		||||
    []
 | 
			
		||||
  );
 | 
			
		||||
  if (verify) {
 | 
			
		||||
    await verifyContract(eContractid.LendingPoolAddressesProvider, instance.address, []);
 | 
			
		||||
  }
 | 
			
		||||
  return instance;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
export const deployLendingPoolAddressesProviderRegistry = async () =>
 | 
			
		||||
  await deployContract<LendingPoolAddressesProviderRegistry>(
 | 
			
		||||
export const deployLendingPoolAddressesProviderRegistry = async (verify?: boolean) => {
 | 
			
		||||
  const instance = await deployContract<LendingPoolAddressesProviderRegistry>(
 | 
			
		||||
    eContractid.LendingPoolAddressesProviderRegistry,
 | 
			
		||||
    []
 | 
			
		||||
  );
 | 
			
		||||
  if (verify) {
 | 
			
		||||
    await verifyContract(eContractid.LendingPoolAddressesProviderRegistry, instance.address, []);
 | 
			
		||||
  }
 | 
			
		||||
  return instance;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
export const deployFeeProvider = async () =>
 | 
			
		||||
  await deployContract<FeeProvider>(eContractid.FeeProvider, []);
 | 
			
		||||
export const deployFeeProvider = async (verify?: boolean) => {
 | 
			
		||||
  const instance = await deployContract<FeeProvider>(eContractid.FeeProvider, []);
 | 
			
		||||
 | 
			
		||||
export const deployLendingPoolConfigurator = async () =>
 | 
			
		||||
  await deployContract<LendingPoolConfigurator>(eContractid.LendingPoolConfigurator, []);
 | 
			
		||||
  if (verify) {
 | 
			
		||||
    await verifyContract(eContractid.FeeProvider, instance.address, []);
 | 
			
		||||
  }
 | 
			
		||||
  return instance;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
export const deployLendingPoolConfigurator = async (verify?: boolean) => {
 | 
			
		||||
  const instance = await deployContract<LendingPoolConfigurator>(
 | 
			
		||||
    eContractid.LendingPoolConfigurator,
 | 
			
		||||
    []
 | 
			
		||||
  );
 | 
			
		||||
  if (verify) {
 | 
			
		||||
    await verifyContract(eContractid.LendingPoolConfigurator, instance.address, []);
 | 
			
		||||
  }
 | 
			
		||||
  return instance;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
const deployLibrary = async (libraryId: eContractid) => {
 | 
			
		||||
  const factory = await BRE.ethers.getContractFactory(libraryId);
 | 
			
		||||
| 
						 | 
				
			
			@ -162,20 +196,27 @@ export const linkLibrariesToArtifact = async (artifact: Artifact) => {
 | 
			
		|||
  return factory;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
export const deployLendingPool = async () => {
 | 
			
		||||
export const deployLendingPool = async (verify?: boolean) => {
 | 
			
		||||
  const lendingPoolArtifact = await readArtifact(
 | 
			
		||||
    BRE.config.paths.artifacts,
 | 
			
		||||
    eContractid.LendingPool
 | 
			
		||||
  );
 | 
			
		||||
 | 
			
		||||
  const factory = await linkLibrariesToArtifact(lendingPoolArtifact);
 | 
			
		||||
 | 
			
		||||
  const lendingPool = await factory.deploy();
 | 
			
		||||
  return (await lendingPool.deployed()) as LendingPool;
 | 
			
		||||
  const instance = (await lendingPool.deployed()) as LendingPool;
 | 
			
		||||
  if (verify) {
 | 
			
		||||
    await verifyContract(eContractid.LendingPool, instance.address, []);
 | 
			
		||||
  }
 | 
			
		||||
  return instance;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
export const deployPriceOracle = async () =>
 | 
			
		||||
  await deployContract<PriceOracle>(eContractid.PriceOracle, []);
 | 
			
		||||
export const deployPriceOracle = async (verify?: boolean) => {
 | 
			
		||||
  const instance = await deployContract<PriceOracle>(eContractid.PriceOracle, []);
 | 
			
		||||
  if (verify) {
 | 
			
		||||
    await verifyContract(eContractid.PriceOracle, instance.address, []);
 | 
			
		||||
  }
 | 
			
		||||
  return instance;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
export const deployMockAggregator = async (price: tStringTokenSmallUnits) =>
 | 
			
		||||
  await deployContract<MockAggregator>(eContractid.MockAggregator, [price]);
 | 
			
		||||
| 
						 | 
				
			
			@ -482,3 +523,179 @@ export const convertToCurrencyUnits = async (tokenAddress: string, amount: strin
 | 
			
		|||
  const amountInCurrencyUnits = new BigNumber(amount).div(currencyUnit);
 | 
			
		||||
  return amountInCurrencyUnits.toFixed();
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
export const deployAllMockTokens = async (verify?: boolean) => {
 | 
			
		||||
  const tokens: {[symbol: string]: MockContract | MintableErc20} = {};
 | 
			
		||||
 | 
			
		||||
  const protoConfigData = getReservesConfigByPool(AavePools.proto);
 | 
			
		||||
  const secondaryConfigData = getReservesConfigByPool(AavePools.secondary);
 | 
			
		||||
 | 
			
		||||
  for (const tokenSymbol of Object.keys(TokenContractId)) {
 | 
			
		||||
    let decimals = 18;
 | 
			
		||||
 | 
			
		||||
    let configData = (<any>protoConfigData)[tokenSymbol];
 | 
			
		||||
 | 
			
		||||
    if (!configData) {
 | 
			
		||||
      configData = (<any>secondaryConfigData)[tokenSymbol];
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    if (!configData) {
 | 
			
		||||
      decimals = 18;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    tokens[tokenSymbol] = await deployMintableErc20([
 | 
			
		||||
      tokenSymbol,
 | 
			
		||||
      tokenSymbol,
 | 
			
		||||
      configData ? configData.reserveDecimals : 18,
 | 
			
		||||
    ]);
 | 
			
		||||
    await registerContractInJsonDb(tokenSymbol.toUpperCase(), tokens[tokenSymbol]);
 | 
			
		||||
 | 
			
		||||
    if (verify) {
 | 
			
		||||
      await verifyContract(eContractid.MintableERC20, tokens[tokenSymbol].address, []);
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
  return tokens;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
export const getMockedTokens = async () => {
 | 
			
		||||
  const db = getDb();
 | 
			
		||||
  const tokens: MockTokenMap = await Object.keys(TokenContractId).reduce<Promise<MockTokenMap>>(
 | 
			
		||||
    async (acc, tokenSymbol) => {
 | 
			
		||||
      const accumulator = await acc;
 | 
			
		||||
      const address = db.get(`${tokenSymbol.toUpperCase()}.${BRE.network.name}`).value().address;
 | 
			
		||||
      accumulator[tokenSymbol] = await getContract<MintableErc20>(
 | 
			
		||||
        eContractid.MintableERC20,
 | 
			
		||||
        address
 | 
			
		||||
      );
 | 
			
		||||
      return Promise.resolve(acc);
 | 
			
		||||
    },
 | 
			
		||||
    Promise.resolve({})
 | 
			
		||||
  );
 | 
			
		||||
  return tokens;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
export const getPairsTokenAggregator = (
 | 
			
		||||
  allAssetsAddresses: {
 | 
			
		||||
    [tokenSymbol: string]: tEthereumAddress;
 | 
			
		||||
  },
 | 
			
		||||
  aggregatorsAddresses: {[tokenSymbol: string]: tEthereumAddress}
 | 
			
		||||
): [string[], string[]] => {
 | 
			
		||||
  const {ETH, ...assetsAddressesWithoutEth} = allAssetsAddresses;
 | 
			
		||||
 | 
			
		||||
  const pairs = Object.entries(assetsAddressesWithoutEth).map(([tokenSymbol, tokenAddress]) => {
 | 
			
		||||
    if (tokenSymbol !== 'ETH') {
 | 
			
		||||
      const aggregatorAddressIndex = Object.keys(aggregatorsAddresses).findIndex(
 | 
			
		||||
        (value) => value === tokenSymbol
 | 
			
		||||
      );
 | 
			
		||||
      const [, aggregatorAddress] = (Object.entries(aggregatorsAddresses) as [
 | 
			
		||||
        string,
 | 
			
		||||
        tEthereumAddress
 | 
			
		||||
      ][])[aggregatorAddressIndex];
 | 
			
		||||
      return [tokenAddress, aggregatorAddress];
 | 
			
		||||
    }
 | 
			
		||||
  });
 | 
			
		||||
 | 
			
		||||
  const mappedPairs = pairs.map(([asset]) => asset);
 | 
			
		||||
  const mappedAggregators = pairs.map(([, source]) => source);
 | 
			
		||||
 | 
			
		||||
  return [mappedPairs, mappedAggregators];
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
export const initReserves = async (
 | 
			
		||||
  reservesParams: iMultiPoolsAssets<IReserveParams>,
 | 
			
		||||
  tokenAddresses: {[symbol: string]: tEthereumAddress},
 | 
			
		||||
  lendingPoolAddressesProvider: LendingPoolAddressesProvider,
 | 
			
		||||
  lendingPool: LendingPool,
 | 
			
		||||
  lendingPoolConfigurator: LendingPoolConfigurator,
 | 
			
		||||
  aavePool: AavePools
 | 
			
		||||
) => {
 | 
			
		||||
  if (aavePool !== AavePools.proto && aavePool !== AavePools.secondary) {
 | 
			
		||||
    console.log(`Invalid Aave pool ${aavePool}`);
 | 
			
		||||
    process.exit(1);
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  for (let [assetSymbol, {reserveDecimals}] of Object.entries(reservesParams) as [
 | 
			
		||||
    string,
 | 
			
		||||
    IReserveParams
 | 
			
		||||
  ][]) {
 | 
			
		||||
    const assetAddressIndex = Object.keys(tokenAddresses).findIndex(
 | 
			
		||||
      (value) => value === assetSymbol
 | 
			
		||||
    );
 | 
			
		||||
    const [, tokenAddress] = (Object.entries(tokenAddresses) as [string, string][])[
 | 
			
		||||
      assetAddressIndex
 | 
			
		||||
    ];
 | 
			
		||||
 | 
			
		||||
    const {isActive: reserveInitialized} = await lendingPool.getReserveConfigurationData(
 | 
			
		||||
      tokenAddress
 | 
			
		||||
    );
 | 
			
		||||
 | 
			
		||||
    if (reserveInitialized) {
 | 
			
		||||
      console.log(`Reserve ${assetSymbol} is already active, skipping configuration`);
 | 
			
		||||
      continue;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    try {
 | 
			
		||||
      const reserveParamIndex = Object.keys(reservesParams).findIndex(
 | 
			
		||||
        (value) => value === assetSymbol
 | 
			
		||||
      );
 | 
			
		||||
      const [
 | 
			
		||||
        ,
 | 
			
		||||
        {
 | 
			
		||||
          baseVariableBorrowRate,
 | 
			
		||||
          variableRateSlope1,
 | 
			
		||||
          variableRateSlope2,
 | 
			
		||||
          stableRateSlope1,
 | 
			
		||||
          stableRateSlope2,
 | 
			
		||||
        },
 | 
			
		||||
      ] = (Object.entries(reservesParams) as [string, IReserveParams][])[reserveParamIndex];
 | 
			
		||||
      const rateStrategyContract = await deployDefaultReserveInterestRateStrategy([
 | 
			
		||||
        lendingPoolAddressesProvider.address,
 | 
			
		||||
        baseVariableBorrowRate,
 | 
			
		||||
        variableRateSlope1,
 | 
			
		||||
        variableRateSlope2,
 | 
			
		||||
        stableRateSlope1,
 | 
			
		||||
        stableRateSlope2,
 | 
			
		||||
      ]);
 | 
			
		||||
 | 
			
		||||
      const stableDebtToken = await deployStableDebtToken([
 | 
			
		||||
        `Aave stable debt bearing ${assetSymbol === 'WETH' ? 'ETH' : assetSymbol}`,
 | 
			
		||||
        `stableDebt${assetSymbol === 'WETH' ? 'ETH' : assetSymbol}`,
 | 
			
		||||
        tokenAddress,
 | 
			
		||||
        lendingPool.address,
 | 
			
		||||
      ]);
 | 
			
		||||
 | 
			
		||||
      const variableDebtToken = await deployVariableDebtToken([
 | 
			
		||||
        `Aave variable debt bearing ${assetSymbol === 'WETH' ? 'ETH' : assetSymbol}`,
 | 
			
		||||
        `variableDebt${assetSymbol === 'WETH' ? 'ETH' : assetSymbol}`,
 | 
			
		||||
        tokenAddress,
 | 
			
		||||
        lendingPool.address,
 | 
			
		||||
      ]);
 | 
			
		||||
 | 
			
		||||
      const aToken = await deployGenericAToken([
 | 
			
		||||
        lendingPool.address,
 | 
			
		||||
        tokenAddress,
 | 
			
		||||
        `Aave interest bearing ${assetSymbol === 'WETH' ? 'ETH' : assetSymbol}`,
 | 
			
		||||
        `a${assetSymbol === 'WETH' ? 'ETH' : assetSymbol}`,
 | 
			
		||||
      ]);
 | 
			
		||||
 | 
			
		||||
      if (process.env.POOL === AavePools.secondary) {
 | 
			
		||||
        if (assetSymbol.search('UNI') === -1) {
 | 
			
		||||
          assetSymbol = `Uni${assetSymbol}`;
 | 
			
		||||
        } else {
 | 
			
		||||
          assetSymbol = assetSymbol.replace(/_/g, '').replace('UNI', 'Uni');
 | 
			
		||||
        }
 | 
			
		||||
      }
 | 
			
		||||
 | 
			
		||||
      await lendingPoolConfigurator.initReserve(
 | 
			
		||||
        tokenAddress,
 | 
			
		||||
        aToken.address,
 | 
			
		||||
        stableDebtToken.address,
 | 
			
		||||
        variableDebtToken.address,
 | 
			
		||||
        reserveDecimals,
 | 
			
		||||
        rateStrategyContract.address
 | 
			
		||||
      );
 | 
			
		||||
    } catch (e) {
 | 
			
		||||
      console.log(`Reserve initialization for ${assetSymbol} failed with error ${e}. Skipped.`);
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
};
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -3,7 +3,7 @@ import BN = require('bn.js');
 | 
			
		|||
import low from 'lowdb';
 | 
			
		||||
import FileSync from 'lowdb/adapters/FileSync';
 | 
			
		||||
import {WAD} from './constants';
 | 
			
		||||
import {Wallet} from 'ethers';
 | 
			
		||||
import {Wallet, ContractTransaction} from 'ethers';
 | 
			
		||||
import {BuidlerRuntimeEnvironment} from '@nomiclabs/buidler/types';
 | 
			
		||||
 | 
			
		||||
export const toWad = (value: string | number) => new BigNumber(value).times(WAD).toFixed();
 | 
			
		||||
| 
						 | 
				
			
			@ -40,3 +40,5 @@ export const increaseTime = async (secondsToIncrease: number) => {
 | 
			
		|||
  await BRE.ethers.provider.send('evm_increaseTime', [secondsToIncrease]);
 | 
			
		||||
  await BRE.ethers.provider.send('evm_mine', []);
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
export const waitForTx = async (tx: ContractTransaction) => await tx.wait();
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -1,4 +1,6 @@
 | 
			
		|||
import BigNumber from 'bignumber.js';
 | 
			
		||||
import {MockContract} from 'ethereum-waffle';
 | 
			
		||||
import {MintableErc20} from '../types/MintableErc20';
 | 
			
		||||
 | 
			
		||||
export enum eEthereumNetwork {
 | 
			
		||||
  buidlerevm = 'buidlerevm',
 | 
			
		||||
| 
						 | 
				
			
			@ -224,3 +226,9 @@ export enum RateMode {
 | 
			
		|||
  Stable = '1',
 | 
			
		||||
  Variable = '2',
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
export interface ObjectString {
 | 
			
		||||
  [key: string]: string;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
export type MockTokenMap = {[symbol: string]: MockContract | MintableErc20};
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
							
								
								
									
										13
									
								
								package.json
									
									
									
									
									
								
							
							
						
						
									
										13
									
								
								package.json
									
									
									
									
									
								
							| 
						 | 
				
			
			@ -13,10 +13,15 @@
 | 
			
		|||
    "types-gen": "typechain --target ethers-v5 --outDir ./types './artifacts/*.json'",
 | 
			
		||||
    "test": "buidler test",
 | 
			
		||||
    "test-scenarios": "buidler test test/__setup.spec.ts test/scenario.spec.ts",
 | 
			
		||||
    "dev:coverage": "buidler coverage",
 | 
			
		||||
    "dev:deployment": "buidler dev-deployment",
 | 
			
		||||
    "dev:deployExample": "buidler deploy-Example",
 | 
			
		||||
    "dev:prettier": "prettier --write ."
 | 
			
		||||
    "coverage": "buidler coverage",
 | 
			
		||||
    "evm:dev:migration": "buidler dev-migration",
 | 
			
		||||
    "evm:full:migration": "buidler full-migration",
 | 
			
		||||
    "kovan:dev:migration": "npm run buidler-kovan -- dev-migration --verify",
 | 
			
		||||
    "kovan:full:migration": "npm run buidler-kovan -- full-migration --verify",
 | 
			
		||||
    "ropsten:dev:migration": "npm run buidler-ropsten -- dev-migration --verify",
 | 
			
		||||
    "ropsten:full:migration": "npm run buidler-ropsten -- full-migration --verify",
 | 
			
		||||
    "main:dev:migration": "npm run buidler-main -- dev-migration --verify",
 | 
			
		||||
    "main:full:migration": "npm run buidler-main -- full-migration --verify"
 | 
			
		||||
  },
 | 
			
		||||
  "devDependencies": {
 | 
			
		||||
    "@nomiclabs/buidler": "1.4.4",
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -9,7 +9,6 @@ import {
 | 
			
		|||
  deployLendingPool,
 | 
			
		||||
  deployPriceOracle,
 | 
			
		||||
  getLendingPoolConfiguratorProxy,
 | 
			
		||||
  deployMockAggregator,
 | 
			
		||||
  deployChainlinkProxyPriceProvider,
 | 
			
		||||
  deployLendingRateOracle,
 | 
			
		||||
  deployDefaultReserveInterestRateStrategy,
 | 
			
		||||
| 
						 | 
				
			
			@ -27,16 +26,14 @@ import {
 | 
			
		|||
  deployStableDebtToken,
 | 
			
		||||
  deployVariableDebtToken,
 | 
			
		||||
  deployGenericAToken,
 | 
			
		||||
  getPairsTokenAggregator,
 | 
			
		||||
} from '../helpers/contracts-helpers';
 | 
			
		||||
import {LendingPoolAddressesProvider} from '../types/LendingPoolAddressesProvider';
 | 
			
		||||
import {Wallet, ContractTransaction, ethers, Signer} from 'ethers';
 | 
			
		||||
import {Signer} from 'ethers';
 | 
			
		||||
import {
 | 
			
		||||
  TokenContractId,
 | 
			
		||||
  eContractid,
 | 
			
		||||
  iAssetBase,
 | 
			
		||||
  tEthereumAddress,
 | 
			
		||||
  iAssetAggregatorBase,
 | 
			
		||||
  IMarketRates,
 | 
			
		||||
  iMultiPoolsAssets,
 | 
			
		||||
  AavePools,
 | 
			
		||||
  IReserveParams,
 | 
			
		||||
| 
						 | 
				
			
			@ -52,19 +49,16 @@ import {
 | 
			
		|||
  getFeeDistributionParamsCommon,
 | 
			
		||||
  ZERO_ADDRESS,
 | 
			
		||||
} from '../helpers/constants';
 | 
			
		||||
import {PriceOracle} from '../types/PriceOracle';
 | 
			
		||||
import {MockAggregator} from '../types/MockAggregator';
 | 
			
		||||
import {LendingRateOracle} from '../types/LendingRateOracle';
 | 
			
		||||
import {LendingPool} from '../types/LendingPool';
 | 
			
		||||
import {LendingPoolConfigurator} from '../types/LendingPoolConfigurator';
 | 
			
		||||
import {initializeMakeSuite} from './helpers/make-suite';
 | 
			
		||||
import path from 'path';
 | 
			
		||||
import fs from 'fs';
 | 
			
		||||
 | 
			
		||||
['misc'].forEach((folder) => {
 | 
			
		||||
  const tasksPath = path.join('/src/', 'tasks', folder);
 | 
			
		||||
  fs.readdirSync(tasksPath).forEach((task) => require(`${tasksPath}/${task}`));
 | 
			
		||||
});
 | 
			
		||||
import {
 | 
			
		||||
  setInitialAssetPricesInOracle,
 | 
			
		||||
  setInitialMarketRatesInRatesOracle,
 | 
			
		||||
  deployAllMockAggregators,
 | 
			
		||||
} from '../helpers/oracles-helpers';
 | 
			
		||||
import {waitForTx} from '../helpers/misc-utils';
 | 
			
		||||
 | 
			
		||||
const deployAllMockTokens = async (deployer: Signer) => {
 | 
			
		||||
  const tokens: {[symbol: string]: MockContract | MintableErc20} = {};
 | 
			
		||||
| 
						 | 
				
			
			@ -96,181 +90,6 @@ const deployAllMockTokens = async (deployer: Signer) => {
 | 
			
		|||
  return tokens;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
const setInitialAssetPricesInOracle = async (
 | 
			
		||||
  prices: iAssetBase<tEthereumAddress>,
 | 
			
		||||
  assetsAddresses: iAssetBase<tEthereumAddress>,
 | 
			
		||||
  priceOracleInstance: PriceOracle
 | 
			
		||||
) => {
 | 
			
		||||
  for (const [assetSymbol, price] of Object.entries(prices) as [string, string][]) {
 | 
			
		||||
    const assetAddressIndex = Object.keys(assetsAddresses).findIndex(
 | 
			
		||||
      (value) => value === assetSymbol
 | 
			
		||||
    );
 | 
			
		||||
    const [, assetAddress] = (Object.entries(assetsAddresses) as [string, string][])[
 | 
			
		||||
      assetAddressIndex
 | 
			
		||||
    ];
 | 
			
		||||
    await waitForTx(await priceOracleInstance.setAssetPrice(assetAddress, price));
 | 
			
		||||
  }
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
const deployAllMockAggregators = async (initialPrices: iAssetAggregatorBase<string>) => {
 | 
			
		||||
  const aggregators: {[tokenSymbol: string]: MockAggregator} = {};
 | 
			
		||||
  for (const tokenContractName of Object.keys(initialPrices)) {
 | 
			
		||||
    if (tokenContractName !== 'ETH') {
 | 
			
		||||
      const priceIndex = Object.keys(initialPrices).findIndex(
 | 
			
		||||
        (value) => value === tokenContractName
 | 
			
		||||
      );
 | 
			
		||||
      const [, price] = (Object.entries(initialPrices) as [string, string][])[priceIndex];
 | 
			
		||||
      aggregators[tokenContractName] = await deployMockAggregator(price);
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
  return aggregators;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
const getPairsTokenAggregator = (
 | 
			
		||||
  allAssetsAddresses: {
 | 
			
		||||
    [tokenSymbol: string]: tEthereumAddress;
 | 
			
		||||
  },
 | 
			
		||||
  aggregatorsAddresses: {[tokenSymbol: string]: tEthereumAddress}
 | 
			
		||||
): [string[], string[]] => {
 | 
			
		||||
  const {ETH, ...assetsAddressesWithoutEth} = allAssetsAddresses;
 | 
			
		||||
 | 
			
		||||
  const pairs = Object.entries(assetsAddressesWithoutEth).map(([tokenSymbol, tokenAddress]) => {
 | 
			
		||||
    if (tokenSymbol !== 'ETH') {
 | 
			
		||||
      const aggregatorAddressIndex = Object.keys(aggregatorsAddresses).findIndex(
 | 
			
		||||
        (value) => value === tokenSymbol
 | 
			
		||||
      );
 | 
			
		||||
      const [, aggregatorAddress] = (Object.entries(aggregatorsAddresses) as [
 | 
			
		||||
        string,
 | 
			
		||||
        tEthereumAddress
 | 
			
		||||
      ][])[aggregatorAddressIndex];
 | 
			
		||||
      return [tokenAddress, aggregatorAddress];
 | 
			
		||||
    }
 | 
			
		||||
  });
 | 
			
		||||
 | 
			
		||||
  const mappedPairs = pairs.map(([asset]) => asset);
 | 
			
		||||
  const mappedAggregators = pairs.map(([, source]) => source);
 | 
			
		||||
 | 
			
		||||
  return [mappedPairs, mappedAggregators];
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
const setInitialMarketRatesInRatesOracle = async (
 | 
			
		||||
  marketRates: iMultiPoolsAssets<IMarketRates>,
 | 
			
		||||
  assetsAddresses: {[x: string]: tEthereumAddress},
 | 
			
		||||
  lendingRateOracleInstance: LendingRateOracle
 | 
			
		||||
) => {
 | 
			
		||||
  for (const [assetSymbol, {borrowRate}] of Object.entries(marketRates) as [
 | 
			
		||||
    string,
 | 
			
		||||
    IMarketRates
 | 
			
		||||
  ][]) {
 | 
			
		||||
    const assetAddressIndex = Object.keys(assetsAddresses).findIndex(
 | 
			
		||||
      (value) => value === assetSymbol
 | 
			
		||||
    );
 | 
			
		||||
    const [, assetAddress] = (Object.entries(assetsAddresses) as [string, string][])[
 | 
			
		||||
      assetAddressIndex
 | 
			
		||||
    ];
 | 
			
		||||
    await lendingRateOracleInstance.setMarketBorrowRate(assetAddress, borrowRate);
 | 
			
		||||
  }
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
const initReserves = async (
 | 
			
		||||
  reservesParams: iMultiPoolsAssets<IReserveParams>,
 | 
			
		||||
  tokenAddresses: {[symbol: string]: tEthereumAddress},
 | 
			
		||||
  lendingPoolAddressesProvider: LendingPoolAddressesProvider,
 | 
			
		||||
  lendingPool: LendingPool,
 | 
			
		||||
  lendingPoolConfigurator: LendingPoolConfigurator,
 | 
			
		||||
  aavePool: AavePools
 | 
			
		||||
) => {
 | 
			
		||||
  if (aavePool !== AavePools.proto && aavePool !== AavePools.secondary) {
 | 
			
		||||
    console.log(`Invalid Aave pool ${aavePool}`);
 | 
			
		||||
    process.exit(1);
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  for (let [assetSymbol, {reserveDecimals}] of Object.entries(reservesParams) as [
 | 
			
		||||
    string,
 | 
			
		||||
    IReserveParams
 | 
			
		||||
  ][]) {
 | 
			
		||||
    const assetAddressIndex = Object.keys(tokenAddresses).findIndex(
 | 
			
		||||
      (value) => value === assetSymbol
 | 
			
		||||
    );
 | 
			
		||||
    const [, tokenAddress] = (Object.entries(tokenAddresses) as [string, string][])[
 | 
			
		||||
      assetAddressIndex
 | 
			
		||||
    ];
 | 
			
		||||
 | 
			
		||||
    const {isActive: reserveInitialized} = await lendingPool.getReserveConfigurationData(
 | 
			
		||||
      tokenAddress
 | 
			
		||||
    );
 | 
			
		||||
 | 
			
		||||
    if (reserveInitialized) {
 | 
			
		||||
      console.log(`Reserve ${assetSymbol} is already active, skipping configuration`);
 | 
			
		||||
      continue;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    try {
 | 
			
		||||
      const reserveParamIndex = Object.keys(reservesParams).findIndex(
 | 
			
		||||
        (value) => value === assetSymbol
 | 
			
		||||
      );
 | 
			
		||||
      const [
 | 
			
		||||
        ,
 | 
			
		||||
        {
 | 
			
		||||
          baseVariableBorrowRate,
 | 
			
		||||
          variableRateSlope1,
 | 
			
		||||
          variableRateSlope2,
 | 
			
		||||
          stableRateSlope1,
 | 
			
		||||
          stableRateSlope2,
 | 
			
		||||
        },
 | 
			
		||||
      ] = (Object.entries(reservesParams) as [string, IReserveParams][])[reserveParamIndex];
 | 
			
		||||
      const rateStrategyContract = await deployDefaultReserveInterestRateStrategy([
 | 
			
		||||
        lendingPoolAddressesProvider.address,
 | 
			
		||||
        baseVariableBorrowRate,
 | 
			
		||||
        variableRateSlope1,
 | 
			
		||||
        variableRateSlope2,
 | 
			
		||||
        stableRateSlope1,
 | 
			
		||||
        stableRateSlope2,
 | 
			
		||||
      ]);
 | 
			
		||||
 | 
			
		||||
      const stableDebtToken = await deployStableDebtToken([
 | 
			
		||||
        `Aave stable debt bearing ${assetSymbol === 'WETH' ? 'ETH' : assetSymbol}`,
 | 
			
		||||
        `stableDebt${assetSymbol === 'WETH' ? 'ETH' : assetSymbol}`,
 | 
			
		||||
        tokenAddress,
 | 
			
		||||
        lendingPool.address,
 | 
			
		||||
      ]);
 | 
			
		||||
 | 
			
		||||
      const variableDebtToken = await deployVariableDebtToken([
 | 
			
		||||
        `Aave variable debt bearing ${assetSymbol === 'WETH' ? 'ETH' : assetSymbol}`,
 | 
			
		||||
        `variableDebt${assetSymbol === 'WETH' ? 'ETH' : assetSymbol}`,
 | 
			
		||||
        tokenAddress,
 | 
			
		||||
        lendingPool.address,
 | 
			
		||||
      ]);
 | 
			
		||||
 | 
			
		||||
      const aToken = await deployGenericAToken([
 | 
			
		||||
        lendingPool.address,
 | 
			
		||||
        tokenAddress,
 | 
			
		||||
        `Aave interest bearing ${assetSymbol === 'WETH' ? 'ETH' : assetSymbol}`,
 | 
			
		||||
        `a${assetSymbol === 'WETH' ? 'ETH' : assetSymbol}`,
 | 
			
		||||
      ]);
 | 
			
		||||
 | 
			
		||||
      if (process.env.POOL === AavePools.secondary) {
 | 
			
		||||
        if (assetSymbol.search('UNI') === -1) {
 | 
			
		||||
          assetSymbol = `Uni${assetSymbol}`;
 | 
			
		||||
        } else {
 | 
			
		||||
          assetSymbol = assetSymbol.replace(/_/g, '').replace('UNI', 'Uni');
 | 
			
		||||
        }
 | 
			
		||||
      }
 | 
			
		||||
 | 
			
		||||
      await lendingPoolConfigurator.initReserve(
 | 
			
		||||
        tokenAddress,
 | 
			
		||||
        aToken.address,
 | 
			
		||||
        stableDebtToken.address,
 | 
			
		||||
        variableDebtToken.address,
 | 
			
		||||
        reserveDecimals,
 | 
			
		||||
        rateStrategyContract.address
 | 
			
		||||
      );
 | 
			
		||||
    } catch (e) {
 | 
			
		||||
      console.log(`Reserve initialization for ${assetSymbol} failed with error ${e}. Skipped.`);
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
const enableReservesToBorrow = async (
 | 
			
		||||
  reservesParams: iMultiPoolsAssets<IReserveParams>,
 | 
			
		||||
  tokenAddresses: {[symbol: string]: tEthereumAddress},
 | 
			
		||||
| 
						 | 
				
			
			@ -348,8 +167,6 @@ const enableReservesAsCollateral = async (
 | 
			
		|||
  }
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
export const waitForTx = async (tx: ContractTransaction) => await tx.wait();
 | 
			
		||||
 | 
			
		||||
const buildTestEnv = async (deployer: Signer, secondaryWallet: Signer) => {
 | 
			
		||||
  console.time('setup');
 | 
			
		||||
  const lendingPoolManager = await deployer.getAddress();
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
		Loading…
	
		Reference in New Issue
	
	Block a user