Commit e1d7d530 authored by Kelvin Fichter's avatar Kelvin Fichter

feat: update deployment for upgrades

parent 1527cf6f
/* Imports: External */ /* Imports: External */
import { DeployFunction } from 'hardhat-deploy/dist/types' import { DeployFunction } from 'hardhat-deploy/dist/types'
/* Imports: Internal */
import { registerAddress } from '../src/hardhat-deploy-ethers'
import { predeploys } from '../src/predeploys'
const deployFn: DeployFunction = async (hre) => { const deployFn: DeployFunction = async (hre) => {
const { deploy } = hre.deployments const { deploy } = hre.deployments
const { deployer } = await hre.getNamedAccounts() const { deployer } = await hre.getNamedAccounts()
...@@ -14,31 +10,6 @@ const deployFn: DeployFunction = async (hre) => { ...@@ -14,31 +10,6 @@ const deployFn: DeployFunction = async (hre) => {
args: [], args: [],
log: true, log: true,
}) })
// L2CrossDomainMessenger is the address of the predeploy on L2. We can refactor off-chain
// services such that we can remove the need to set this address, but for now it's easier
// to simply keep setting the address.
await registerAddress({
hre,
name: 'L2CrossDomainMessenger',
address: predeploys.L2CrossDomainMessenger,
})
// OVM_Sequencer is the address allowed to submit "Sequencer" blocks to the
// CanonicalTransactionChain.
await registerAddress({
hre,
name: 'OVM_Sequencer',
address: (hre as any).deployConfig.ovmSequencerAddress,
})
// OVM_Proposer is the address allowed to submit state roots (transaction results) to the
// StateCommitmentChain.
await registerAddress({
hre,
name: 'OVM_Proposer',
address: (hre as any).deployConfig.ovmProposerAddress,
})
} }
deployFn.tags = ['Lib_AddressManager'] deployFn.tags = ['Lib_AddressManager']
......
...@@ -22,6 +22,6 @@ const deployFn: DeployFunction = async (hre) => { ...@@ -22,6 +22,6 @@ const deployFn: DeployFunction = async (hre) => {
} }
deployFn.dependencies = ['Lib_AddressManager'] deployFn.dependencies = ['Lib_AddressManager']
deployFn.tags = ['ChainStorageContainer_ctc_batches'] deployFn.tags = ['ChainStorageContainer_ctc_batches', 'upgrade']
export default deployFn export default deployFn
...@@ -22,6 +22,6 @@ const deployFn: DeployFunction = async (hre) => { ...@@ -22,6 +22,6 @@ const deployFn: DeployFunction = async (hre) => {
} }
deployFn.dependencies = ['Lib_AddressManager'] deployFn.dependencies = ['Lib_AddressManager']
deployFn.tags = ['ChainStorageContainer_ctc_queue'] deployFn.tags = ['ChainStorageContainer_ctc_queue', 'upgrade']
export default deployFn export default deployFn
...@@ -22,6 +22,6 @@ const deployFn: DeployFunction = async (hre) => { ...@@ -22,6 +22,6 @@ const deployFn: DeployFunction = async (hre) => {
} }
deployFn.dependencies = ['Lib_AddressManager'] deployFn.dependencies = ['Lib_AddressManager']
deployFn.tags = ['ChainStorageContainer_scc_batches'] deployFn.tags = ['ChainStorageContainer_scc_batches', 'upgrade']
export default deployFn export default deployFn
...@@ -26,6 +26,6 @@ const deployFn: DeployFunction = async (hre) => { ...@@ -26,6 +26,6 @@ const deployFn: DeployFunction = async (hre) => {
} }
deployFn.dependencies = ['Lib_AddressManager'] deployFn.dependencies = ['Lib_AddressManager']
deployFn.tags = ['CanonicalTransactionChain'] deployFn.tags = ['CanonicalTransactionChain', 'upgrade']
export default deployFn export default deployFn
...@@ -25,6 +25,6 @@ const deployFn: DeployFunction = async (hre) => { ...@@ -25,6 +25,6 @@ const deployFn: DeployFunction = async (hre) => {
} }
deployFn.dependencies = ['Lib_AddressManager'] deployFn.dependencies = ['Lib_AddressManager']
deployFn.tags = ['StateCommitmentChain'] deployFn.tags = ['StateCommitmentChain', 'upgrade']
export default deployFn export default deployFn
...@@ -21,6 +21,6 @@ const deployFn: DeployFunction = async (hre) => { ...@@ -21,6 +21,6 @@ const deployFn: DeployFunction = async (hre) => {
} }
deployFn.dependencies = ['Lib_AddressManager'] deployFn.dependencies = ['Lib_AddressManager']
deployFn.tags = ['BondManager'] deployFn.tags = ['BondManager', 'upgrade']
export default deployFn export default deployFn
...@@ -17,7 +17,8 @@ const deployFn: DeployFunction = async (hre) => { ...@@ -17,7 +17,8 @@ const deployFn: DeployFunction = async (hre) => {
await deployAndRegister({ await deployAndRegister({
hre, hre,
name: 'L1CrossDomainMessenger', name: 'OVM_L1CrossDomainMessenger',
contract: 'L1CrossDomainMessenger',
args: [], args: [],
postDeployAction: async (contract) => { postDeployAction: async (contract) => {
// Theoretically it's not necessary to initialize this contract since it sits behind // Theoretically it's not necessary to initialize this contract since it sits behind
...@@ -39,6 +40,6 @@ const deployFn: DeployFunction = async (hre) => { ...@@ -39,6 +40,6 @@ const deployFn: DeployFunction = async (hre) => {
} }
deployFn.dependencies = ['Lib_AddressManager'] deployFn.dependencies = ['Lib_AddressManager']
deployFn.tags = ['L1CrossDomainMessenger'] deployFn.tags = ['L1CrossDomainMessenger', 'upgrade']
export default deployFn export default deployFn
...@@ -20,7 +20,7 @@ const deployFn: DeployFunction = async (hre) => { ...@@ -20,7 +20,7 @@ const deployFn: DeployFunction = async (hre) => {
name: 'Proxy__L1CrossDomainMessenger', name: 'Proxy__L1CrossDomainMessenger',
contract: 'Lib_ResolvedDelegateProxy', contract: 'Lib_ResolvedDelegateProxy',
iface: 'L1CrossDomainMessenger', iface: 'L1CrossDomainMessenger',
args: [Lib_AddressManager.address, 'L1CrossDomainMessenger'], args: [Lib_AddressManager.address, 'OVM_L1CrossDomainMessenger'],
postDeployAction: async (contract) => { postDeployAction: async (contract) => {
console.log(`Initializing Proxy__L1CrossDomainMessenger...`) console.log(`Initializing Proxy__L1CrossDomainMessenger...`)
await contract.initialize(Lib_AddressManager.address) await contract.initialize(Lib_AddressManager.address)
......
/* Imports: External */ /* Imports: External */
import { DeployFunction } from 'hardhat-deploy/dist/types' import { DeployFunction } from 'hardhat-deploy/dist/types'
import { ethers } from 'ethers'
import { hexStringEquals } from '@eth-optimism/core-utils'
/* Imports: Internal */ /* Imports: Internal */
import { predeploys } from '../src/predeploys' import { deployAndRegister } from '../src/hardhat-deploy-ethers'
import {
getContractInterface,
getContractDefinition,
} from '../src/contract-defs'
import {
getDeployedContract,
deployAndRegister,
waitUntilTrue,
} from '../src/hardhat-deploy-ethers'
const deployFn: DeployFunction = async (hre) => { const deployFn: DeployFunction = async (hre) => {
const { deployer } = await hre.getNamedAccounts() const { deployer } = await hre.getNamedAccounts()
const Lib_AddressManager = await getDeployedContract(
hre,
'Lib_AddressManager'
)
await deployAndRegister({ await deployAndRegister({
hre, hre,
...@@ -28,93 +13,10 @@ const deployFn: DeployFunction = async (hre) => { ...@@ -28,93 +13,10 @@ const deployFn: DeployFunction = async (hre) => {
contract: 'L1ChugSplashProxy', contract: 'L1ChugSplashProxy',
iface: 'L1StandardBridge', iface: 'L1StandardBridge',
args: [deployer], args: [deployer],
postDeployAction: async (contract) => {
// Because of the `iface` parameter supplied to the deployment function above, the `contract`
// variable that we here will have the interface of the L1StandardBridge contract. However,
// we also need to interact with the contract as if it were a L1ChugSplashProxy contract so
// we instantiate a new ethers.Contract object with the same address and signer but with the
// L1ChugSplashProxy interface.
const proxy = new ethers.Contract(
contract.address,
getContractInterface('L1ChugSplashProxy'),
contract.signer
)
// First we need to set the correct implementation code. We'll set the code and then check
// that the code was indeed correctly set.
const bridgeArtifact = getContractDefinition('L1StandardBridge')
const bridgeCode = bridgeArtifact.deployedBytecode
console.log(`Setting bridge code...`)
await proxy.setCode(bridgeCode)
console.log(`Confirming that bridge code is correct...`)
await waitUntilTrue(async () => {
const implementation = await proxy.callStatic.getImplementation()
return (
!hexStringEquals(implementation, ethers.constants.AddressZero) &&
hexStringEquals(
await contract.provider.getCode(implementation),
bridgeCode
)
)
})
// Next we need to set the `messenger` address by executing a setStorage operation. We'll
// check that this operation was correctly executed by calling `messenger()` and checking
// that the result matches the value we initialized.
const l1CrossDomainMessengerAddress = await Lib_AddressManager.getAddress(
'Proxy__L1CrossDomainMessenger'
)
console.log(`Setting messenger address...`)
await proxy.setStorage(
ethers.utils.hexZeroPad('0x00', 32),
ethers.utils.hexZeroPad(l1CrossDomainMessengerAddress, 32)
)
console.log(`Confirming that messenger address was correctly set...`)
await waitUntilTrue(async () => {
return hexStringEquals(
await contract.messenger(),
l1CrossDomainMessengerAddress
)
})
// Now we set the bridge address in the same manner as the messenger address.
console.log(`Setting l2 bridge address...`)
await proxy.setStorage(
ethers.utils.hexZeroPad('0x01', 32),
ethers.utils.hexZeroPad(predeploys.L2StandardBridge, 32)
)
console.log(`Confirming that l2 bridge address was correctly set...`)
await waitUntilTrue(async () => {
return hexStringEquals(
await contract.l2TokenBridge(),
predeploys.L2StandardBridge
)
})
// Finally we transfer ownership of the proxy to the ovmAddressManagerOwner address.
console.log(`Setting owner address...`)
const owner = (hre as any).deployConfig.ovmAddressManagerOwner
await proxy.setOwner(owner)
console.log(`Confirming that owner address was correctly set...`)
await waitUntilTrue(async () => {
return hexStringEquals(
await proxy.connect(proxy.signer.provider).callStatic.getOwner({
from: ethers.constants.AddressZero,
}),
owner
)
})
},
}) })
} }
deployFn.dependencies = ['Lib_AddressManager', 'L1StandardBridge'] deployFn.dependencies = ['Lib_AddressManager']
deployFn.tags = ['Proxy__L1StandardBridge'] deployFn.tags = ['Proxy__L1StandardBridge']
export default deployFn export default deployFn
/* Imports: External */
import { DeployFunction } from 'hardhat-deploy/dist/types'
import { ethers } from 'ethers'
import { hexStringEquals } from '@eth-optimism/core-utils'
/* Imports: Internal */
import { predeploys } from '../src/predeploys'
import {
getContractInterface,
getContractDefinition,
} from '../src/contract-defs'
import {
getDeployedContract,
waitUntilTrue,
} from '../src/hardhat-deploy-ethers'
const deployFn: DeployFunction = async (hre) => {
const { deployer } = await hre.getNamedAccounts()
const Lib_AddressManager = await getDeployedContract(
hre,
'Lib_AddressManager'
)
// Set up a reference to the proxy as if it were the L1StandardBridge contract.
const contract = await getDeployedContract(hre, 'Proxy__L1StandardBridge', {
iface: 'L1StandardBridge',
signerOrProvider: deployer,
})
// Because of the `iface` parameter supplied to the deployment function above, the `contract`
// variable that we here will have the interface of the L1StandardBridge contract. However,
// we also need to interact with the contract as if it were a L1ChugSplashProxy contract so
// we instantiate a new ethers.Contract object with the same address and signer but with the
// L1ChugSplashProxy interface.
const proxy = new ethers.Contract(
contract.address,
getContractInterface('L1ChugSplashProxy'),
contract.signer
)
// First we need to set the correct implementation code. We'll set the code and then check
// that the code was indeed correctly set.
const bridgeArtifact = getContractDefinition('L1StandardBridge')
const bridgeCode = bridgeArtifact.deployedBytecode
console.log(`Setting bridge code...`)
await proxy.setCode(bridgeCode)
console.log(`Confirming that bridge code is correct...`)
await waitUntilTrue(async () => {
const implementation = await proxy.callStatic.getImplementation()
return (
!hexStringEquals(implementation, ethers.constants.AddressZero) &&
hexStringEquals(
await contract.provider.getCode(implementation),
bridgeCode
)
)
})
// Next we need to set the `messenger` address by executing a setStorage operation. We'll
// check that this operation was correctly executed by calling `messenger()` and checking
// that the result matches the value we initialized.
const l1CrossDomainMessengerAddress = await Lib_AddressManager.getAddress(
'Proxy__L1CrossDomainMessenger'
)
console.log(`Setting messenger address...`)
await proxy.setStorage(
ethers.utils.hexZeroPad('0x00', 32),
ethers.utils.hexZeroPad(l1CrossDomainMessengerAddress, 32)
)
console.log(`Confirming that messenger address was correctly set...`)
await waitUntilTrue(async () => {
return hexStringEquals(
await contract.messenger(),
l1CrossDomainMessengerAddress
)
})
// Now we set the bridge address in the same manner as the messenger address.
console.log(`Setting l2 bridge address...`)
await proxy.setStorage(
ethers.utils.hexZeroPad('0x01', 32),
ethers.utils.hexZeroPad(predeploys.L2StandardBridge, 32)
)
console.log(`Confirming that l2 bridge address was correctly set...`)
await waitUntilTrue(async () => {
return hexStringEquals(
await contract.l2TokenBridge(),
predeploys.L2StandardBridge
)
})
// Finally we transfer ownership of the proxy to the ovmAddressManagerOwner address.
console.log(`Setting owner address...`)
const owner = (hre as any).deployConfig.ovmAddressManagerOwner
await proxy.setOwner(owner)
console.log(`Confirming that owner address was correctly set...`)
await waitUntilTrue(async () => {
return hexStringEquals(
await proxy.connect(proxy.signer.provider).callStatic.getOwner({
from: ethers.constants.AddressZero,
}),
owner
)
})
}
deployFn.dependencies = ['Lib_AddressManager', 'Proxy__L1StandardBridge']
deployFn.tags = ['L1StandardBridge', 'upgrade']
export default deployFn
/* Imports: External */
import { DeployFunction } from 'hardhat-deploy/dist/types'
/* Imports: Internal */
import { registerAddress } from '../src/hardhat-deploy-ethers'
import { predeploys } from '../src/predeploys'
const deployFn: DeployFunction = async (hre) => {
// L2CrossDomainMessenger is the address of the predeploy on L2. We can refactor off-chain
// services such that we can remove the need to set this address, but for now it's easier
// to simply keep setting the address.
await registerAddress({
hre,
name: 'L2CrossDomainMessenger',
address: predeploys.L2CrossDomainMessenger,
})
// OVM_Sequencer is the address allowed to submit "Sequencer" blocks to the
// CanonicalTransactionChain.
await registerAddress({
hre,
name: 'OVM_Sequencer',
address: (hre as any).deployConfig.ovmSequencerAddress,
})
// OVM_Proposer is the address allowed to submit state roots (transaction results) to the
// StateCommitmentChain.
await registerAddress({
hre,
name: 'OVM_Proposer',
address: (hre as any).deployConfig.ovmProposerAddress,
})
}
deployFn.tags = ['set-addresses', 'upgrade']
export default deployFn
...@@ -39,6 +39,6 @@ const deployFn: DeployFunction = async (hre) => { ...@@ -39,6 +39,6 @@ const deployFn: DeployFunction = async (hre) => {
} }
deployFn.dependencies = ['Lib_AddressManager'] deployFn.dependencies = ['Lib_AddressManager']
deployFn.tags = ['finalize'] deployFn.tags = ['finalize', 'upgrade']
export default deployFn export default deployFn
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