diff --git a/.gitignore b/.gitignore index e92090f4db..a1b1cc1f15 100644 --- a/.gitignore +++ b/.gitignore @@ -13,6 +13,7 @@ yarn-error.log !.yarn/plugins .pnp.* .node-version +.go-version dist artifacts diff --git a/op-bindings/predeploys/addresses.go b/op-bindings/predeploys/addresses.go index 8dee1d6ab2..b337098b72 100644 --- a/op-bindings/predeploys/addresses.go +++ b/op-bindings/predeploys/addresses.go @@ -18,7 +18,7 @@ const ( L1Block = "0x4200000000000000000000000000000000000015" GovernanceToken = "0x4200000000000000000000000000000000000042" LegacyMessagePasser = "0x4200000000000000000000000000000000000000" - L2ERC721Bridge = "0x4200000000000000000000000000000000000014" + OPStackL2ERC721Bridge = "0x4200000000000000000000000000000000000014" // Reserved(but do not use) OptimismMintableERC721Factory = "0x4200000000000000000000000000000000000017" ProxyAdmin = "0x4200000000000000000000000000000000000018" BaseFeeVault = "0x4200000000000000000000000000000000000019" @@ -26,6 +26,9 @@ const ( SchemaRegistry = "0x4200000000000000000000000000000000000020" EAS = "0x4200000000000000000000000000000000000021" Create2Deployer = "0x13b0D85CcB8bf860b6b79AF3029fCA081AE9beF2" + + // Oasys' L2 ERC721 Bridge was released before OPStack and has a different address. + OasysL2ERC721Bridge = "0x6200000000000000000000000000000000000001" ) var ( @@ -41,7 +44,9 @@ var ( L1BlockAddr = common.HexToAddress(L1Block) GovernanceTokenAddr = common.HexToAddress(GovernanceToken) LegacyMessagePasserAddr = common.HexToAddress(LegacyMessagePasser) - L2ERC721BridgeAddr = common.HexToAddress(L2ERC721Bridge) + L2ERC721BridgeAddr = common.HexToAddress(OasysL2ERC721Bridge) + OPStackL2ERC721BridgeAddr = common.HexToAddress(OPStackL2ERC721Bridge) + OasysL2ERC721BridgeAddr = common.HexToAddress(OasysL2ERC721Bridge) OptimismMintableERC721FactoryAddr = common.HexToAddress(OptimismMintableERC721Factory) ProxyAdminAddr = common.HexToAddress(ProxyAdmin) BaseFeeVaultAddr = common.HexToAddress(BaseFeeVault) diff --git a/op-chain-ops/genesis/helpers.go b/op-chain-ops/genesis/helpers.go index 475b597ccc..66b1bfd059 100644 --- a/op-chain-ops/genesis/helpers.go +++ b/op-chain-ops/genesis/helpers.go @@ -6,6 +6,7 @@ import ( "fmt" "math/big" + "github.com/ethereum-optimism/optimism/op-bindings/predeploys" "github.com/ethereum/go-ethereum" "github.com/ethereum/go-ethereum/common" "github.com/ethereum/go-ethereum/common/hexutil" @@ -26,6 +27,12 @@ var ( ImplementationSlot = common.HexToHash("0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc") // AdminSlot represents the EIP 1967 admin storage slot AdminSlot = common.HexToHash("0xb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d6103") + + // Namespace for L2 predeploy contracts made by Oasys. + oasysCodeNamespace = common.HexToAddress("0xC0F6C0f6C0F6C0f6C0f6c0F6C0f6C0F6c0f60000") + bigOasysCodeNamespace = new(big.Int).SetBytes(oasysCodeNamespace.Bytes()) + oasysL2PredeployNamespace = common.HexToAddress("0x6200000000000000000000000000000000000000") + OasysBigL2PredeployNamespace = new(big.Int).SetBytes(oasysL2PredeployNamespace.Bytes()) ) // DevAccounts represent the standard hardhat development accounts. @@ -65,11 +72,15 @@ var devBalance = hexutil.MustDecodeBig("0x20000000000000000000000000000000000000 // AddressToCodeNamespace takes a predeploy address and computes // the implementation address that the implementation should be deployed at func AddressToCodeNamespace(addr common.Address) (common.Address, error) { - if !IsL2DevPredeploy(addr) { + if addr == predeploys.OPStackL2ERC721BridgeAddr { + return common.Address{}, fmt.Errorf("do not use the OPStack's L2ERC721Bridge") + } + namespace := getCodeNamespace(addr) + if namespace == nil { return common.Address{}, fmt.Errorf("cannot handle non predeploy: %s", addr) } bigAddress := new(big.Int).SetBytes(addr[18:]) - num := new(big.Int).Or(bigCodeNamespace, bigAddress) + num := new(big.Int).Or(namespace, bigAddress) return common.BigToAddress(num), nil } @@ -107,3 +118,13 @@ func newHexBig(in uint64) *hexutil.Big { hb := hexutil.Big(*b) return &hb } + +func getCodeNamespace(addr common.Address) *big.Int { + if bytes.Equal(addr[0:2], []byte{0x42, 0x00}) { + return bigCodeNamespace + } + if bytes.Equal(addr[0:2], []byte{0x62, 0x00}) { + return bigOasysCodeNamespace + } + return nil +} diff --git a/op-chain-ops/genesis/layer_two.go b/op-chain-ops/genesis/layer_two.go index 236dc16de8..1ff9330377 100644 --- a/op-chain-ops/genesis/layer_two.go +++ b/op-chain-ops/genesis/layer_two.go @@ -43,6 +43,10 @@ func BuildL2Genesis(config *DeployConfig, l1StartBlock *types.Block) (*core.Gene if err != nil { return nil, err } + err = setProxies(db, predeploys.ProxyAdminAddr, OasysBigL2PredeployNamespace, 256) + if err != nil { + return nil, err + } // Set up the implementations deployResults, err := immutables.BuildOptimism(immutable) diff --git a/op-chain-ops/genesis/layer_two_test.go b/op-chain-ops/genesis/layer_two_test.go index dfa3e3fde4..391ee3fd04 100644 --- a/op-chain-ops/genesis/layer_two_test.go +++ b/op-chain-ops/genesis/layer_two_test.go @@ -91,7 +91,12 @@ func TestBuildL2MainnetGenesis(t *testing.T) { config.EnableGovernance = true config.FundDevAccounts = false gen := testBuildL2Genesis(t, config) - require.Equal(t, 2323, len(gen.Alloc)) + expect := + 256 + // `SetPrecompileBalances()` + 2048 + // `setProxies()` with BigL2PredeployNamespace + 256 + // `setProxies()` with OasysBigL2PredeployNamespace + 20 // Implementations + require.Equal(t, expect, len(gen.Alloc)) } func TestBuildL2MainnetNoGovernanceGenesis(t *testing.T) { @@ -100,5 +105,10 @@ func TestBuildL2MainnetNoGovernanceGenesis(t *testing.T) { config.EnableGovernance = false config.FundDevAccounts = false gen := testBuildL2Genesis(t, config) - require.Equal(t, 2323, len(gen.Alloc)) + expect := + 256 + // `SetPrecompileBalances()` + 2048 + // `setProxies()` with BigL2PredeployNamespace + 256 + // `setProxies()` with OasysBigL2PredeployNamespace + 20 // Implementations + require.Equal(t, expect, len(gen.Alloc)) }