Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -1,7 +1,9 @@
// SPDX-License-Identifier: MIT
pragma solidity 0.8.15;

import { Ownable } from "@openzeppelin/contracts/access/Ownable.sol";
import {
OwnableUpgradeable
} from "@openzeppelin/contracts-upgradeable/access/OwnableUpgradeable.sol";
import { L2OutputOracle } from "../L1/L2OutputOracle.sol";
import { OptimismPortal } from "../L1/OptimismPortal.sol";
import { L1CrossDomainMessenger } from "../L1/L1CrossDomainMessenger.sol";
Expand All @@ -21,7 +23,7 @@ import { SystemConfig } from "../L1/SystemConfig.sol";
* system. The SystemDictator is designed to support both fresh network deployments and
* upgrades to existing pre-Bedrock systems.
*/
contract SystemDictator is Ownable {
contract SystemDictator is OwnableUpgradeable {
/**
* @notice Basic system configuration.
*/
Expand Down Expand Up @@ -111,7 +113,7 @@ contract SystemDictator is Ownable {
/**
* @notice Current step;
*/
uint8 public currentStep = 1;
uint8 public currentStep;

/**
* @notice Whether or not dynamic config has been set.
Expand Down Expand Up @@ -142,8 +144,10 @@ contract SystemDictator is Ownable {
/**
* @param _config System configuration.
*/
constructor(DeployConfig memory _config) Ownable() {
function initialize(DeployConfig memory _config) public initializer {
config = _config;
currentStep = 1;
__Ownable_init();
_transferOwnership(config.globalConfig.controller);
}

Expand Down
23 changes: 23 additions & 0 deletions packages/contracts-bedrock/deploy/009-SystemDictatorProxy.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
import { DeployFunction } from 'hardhat-deploy/dist/types'

import {
assertContractVariable,
deployAndVerifyAndThen,
} from '../src/deploy-utils'

const deployFn: DeployFunction = async (hre) => {
const { deployer } = await hre.getNamedAccounts()
await deployAndVerifyAndThen({
hre,
name: 'SystemDictatorProxy',
contract: 'Proxy',
args: [deployer],
postDeployAction: async (contract) => {
await assertContractVariable(contract, 'admin', deployer)
},
})
}

deployFn.tags = ['SystemDictatorProxy']

export default deployFn
62 changes: 0 additions & 62 deletions packages/contracts-bedrock/deploy/017-SystemDictator.ts

This file was deleted.

17 changes: 17 additions & 0 deletions packages/contracts-bedrock/deploy/018-SystemDictatorImpl.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
import { DeployFunction } from 'hardhat-deploy/dist/types'
import '@eth-optimism/hardhat-deploy-config'
import 'hardhat-deploy'

import { deployAndVerifyAndThen } from '../src/deploy-utils'

const deployFn: DeployFunction = async (hre) => {
await deployAndVerifyAndThen({
hre,
name: 'SystemDictator',
args: [],
})
}

deployFn.tags = ['SystemDictatorImpl']

export default deployFn
137 changes: 137 additions & 0 deletions packages/contracts-bedrock/deploy/019-SystemDictatorInit.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,137 @@
import { ethers } from 'ethers'
import { DeployFunction } from 'hardhat-deploy/dist/types'
import { awaitCondition } from '@eth-optimism/core-utils'
import '@eth-optimism/hardhat-deploy-config'
import 'hardhat-deploy'

import {
assertDictatorConfig,
makeDictatorConfig,
getContractsFromArtifacts,
} from '../src/deploy-utils'

const deployFn: DeployFunction = async (hre) => {
const { deployer } = await hre.getNamedAccounts()

let controller = hre.deployConfig.controller
if (controller === ethers.constants.AddressZero) {
if (hre.network.config.live === false) {
console.log(`WARNING!!!`)
console.log(`WARNING!!!`)
console.log(`WARNING!!!`)
console.log(`WARNING!!! A controller address was not provided.`)
console.log(
`WARNING!!! Make sure you are ONLY doing this on a test network.`
)
controller = deployer
} else {
throw new Error(
`controller address MUST NOT be the deployer on live networks`
)
}
}

let finalOwner = hre.deployConfig.finalSystemOwner
if (finalOwner === ethers.constants.AddressZero) {
if (hre.network.config.live === false) {
console.log(`WARNING!!!`)
console.log(`WARNING!!!`)
console.log(`WARNING!!!`)
console.log(`WARNING!!! A proxy admin owner address was not provided.`)
console.log(
`WARNING!!! Make sure you are ONLY doing this on a test network.`
)
finalOwner = deployer
} else {
throw new Error(`must specify the finalSystemOwner on live networks`)
}
}

// Load the contracts we need to interact with.
const [
SystemDictator,
SystemDictatorProxy,
SystemDictatorProxyWithSigner,
SystemDictatorImpl,
] = await getContractsFromArtifacts(hre, [
{
name: 'SystemDictatorProxy',
iface: 'SystemDictator',
signerOrProvider: deployer,
},
{
name: 'SystemDictatorProxy',
},
{
name: 'SystemDictatorProxy',
signerOrProvider: deployer,
},
{
name: 'SystemDictator',
signerOrProvider: deployer,
},
])

// Load the dictator configuration.
const config = await makeDictatorConfig(hre, controller, finalOwner, false)

// Update the implementation if necessary.
if (
(await SystemDictatorProxy.callStatic.implementation({
from: ethers.constants.AddressZero,
})) !== SystemDictatorImpl.address
) {
console.log('Upgrading the SystemDictator proxy...')

// Upgrade and initialize the proxy.
await SystemDictatorProxyWithSigner.upgradeToAndCall(
SystemDictatorImpl.address,
SystemDictatorImpl.interface.encodeFunctionData('initialize', [config])
)

// Wait for the transaction to execute properly.
await awaitCondition(
async () => {
return (
(await SystemDictatorProxy.callStatic.implementation({
from: ethers.constants.AddressZero,
})) === SystemDictatorImpl.address
)
},
30000,
1000
)

// Verify that the contract was initialized correctly.
await assertDictatorConfig(SystemDictator, config)
}

// Update the owner if necessary.
if (
(await SystemDictatorProxy.callStatic.admin({
from: ethers.constants.AddressZero,
})) !== controller
) {
console.log('Transferring ownership of the SystemDictator proxy...')

// Transfer ownership to the controller address.
await SystemDictatorProxyWithSigner.transferOwnership(controller)

// Wait for the transaction to execute properly.
await awaitCondition(
async () => {
return (
(await SystemDictatorProxy.callStatic.admin({
from: ethers.constants.AddressZero,
})) === controller
)
},
30000,
1000
)
}
}

deployFn.tags = ['SystemDictatorImpl']

export default deployFn
Original file line number Diff line number Diff line change
Expand Up @@ -70,7 +70,8 @@ const deployFn: DeployFunction = async (hre) => {
L1ERC721Bridge,
] = await getContractsFromArtifacts(hre, [
{
name: 'SystemDictator',
name: 'SystemDictatorProxy',
iface: 'SystemDictator',
signerOrProvider: deployer,
},
{
Expand Down