Upgrading Optimism L1 smart contracts from v1.3.0 to v1.8.0
This guide provides specific instructions for upgrading the OP Stack's Layer 1 contracts from op-contracts/v1.3.0
to op-contracts/v1.8.0
. This upgrade includes important changes to the system configuration and introduces the Fault Proof System.
Overview of the Holocene upgrade
The Holocene upgrade is a protocol upgrade. Learn more about it in the Holocene notice page (opens in a new tab). This guide shows you how to take your OP Stack chain from the L2 Output Oracle System to a permissioned Fault Proof System contract version associated with the Holocene upgrade.
Formatting config files
You need your chain's deployments.json
and deploy-config.json
Ensure both files are correctly formatted, using the exact field names shown in the below examples, with ALL values - particularly the relevant ones - updated for your specific chain:
deployments.json
:
{
"AddressManager": "0xEF8115F2733fb2033a7c756402Fc1deaa56550Ef",
"L2OutputOracleProxy": "0x9E6204F750cD866b299594e2aC9eA824E2e5f95c",
"OptimismMintableERC20FactoryProxy": "0xc52BC7344e24e39dF1bf026fe05C4e6E23CfBcFf",
"L1StandardBridgeProxy": "0x3e2Ea9B92B7E48A52296fD261dc26fd995284631",
"ProxyAdmin": "0xD4ef175B9e72cAEe9f1fe7660a6Ec19009903b49",
"L1CrossDomainMessengerProxy": "0xdC40a14d9abd6F410226f1E6de71aE03441ca506",
"L1ERC721BridgeProxy": "0x83A4521A3573Ca87f3a971B169C5A0E1d34481c3",
"OptimismPortalProxy": "0x1a0ad011913A150f69f6A19DF447A0CfD9551054",
"SystemConfigProxy": "0xA3cAB0126d5F504B071b81a3e8A2BBBF17930d86"
}
deploy-config.json
:
{
"l1StartingBlockTag": "0x10aa183",
"l1ChainID": 1,
"l2ChainID": 7777777,
"l2BlockTime": 2,
"finalizationPeriodSeconds": 604800,
"controller": "0xEe729F57F0111FD0F660867d0F522f983202a5aF",
"baseFeeVaultRecipient": "0xe900b3Edc1BA0430CFa9a204A1027B90825ac951",
"l1FeeVaultRecipient": "0xe900b3Edc1BA0430CFa9a204A1027B90825ac951",
"sequencerFeeVaultRecipient": "0xe900b3Edc1BA0430CFa9a204A1027B90825ac951",
"l2GenesisBlockBaseFeePerGas": "0x3b9aca00",
"governanceTokenOwner": "0xC72aE5c7cc9a332699305E29F68Be66c73b60542",
"governanceTokenSymbol": "OP",
"governanceTokenName": "Optimism",
"maxSequencerDrift": 600,
"sequencerWindowSize": 3600,
"channelTimeout": 300,
"p2pSequencerAddress": "0x3Dc8Dfd0709C835cAd15a6A27e089FF4cF4C9228",
"optimismL2FeeRecipient": "0x63AA492609175d1824dD668BDadF0042E74b0fC8",
"batchInboxAddress": "0x6F54Ca6F6EdE96662024Ffd61BFd18f3f4e34DFf",
"batchSenderAddress": "0x625726c858dBF78c0125436C943Bf4b4bE9d9033",
"l2GenesisRegolithTimeOffset": "0x0",
"l2OutputOracleSubmissionInterval": 180,
"l2OutputOracleStartingTimestamp": -1,
"l2OutputOracleStartingBlockNumber": "0x0",
"l2GenesisBlockGasLimit": "0x1c9c380",
"fundDevAccounts": false,
"gasPriceOracleOverhead": 188,
"gasPriceOracleScalar": 684000,
"eip1559Denominator": 50,
"eip1559Elasticity": 6,
"optimismBaseFeeRecipient": "0xea4591A6e5a31CF0b822A4f563163CeeBeEe4eb1",
"optimismL1FeeRecipient": "0xdD7aCF916c3E3Fb959CA3bB29beFffcAD2e90be6",
"l2CrossDomainMessengerOwner": "0xA53EF9bBec25fdA4b6Da7EF5617565794369A2A5",
"gasPriceOracleOwner": "0x9c3651E0B3CE47A0b17d775077E3d9B712582be0",
- RELEVANT VALUES
"systemConfigOwner": "0xC72aE5c7cc9a332699305E29F68Be66c73b60542",
"finalSystemOwner": "0xC72aE5c7cc9a332699305E29F68Be66c73b60542",
"superchainConfigGuardian": "0x9BA6e03D8B90dE867373Db8cF1A58d2F7F006b3A",
"portalGuardian": "0xC72aE5c7cc9a332699305E29F68Be66c73b60542",
"l2OutputOracleProposer": "0x48247032092e7b0ecf5dEF611ad89eaf3fC888Dd",
"l2OutputOracleOwner": "0xDA1F62857EA7f10444725c6c435235243D623540",
"proxyAdmin": "0x027860cA56cF779371461C14c3a483c94e1aA8a0",
"proxyAdminOwner": "0xb0cCdbD6fe09D2199171BE19450aF249250518A0",
"l2OutputOracleChallenger": "0xcA4571b1ecBeC86Ea2E660d242c1c29FcB55Dc72",
- add the below values if not in the config file already, making sure they are correct for your chain
"useFaultProofs": true,
"faultGameMaxDepth": 73,
"faultGameSplitDepth": 30,
"faultGameWithdrawalDelay": 604800,
"faultGameMaxClockDuration": 302400,
"faultGameClockExtension": 10800,
- You can update this to the latest absolute prestate hash in the Superchain Registry; however, the permissioned Fault Proof System doesn't use this. This comes into play when you upgrade your chain to the permissionless Fault Proof System.
"faultGameAbsolutePrestate": "0x03925193e3e89f87835bbdf3a813f60b2aa818a36bbe71cd5d8fd7e79f52bafe",
- add the below values if not in the config file already, making sure they are correct for your chain
"faultGameGenesisBlock": 0,
"faultGameGenesisOutputRoot": "0xdead000000000000000000000000000000000000000000000000000000000000",
"respectedGameType": 1,
"preimageOracleMinProposalSize": 126000,
"preimageOracleChallengePeriod": 86400,
"proofMaturityDelaySeconds": 604800,
"disputeGameFinalityDelaySeconds": 302400,
"enableGovernance": false,
"systemConfigStartBlock": 0,
"requiredProtocolVersion": "0x0000000000000000000000000000000000000003000000010000000000000000",
"recommendedProtocolVersion": "0x0000000000000000000000000000000000000003000000010000000000000000",
- make sure to add the below if not present already, these values won't matter but the script needs them to be present in the config
"sequencerFeeVaultWithdrawalNetwork": 0,
"baseFeeVaultWithdrawalNetwork": 0,
"l1FeeVaultWithdrawalNetwork": 0,
"baseFeeVaultMinimumWithdrawalAmount": "0x8ac7230489e80000",
"l1FeeVaultMinimumWithdrawalAmount": "0x8ac7230489e80000",
"sequencerFeeVaultMinimumWithdrawalAmount": "0x8ac7230489e80000"
}
Make sure that important addresses (like the ProxyAdmin
, ProxyAdminOwner
, all L1 addresses, L2OO
) are actually up to date by cross checking the Superchain Registry and on-chain (you can do this easily with op-fetcher
(opens in a new tab), especially for the deployments.json
.
Step-by-step upgrade process
1. Create your working directory
Create a working directory:
mkdir upgrade-dir
cd upgrade-dir
And then create an outputs directory:
mkdir outputs
2. Copy config files
Copy your deployments.json
and deploy-config.json
into the working directory
3. Configure and deploy environment
Create and update an .env
file with the required information:
##############################################
# ↓ Required ↓ #
##############################################
# Can be "mainnet" or "sepolia"
NETWORK=
# Etherscan API key used to verify contract bytecode
ETHERSCAN_API_KEY=
# RPC URL for the L1 network that matches $NETWORK
ETH_RPC_URL=
# Private key used to deploy the new contracts for this upgrade
PRIVATE_KEY=
# Base fee scalar for the SystemConfig
BASE_FEE_SCALAR=
# Blob base fee scalar for the SystemConfig
BLOB_BASE_FEE_SCALAR=
# Check if required files and folders exist
if [ ! -f "./deploy_config.json" ]; then
echo "Error: deploy_config.json not found"
fi
if [ ! -f "./deployments.json" ]; then
echo "Error: deployments.json not found"
fi
if [ ! -d "./outputs" ]; then
echo "Error: outputs folder not found"
fi
4. Run the deployment process
Run the deployment process with the following command:
docker run -t
--env-file .env
-v ./deploy_config.json:/deploy_config.json
-v ./deployments.json:/deployments.json
-v ./outputs:/outputs
kfoplabs/upgrade-v1.3.0-v1.8.0-permissioned /deploy_config.json /deployments.json
5. Verify outputs
The deployment should output four files:
deploy.log
is a log of the deployment processdeployments.json
includes the newly deployed contract addressesbundle.json
is the safe transaction bundletransactions.json
is the summary of the executed deployment transactionsstandard-addresses.json
is the addresses ofSystemConfigImpl
,OptimismPortal2Impl
,L1CrossDomainMessengerImpl
,L1StandardBridgeImpl
,L1ERC721BridgeImpl
, andOptimismMintableERC20FactoryImpl
validation.txt
is used for Tenderly state diff validation. Some info needed for the superchain-ops task might be missing from this file, and will instead be generated during the Tenderly simulation.
6. Verify outputs
Now you have the calldata that can be executed onchain to perform the L1 contract upgrade. You should simulate this upgrade and make sure the changes are expected. You can reference the validation files of previously executed upgrade tasks in the superchain-ops repo (opens in a new tab) to see what the expected changes are. Once you're confident the state changes are expected, you can sign and execute the upgrade.