Commit 1febf8a1 authored by protolambda's avatar protolambda

contracts-bedrock: ProtocolVersions contract

Including bindings and option updates.
Co-authored-by: default avatarMark Tyneway <mark.tyneway@gmail.com>
parent d5bc25d3
...@@ -35,5 +35,6 @@ ...@@ -35,5 +35,6 @@
"PreimageOracle", "PreimageOracle",
"BlockOracle", "BlockOracle",
"EAS", "EAS",
"SchemaRegistry" "SchemaRegistry",
"ProtocolVersions"
] ]
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
// Code generated - DO NOT EDIT.
// This file is a generated binding and any manual changes will be lost.
package bindings
import (
"encoding/json"
"github.com/ethereum-optimism/optimism/op-bindings/solc"
)
const ProtocolVersionsStorageLayoutJSON = "{\"storage\":[{\"astId\":1000,\"contract\":\"src/L1/ProtocolVersions.sol:ProtocolVersions\",\"label\":\"_initialized\",\"offset\":0,\"slot\":\"0\",\"type\":\"t_uint8\"},{\"astId\":1001,\"contract\":\"src/L1/ProtocolVersions.sol:ProtocolVersions\",\"label\":\"_initializing\",\"offset\":1,\"slot\":\"0\",\"type\":\"t_bool\"},{\"astId\":1002,\"contract\":\"src/L1/ProtocolVersions.sol:ProtocolVersions\",\"label\":\"__gap\",\"offset\":0,\"slot\":\"1\",\"type\":\"t_array(t_uint256)50_storage\"},{\"astId\":1003,\"contract\":\"src/L1/ProtocolVersions.sol:ProtocolVersions\",\"label\":\"_owner\",\"offset\":0,\"slot\":\"51\",\"type\":\"t_address\"},{\"astId\":1004,\"contract\":\"src/L1/ProtocolVersions.sol:ProtocolVersions\",\"label\":\"__gap\",\"offset\":0,\"slot\":\"52\",\"type\":\"t_array(t_uint256)49_storage\"}],\"types\":{\"t_address\":{\"encoding\":\"inplace\",\"label\":\"address\",\"numberOfBytes\":\"20\"},\"t_array(t_uint256)49_storage\":{\"encoding\":\"inplace\",\"label\":\"uint256[49]\",\"numberOfBytes\":\"1568\",\"base\":\"t_uint256\"},\"t_array(t_uint256)50_storage\":{\"encoding\":\"inplace\",\"label\":\"uint256[50]\",\"numberOfBytes\":\"1600\",\"base\":\"t_uint256\"},\"t_bool\":{\"encoding\":\"inplace\",\"label\":\"bool\",\"numberOfBytes\":\"1\"},\"t_uint256\":{\"encoding\":\"inplace\",\"label\":\"uint256\",\"numberOfBytes\":\"32\"},\"t_uint8\":{\"encoding\":\"inplace\",\"label\":\"uint8\",\"numberOfBytes\":\"1\"}}}"
var ProtocolVersionsStorageLayout = new(solc.StorageLayout)
var ProtocolVersionsDeployedBin = "0x608060405234801561001057600080fd5b50600436106100d45760003560e01c80638da5cb5b11610081578063f2fde38b1161005b578063f2fde38b146101b8578063f7d12760146101cb578063ffa1ad74146101d357600080fd5b80638da5cb5b14610180578063d798b1ac146101a8578063dc8452cd146101b057600080fd5b80635fd579af116100b25780635fd579af14610152578063715018a6146101655780637a1ac61e1461016d57600080fd5b80630457d6f2146100d9578063206a8300146100ee57806354fd4d5014610109575b600080fd5b6100ec6100e7366004610859565b6101db565b005b6100f66101ef565b6040519081526020015b60405180910390f35b6101456040518060400160405280600581526020017f302e312e3000000000000000000000000000000000000000000000000000000081525081565b60405161010091906108dd565b6100ec610160366004610859565b61021d565b6100ec61022e565b6100ec61017b366004610920565b610242565b60335460405173ffffffffffffffffffffffffffffffffffffffff9091168152602001610100565b6100f66103ad565b6100f66103e6565b6100ec6101c6366004610953565b610416565b6100f66104ca565b6100f6600081565b6101e36104f5565b6101ec81610576565b50565b61021a60017f4aaefe95bd84fd3f32700cf3b7566bc944b73138e41958b5785826df2aecace161096e565b81565b6102256104f5565b6101ec8161062d565b6102366104f5565b61024060006106a8565b565b600054600290610100900460ff16158015610264575060005460ff8083169116105b6102f5576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602e60248201527f496e697469616c697a61626c653a20636f6e747261637420697320616c72656160448201527f647920696e697469616c697a656400000000000000000000000000000000000060648201526084015b60405180910390fd5b600080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00001660ff83161761010017905561032e61071f565b61033784610416565b61034083610576565b6103498261062d565b600080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00ff16905560405160ff821681527f7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb38474024989060200160405180910390a150505050565b60006103e16103dd60017fe314dfc40f0025322aacc0ba8ef420b62fb3b702cf01e0cdf3d829117ac2ff1b61096e565b5490565b905090565b60006103e16103dd60017f4aaefe95bd84fd3f32700cf3b7566bc944b73138e41958b5785826df2aecace161096e565b61041e6104f5565b73ffffffffffffffffffffffffffffffffffffffff81166104c1576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602660248201527f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160448201527f646472657373000000000000000000000000000000000000000000000000000060648201526084016102ec565b6101ec816106a8565b61021a60017fe314dfc40f0025322aacc0ba8ef420b62fb3b702cf01e0cdf3d829117ac2ff1b61096e565b60335473ffffffffffffffffffffffffffffffffffffffff163314610240576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e657260448201526064016102ec565b6105a8816105a560017f4aaefe95bd84fd3f32700cf3b7566bc944b73138e41958b5785826df2aecace161096e565b55565b6000816040516020016105bd91815260200190565b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0818403018152919052905060005b60007f1d2b0bda21d56b8bd12d4f94ebacffdfb35f5e226f84b461103bb8beab6353be8360405161062191906108dd565b60405180910390a35050565b61065c816105a560017fe314dfc40f0025322aacc0ba8ef420b62fb3b702cf01e0cdf3d829117ac2ff1b61096e565b60008160405160200161067191815260200190565b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0818403018152919052905060016105f0565b6033805473ffffffffffffffffffffffffffffffffffffffff8381167fffffffffffffffffffffffff0000000000000000000000000000000000000000831681179093556040519116919082907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e090600090a35050565b600054610100900460ff166107b6576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602b60248201527f496e697469616c697a61626c653a20636f6e7472616374206973206e6f74206960448201527f6e697469616c697a696e6700000000000000000000000000000000000000000060648201526084016102ec565b610240600054610100900460ff16610850576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602b60248201527f496e697469616c697a61626c653a20636f6e7472616374206973206e6f74206960448201527f6e697469616c697a696e6700000000000000000000000000000000000000000060648201526084016102ec565b610240336106a8565b60006020828403121561086b57600080fd5b5035919050565b6000815180845260005b818110156108985760208185018101518683018201520161087c565b818111156108aa576000602083870101525b50601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0169290920160200192915050565b6020815260006108f06020830184610872565b9392505050565b803573ffffffffffffffffffffffffffffffffffffffff8116811461091b57600080fd5b919050565b60008060006060848603121561093557600080fd5b61093e846108f7565b95602085013595506040909401359392505050565b60006020828403121561096557600080fd5b6108f0826108f7565b6000828210156109a7577f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b50039056fea164736f6c634300080f000a"
func init() {
if err := json.Unmarshal([]byte(ProtocolVersionsStorageLayoutJSON), ProtocolVersionsStorageLayout); err != nil {
panic(err)
}
layouts["ProtocolVersions"] = ProtocolVersionsStorageLayout
deployedBytecodes["ProtocolVersions"] = ProtocolVersionsDeployedBin
}
...@@ -8,7 +8,6 @@ import ( ...@@ -8,7 +8,6 @@ import (
"math/big" "math/big"
"os" "os"
"path/filepath" "path/filepath"
"reflect" "reflect"
"github.com/ethereum/go-ethereum/common" "github.com/ethereum/go-ethereum/common"
...@@ -198,6 +197,12 @@ type DeployConfig struct { ...@@ -198,6 +197,12 @@ type DeployConfig struct {
// FundDevAccounts configures whether or not to fund the dev accounts. Should only be used // FundDevAccounts configures whether or not to fund the dev accounts. Should only be used
// during devnet deployments. // during devnet deployments.
FundDevAccounts bool `json:"fundDevAccounts"` FundDevAccounts bool `json:"fundDevAccounts"`
// RequiredProtocolVersion indicates the protocol version that
// nodes are required to adopt, to stay in sync with the network.
RequiredProtocolVersion common.Hash `json:"requiredProtocolVersion"`
// RequiredProtocolVersion indicates the protocol version that
// nodes are recommended to adopt, to stay in sync with the network.
RecommendedProtocolVersion common.Hash `json:"recommendedProtocolVersion"`
} }
// Copy will deeply copy the DeployConfig. This does a JSON roundtrip to copy // Copy will deeply copy the DeployConfig. This does a JSON roundtrip to copy
...@@ -522,6 +527,8 @@ type L1Deployments struct { ...@@ -522,6 +527,8 @@ type L1Deployments struct {
ProxyAdmin common.Address `json:"ProxyAdmin"` ProxyAdmin common.Address `json:"ProxyAdmin"`
SystemConfig common.Address `json:"SystemConfig"` SystemConfig common.Address `json:"SystemConfig"`
SystemConfigProxy common.Address `json:"SystemConfigProxy"` SystemConfigProxy common.Address `json:"SystemConfigProxy"`
ProtocolVersions common.Address `json:"ProtocolVersions"`
ProtocolVersionsProxy common.Address `json:"ProtocolVersionsProxy"`
} }
// GetName will return the name of the contract given an address. // GetName will return the name of the contract given an address.
......
...@@ -89,6 +89,8 @@ func TestL1Deployments(t *testing.T) { ...@@ -89,6 +89,8 @@ func TestL1Deployments(t *testing.T) {
require.NotEqual(t, deployments.ProxyAdmin, common.Address{}) require.NotEqual(t, deployments.ProxyAdmin, common.Address{})
require.NotEqual(t, deployments.SystemConfig, common.Address{}) require.NotEqual(t, deployments.SystemConfig, common.Address{})
require.NotEqual(t, deployments.SystemConfigProxy, common.Address{}) require.NotEqual(t, deployments.SystemConfigProxy, common.Address{})
require.NotEqual(t, deployments.ProtocolVersions, common.Address{})
require.NotEqual(t, deployments.ProtocolVersionsProxy, common.Address{})
require.Equal(t, "AddressManager", deployments.GetName(deployments.AddressManager)) require.Equal(t, "AddressManager", deployments.GetName(deployments.AddressManager))
require.Equal(t, "OptimismPortalProxy", deployments.GetName(deployments.OptimismPortalProxy)) require.Equal(t, "OptimismPortalProxy", deployments.GetName(deployments.OptimismPortalProxy))
......
...@@ -16,5 +16,7 @@ ...@@ -16,5 +16,7 @@
"OptimismPortalProxy": "0xaC425EECd4Fd8E9E669a62906D99aF89B9951516", "OptimismPortalProxy": "0xaC425EECd4Fd8E9E669a62906D99aF89B9951516",
"ProxyAdmin": "0x3218c3b0dC0386BAe83A58E5F908c4b070210b4F", "ProxyAdmin": "0x3218c3b0dC0386BAe83A58E5F908c4b070210b4F",
"SystemConfig": "0x36bAcDD96F28e1ac0780bB9CbE6e20780840730F", "SystemConfig": "0x36bAcDD96F28e1ac0780bB9CbE6e20780840730F",
"SystemConfigProxy": "0x14065A373936533A0c88b7986CADabDD62d471e6" "SystemConfigProxy": "0x14065A373936533A0c88b7986CADabDD62d471e6",
"ProtocolVersions": "0x883C06a27D76B1CEbdf7EB376f5556c355afC8e5",
"ProtocolVersionsProxy": "0x3732a4D4Ab006cA4825822baEA1569A107683fa1"
} }
...@@ -67,5 +67,7 @@ ...@@ -67,5 +67,7 @@
"faultGameAbsolutePrestate": "0x0000000000000000000000000000000000000000000000000000000000000000", "faultGameAbsolutePrestate": "0x0000000000000000000000000000000000000000000000000000000000000000",
"faultGameMaxDepth": 63, "faultGameMaxDepth": 63,
"faultGameMaxDuration": 604800, "faultGameMaxDuration": 604800,
"systemConfigStartBlock": 0 "systemConfigStartBlock": 0,
"requiredProtocolVersion": "0x0000000000000000000000000000000000000000000000000000000000000000",
"recommendedProtocolVersion": "0x0000000000000000000000000000000000000000000000000000000000000000"
} }
...@@ -526,6 +526,10 @@ PreimageOracle_Test:test_loadKeccak256PreimagePart_outOfBoundsOffset_reverts() ( ...@@ -526,6 +526,10 @@ PreimageOracle_Test:test_loadKeccak256PreimagePart_outOfBoundsOffset_reverts() (
PreimageOracle_Test:test_loadKeccak256PreimagePart_succeeds() (gas: 76098) PreimageOracle_Test:test_loadKeccak256PreimagePart_succeeds() (gas: 76098)
PreimageOracle_Test:test_loadLocalData_onePart_succeeds() (gas: 75840) PreimageOracle_Test:test_loadLocalData_onePart_succeeds() (gas: 75840)
PreimageOracle_Test:test_loadLocalData_outOfBoundsOffset_reverts() (gas: 8803) PreimageOracle_Test:test_loadLocalData_outOfBoundsOffset_reverts() (gas: 8803)
ProtocolVersions_Initialize_Test:test_initialize_events_succeeds() (gas: 52175)
ProtocolVersions_Initialize_Test:test_initialize_values_succeeds() (gas: 32301)
ProtocolVersions_Setters_TestFail:test_setRecommended_notOwner_reverts() (gas: 15508)
ProtocolVersions_Setters_TestFail:test_setRequired_notOwner_reverts() (gas: 15520)
ProxyAdmin_Test:test_chugsplashChangeProxyAdmin_succeeds() (gas: 35586) ProxyAdmin_Test:test_chugsplashChangeProxyAdmin_succeeds() (gas: 35586)
ProxyAdmin_Test:test_chugsplashGetProxyAdmin_succeeds() (gas: 15675) ProxyAdmin_Test:test_chugsplashGetProxyAdmin_succeeds() (gas: 15675)
ProxyAdmin_Test:test_chugsplashGetProxyImplementation_succeeds() (gas: 51084) ProxyAdmin_Test:test_chugsplashGetProxyImplementation_succeeds() (gas: 51084)
...@@ -666,4 +670,4 @@ TransactorTest:test_constructor_succeeds() (gas: 9739) ...@@ -666,4 +670,4 @@ TransactorTest:test_constructor_succeeds() (gas: 9739)
TransactorTest:test_delegateCall_succeeds() (gas: 20909) TransactorTest:test_delegateCall_succeeds() (gas: 20909)
TransactorTest:test_delegateCall_unauthorized_reverts() (gas: 16550) TransactorTest:test_delegateCall_unauthorized_reverts() (gas: 16550)
TransferOnionTest:test_constructor_succeeds() (gas: 564855) TransferOnionTest:test_constructor_succeeds() (gas: 564855)
TransferOnionTest:test_unwrap_succeeds() (gas: 724955) TransferOnionTest:test_unwrap_succeeds() (gas: 724955)
\ No newline at end of file
...@@ -46,5 +46,7 @@ ...@@ -46,5 +46,7 @@
"faultGameAbsolutePrestate": "0x03c7ae758795765c6664a5d39bf63841c71ff191e9189522bad8ebff5d4eca98", "faultGameAbsolutePrestate": "0x03c7ae758795765c6664a5d39bf63841c71ff191e9189522bad8ebff5d4eca98",
"faultGameMaxDepth": 30, "faultGameMaxDepth": 30,
"faultGameMaxDuration": 1200, "faultGameMaxDuration": 1200,
"systemConfigStartBlock": 0 "systemConfigStartBlock": 0,
"requiredProtocolVersion": "0x0000000000000000000000000000000000000000000000000000000000000000",
"recommendedProtocolVersion": "0x0000000000000000000000000000000000000000000000000000000000000000"
} }
...@@ -28,6 +28,7 @@ import { PreimageOracle } from "src/cannon/PreimageOracle.sol"; ...@@ -28,6 +28,7 @@ import { PreimageOracle } from "src/cannon/PreimageOracle.sol";
import { MIPS } from "src/cannon/MIPS.sol"; import { MIPS } from "src/cannon/MIPS.sol";
import { BlockOracle } from "src/dispute/BlockOracle.sol"; import { BlockOracle } from "src/dispute/BlockOracle.sol";
import { L1ERC721Bridge } from "src/L1/L1ERC721Bridge.sol"; import { L1ERC721Bridge } from "src/L1/L1ERC721Bridge.sol";
import { ProtocolVersions, ProtocolVersion } from "src/L1/ProtocolVersions.sol";
import { Predeploys } from "src/libraries/Predeploys.sol"; import { Predeploys } from "src/libraries/Predeploys.sol";
import { Chains } from "./Chains.sol"; import { Chains } from "./Chains.sol";
...@@ -80,6 +81,7 @@ contract Deploy is Deployer { ...@@ -80,6 +81,7 @@ contract Deploy is Deployer {
initializeL1CrossDomainMessenger(); initializeL1CrossDomainMessenger();
initializeL2OutputOracle(); initializeL2OutputOracle();
initializeOptimismPortal(); initializeOptimismPortal();
initializeProtocolVersions();
setAlphabetFaultGameImplementation(); setAlphabetFaultGameImplementation();
setCannonFaultGameImplementation(); setCannonFaultGameImplementation();
...@@ -103,6 +105,18 @@ contract Deploy is Deployer { ...@@ -103,6 +105,18 @@ contract Deploy is Deployer {
} }
} }
/// @notice Modifier that will only allow a function to be called on a public
/// testnet or devnet.
modifier onlyTestnetOrDevnet() {
uint256 chainid = block.chainid;
if (
chainid == Chains.Goerli || chainid == Chains.Sepolia || chainid == Chains.LocalDevnet
|| chainid == Chains.GethDevnet
) {
_;
}
}
/// @notice Deploy all of the proxies /// @notice Deploy all of the proxies
function deployProxies() public { function deployProxies() public {
deployAddressManager(); deployAddressManager();
...@@ -116,6 +130,7 @@ contract Deploy is Deployer { ...@@ -116,6 +130,7 @@ contract Deploy is Deployer {
deployOptimismMintableERC20FactoryProxy(); deployOptimismMintableERC20FactoryProxy();
deployL1ERC721BridgeProxy(); deployL1ERC721BridgeProxy();
deployDisputeGameFactoryProxy(); deployDisputeGameFactoryProxy();
deployProtocolVersionsProxy();
transferAddressManagerOwnership(); transferAddressManagerOwnership();
} }
...@@ -133,6 +148,7 @@ contract Deploy is Deployer { ...@@ -133,6 +148,7 @@ contract Deploy is Deployer {
deployBlockOracle(); deployBlockOracle();
deployPreimageOracle(); deployPreimageOracle();
deployMips(); deployMips();
deployProtocolVersions();
} }
/// @notice Deploy the AddressManager /// @notice Deploy the AddressManager
...@@ -291,6 +307,22 @@ contract Deploy is Deployer { ...@@ -291,6 +307,22 @@ contract Deploy is Deployer {
addr_ = address(proxy); addr_ = address(proxy);
} }
/// @notice Deploy the ProtocolVersionsProxy
function deployProtocolVersionsProxy() public onlyTestnetOrDevnet broadcast returns (address addr_) {
address proxyAdmin = mustGetAddress("ProxyAdmin");
Proxy proxy = new Proxy({
_admin: proxyAdmin
});
address admin = address(uint160(uint256(vm.load(address(proxy), OWNER_KEY))));
require(admin == proxyAdmin);
save("ProtocolVersionsProxy", address(proxy));
console.log("ProtocolVersionsProxy deployed at %s", address(proxy));
addr_ = address(proxy);
}
/// @notice Deploy the L1CrossDomainMessenger /// @notice Deploy the L1CrossDomainMessenger
function deployL1CrossDomainMessenger() public broadcast returns (address addr_) { function deployL1CrossDomainMessenger() public broadcast returns (address addr_) {
L1CrossDomainMessenger messenger = new L1CrossDomainMessenger{ salt: IMPL_SALT }(); L1CrossDomainMessenger messenger = new L1CrossDomainMessenger{ salt: IMPL_SALT }();
...@@ -380,6 +412,15 @@ contract Deploy is Deployer { ...@@ -380,6 +412,15 @@ contract Deploy is Deployer {
addr_ = address(oracle); addr_ = address(oracle);
} }
/// @notice Deploy the ProtocolVersions
function deployProtocolVersions() public onlyTestnetOrDevnet broadcast returns (address addr_) {
ProtocolVersions versions = new ProtocolVersions{ salt: IMPL_SALT }();
save("ProtocolVersions", address(versions));
console.log("ProtocolVersions deployed at %s", address(versions));
addr_ = address(versions);
}
/// @notice Deploy the PreimageOracle /// @notice Deploy the PreimageOracle
function deployPreimageOracle() public onlyDevnet broadcast returns (address addr_) { function deployPreimageOracle() public onlyDevnet broadcast returns (address addr_) {
PreimageOracle preimageOracle = new PreimageOracle{ salt: IMPL_SALT }(); PreimageOracle preimageOracle = new PreimageOracle{ salt: IMPL_SALT }();
...@@ -742,6 +783,37 @@ contract Deploy is Deployer { ...@@ -742,6 +783,37 @@ contract Deploy is Deployer {
require(portal.paused() == false); require(portal.paused() == false);
} }
function initializeProtocolVersions() public onlyTestnetOrDevnet broadcast {
ProxyAdmin proxyAdmin = ProxyAdmin(mustGetAddress("ProxyAdmin"));
address protocolVersionsProxy = mustGetAddress("ProtocolVersionsProxy");
address protocolVersions = mustGetAddress("ProtocolVersions");
address finalSystemOwner = cfg.finalSystemOwner();
uint256 requiredProtocolVersion = cfg.requiredProtocolVersion();
uint256 recommendedProtocolVersion = cfg.recommendedProtocolVersion();
proxyAdmin.upgradeAndCall({
_proxy: payable(protocolVersionsProxy),
_implementation: protocolVersions,
_data: abi.encodeCall(
ProtocolVersions.initialize,
(
finalSystemOwner,
ProtocolVersion.wrap(requiredProtocolVersion),
ProtocolVersion.wrap(recommendedProtocolVersion)
)
)
});
ProtocolVersions versions = ProtocolVersions(protocolVersionsProxy);
string memory version = versions.version();
console.log("ProtocolVersions version: %s", version);
require(versions.owner() == finalSystemOwner);
require(ProtocolVersion.unwrap(versions.required()) == requiredProtocolVersion);
require(ProtocolVersion.unwrap(versions.recommended()) == recommendedProtocolVersion);
}
/// @notice Transfer ownership of the ProxyAdmin contract to the final system owner /// @notice Transfer ownership of the ProxyAdmin contract to the final system owner
function transferProxyAdminOwnership() public broadcast { function transferProxyAdminOwnership() public broadcast {
ProxyAdmin proxyAdmin = ProxyAdmin(mustGetAddress("ProxyAdmin")); ProxyAdmin proxyAdmin = ProxyAdmin(mustGetAddress("ProxyAdmin"));
......
...@@ -48,6 +48,8 @@ contract DeployConfig is Script { ...@@ -48,6 +48,8 @@ contract DeployConfig is Script {
uint256 public faultGameMaxDepth; uint256 public faultGameMaxDepth;
uint256 public faultGameMaxDuration; uint256 public faultGameMaxDuration;
uint256 public systemConfigStartBlock; uint256 public systemConfigStartBlock;
uint256 public requiredProtocolVersion;
uint256 public recommendedProtocolVersion;
constructor(string memory _path) { constructor(string memory _path) {
console.log("DeployConfig: reading file %s", _path); console.log("DeployConfig: reading file %s", _path);
...@@ -94,6 +96,13 @@ contract DeployConfig is Script { ...@@ -94,6 +96,13 @@ contract DeployConfig is Script {
faultGameAbsolutePrestate = stdJson.readUint(_json, "$.faultGameAbsolutePrestate"); faultGameAbsolutePrestate = stdJson.readUint(_json, "$.faultGameAbsolutePrestate");
faultGameMaxDepth = stdJson.readUint(_json, "$.faultGameMaxDepth"); faultGameMaxDepth = stdJson.readUint(_json, "$.faultGameMaxDepth");
faultGameMaxDuration = stdJson.readUint(_json, "$.faultGameMaxDuration"); faultGameMaxDuration = stdJson.readUint(_json, "$.faultGameMaxDuration");
requiredProtocolVersion = stdJson.readUint(_json, "$.requiredProtocolVersion");
recommendedProtocolVersion = stdJson.readUint(_json, "$.recommendedProtocolVersion");
}
if (block.chainid == Chains.Goerli || block.chainid == Chains.Sepolia) {
requiredProtocolVersion = stdJson.readUint(_json, "$.requiredProtocolVersion");
recommendedProtocolVersion = stdJson.readUint(_json, "$.recommendedProtocolVersion");
} }
} }
......
...@@ -6,6 +6,7 @@ ...@@ -6,6 +6,7 @@
"src/L1/L1StandardBridge.sol": "0x12e227c6054660a83b92d823a7447db96a7d476b7a94e0f1807772d400329880", "src/L1/L1StandardBridge.sol": "0x12e227c6054660a83b92d823a7447db96a7d476b7a94e0f1807772d400329880",
"src/L1/L2OutputOracle.sol": "0x2e298bccb5fe73cf365e23bb56ebe974534549e0052bfe0f86372c52067153e6", "src/L1/L2OutputOracle.sol": "0x2e298bccb5fe73cf365e23bb56ebe974534549e0052bfe0f86372c52067153e6",
"src/L1/OptimismPortal.sol": "0xc8e41a7c3405c1b04c98f4b6bc7d20ff6f20cd3132134a3106670f5a475978c7", "src/L1/OptimismPortal.sol": "0xc8e41a7c3405c1b04c98f4b6bc7d20ff6f20cd3132134a3106670f5a475978c7",
"src/L1/ProtocolVersions.sol": "0x2f980d89b583936c7af5d71a1e2c73d026d895c1687abdd09815e4581032cee5",
"src/L1/SystemConfig.sol": "0xd508b84ef7c6d57be1e2e7eef92fc340f6bb3d68d999bdf2fabe12d110f9615c", "src/L1/SystemConfig.sol": "0xd508b84ef7c6d57be1e2e7eef92fc340f6bb3d68d999bdf2fabe12d110f9615c",
"src/L2/BaseFeeVault.sol": "0xc347c1aebe69178e72d2b1d3e700bbf84e39975319465bb85d69fd0d60fc1759", "src/L2/BaseFeeVault.sol": "0xc347c1aebe69178e72d2b1d3e700bbf84e39975319465bb85d69fd0d60fc1759",
"src/L2/GasPriceOracle.sol": "0x88efffbd40f8d012d700a5d7fde0d92266f65e9d7006cd8f034bacaa036d0eb2", "src/L2/GasPriceOracle.sol": "0x88efffbd40f8d012d700a5d7fde0d92266f65e9d7006cd8f034bacaa036d0eb2",
......
// SPDX-License-Identifier: MIT
pragma solidity 0.8.15;
import { OwnableUpgradeable } from "@openzeppelin/contracts-upgradeable/access/OwnableUpgradeable.sol";
import { ISemver } from "src/universal/ISemver.sol";
/// @notice ProtocolVersion is a numeric identifier of the protocol version.
type ProtocolVersion is uint256;
/// @title ProtocolVersions
/// @notice The ProtocolVersions contract is used to manage superchain protocol version information.
contract ProtocolVersions is OwnableUpgradeable, ISemver {
/// @notice Enum representing different types of updates.
/// @custom:value REQUIRED_PROTOCOL_VERSION Represents an update to the required protocol version.
/// @custom:value RECOMMENDED_PROTOCOL_VERSION Represents an update to the recommended protocol version.
enum UpdateType {
REQUIRED_PROTOCOL_VERSION,
RECOMMENDED_PROTOCOL_VERSION
}
/// @notice Version identifier, used for upgrades.
uint256 public constant VERSION = 0;
/// @notice Storage slot that the required protocol version is stored at.
bytes32 public constant REQUIRED_SLOT = bytes32(uint256(keccak256("protocolversion.required")) - 1);
/// @notice Storage slot that the recommended protocol version is stored at.
bytes32 public constant RECOMMENDED_SLOT = bytes32(uint256(keccak256("protocolversion.recommended")) - 1);
/// @notice Emitted when configuration is updated.
/// @param version ProtocolVersion version.
/// @param updateType Type of update.
/// @param data Encoded update data.
event ConfigUpdate(uint256 indexed version, UpdateType indexed updateType, bytes data);
/// @notice Semantic version.
/// @custom:semver 0.1.0
string public constant version = "0.1.0";
/// @notice Constructs the ProtocolVersion contract. Cannot set
/// the owner to `address(0)` due to the Ownable contract's
/// implementation, so set it to `address(0xdEaD)`
/// A zero version is considered empty and is ignored by nodes.
constructor() {
initialize({
_owner: address(0xdEaD),
_required: ProtocolVersion.wrap(uint256(0)),
_recommended: ProtocolVersion.wrap(uint256(0))
});
}
/// @notice Initializer.
/// @param _owner Initial owner of the contract.
/// @param _required Required protocol version to operate on this chain.
/// @param _recommended Recommended protocol version to operate on thi chain.
function initialize(
address _owner,
ProtocolVersion _required,
ProtocolVersion _recommended
)
public
reinitializer(2)
{
__Ownable_init();
transferOwnership(_owner);
_setRequired(_required);
_setRecommended(_recommended);
}
/// @notice Returns a ProtocolVersion stored in an arbitrary storage slot.
/// These storage slots decouple the storage layout from solc's automation.
/// @param _slot The storage slot to retrieve the address from.
function _getProtocolVersion(bytes32 _slot) internal view returns (ProtocolVersion out_) {
assembly {
out_ := sload(_slot)
}
}
/// @notice Stores a ProtocolVersion in an arbitrary storage slot, `_slot`.
/// @param _version The protocol version to store
/// @param _slot The storage slot to store the address in.
/// @dev WARNING! This function must be used cautiously, as it allows for overwriting values
/// in arbitrary storage slots.
function _setProtocolVersion(ProtocolVersion _version, bytes32 _slot) internal {
assembly {
sstore(_slot, _version)
}
}
/// @notice High level getter for the required protocol version.
/// @return out_ Required protocol version to sync to the head of the chain.
function required() external view returns (ProtocolVersion out_) {
out_ = _getProtocolVersion(REQUIRED_SLOT);
}
/// @notice Updates the required protocol version. Can only be called by the owner.
/// @param _required New required protocol version.
function setRequired(ProtocolVersion _required) external onlyOwner {
_setRequired(_required);
}
/// @notice Internal function for updating the required protocol version.
/// @param _required New required protocol version.
function _setRequired(ProtocolVersion _required) internal {
_setProtocolVersion(_required, REQUIRED_SLOT);
bytes memory data = abi.encode(_required);
emit ConfigUpdate(VERSION, UpdateType.REQUIRED_PROTOCOL_VERSION, data);
}
/// @notice High level getter for the recommended protocol version.
/// @return out_ Recommended protocol version to sync to the head of the chain.
function recommended() external view returns (ProtocolVersion out_) {
out_ = _getProtocolVersion(RECOMMENDED_SLOT);
}
/// @notice Updates the recommended protocol version. Can only be called by the owner.
/// @param _recommended New recommended protocol version.
function setRecommended(ProtocolVersion _recommended) external onlyOwner {
_setRecommended(_recommended);
}
/// @notice Internal function for updating the recommended protocol version.
/// @param _recommended New recommended protocol version.
function _setRecommended(ProtocolVersion _recommended) internal {
_setProtocolVersion(_recommended, RECOMMENDED_SLOT);
bytes memory data = abi.encode(_recommended);
emit ConfigUpdate(VERSION, UpdateType.RECOMMENDED_PROTOCOL_VERSION, data);
}
}
// SPDX-License-Identifier: MIT
pragma solidity 0.8.15;
// Testing utilities
import { CommonTest } from "./CommonTest.t.sol";
// Libraries
import { Constants } from "src/libraries/Constants.sol";
// Target contract dependencies
import { Proxy } from "src/universal/Proxy.sol";
// Target contract
import { ProtocolVersions, ProtocolVersion } from "src/L1/ProtocolVersions.sol";
contract ProtocolVersions_Init is CommonTest {
ProtocolVersions protocolVersions;
ProtocolVersions protocolVersionsImpl;
event ConfigUpdate(uint256 indexed version, ProtocolVersions.UpdateType indexed updateType, bytes data);
// Dummy values used to test getters
ProtocolVersion constant required = ProtocolVersion.wrap(0xabcd);
ProtocolVersion constant recommended = ProtocolVersion.wrap(0x1234);
function setUp() public virtual override {
super.setUp();
Proxy proxy = new Proxy(multisig);
protocolVersionsImpl = new ProtocolVersions();
vm.prank(multisig);
proxy.upgradeToAndCall(
address(protocolVersionsImpl),
abi.encodeCall(
ProtocolVersions.initialize,
(
alice, // _owner,
required,
recommended
)
)
);
protocolVersions = ProtocolVersions(address(proxy));
}
}
contract ProtocolVersions_Initialize_Test is ProtocolVersions_Init {
/// @dev Tests that initialization sets the correct values.
function test_initialize_values_succeeds() external {
assertEq(ProtocolVersion.unwrap(protocolVersions.required()), ProtocolVersion.unwrap(required));
assertEq(ProtocolVersion.unwrap(protocolVersions.recommended()), ProtocolVersion.unwrap(recommended));
assertEq(protocolVersions.owner(), alice);
assertEq(ProtocolVersion.unwrap(protocolVersionsImpl.required()), 0);
assertEq(ProtocolVersion.unwrap(protocolVersionsImpl.recommended()), 0);
assertEq(protocolVersionsImpl.owner(), address(0xdEad));
}
/// @dev Ensures that the events are emitted during initialization.
function test_initialize_events_succeeds() external {
//vm.store(address(protocolVersions), bytes32(uint256(106)), bytes32(0));
assertEq(protocolVersionsImpl.owner(), address(0xdEad));
// Wipe out the initialized slot so the proxy can be initialized again
vm.store(address(protocolVersions), bytes32(0), bytes32(0));
// The order depends here
vm.expectEmit(true, true, true, true, address(protocolVersions));
emit ConfigUpdate(0, ProtocolVersions.UpdateType.REQUIRED_PROTOCOL_VERSION, abi.encode(required));
vm.expectEmit(true, true, true, true, address(protocolVersions));
emit ConfigUpdate(0, ProtocolVersions.UpdateType.RECOMMENDED_PROTOCOL_VERSION, abi.encode(recommended));
vm.prank(multisig);
Proxy(payable(address(protocolVersions))).upgradeToAndCall(
address(protocolVersionsImpl),
abi.encodeCall(
ProtocolVersions.initialize,
(
alice, // _owner
required, // _required
recommended // recommended
)
)
);
}
}
contract ProtocolVersions_Setters_TestFail is ProtocolVersions_Init {
/// @dev Tests that `setRequired` reverts if the caller is not the owner.
function test_setRequired_notOwner_reverts() external {
vm.expectRevert("Ownable: caller is not the owner");
protocolVersions.setRequired(ProtocolVersion.wrap(0));
}
/// @dev Tests that `setRecommended` reverts if the caller is not the owner.
function test_setRecommended_notOwner_reverts() external {
vm.expectRevert("Ownable: caller is not the owner");
protocolVersions.setRecommended(ProtocolVersion.wrap(0));
}
}
contract ProtocolVersions_Setters_Test is ProtocolVersions_Init {
/// @dev Tests that `setRequired` updates the required protocol version successfully.
function testFuzz_setRequired_succeeds(uint256 _version) external {
vm.expectEmit(true, true, true, true);
emit ConfigUpdate(0, ProtocolVersions.UpdateType.REQUIRED_PROTOCOL_VERSION, abi.encode(_version));
vm.prank(protocolVersions.owner());
protocolVersions.setRequired(ProtocolVersion.wrap(_version));
assertEq(ProtocolVersion.unwrap(protocolVersions.required()), _version);
}
/// @dev Tests that `setRecommended` updates the recommended protocol version successfully.
function testFuzz_setRecommended_succeeds(uint256 _version) external {
vm.expectEmit(true, true, true, true);
emit ConfigUpdate(0, ProtocolVersions.UpdateType.RECOMMENDED_PROTOCOL_VERSION, abi.encode(_version));
vm.prank(protocolVersions.owner());
protocolVersions.setRecommended(ProtocolVersion.wrap(_version));
assertEq(ProtocolVersion.unwrap(protocolVersions.recommended()), _version);
}
}
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