Commit 7b4a0a87 authored by mergify[bot]'s avatar mergify[bot] Committed by GitHub

Merge pull request #4141 from ethereum-optimism/sc/ctb-migration-fixes

fix(ctb): various migration fixes
parents 2d0601ca 7bc01454
...@@ -5,6 +5,7 @@ import { L2OutputOracle } from "../L1/L2OutputOracle.sol"; ...@@ -5,6 +5,7 @@ import { L2OutputOracle } from "../L1/L2OutputOracle.sol";
import { OptimismPortal } from "../L1/OptimismPortal.sol"; import { OptimismPortal } from "../L1/OptimismPortal.sol";
import { L1CrossDomainMessenger } from "../L1/L1CrossDomainMessenger.sol"; import { L1CrossDomainMessenger } from "../L1/L1CrossDomainMessenger.sol";
import { L1ChugSplashProxy } from "../legacy/L1ChugSplashProxy.sol"; import { L1ChugSplashProxy } from "../legacy/L1ChugSplashProxy.sol";
import { Proxy } from "../universal/Proxy.sol";
import { ProxyAdmin } from "../universal/ProxyAdmin.sol"; import { ProxyAdmin } from "../universal/ProxyAdmin.sol";
import { PortalSender } from "./PortalSender.sol"; import { PortalSender } from "./PortalSender.sol";
import { SystemConfig } from "../L1/SystemConfig.sol"; import { SystemConfig } from "../L1/SystemConfig.sol";
...@@ -137,6 +138,11 @@ contract MigrationSystemDictator is BaseSystemDictator { ...@@ -137,6 +138,11 @@ contract MigrationSystemDictator is BaseSystemDictator {
L1ChugSplashProxy(payable(config.proxyAddressConfig.l1StandardBridgeProxy)).setOwner( L1ChugSplashProxy(payable(config.proxyAddressConfig.l1StandardBridgeProxy)).setOwner(
address(config.globalConfig.proxyAdmin) address(config.globalConfig.proxyAdmin)
); );
// Transfer ownership of the L1ERC721Bridge to the ProxyAdmin.
Proxy(payable(config.proxyAddressConfig.l1ERC721BridgeProxy)).changeAdmin(
address(config.globalConfig.proxyAdmin)
);
} }
/** /**
...@@ -273,6 +279,11 @@ contract MigrationSystemDictator is BaseSystemDictator { ...@@ -273,6 +279,11 @@ contract MigrationSystemDictator is BaseSystemDictator {
L1ChugSplashProxy(payable(config.proxyAddressConfig.l1StandardBridgeProxy)).setOwner( L1ChugSplashProxy(payable(config.proxyAddressConfig.l1StandardBridgeProxy)).setOwner(
address(config.globalConfig.finalOwner) address(config.globalConfig.finalOwner)
); );
// Transfer ownership of the L1ERC721Bridge to the final owner.
Proxy(payable(config.proxyAddressConfig.l1ERC721BridgeProxy)).changeAdmin(
address(config.globalConfig.finalOwner)
);
} }
finalized = true; finalized = true;
......
...@@ -2,40 +2,34 @@ ...@@ -2,40 +2,34 @@
"l1ChainID": 900, "l1ChainID": 900,
"l2ChainID": 901, "l2ChainID": 901,
"l2BlockTime": 2, "l2BlockTime": 2,
"maxSequencerDrift": 300, "maxSequencerDrift": 300,
"sequencerWindowSize": 15, "sequencerWindowSize": 15,
"channelTimeout": 40, "channelTimeout": 40,
"p2pSequencerAddress": "0x9965507D1a55bcC2695C58ba16FB37d819B0A4dc", "p2pSequencerAddress": "0x9965507D1a55bcC2695C58ba16FB37d819B0A4dc",
"batchInboxAddress": "0xff00000000000000000000000000000000000000", "batchInboxAddress": "0xff00000000000000000000000000000000000000",
"batchSenderAddress": "0x3C44CdDdB6a900fa2b585dd299e03d12FA4293BC", "batchSenderAddress": "0x3C44CdDdB6a900fa2b585dd299e03d12FA4293BC",
"systemConfigOwner": "0xa0Ee7A142d267C1f36714E4a8F75612F20a79720", "systemConfigOwner": "0xa0Ee7A142d267C1f36714E4a8F75612F20a79720",
"l2OutputOracleSubmissionInterval": 20, "l2OutputOracleSubmissionInterval": 20,
"l2OutputOracleStartingTimestamp": -1, "l2OutputOracleStartingTimestamp": -1,
"l2OutputOracleProposer": "0x70997970C51812dc3A010C7d01b50e0d17dc79C8", "l2OutputOracleProposer": "0x70997970C51812dc3A010C7d01b50e0d17dc79C8",
"l2OutputOracleChallenger": "0x15d34AAf54267DB7D7c367839AAf71A00a2C6A65", "l2OutputOracleChallenger": "0x15d34AAf54267DB7D7c367839AAf71A00a2C6A65",
"l2GenesisBlockCoinbase": "0x42000000000000000000000000000000000000f0", "l2GenesisBlockCoinbase": "0x42000000000000000000000000000000000000f0",
"l2GenesisBlockGasLimit": "0xE4E1C0", "l2GenesisBlockGasLimit": "0xE4E1C0",
"l1BlockTime": 15, "l1BlockTime": 15,
"cliqueSignerAddress": "0xca062b0fd91172d89bcd4bb084ac4e21972cc467", "cliqueSignerAddress": "0xca062b0fd91172d89bcd4bb084ac4e21972cc467",
"baseFeeVaultRecipient": "0xBcd4042DE499D14e55001CcbB24a551F3b954096", "baseFeeVaultRecipient": "0xBcd4042DE499D14e55001CcbB24a551F3b954096",
"l1FeeVaultRecipient": "0x71bE63f3384f5fb98995898A86B02Fb2426c5788", "l1FeeVaultRecipient": "0x71bE63f3384f5fb98995898A86B02Fb2426c5788",
"sequencerFeeVaultRecipient": "0xfabb0ac9d68b0b445fb7357272ff202c5651694a", "sequencerFeeVaultRecipient": "0xfabb0ac9d68b0b445fb7357272ff202c5651694a",
"proxyAdminOwner": "0xBcd4042DE499D14e55001CcbB24a551F3b954096", "proxyAdminOwner": "0xBcd4042DE499D14e55001CcbB24a551F3b954096",
"l2CrossDomainMessengerOwner": "0xBcd4042DE499D14e55001CcbB24a551F3b954096", "l2CrossDomainMessengerOwner": "0xBcd4042DE499D14e55001CcbB24a551F3b954096",
"finalizationPeriodSeconds": 2, "finalizationPeriodSeconds": 2,
"deploymentWaitConfirmations": 1, "deploymentWaitConfirmations": 1,
"fundDevAccounts": true, "fundDevAccounts": true,
"l2GenesisBlockBaseFeePerGas": "0x3B9ACA00", "l2GenesisBlockBaseFeePerGas": "0x3B9ACA00",
"gasPriceOracleOverhead": 2100, "gasPriceOracleOverhead": 2100,
"gasPriceOracleScalar": 1000000, "gasPriceOracleScalar": 1000000,
"eip1559Denominator": 8, "eip1559Denominator": 8,
"eip1559Elasticity": 2 "eip1559Elasticity": 2,
} "l1GenesisBlockTimestamp": "0x638a4554",
"l1StartingBlockTag": "earliest"
}
\ No newline at end of file
{
"finalSystemOwner": "0xf80267194936da1E98dB10bcE06F3147D580a62e",
"controller": "0xf80267194936da1E98dB10bcE06F3147D580a62e",
"l1StartingBlockTag": "latest",
"l1ChainID": 5,
"l2ChainID": 111,
"l2BlockTime": 2,
"maxSequencerDrift": 1000,
"sequencerWindowSize": 120,
"channelTimeout": 120,
"p2pSequencerAddress": "0x9965507D1a55bcC2695C58ba16FB37d819B0A4dc",
"batchInboxAddress": "0xff00000000000000000000000000000000000002",
"batchSenderAddress": "0xa11d2b908470e17923fff184d48269bebbd9b2a5",
"systemConfigOwner": "0xa0Ee7A142d267C1f36714E4a8F75612F20a79720",
"l2OutputOracleSubmissionInterval": 6,
"l2OutputOracleStartingTimestamp": -1,
"l2OutputOracleProposer": "0x6c23a0dcdfc44b7a57bed148de598895e398d984",
"l2OutputOracleChallenger": "0x6925b8704ff96dee942623d6fb5e946ef5884b63",
"baseFeeVaultRecipient": "0xf116a24056b647e3211d095c667e951536cdebaa",
"l1FeeVaultRecipient": "0xc731837b696ca3d9720d23336925368ceaa58f83",
"sequencerFeeVaultRecipient": "0xf116a24056b647e3211d095c667e951536cdebaa",
"deploymentWaitConfirmations": 1
}
...@@ -3,18 +3,17 @@ import { DeployFunction } from 'hardhat-deploy/dist/types' ...@@ -3,18 +3,17 @@ import { DeployFunction } from 'hardhat-deploy/dist/types'
import { import {
assertContractVariable, assertContractVariable,
deployAndVerifyAndThen, deployAndVerifyAndThen,
getDeploymentAddress,
} from '../src/deploy-utils' } from '../src/deploy-utils'
const deployFn: DeployFunction = async (hre) => { const deployFn: DeployFunction = async (hre) => {
const proxyAdmin = await getDeploymentAddress(hre, 'ProxyAdmin') const { deployer } = await hre.getNamedAccounts()
await deployAndVerifyAndThen({ await deployAndVerifyAndThen({
hre, hre,
name: 'L1ERC721BridgeProxy', name: 'L1ERC721BridgeProxy',
contract: 'Proxy', contract: 'Proxy',
args: [proxyAdmin], args: [deployer],
postDeployAction: async (contract) => { postDeployAction: async (contract) => {
await assertContractVariable(contract, 'admin', proxyAdmin) await assertContractVariable(contract, 'admin', deployer)
}, },
}) })
} }
......
...@@ -65,6 +65,8 @@ const deployFn: DeployFunction = async (hre) => { ...@@ -65,6 +65,8 @@ const deployFn: DeployFunction = async (hre) => {
L2OutputOracle, L2OutputOracle,
OptimismPortal, OptimismPortal,
OptimismMintableERC20Factory, OptimismMintableERC20Factory,
L1ERC721BridgeProxy,
L1ERC721BridgeProxyWithSigner,
L1ERC721Bridge, L1ERC721Bridge,
] = await getContractsFromArtifacts(hre, [ ] = await getContractsFromArtifacts(hre, [
{ {
...@@ -111,6 +113,13 @@ const deployFn: DeployFunction = async (hre) => { ...@@ -111,6 +113,13 @@ const deployFn: DeployFunction = async (hre) => {
iface: 'OptimismMintableERC20Factory', iface: 'OptimismMintableERC20Factory',
signerOrProvider: deployer, signerOrProvider: deployer,
}, },
{
name: 'L1ERC721BridgeProxy',
},
{
name: 'L1ERC721BridgeProxy',
signerOrProvider: deployer,
},
{ {
name: 'L1ERC721BridgeProxy', name: 'L1ERC721BridgeProxy',
iface: 'L1ERC721Bridge', iface: 'L1ERC721Bridge',
...@@ -126,8 +135,16 @@ const deployFn: DeployFunction = async (hre) => { ...@@ -126,8 +135,16 @@ const deployFn: DeployFunction = async (hre) => {
console.log(`Proxy admin already owned by MSD`) console.log(`Proxy admin already owned by MSD`)
} }
// We don't need to transfer proxy addresses if we're already beyond the proxy transfer step.
const needsProxyTransfer =
(await MigrationSystemDictator.currentStep()) <=
(await MigrationSystemDictator.PROXY_TRANSFER_STEP())
// Transfer ownership of the AddressManager to MigrationSystemDictator. // Transfer ownership of the AddressManager to MigrationSystemDictator.
if ((await AddressManager.owner()) !== MigrationSystemDictator.address) { if (
needsProxyTransfer &&
(await AddressManager.owner()) !== MigrationSystemDictator.address
) {
if (isLiveDeployer) { if (isLiveDeployer) {
console.log(`Setting AddressManager owner to MSD`) console.log(`Setting AddressManager owner to MSD`)
await AddressManager.transferOwnership(MigrationSystemDictator.address) await AddressManager.transferOwnership(MigrationSystemDictator.address)
...@@ -137,16 +154,21 @@ const deployFn: DeployFunction = async (hre) => { ...@@ -137,16 +154,21 @@ const deployFn: DeployFunction = async (hre) => {
} }
// Wait for the ownership transfer to complete. // Wait for the ownership transfer to complete.
await awaitCondition(async () => { await awaitCondition(
const owner = await AddressManager.owner() async () => {
return owner === MigrationSystemDictator.address const owner = await AddressManager.owner()
}) return owner === MigrationSystemDictator.address
},
30000,
1000
)
} else { } else {
console.log(`AddressManager already owned by the MigrationSystemDictator`) console.log(`AddressManager already owned by the MigrationSystemDictator`)
} }
// Transfer ownership of the L1CrossDomainMessenger to MigrationSystemDictator. // Transfer ownership of the L1CrossDomainMessenger to MigrationSystemDictator.
if ( if (
needsProxyTransfer &&
(await AddressManager.getAddress('OVM_L1CrossDomainMessenger')) !== (await AddressManager.getAddress('OVM_L1CrossDomainMessenger')) !==
ethers.constants.AddressZero && ethers.constants.AddressZero &&
(await L1CrossDomainMessenger.owner()) !== MigrationSystemDictator.address (await L1CrossDomainMessenger.owner()) !== MigrationSystemDictator.address
...@@ -162,16 +184,21 @@ const deployFn: DeployFunction = async (hre) => { ...@@ -162,16 +184,21 @@ const deployFn: DeployFunction = async (hre) => {
} }
// Wait for the ownership transfer to complete. // Wait for the ownership transfer to complete.
await awaitCondition(async () => { await awaitCondition(
const owner = await L1CrossDomainMessenger.owner() async () => {
return owner === MigrationSystemDictator.address const owner = await L1CrossDomainMessenger.owner()
}) return owner === MigrationSystemDictator.address
},
30000,
1000
)
} else { } else {
console.log(`L1CrossDomainMessenger already owned by MSD`) console.log(`L1CrossDomainMessenger already owned by MSD`)
} }
// Transfer ownership of the L1StandardBridge (proxy) to MigrationSystemDictator. // Transfer ownership of the L1StandardBridge (proxy) to MigrationSystemDictator.
if ( if (
needsProxyTransfer &&
(await L1StandardBridgeProxy.callStatic.getOwner({ (await L1StandardBridgeProxy.callStatic.getOwner({
from: ethers.constants.AddressZero, from: ethers.constants.AddressZero,
})) !== MigrationSystemDictator.address })) !== MigrationSystemDictator.address
...@@ -187,16 +214,52 @@ const deployFn: DeployFunction = async (hre) => { ...@@ -187,16 +214,52 @@ const deployFn: DeployFunction = async (hre) => {
} }
// Wait for the ownership transfer to complete. // Wait for the ownership transfer to complete.
await awaitCondition(async () => { await awaitCondition(
const owner = await L1StandardBridgeProxy.callStatic.getOwner({ async () => {
from: ethers.constants.AddressZero, const owner = await L1StandardBridgeProxy.callStatic.getOwner({
}) from: ethers.constants.AddressZero,
return owner === MigrationSystemDictator.address })
}) return owner === MigrationSystemDictator.address
},
30000,
1000
)
} else { } else {
console.log(`L1StandardBridge already owned by MSD`) console.log(`L1StandardBridge already owned by MSD`)
} }
// Transfer ownership of the L1ERC721Bridge (proxy) to MigrationSystemDictator.
if (
needsProxyTransfer &&
(await L1ERC721BridgeProxy.callStatic.admin({
from: ethers.constants.AddressZero,
})) !== MigrationSystemDictator.address
) {
if (isLiveDeployer) {
console.log(`Setting L1ERC721Bridge owner to MSD`)
await L1ERC721BridgeProxyWithSigner.changeAdmin(
MigrationSystemDictator.address
)
} else {
console.log(`Please transfer L1ERC721Bridge (proxy) owner to MSD`)
console.log(`MSD address: ${MigrationSystemDictator.address}`)
}
// Wait for the ownership transfer to complete.
await awaitCondition(
async () => {
const owner = await L1ERC721BridgeProxy.callStatic.admin({
from: ethers.constants.AddressZero,
})
return owner === MigrationSystemDictator.address
},
30000,
1000
)
} else {
console.log(`L1ERC721Bridge already owned by MSD`)
}
const checks = { const checks = {
1: async () => { 1: async () => {
await assertContractVariable( await assertContractVariable(
...@@ -298,10 +361,7 @@ const deployFn: DeployFunction = async (hre) => { ...@@ -298,10 +361,7 @@ const deployFn: DeployFunction = async (hre) => {
await L1CrossDomainMessenger.xDomainMessageSender() await L1CrossDomainMessenger.xDomainMessageSender()
assert(false, `L1CrossDomainMessenger was not initialized properly`) assert(false, `L1CrossDomainMessenger was not initialized properly`)
} catch (err) { } catch (err) {
assert( // Expected.
err.message.includes('xDomainMessageSender is not set'),
`L1CrossDomainMessenger was not initialized properly`
)
} }
await assertContractVariable( await assertContractVariable(
L1CrossDomainMessenger, L1CrossDomainMessenger,
...@@ -371,6 +431,14 @@ const deployFn: DeployFunction = async (hre) => { ...@@ -371,6 +431,14 @@ const deployFn: DeployFunction = async (hre) => {
} else { } else {
console.log(`Please update dynamic oracle config...`) console.log(`Please update dynamic oracle config...`)
} }
await awaitCondition(
async () => {
return MigrationSystemDictator.dynamicConfigSet()
},
30000,
1000
)
} }
if (isLiveDeployer) { if (isLiveDeployer) {
...@@ -380,10 +448,14 @@ const deployFn: DeployFunction = async (hre) => { ...@@ -380,10 +448,14 @@ const deployFn: DeployFunction = async (hre) => {
console.log(`Please execute step ${i}...`) console.log(`Please execute step ${i}...`)
} }
await awaitCondition(async () => { await awaitCondition(
const step = await MigrationSystemDictator.currentStep() async () => {
return step === i + 1 const step = await MigrationSystemDictator.currentStep()
}) return step === i + 1
},
30000,
1000
)
// Run post step checks // Run post step checks
await checks[i]() await checks[i]()
...@@ -400,12 +472,15 @@ const deployFn: DeployFunction = async (hre) => { ...@@ -400,12 +472,15 @@ const deployFn: DeployFunction = async (hre) => {
console.log(`Please finalize deployment...`) console.log(`Please finalize deployment...`)
} }
await awaitCondition(async () => { await awaitCondition(
return MigrationSystemDictator.finalized() async () => {
}) return MigrationSystemDictator.finalized()
},
30000,
1000
)
await assertContractVariable(L1CrossDomainMessenger, 'owner', finalOwner) await assertContractVariable(L1CrossDomainMessenger, 'owner', finalOwner)
await assertContractVariable(ProxyAdmin, 'owner', finalOwner) await assertContractVariable(ProxyAdmin, 'owner', finalOwner)
} }
} }
......
import { ethers } from 'ethers' import { ethers } from 'ethers'
import { HardhatUserConfig } from 'hardhat/config' import { HardhatUserConfig } from 'hardhat/config'
import dotenv from 'dotenv'
// Hardhat plugins // Hardhat plugins
import '@eth-optimism/hardhat-deploy-config' import '@eth-optimism/hardhat-deploy-config'
...@@ -13,10 +14,8 @@ import './tasks' ...@@ -13,10 +14,8 @@ import './tasks'
// Deploy configuration // Deploy configuration
import { deployConfigSpec } from './src/deploy-config' import { deployConfigSpec } from './src/deploy-config'
let bytecodeHash = 'none' // Load environment variables
if (process.env.FOUNDRY_PROFILE === 'echidna') { dotenv.config()
bytecodeHash = 'ipfs'
}
const config: HardhatUserConfig = { const config: HardhatUserConfig = {
networks: { networks: {
...@@ -57,6 +56,12 @@ const config: HardhatUserConfig = { ...@@ -57,6 +56,12 @@ const config: HardhatUserConfig = {
accounts: [process.env.PRIVATE_KEY_DEPLOYER || ethers.constants.HashZero], accounts: [process.env.PRIVATE_KEY_DEPLOYER || ethers.constants.HashZero],
live: false, live: false,
}, },
'goerli-forked': {
chainId: 5,
url: process.env.L1_RPC || '',
accounts: [process.env.PRIVATE_KEY_DEPLOYER || ethers.constants.HashZero],
live: true,
},
}, },
foundry: { foundry: {
buildInfo: true, buildInfo: true,
...@@ -91,6 +96,10 @@ const config: HardhatUserConfig = { ...@@ -91,6 +96,10 @@ const config: HardhatUserConfig = {
'../contracts/deployments/mainnet', '../contracts/deployments/mainnet',
'../contracts-periphery/deployments/mainnet', '../contracts-periphery/deployments/mainnet',
], ],
'goerli-forked': [
'../contracts/deployments/goerli',
'../contracts-periphery/deployments/goerli',
],
}, },
}, },
solidity: { solidity: {
...@@ -110,7 +119,8 @@ const config: HardhatUserConfig = { ...@@ -110,7 +119,8 @@ const config: HardhatUserConfig = {
], ],
settings: { settings: {
metadata: { metadata: {
bytecodeHash, bytecodeHash:
process.env.FOUNDRY_PROFILE === 'echidna' ? 'ipfs' : 'none',
}, },
outputSelection: { outputSelection: {
'*': { '*': {
......
...@@ -4,6 +4,10 @@ import { ethers, Contract } from 'ethers' ...@@ -4,6 +4,10 @@ import { ethers, Contract } from 'ethers'
import { Provider } from '@ethersproject/abstract-provider' import { Provider } from '@ethersproject/abstract-provider'
import { Signer } from '@ethersproject/abstract-signer' import { Signer } from '@ethersproject/abstract-signer'
import { sleep, getChainId } from '@eth-optimism/core-utils' import { sleep, getChainId } from '@eth-optimism/core-utils'
import { HardhatRuntimeEnvironment } from 'hardhat/types'
import 'hardhat-deploy'
import '@eth-optimism/hardhat-deploy-config'
import '@nomiclabs/hardhat-ethers'
export interface DictatorConfig { export interface DictatorConfig {
globalConfig: { globalConfig: {
...@@ -48,7 +52,7 @@ export const deployAndVerifyAndThen = async ({ ...@@ -48,7 +52,7 @@ export const deployAndVerifyAndThen = async ({
iface, iface,
postDeployAction, postDeployAction,
}: { }: {
hre: any hre: HardhatRuntimeEnvironment
name: string name: string
args: any[] args: any[]
contract?: string contract?: string
...@@ -58,6 +62,17 @@ export const deployAndVerifyAndThen = async ({ ...@@ -58,6 +62,17 @@ export const deployAndVerifyAndThen = async ({
const { deploy } = hre.deployments const { deploy } = hre.deployments
const { deployer } = await hre.getNamedAccounts() const { deployer } = await hre.getNamedAccounts()
// Hardhat deploy will usually do this check for us, but currently doesn't also consider
// external deployments when doing this check. By doing the check ourselves, we also get to
// consider external deployments. If we already have the deployment, return early.
const existing = await hre.deployments.getOrNull(name)
if (existing) {
console.log(
`skipping ${name} deployment, using existing at ${existing.address}`
)
return
}
const result = await deploy(name, { const result = await deploy(name, {
contract, contract,
from: deployer, from: deployer,
...@@ -69,38 +84,14 @@ export const deployAndVerifyAndThen = async ({ ...@@ -69,38 +84,14 @@ export const deployAndVerifyAndThen = async ({
await hre.ethers.provider.waitForTransaction(result.transactionHash) await hre.ethers.provider.waitForTransaction(result.transactionHash)
if (result.newlyDeployed) { if (result.newlyDeployed) {
if (!(await isHardhatNode(hre)) && hre.network.config.live !== false) {
// Verification sometimes fails, even when the contract is correctly deployed and eventually
// verified. Possibly due to a race condition. We don't want to halt the whole deployment
// process just because that happens.
try {
console.log('Verifying on Etherscan...')
await hre.run('verify:verify', {
address: result.address,
constructorArguments: args,
})
console.log('Successfully verified on Etherscan')
} catch (error) {
console.log('Error when verifying bytecode on Etherscan:')
console.log(error)
}
try {
console.log('Verifying on Sourcify...')
await hre.run('sourcify')
console.log('Successfully verified on Sourcify')
} catch (error) {
console.log('Error when verifying bytecode on Sourcify:')
console.log(error)
}
}
if (postDeployAction) { if (postDeployAction) {
const signer = hre.ethers.provider.getSigner(deployer) const signer = hre.ethers.provider.getSigner(deployer)
let abi = result.abi let abi = result.abi
if (iface !== undefined) { if (iface !== undefined) {
const factory = await hre.ethers.getContractFactory(iface) const factory = await hre.ethers.getContractFactory(iface)
abi = factory.interface abi = factory.interface as any
} }
await postDeployAction( await postDeployAction(
getAdvancedContract({ getAdvancedContract({
hre, hre,
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment