UNPKG

@hyperlane-xyz/core

Version:

Core solidity contracts for Hyperlane

215 lines (204 loc) 8.31 kB
import { Signer } from 'ethers' import { ethers } from 'hardhat' import { KeeperRegistryLogicB2_1__factory as KeeperRegistryLogicBFactory } from '../../../typechain/factories/KeeperRegistryLogicB2_1__factory' import { IKeeperRegistryMaster as IKeeperRegistry } from '../../../typechain/IKeeperRegistryMaster' import { IKeeperRegistryMaster__factory as IKeeperRegistryMasterFactory } from '../../../typechain/factories/IKeeperRegistryMaster__factory' import { AutomationRegistryLogicB2_2__factory as AutomationRegistryLogicBFactory } from '../../../typechain/factories/AutomationRegistryLogicB2_2__factory' import { IAutomationRegistryMaster as IAutomationRegistry } from '../../../typechain/IAutomationRegistryMaster' import { IAutomationRegistryMaster__factory as IAutomationRegistryMasterFactory } from '../../../typechain/factories/IAutomationRegistryMaster__factory' import { assert } from 'chai' import { FunctionFragment } from '@ethersproject/abi' import { AutomationRegistryLogicC2_3__factory as AutomationRegistryLogicC2_3Factory } from '../../../typechain/factories/AutomationRegistryLogicC2_3__factory' import { IAutomationRegistryMaster2_3 as IAutomationRegistry2_3 } from '../../../typechain/IAutomationRegistryMaster2_3' import { IAutomationRegistryMaster2_3__factory as IAutomationRegistryMaster2_3Factory } from '../../../typechain/factories/IAutomationRegistryMaster2_3__factory' export const deployRegistry21 = async ( from: Signer, mode: Parameters<KeeperRegistryLogicBFactory['deploy']>[0], link: Parameters<KeeperRegistryLogicBFactory['deploy']>[1], linkNative: Parameters<KeeperRegistryLogicBFactory['deploy']>[2], fastgas: Parameters<KeeperRegistryLogicBFactory['deploy']>[3], ): Promise<IKeeperRegistry> => { const logicBFactory = await ethers.getContractFactory( 'KeeperRegistryLogicB2_1', ) const logicAFactory = await ethers.getContractFactory( 'KeeperRegistryLogicA2_1', ) const registryFactory = await ethers.getContractFactory('KeeperRegistry2_1') const forwarderLogicFactory = await ethers.getContractFactory( 'AutomationForwarderLogic', ) const forwarderLogic = await forwarderLogicFactory.connect(from).deploy() const logicB = await logicBFactory .connect(from) .deploy(mode, link, linkNative, fastgas, forwarderLogic.address) const logicA = await logicAFactory.connect(from).deploy(logicB.address) const master = await registryFactory.connect(from).deploy(logicA.address) return IKeeperRegistryMasterFactory.connect(master.address, from) } type InterfaceABI = ConstructorParameters<typeof ethers.utils.Interface>[0] type Entry = { inputs?: any[] outputs?: any[] name?: string type: string } export const assertSatisfiesEvents = ( contractABI: InterfaceABI, expectedABI: InterfaceABI, ) => { const implementer = new ethers.utils.Interface(contractABI) const expected = new ethers.utils.Interface(expectedABI) for (const eventName in expected.events) { assert.isDefined( implementer.events[eventName], `missing event: ${eventName}`, ) } } export const entryID = (entry: Entry) => { // remove "internal type" and "name" since they don't affect the ability // of a contract to satisfy an interface const preimage = Object.assign({}, entry) if (entry.inputs) { preimage.inputs = entry.inputs.map(({ type }) => ({ type, })) } if (entry.outputs) { preimage.outputs = entry.outputs.map(({ type }) => ({ type, })) } return ethers.utils.id(JSON.stringify(preimage)) } export const assertSatisfiesInterface = ( contractABI: InterfaceABI, expectedABI: InterfaceABI, ) => { const implementer = new ethers.utils.Interface(contractABI) const expected = new ethers.utils.Interface(expectedABI) for (const functionName in expected.functions) { assert.isDefined( implementer.functions[functionName], `missing function ${functionName}`, ) // these are technically pure in those interfaces. but in the master interface, they are view functions // bc the underlying contracts define constants for these values and return them in these getters if ( functionName === 'typeAndVersion()' || functionName === 'upkeepVersion()' || functionName === 'upkeepTranscoderVersion()' ) { assert.equal( implementer.functions[functionName].constant, expected.functions[functionName].constant, `property constant does not match for function ${functionName}`, ) assert.equal( implementer.functions[functionName].payable, expected.functions[functionName].payable, `property payable does not match for function ${functionName}`, ) continue } // addFunds is a payable function starting from v2.3, skipping the stateMutability check if (functionName === 'addFunds(uint256,uint96)') { continue } const propertiesToMatch: (keyof FunctionFragment)[] = [ 'constant', 'stateMutability', 'payable', ] for (const property of propertiesToMatch) { assert.equal( implementer.functions[functionName][property], expected.functions[functionName][property], `property ${property} does not match for function ${functionName}`, ) } } } export const deployRegistry22 = async ( from: Signer, link: Parameters<AutomationRegistryLogicBFactory['deploy']>[0], linkNative: Parameters<AutomationRegistryLogicBFactory['deploy']>[1], fastgas: Parameters<AutomationRegistryLogicBFactory['deploy']>[2], allowedReadOnlyAddress: Parameters< AutomationRegistryLogicBFactory['deploy'] >[3], ): Promise<IAutomationRegistry> => { const logicBFactory = await ethers.getContractFactory( 'AutomationRegistryLogicB2_2', ) const logicAFactory = await ethers.getContractFactory( 'AutomationRegistryLogicA2_2', ) const registryFactory = await ethers.getContractFactory( 'AutomationRegistry2_2', ) const forwarderLogicFactory = await ethers.getContractFactory( 'AutomationForwarderLogic', ) const forwarderLogic = await forwarderLogicFactory.connect(from).deploy() const logicB = await logicBFactory .connect(from) .deploy( link, linkNative, fastgas, forwarderLogic.address, allowedReadOnlyAddress, ) const logicA = await logicAFactory.connect(from).deploy(logicB.address) const master = await registryFactory.connect(from).deploy(logicA.address) return IAutomationRegistryMasterFactory.connect(master.address, from) } export const deployRegistry23 = async ( from: Signer, link: Parameters<AutomationRegistryLogicC2_3Factory['deploy']>[0], linkUSD: Parameters<AutomationRegistryLogicC2_3Factory['deploy']>[1], nativeUSD: Parameters<AutomationRegistryLogicC2_3Factory['deploy']>[2], fastgas: Parameters<AutomationRegistryLogicC2_3Factory['deploy']>[2], allowedReadOnlyAddress: Parameters< AutomationRegistryLogicC2_3Factory['deploy'] >[3], payoutMode: Parameters<AutomationRegistryLogicC2_3Factory['deploy']>[6], wrappedNativeTokenAddress: Parameters< AutomationRegistryLogicC2_3Factory['deploy'] >[7], ): Promise<IAutomationRegistry2_3> => { const logicCFactory = await ethers.getContractFactory( 'AutomationRegistryLogicC2_3', ) const logicBFactory = await ethers.getContractFactory( 'AutomationRegistryLogicB2_3', ) const logicAFactory = await ethers.getContractFactory( 'AutomationRegistryLogicA2_3', ) const registryFactory = await ethers.getContractFactory( 'AutomationRegistry2_3', ) const forwarderLogicFactory = await ethers.getContractFactory( 'AutomationForwarderLogic', ) const forwarderLogic = await forwarderLogicFactory.connect(from).deploy() const logicC = await logicCFactory .connect(from) .deploy( link, linkUSD, nativeUSD, fastgas, forwarderLogic.address, allowedReadOnlyAddress, payoutMode, wrappedNativeTokenAddress, ) const logicB = await logicBFactory.connect(from).deploy(logicC.address) const logicA = await logicAFactory.connect(from).deploy(logicB.address) const master = await registryFactory.connect(from).deploy(logicA.address) return IAutomationRegistryMaster2_3Factory.connect(master.address, from) }