From 329a48cd03028229ef9e2e2985d59174cdfe8c01 Mon Sep 17 00:00:00 2001 From: miguelmtzinf Date: Mon, 17 May 2021 14:35:21 +0200 Subject: [PATCH] feat: Add defender utils and use of signer --- helpers/configuration.ts | 10 ++---- helpers/contracts-deployments.ts | 8 +++-- helpers/contracts-getters.ts | 4 +-- helpers/contracts-helpers.ts | 22 +++++++++---- helpers/defender-utils.ts | 41 ++++++++++++++++++++++++ helpers/misc-utils.ts | 14 ++++++++ tasks/dev/2_address_provider_registry.ts | 3 +- tasks/misc/set-bre.ts | 8 +---- test-suites/test-aave/__setup.spec.ts | 5 ++- test-suites/test-amm/__setup.spec.ts | 5 ++- tsconfig.json | 2 +- 11 files changed, 89 insertions(+), 33 deletions(-) create mode 100644 helpers/defender-utils.ts diff --git a/helpers/configuration.ts b/helpers/configuration.ts index 9b21d08d..82e74e41 100644 --- a/helpers/configuration.ts +++ b/helpers/configuration.ts @@ -6,7 +6,7 @@ import { ICommonConfiguration, eNetwork, } from './types'; -import { getParamPerPool } from './contracts-helpers'; +import { getEthersSignersAddresses, getParamPerPool } from './contracts-helpers'; import AaveConfig from '../markets/aave'; import MaticConfig from '../markets/matic'; import AmmConfig from '../markets/amm'; @@ -66,9 +66,7 @@ export const getGenesisPoolAdmin = async ( if (targetAddress) { return targetAddress; } - const addressList = await Promise.all( - (await DRE.ethers.getSigners()).map((signer) => signer.getAddress()) - ); + const addressList = await getEthersSignersAddresses(); const addressIndex = config.PoolAdminIndex; return addressList[addressIndex]; }; @@ -81,9 +79,7 @@ export const getEmergencyAdmin = async ( if (targetAddress) { return targetAddress; } - const addressList = await Promise.all( - (await DRE.ethers.getSigners()).map((signer) => signer.getAddress()) - ); + const addressList = await getEthersSignersAddresses(); const addressIndex = config.EmergencyAdminIndex; return addressList[addressIndex]; }; diff --git a/helpers/contracts-deployments.ts b/helpers/contracts-deployments.ts index 6ae58383..2d764885 100644 --- a/helpers/contracts-deployments.ts +++ b/helpers/contracts-deployments.ts @@ -137,7 +137,9 @@ export const deployGenericLogic = async (reserveLogic: Contract, verify?: boolea linkedGenericLogicByteCode ); - const genericLogic = await (await genericLogicFactory.deploy()).deployed(); + const genericLogic = await ( + await genericLogicFactory.connect(await getFirstSigner()).deploy() + ).deployed(); return withSaveAndVerify(genericLogic, eContractid.GenericLogic, [], verify); }; @@ -158,7 +160,9 @@ export const deployValidationLogic = async ( linkedValidationLogicByteCode ); - const validationLogic = await (await validationLogicFactory.deploy()).deployed(); + const validationLogic = await ( + await validationLogicFactory.connect(await getFirstSigner()).deploy() + ).deployed(); return withSaveAndVerify(validationLogic, eContractid.ValidationLogic, [], verify); }; diff --git a/helpers/contracts-getters.ts b/helpers/contracts-getters.ts index 41089e39..b441363c 100644 --- a/helpers/contracts-getters.ts +++ b/helpers/contracts-getters.ts @@ -32,11 +32,11 @@ import { FlashLiquidationAdapterFactory, } from '../types'; import { IERC20DetailedFactory } from '../types/IERC20DetailedFactory'; -import { MockTokenMap } from './contracts-helpers'; +import { getEthersSigners, MockTokenMap } from './contracts-helpers'; import { DRE, getDb, notFalsyOrZeroAddress } from './misc-utils'; import { eContractid, PoolConfiguration, tEthereumAddress, TokenContractId } from './types'; -export const getFirstSigner = async () => (await DRE.ethers.getSigners())[0]; +export const getFirstSigner = async () => (await getEthersSigners())[0]; export const getLendingPoolAddressesProvider = async (address?: tEthereumAddress) => { return await LendingPoolAddressesProviderFactory.connect( diff --git a/helpers/contracts-helpers.ts b/helpers/contracts-helpers.ts index b4ab51c2..cb7c016e 100644 --- a/helpers/contracts-helpers.ts +++ b/helpers/contracts-helpers.ts @@ -23,9 +23,10 @@ import { MintableERC20 } from '../types/MintableERC20'; import { Artifact } from 'hardhat/types'; import { Artifact as BuidlerArtifact } from '@nomiclabs/buidler/types'; import { verifyEtherscanContract } from './etherscan-verification'; -import { getIErc20Detailed } from './contracts-getters'; +import { getFirstSigner, getIErc20Detailed } from './contracts-getters'; import { usingTenderly, verifyAtTenderly } from './tenderly-utils'; import { usingPolygon, verifyAtPolygon } from './polygon-utils'; +import { getDefenderRelaySigner, usingDefender } from './defender-utils'; export type MockTokenMap = { [symbol: string]: MintableERC20 }; @@ -66,11 +67,18 @@ export const rawInsertContractAddressInDb = async (id: string, address: tEthereu }) .write(); -export const getEthersSigners = async (): Promise => - await Promise.all(await DRE.ethers.getSigners()); +export const getEthersSigners = async (): Promise => { + const ethersSigners = await Promise.all(await DRE.ethers.getSigners()); + + if (usingDefender()) { + const [, ...users] = ethersSigners; + return [await getDefenderRelaySigner(), ...users]; + } + return ethersSigners; +}; export const getEthersSignersAddresses = async (): Promise => - await Promise.all((await DRE.ethers.getSigners()).map((signer) => signer.getAddress())); + await Promise.all((await getEthersSigners()).map((signer) => signer.getAddress())); export const getCurrentBlock = async () => { return DRE.ethers.provider.getBlockNumber(); @@ -83,9 +91,9 @@ export const deployContract = async ( contractName: string, args: any[] ): Promise => { - const contract = (await (await DRE.ethers.getContractFactory(contractName)).deploy( - ...args - )) as ContractType; + const contract = (await (await DRE.ethers.getContractFactory(contractName)) + .connect(await getFirstSigner()) + .deploy(...args)) as ContractType; await waitForTx(contract.deployTransaction); await registerContractInJsonDb(contractName, contract); return contract; diff --git a/helpers/defender-utils.ts b/helpers/defender-utils.ts new file mode 100644 index 00000000..e23ee9f6 --- /dev/null +++ b/helpers/defender-utils.ts @@ -0,0 +1,41 @@ +import { formatEther } from '@ethersproject/units'; +import { DefenderRelaySigner, DefenderRelayProvider } from 'defender-relay-client/lib/ethers'; +import { Signer } from 'ethers'; +import { HardhatRuntimeEnvironment } from 'hardhat/types'; +import { DRE, impersonateAccountsHardhat } from './misc-utils'; +import { usingTenderly } from './tenderly-utils'; + +export const usingDefender = () => process.env.DEFENDER === 'true'; + +export const getDefenderRelaySigner = async () => { + const { DEFENDER_API_KEY, DEFENDER_SECRET_KEY } = process.env; + let defenderSigner: Signer; + + if (!DEFENDER_API_KEY || !DEFENDER_SECRET_KEY) { + throw new Error('Defender secrets required'); + } + + const credentials = { apiKey: DEFENDER_API_KEY, apiSecret: DEFENDER_SECRET_KEY }; + + defenderSigner = new DefenderRelaySigner(credentials, new DefenderRelayProvider(credentials), { + speed: 'fast', + }); + + const defenderAddress = await defenderSigner.getAddress(); + console.log(' - Using Defender Relay: ', defenderAddress); + + // Reemplace signer if FORK=main is active + if (process.env.FORK === 'main') { + console.log(' - Impersonating Defender Relay'); + await impersonateAccountsHardhat([defenderAddress]); + defenderSigner = await (DRE as HardhatRuntimeEnvironment).ethers.getSigner(defenderAddress); + } + // Reemplace signer if Tenderly network is active + if (usingTenderly()) { + console.log(' - Impersonating Defender Relay via Tenderly'); + defenderSigner = await (DRE as HardhatRuntimeEnvironment).ethers.getSigner(defenderAddress); + } + console.log(' - Balance: ', formatEther(await defenderSigner.getBalance())); + + return defenderSigner; +}; diff --git a/helpers/misc-utils.ts b/helpers/misc-utils.ts index 54d5fa44..0315dfe0 100644 --- a/helpers/misc-utils.ts +++ b/helpers/misc-utils.ts @@ -115,3 +115,17 @@ export const notFalsyOrZeroAddress = (address: tEthereumAddress | null | undefin } return isAddress(address) && !isZeroAddress(address); }; + +export const impersonateAccountsHardhat = async (accounts: string[]) => { + if (process.env.TENDERLY === 'true') { + return; + } + // eslint-disable-next-line no-restricted-syntax + for (const account of accounts) { + // eslint-disable-next-line no-await-in-loop + await (DRE as HardhatRuntimeEnvironment).network.provider.request({ + method: 'hardhat_impersonateAccount', + params: [account], + }); + } +}; diff --git a/tasks/dev/2_address_provider_registry.ts b/tasks/dev/2_address_provider_registry.ts index ed85478f..bfa201d4 100644 --- a/tasks/dev/2_address_provider_registry.ts +++ b/tasks/dev/2_address_provider_registry.ts @@ -3,6 +3,7 @@ import { deployLendingPoolAddressesProvider, deployLendingPoolAddressesProviderRegistry, } from '../../helpers/contracts-deployments'; +import { getEthersSigners } from '../../helpers/contracts-helpers'; import { waitForTx } from '../../helpers/misc-utils'; import { AaveConfig } from '../../markets/aave'; @@ -14,7 +15,7 @@ task( .setAction(async ({ verify }, localBRE) => { await localBRE.run('set-DRE'); - const admin = await (await localBRE.ethers.getSigners())[0].getAddress(); + const admin = await (await getEthersSigners())[0].getAddress(); const addressesProvider = await deployLendingPoolAddressesProvider(AaveConfig.MarketId, verify); await waitForTx(await addressesProvider.setPoolAdmin(admin)); diff --git a/tasks/misc/set-bre.ts b/tasks/misc/set-bre.ts index 63aafd1e..76531579 100644 --- a/tasks/misc/set-bre.ts +++ b/tasks/misc/set-bre.ts @@ -3,7 +3,6 @@ import { DRE, setDRE } from '../../helpers/misc-utils'; import { EthereumNetworkNames } from '../../helpers/types'; import { usingTenderly } from '../../helpers/tenderly-utils'; import { HardhatRuntimeEnvironment } from 'hardhat/types'; -import { getFirstSigner } from '../../helpers/contracts-getters'; import { formatEther } from 'ethers/lib/utils'; import { fork } from 'child_process'; import { env } from 'process'; @@ -26,16 +25,11 @@ task(`set-DRE`, `Inits the DRE, to have access to all the plugins' objects`).set console.log('- Creating a new Tenderly Fork'); await _DRE.tenderlyRPC.initializeFork(); } - const provider = new _DRE.ethers.providers.Web3Provider(_DRE.tenderlyRPC as any); + const provider = new _DRE.ethers.providers.Web3Provider(_DRE.tenderlyRPC); _DRE.ethers.provider = provider; console.log('- Initialized Tenderly fork:'); console.log(' - Fork: ', _DRE.tenderlyRPC.getFork()); console.log(' - Head: ', _DRE.tenderlyRPC.getHead()); - console.log(' - First account:', await (await _DRE.ethers.getSigners())[0].getAddress()); - console.log( - ' - Balance:', - formatEther(await (await _DRE.ethers.getSigners())[0].getBalance()) - ); } console.log('- Enviroment'); diff --git a/test-suites/test-aave/__setup.spec.ts b/test-suites/test-aave/__setup.spec.ts index 54110d6e..c004d10f 100644 --- a/test-suites/test-aave/__setup.spec.ts +++ b/test-suites/test-aave/__setup.spec.ts @@ -4,6 +4,7 @@ import { insertContractAddressInDb, getEthersSigners, registerContractInJsonDb, + getEthersSignersAddresses, } from '../../helpers/contracts-helpers'; import { deployLendingPoolAddressesProvider, @@ -102,9 +103,7 @@ const buildTestEnv = async (deployer: Signer, secondaryWallet: Signer) => { 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()) - ); + const addressList = await getEthersSignersAddresses(); await waitForTx(await addressesProvider.setEmergencyAdmin(addressList[2])); diff --git a/test-suites/test-amm/__setup.spec.ts b/test-suites/test-amm/__setup.spec.ts index 3254f2c4..0fae3acd 100644 --- a/test-suites/test-amm/__setup.spec.ts +++ b/test-suites/test-amm/__setup.spec.ts @@ -4,6 +4,7 @@ import { insertContractAddressInDb, getEthersSigners, registerContractInJsonDb, + getEthersSignersAddresses, } from '../../helpers/contracts-helpers'; import { deployLendingPoolAddressesProvider, @@ -101,9 +102,7 @@ const buildTestEnv = async (deployer: Signer, secondaryWallet: Signer) => { 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()) - ); + const addressList = await getEthersSignersAddresses(); await waitForTx(await addressesProvider.setEmergencyAdmin(addressList[2])); diff --git a/tsconfig.json b/tsconfig.json index 9974c3b6..44c4df6f 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -8,7 +8,7 @@ "noImplicitAny": false, "resolveJsonModule": true }, - "include": ["./scripts", "./test", "./tasks", "test-suites/test-aave/uniswapAdapters.repay.spec.ts", "test-suites/test-aave/upgradeability.spec.ts", "test-suites/test-aave/variable-debt-token.spec.ts", "test-suites/test-aave/weth-gateway.spec.ts"], + "include": ["./scripts", "./test", "./tasks", "./helpers", "test-suites/test-aave/uniswapAdapters.repay.spec.ts", "test-suites/test-aave/upgradeability.spec.ts", "test-suites/test-aave/variable-debt-token.spec.ts", "test-suites/test-aave/weth-gateway.spec.ts"], "files": [ "./hardhat.config.ts", "./modules/tenderly/tenderly.d.ts",