diff --git a/packages/ua-utils-evm-hardhat-test/hardhat.config.ts b/packages/ua-utils-evm-hardhat-test/hardhat.config.ts index 230b94e96..3b5080e82 100644 --- a/packages/ua-utils-evm-hardhat-test/hardhat.config.ts +++ b/packages/ua-utils-evm-hardhat-test/hardhat.config.ts @@ -4,6 +4,7 @@ import assert from 'assert' import { withLayerZeroArtifacts } from '@layerzerolabs/utils-evm-hardhat' import { EndpointId } from '@layerzerolabs/lz-definitions' import { HardhatUserConfig } from 'hardhat/types' +import '@layerzerolabs/ua-utils-evm-hardhat/tasks' const MNEMONIC = process.env.MNEMONIC assert(MNEMONIC, `Missing MNEMONIC environment variable`) diff --git a/packages/ua-utils-evm-hardhat-test/test/task/getDefaultConfig.test.ts b/packages/ua-utils-evm-hardhat-test/test/task/getDefaultConfig.test.ts new file mode 100644 index 000000000..ac712b807 --- /dev/null +++ b/packages/ua-utils-evm-hardhat-test/test/task/getDefaultConfig.test.ts @@ -0,0 +1,51 @@ +import { describe } from 'mocha' +import { defaultExecutorConfig, defaultUlnConfig, setupDefaultEndpoint } from '../__utils__/endpoint' +import { getNetworkRuntimeEnvironment } from '@layerzerolabs/utils-evm-hardhat' +import hre from 'hardhat' +import { expect, assert } from 'chai' + +describe('task: getDefaultConfig', () => { + beforeEach(async () => { + await setupDefaultEndpoint() + }) + + it('should return default configurations', async () => { + const networks = Object.keys(hre.userConfig.networks ?? {}) + const getDefaultConfigTask = await hre.run('getDefaultConfig', { networks: networks.toString() }) + + for (const localNetwork of networks) { + for (const remoteNetwork of networks) { + if (localNetwork === remoteNetwork) continue + + const defaultConfig = getDefaultConfigTask[localNetwork][remoteNetwork] + const network = await getNetworkRuntimeEnvironment(localNetwork) + const sendUln302 = await network.ethers.getContract('SendUln302') + const receiveUln302 = await network.ethers.getContract('ReceiveUln302') + + // verify defaultSendLibrary & defaultReceiveLibrary + expect(defaultConfig.defaultSendLibrary).to.eql(sendUln302.address) + expect(defaultConfig.defaultReceiveLibrary).to.eql(receiveUln302.address) + + // verify sendUln + expect(defaultConfig.sendExecutorConfig.maxMessageSize).to.eql(defaultExecutorConfig.maxMessageSize) + expect(defaultConfig.sendExecutorConfig.executor).to.eql(defaultExecutorConfig.executor) + expect(defaultConfig.sendUlnConfig.confirmations.toString()).to.eql( + defaultUlnConfig.confirmations.toString() + ) + expect(defaultConfig.sendUlnConfig.optionalDVNThreshold).to.eql(defaultUlnConfig.optionalDVNThreshold) + expect(defaultConfig.sendUlnConfig.requiredDVNs).to.eql(defaultUlnConfig.requiredDVNs) + expect(defaultConfig.sendUlnConfig.optionalDVNs).to.eql(defaultUlnConfig.optionalDVNs) + + // verify receiveUln + expect(defaultConfig.receiveUlnConfig.confirmations.toString()).to.eql( + defaultUlnConfig.confirmations.toString() + ) + expect(defaultConfig.receiveUlnConfig.optionalDVNThreshold).to.eql( + defaultUlnConfig.optionalDVNThreshold + ) + expect(defaultConfig.receiveUlnConfig.requiredDVNs).to.eql(defaultUlnConfig.requiredDVNs) + expect(defaultConfig.receiveUlnConfig.optionalDVNs).to.eql(defaultUlnConfig.optionalDVNs) + } + } + }) +}) diff --git a/packages/ua-utils-evm-hardhat/src/tasks/getDefaultConfig.ts b/packages/ua-utils-evm-hardhat/src/tasks/getDefaultConfig.ts index 55dfbb0f0..491478a45 100644 --- a/packages/ua-utils-evm-hardhat/src/tasks/getDefaultConfig.ts +++ b/packages/ua-utils-evm-hardhat/src/tasks/getDefaultConfig.ts @@ -1,34 +1,119 @@ -import { ethers } from 'ethers' -import { getProvider, getLayerZeroChainId, getEndpointAddress } from '@/utils/crossChainHelper' -import { ENDPOINT_ABI, MESSAGING_LIBRARY_ABI } from '@/constants/abi' - -export default async (taskArgs: any, hre: any) => { - const networks = taskArgs.networks.split(',') - - const configByNetwork = await Promise.all( - networks.map(async (network: string) => { - const provider = getProvider(hre, network) - console.log() - const endpoint = new ethers.Contract(getEndpointAddress(network), ENDPOINT_ABI, provider) - const sendVersion = await endpoint.defaultSendVersion() - const receiveVersion = await endpoint.defaultReceiveVersion() - const sendLibraryAddress = await endpoint.defaultSendLibrary() - const messagingLibrary = new ethers.Contract(sendLibraryAddress, MESSAGING_LIBRARY_ABI, provider) - const config = await messagingLibrary.defaultAppConfig(getLayerZeroChainId(network)) - - return { - network, - sendVersion, - receiveVersion, - inboundProofLibraryVersion: config.inboundProofLibraryVersion, - inboundBlockConfirmations: config.inboundBlockConfirmations.toNumber(), - relayer: config.relayer, - outboundProofType: config.outboundProofType, - outboundBlockConfirmations: config.outboundBlockConfirmations.toNumber(), - oracle: config.oracle, +import { ActionType } from 'hardhat/types' +import { task } from 'hardhat/config' +import 'hardhat-deploy-ethers/internal/type-extensions' +import { createConnectedContractFactory, getEidForNetworkName } from '@layerzerolabs/utils-evm-hardhat' +import { Endpoint, Uln302 } from '@layerzerolabs/protocol-utils-evm' + +interface TaskArgs { + networks: string +} + +export const getDefaultConfig: ActionType = async (taskArgs) => { + const networks = new Set(taskArgs.networks.split(',')) + const contractFactory = createConnectedContractFactory() + const configs: Record> = {} + + for (const localNetworkName of networks) { + const localEid = getEidForNetworkName(localNetworkName) + const localEndpointSDK = new Endpoint(await contractFactory({ eid: localEid, contractName: 'EndpointV2' })) + + configs[localNetworkName] = {} + + for (const remoteNetworkName of networks) { + if (remoteNetworkName === localNetworkName) continue + + const remoteEid = getEidForNetworkName(remoteNetworkName) + + // First we get the SDK for the local send library + const defaultSendLibrary = await localEndpointSDK.defaultSendLibrary(remoteEid) + const localSendUlnSDK = new Uln302( + await contractFactory({ eid: localEid, contractName: 'SendUln302', address: defaultSendLibrary }) + ) + + // Then we get the SDK for the local receive library + const defaultReceiveLibrary = await localEndpointSDK.defaultReceiveLibrary(remoteEid) + const localReceiveUlnSDK = new Uln302( + await contractFactory({ eid: localEid, contractName: 'ReceiveUln302', address: defaultReceiveLibrary }) + ) + + // Now let's get the configs + const sendUlnConfig = await localSendUlnSDK.getUlnConfig(remoteEid) + const sendExecutorConfig = await localSendUlnSDK.getExecutorConfig(remoteEid) + const receiveUlnConfig = await localReceiveUlnSDK.getUlnConfig(remoteEid) + + configs[localNetworkName][remoteNetworkName] = { + defaultSendLibrary: defaultSendLibrary, + defaultReceiveLibrary: defaultReceiveLibrary, + sendUlnConfig, + sendExecutorConfig, + receiveUlnConfig, } - }) - ) - console.table(configByNetwork) + printConsoleTable( + localNetworkName, + remoteNetworkName, + defaultSendLibrary, + defaultReceiveLibrary, + sendUlnConfig, + sendExecutorConfig, + receiveUlnConfig + ) + } + } + return configs +} + +task( + 'getDefaultConfig', + 'outputs the default Send and Receive Messaging Library versions and the default application config' +) + .addParam('networks', 'comma separated list of networks') + .setAction(getDefaultConfig) + +const printConsoleTable = ( + localNetworkName: string, + remoteNetworkName: string, + defaultSendLibrary: string, + defaultReceiveLibrary: string, + sendUlnConfig: Record, + sendExecutorConfig: Record, + receiveUlnConfig: Record +) => { + const defaultLibraryTable = { + network: localNetworkName, + remoteNetwork: remoteNetworkName, + defaultSendLibrary: defaultSendLibrary, + defaultReceiveLibrary: defaultReceiveLibrary, + } + + const sendUln = { + maxMessageSize: sendExecutorConfig.maxMessageSize, + executor: sendExecutorConfig.executor, + confirmations: parseInt(sendUlnConfig.confirmations.toString()), + optionalDVNThreshold: sendUlnConfig.optionalDVNThreshold, + requiredDVNs: sendUlnConfig.requiredDVNs, + optionalDVNs: sendUlnConfig.optionalDVNs, + } + + const receiveUln = { + confirmations: parseInt(receiveUlnConfig.confirmations.toString()), + optionalDVNThreshold: receiveUlnConfig.optionalDVNThreshold, + requiredDVNs: receiveUlnConfig.requiredDVNs, + optionalDVNs: receiveUlnConfig.optionalDVNs, + } + + const sendUlnConfigTable = { + sendUln: sendUln, + } + + const receiveUlnConfigTable = { + receiveUln: receiveUln, + } + + console.log(`************************************************`) + console.log(`${localNetworkName.toUpperCase()}`) + console.log(`************************************************`) + console.table(defaultLibraryTable) + console.table(sendUlnConfigTable) + console.table(receiveUlnConfigTable) } diff --git a/packages/ua-utils-evm-hardhat/src/tasks/index.ts b/packages/ua-utils-evm-hardhat/src/tasks/index.ts index 83bc4ce8f..edfb64bc4 100644 --- a/packages/ua-utils-evm-hardhat/src/tasks/index.ts +++ b/packages/ua-utils-evm-hardhat/src/tasks/index.ts @@ -1,73 +1 @@ -import { task, types } from 'hardhat/config' -import wireAll from './wireAll' -import setConfig from './setConfig' -import getDefaultConfig from './getDefaultConfig' -import getConfig from './getConfig' -import checkWireAllConfig from './checkWireAllConfig' - -task( - 'setConfig', - 'sets Send and Receive Messaging Library versions and a custom application config for contracts implementing ILayerZeroUserApplicationConfig interface', - setConfig -) - .addParam('configPath', 'the application config file path') - .addOptionalParam( - 'name', - 'name of the deployed contracts. Should be specified if the same contract deployed on different chains and the deployment information is located in the deployments folder' - ) - .addOptionalParam( - 'address', - 'address of the deployed contracts. Should be specified if the contract address is the same on all chains' - ) - .addOptionalParam( - 'gnosisConfigPath', - 'the path to a file with Gnosis config. If specified, the transactions will be sent to Gnosis' - ) - .addOptionalParam('gasLimit', 'override execution gasLimit') - -task( - 'getDefaultConfig', - 'outputs the default Send and Receive Messaging Library versions and the default application config', - getDefaultConfig -).addParam('networks', 'comma separated list of networks') - -task( - 'getConfig', - "outputs the application's Send and Receive Messaging Library versions and the config for remote networks", - getConfig -) - .addParam('remoteNetworks', 'comma separated list of remote networks') - .addOptionalParam( - 'name', - 'name of the deployed contract. Should be specified only if the deployment information is located in the deployments folder' - ) - .addOptionalParam('address', 'the contract address') - -task('checkWireAllConfig', '', checkWireAllConfig) - .addParam('e', 'the environment ie: mainnet, testnet or sandbox') - .addFlag('u', 'show use custom adapter params') - .addFlag('t', 'show trusted remote lookup') - .addFlag('m', 'show min destination gas lookup') - .addParam('chains', 'comma separated list of networks') - .addOptionalParam('contract', 'name of contract') - .addOptionalParam('addresses', 'addresses of contracts in same order as chains') - .addOptionalParam('proxyContract', 'name of proxy contract') - .addOptionalParam('proxyChain', 'name of proxy chain') - -task('wireAll', '', wireAll) - .addParam('e', 'the environment ie: mainnet, testnet or sandbox') - .addOptionalParam('noPrompt', 'no prompt', false, types.boolean) - .addOptionalParam( - 'configPath', - 'Optional config path. Default: ./constants/wireUpConfig.json', - './constants/wireUpConfig.json', - types.string - ) - .addOptionalParam('n', 'send to gnosis', false, types.boolean) - .addOptionalParam('gasLimit', 'override execution gasLimit') - .addOptionalParam( - 'gnosisConfigPath', - 'Optional config path. Default: ./constants/gnosisConfig.json', - './constants/gnosisConfig.json', - types.string - ) +import './getDefaultConfig'