Commit fd1e0622 authored by Maurelian's avatar Maurelian Committed by GitHub

Revert "feat: Isthmus Contracts (#12746)"git (#12870)

* Revert "feat: Isthmus Contracts (#12746)"

This reverts commit dad10877.

* temporarily reduce heavy fuzz runs
parent 0ff55dde
...@@ -131,7 +131,7 @@ rules: ...@@ -131,7 +131,7 @@ rules:
- pattern-not: require($ERR); - pattern-not: require($ERR);
- focus-metavariable: $ERR - focus-metavariable: $ERR
- pattern-not-regex: \"(\w+:\s[^"]+)\" - pattern-not-regex: \"(\w+:\s[^"]+)\"
- pattern-not-regex: string\.concat\(\"(\w+:\s)\"[^)]+\) - pattern-not-regex: string\.concat\(\"(\w+:\s[^"]+)\"\,[^"]+\)
- pattern-not-regex: \"([a-zA-Z0-9\s]+-[a-zA-Z0-9\s]+)\" - pattern-not-regex: \"([a-zA-Z0-9\s]+-[a-zA-Z0-9\s]+)\"
- pattern-not-regex: \"([a-zA-Z0-9\s]+-[a-zA-Z0-9\s]+-[a-zA-Z0-9\s]+)\" - pattern-not-regex: \"([a-zA-Z0-9\s]+-[a-zA-Z0-9\s]+-[a-zA-Z0-9\s]+)\"
paths: paths:
...@@ -152,7 +152,7 @@ rules: ...@@ -152,7 +152,7 @@ rules:
- pattern-not: revert $ERR(...); - pattern-not: revert $ERR(...);
- focus-metavariable: $MSG - focus-metavariable: $MSG
- pattern-not-regex: \"(\w+:\s[^"]+)\" - pattern-not-regex: \"(\w+:\s[^"]+)\"
- pattern-not-regex: string\.concat\(\"(\w+:\s)\"[^)]+\) - pattern-not-regex: string\.concat\(\"(\w+:\s[^"]+)\"\,[^"]+\)
- pattern-not-regex: \"([a-zA-Z0-9\s]+-[a-zA-Z0-9\s]+)\" - pattern-not-regex: \"([a-zA-Z0-9\s]+-[a-zA-Z0-9\s]+)\"
- pattern-not-regex: \"([a-zA-Z0-9\s]+-[a-zA-Z0-9\s]+-[a-zA-Z0-9\s]+)\" - pattern-not-regex: \"([a-zA-Z0-9\s]+-[a-zA-Z0-9\s]+-[a-zA-Z0-9\s]+)\"
paths: paths:
......
...@@ -497,9 +497,6 @@ contract SemgrepTest__sol_style_malformed_require { ...@@ -497,9 +497,6 @@ contract SemgrepTest__sol_style_malformed_require {
) )
); );
// ok: sol-style-malformed-require
require(result.length > 0, string.concat("ForgeArtifacts: ", _contractName, "is not initializable"));
// ruleid: sol-style-malformed-require // ruleid: sol-style-malformed-require
require(cond, "MyContract: "); require(cond, "MyContract: ");
...@@ -544,9 +541,6 @@ contract SemgrepTest__sol_style_malformed_revert { ...@@ -544,9 +541,6 @@ contract SemgrepTest__sol_style_malformed_revert {
) )
); );
// ok: sol-style-malformed-revert
revert(string.concat("ForgeArtifacts: ", _contractName, "is not initializable"));
// ruleid: sol-style-malformed-revert // ruleid: sol-style-malformed-revert
revert("MyContract: "); revert("MyContract: ");
......
...@@ -24,7 +24,7 @@ parser.add_argument('--allocs', help='Only create the allocs and exit', type=boo ...@@ -24,7 +24,7 @@ parser.add_argument('--allocs', help='Only create the allocs and exit', type=boo
log = logging.getLogger() log = logging.getLogger()
# Global constants # Global constants
FORKS = ["delta", "ecotone", "fjord", "granite", "holocene", "isthmus"] FORKS = ["delta", "ecotone", "fjord", "granite", "holocene"]
# Global environment variables # Global environment variables
DEVNET_NO_BUILD = os.getenv('DEVNET_NO_BUILD') == "true" DEVNET_NO_BUILD = os.getenv('DEVNET_NO_BUILD') == "true"
......
...@@ -158,8 +158,6 @@ const ( ...@@ -158,8 +158,6 @@ const (
SequencerFeeVaultRecipientRole ChainOperatorRole = 9 SequencerFeeVaultRecipientRole ChainOperatorRole = 9
// SystemConfigOwner is the key that can make SystemConfig changes. // SystemConfigOwner is the key that can make SystemConfig changes.
SystemConfigOwner ChainOperatorRole = 10 SystemConfigOwner ChainOperatorRole = 10
// SystemConfigFeeAdmin is the key that can make SystemConfigFee changes.
SystemConfigFeeAdmin ChainOperatorRole = 11
) )
func (role ChainOperatorRole) String() string { func (role ChainOperatorRole) String() string {
...@@ -186,8 +184,6 @@ func (role ChainOperatorRole) String() string { ...@@ -186,8 +184,6 @@ func (role ChainOperatorRole) String() string {
return "sequencer-fee-vault-recipient" return "sequencer-fee-vault-recipient"
case SystemConfigOwner: case SystemConfigOwner:
return "system-config-owner" return "system-config-owner"
case SystemConfigFeeAdmin:
return "system-config-fee-admin"
default: default:
return fmt.Sprintf("unknown-operator-%d", uint64(role)) return fmt.Sprintf("unknown-operator-%d", uint64(role))
} }
......
...@@ -286,9 +286,6 @@ type OperatorDeployConfig struct { ...@@ -286,9 +286,6 @@ type OperatorDeployConfig struct {
// BatchSenderAddress represents the initial sequencer account that authorizes batches. // BatchSenderAddress represents the initial sequencer account that authorizes batches.
// Transactions sent from this account to the batch inbox address are considered valid. // Transactions sent from this account to the batch inbox address are considered valid.
BatchSenderAddress common.Address `json:"batchSenderAddress"` BatchSenderAddress common.Address `json:"batchSenderAddress"`
// SystemConfigfeeAdmin is the address of the account that has the ability to set the fee parameters.
SystemConfigfeeAdmin common.Address `json:"systemConfigFeeAdmin"`
} }
var _ ConfigChecker = (*OperatorDeployConfig)(nil) var _ ConfigChecker = (*OperatorDeployConfig)(nil)
......
...@@ -22,7 +22,6 @@ ...@@ -22,7 +22,6 @@
"l1GenesisBlockGasLimit": "0x1c9c380", "l1GenesisBlockGasLimit": "0x1c9c380",
"l1GenesisBlockDifficulty": "0x1", "l1GenesisBlockDifficulty": "0x1",
"finalSystemOwner": "0xbcd4042de499d14e55001ccbb24a551f3b954096", "finalSystemOwner": "0xbcd4042de499d14e55001ccbb24a551f3b954096",
"systemConfigFeeAdmin": "0xbcd4042de499d14e55001ccbb24a551f3b954096",
"superchainConfigGuardian": "0x0000000000000000000000000000000000000112", "superchainConfigGuardian": "0x0000000000000000000000000000000000000112",
"finalizationPeriodSeconds": 2, "finalizationPeriodSeconds": 2,
"l1GenesisBlockMixHash": "0x0000000000000000000000000000000000000000000000000000000000000000", "l1GenesisBlockMixHash": "0x0000000000000000000000000000000000000000000000000000000000000000",
......
...@@ -75,7 +75,6 @@ type L2Config struct { ...@@ -75,7 +75,6 @@ type L2Config struct {
Proposer common.Address Proposer common.Address
Challenger common.Address Challenger common.Address
SystemConfigOwner common.Address SystemConfigOwner common.Address
SystemConfigFeeAdmin common.Address
genesis.L2InitializationConfig genesis.L2InitializationConfig
Prefund map[common.Address]*big.Int Prefund map[common.Address]*big.Int
SaltMixer string SaltMixer string
......
...@@ -200,8 +200,7 @@ func DeployL2ToL1(l1Host *script.Host, superCfg *SuperchainConfig, superDeployme ...@@ -200,8 +200,7 @@ func DeployL2ToL1(l1Host *script.Host, superCfg *SuperchainConfig, superDeployme
l1Host.SetTxOrigin(cfg.Deployer) l1Host.SetTxOrigin(cfg.Deployer)
output, err := opcm.DeployOPChainIsthmus(l1Host, opcm.DeployOPChainInputIsthmus{ output, err := opcm.DeployOPChainV160(l1Host, opcm.DeployOPChainInputV160{
DeployOPChainInputV160: opcm.DeployOPChainInputV160{
OpChainProxyAdminOwner: cfg.ProxyAdminOwner, OpChainProxyAdminOwner: cfg.ProxyAdminOwner,
SystemConfigOwner: cfg.SystemConfigOwner, SystemConfigOwner: cfg.SystemConfigOwner,
Batcher: cfg.BatchSenderAddress, Batcher: cfg.BatchSenderAddress,
...@@ -219,8 +218,7 @@ func DeployL2ToL1(l1Host *script.Host, superCfg *SuperchainConfig, superDeployme ...@@ -219,8 +218,7 @@ func DeployL2ToL1(l1Host *script.Host, superCfg *SuperchainConfig, superDeployme
DisputeMaxGameDepth: cfg.DisputeMaxGameDepth, DisputeMaxGameDepth: cfg.DisputeMaxGameDepth,
DisputeSplitDepth: cfg.DisputeSplitDepth, DisputeSplitDepth: cfg.DisputeSplitDepth,
DisputeClockExtension: cfg.DisputeClockExtension, DisputeClockExtension: cfg.DisputeClockExtension,
DisputeMaxClockDuration: cfg.DisputeMaxClockDuration}, DisputeMaxClockDuration: cfg.DisputeMaxClockDuration,
SystemConfigFeeAdmin: cfg.SystemConfigFeeAdmin,
}) })
if err != nil { if err != nil {
return nil, fmt.Errorf("failed to deploy L2 OP chain: %w", err) return nil, fmt.Errorf("failed to deploy L2 OP chain: %w", err)
......
...@@ -178,17 +178,12 @@ func InteropL2DevConfig(l1ChainID, l2ChainID uint64, addrs devkeys.Addresses) (* ...@@ -178,17 +178,12 @@ func InteropL2DevConfig(l1ChainID, l2ChainID uint64, addrs devkeys.Addresses) (*
if err != nil { if err != nil {
return nil, err return nil, err
} }
systemConfigFeeAdmin, err := addrs.Address(chainOps(devkeys.SystemConfigFeeAdmin))
if err != nil {
return nil, err
}
l2Cfg := &L2Config{ l2Cfg := &L2Config{
Deployer: deployer, Deployer: deployer,
Proposer: proposer, Proposer: proposer,
Challenger: challenger, Challenger: challenger,
SystemConfigOwner: systemConfigOwner, SystemConfigOwner: systemConfigOwner,
SystemConfigFeeAdmin: systemConfigFeeAdmin,
L2InitializationConfig: genesis.L2InitializationConfig{ L2InitializationConfig: genesis.L2InitializationConfig{
DevDeployConfig: genesis.DevDeployConfig{ DevDeployConfig: genesis.DevDeployConfig{
FundDevAccounts: true, FundDevAccounts: true,
......
...@@ -12,7 +12,6 @@ import ( ...@@ -12,7 +12,6 @@ import (
"time" "time"
altda "github.com/ethereum-optimism/optimism/op-alt-da" altda "github.com/ethereum-optimism/optimism/op-alt-da"
"github.com/ethereum-optimism/optimism/op-chain-ops/foundry"
"github.com/ethereum-optimism/optimism/op-deployer/pkg/deployer/inspect" "github.com/ethereum-optimism/optimism/op-deployer/pkg/deployer/inspect"
"github.com/ethereum-optimism/optimism/op-node/rollup" "github.com/ethereum-optimism/optimism/op-node/rollup"
...@@ -126,7 +125,7 @@ func TestEndToEndApply(t *testing.T) { ...@@ -126,7 +125,7 @@ func TestEndToEndApply(t *testing.T) {
}) })
require.NoError(t, err) require.NoError(t, err)
env, bundle, _ := createEnv(t, lgr, l1Client, bcaster, deployerAddr, localArtifactsFactory, localArtifactsFactory) env, bundle, _ := createEnv(t, lgr, l1Client, bcaster, deployerAddr)
intent, st := newIntent(t, l1ChainID, dk, l2ChainID1, loc, loc) intent, st := newIntent(t, l1ChainID, dk, l2ChainID1, loc, loc)
cg := ethClientCodeGetter(ctx, l1Client) cg := ethClientCodeGetter(ctx, l1Client)
...@@ -146,7 +145,7 @@ func TestEndToEndApply(t *testing.T) { ...@@ -146,7 +145,7 @@ func TestEndToEndApply(t *testing.T) {
t.Run("subsequent chain", func(t *testing.T) { t.Run("subsequent chain", func(t *testing.T) {
// create a new environment with wiped state to ensure we can continue using the // create a new environment with wiped state to ensure we can continue using the
// state from the previous deployment // state from the previous deployment
env, bundle, _ = createEnv(t, lgr, l1Client, bcaster, deployerAddr, localArtifactsFactory, localArtifactsFactory) env, bundle, _ = createEnv(t, lgr, l1Client, bcaster, deployerAddr)
intent.Chains = append(intent.Chains, newChainIntent(t, dk, l1ChainID, l2ChainID2)) intent.Chains = append(intent.Chains, newChainIntent(t, dk, l1ChainID, l2ChainID2))
require.NoError(t, deployer.ApplyPipeline( require.NoError(t, deployer.ApplyPipeline(
...@@ -208,17 +207,7 @@ func TestApplyExistingOPCM(t *testing.T) { ...@@ -208,17 +207,7 @@ func TestApplyExistingOPCM(t *testing.T) {
}) })
require.NoError(t, err) require.NoError(t, err)
// use the l2 contracts here because the v1.7.0 contracts are compatible with the v1.6.0 env, bundle, _ := createEnv(t, lgr, l1Client, bcaster, deployerAddr)
// contracts and createEnv uses the same artifacts for both L1/L2 in the bundle.
env, bundle, _ := createEnv(
t,
lgr,
l1Client,
bcaster,
deployerAddr,
taggedArtifactsFactory(standard.DefaultL1ContractsTag),
taggedArtifactsFactory(standard.DefaultL2ContractsTag),
)
intent, st := newIntent( intent, st := newIntent(
t, t,
...@@ -390,8 +379,7 @@ func TestProofParamOverrides(t *testing.T) { ...@@ -390,8 +379,7 @@ func TestProofParamOverrides(t *testing.T) {
} }
for _, tt := range tests { for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) { t.Run(tt.name, func(t *testing.T) {
err := checkImmutable(t, allocs, tt.address, tt.caster(t, intent.GlobalDeployOverrides[tt.name])) checkImmutable(t, allocs, tt.address, tt.caster(t, intent.GlobalDeployOverrides[tt.name]))
require.NoError(t, err)
}) })
} }
} }
...@@ -415,9 +403,9 @@ func TestInteropDeployment(t *testing.T) { ...@@ -415,9 +403,9 @@ func TestInteropDeployment(t *testing.T) {
chainState := st.Chains[0] chainState := st.Chains[0]
depManagerSlot := common.HexToHash("0x1708e077affb93e89be2665fb0fb72581be66f84dc00d25fed755ae911905b1c") depManagerSlot := common.HexToHash("0x1708e077affb93e89be2665fb0fb72581be66f84dc00d25fed755ae911905b1c")
require.NoError(t, checkImmutable(t, st.L1StateDump.Data.Accounts, st.ImplementationsDeployment.SystemConfigImplAddress, depManagerSlot)) checkImmutable(t, st.L1StateDump.Data.Accounts, st.ImplementationsDeployment.SystemConfigImplAddress, depManagerSlot)
systemConfigOwnerHash := common.BytesToHash(intent.Chains[0].Roles.SystemConfigOwner.Bytes()) proxyAdminOwnerHash := common.BytesToHash(intent.Chains[0].Roles.SystemConfigOwner.Bytes())
checkStorageSlot(t, st.L1StateDump.Data.Accounts, chainState.SystemConfigProxyAddress, depManagerSlot, systemConfigOwnerHash) checkStorageSlot(t, st.L1StateDump.Data.Accounts, chainState.SystemConfigProxyAddress, depManagerSlot, proxyAdminOwnerHash)
} }
func TestAltDADeployment(t *testing.T) { func TestAltDADeployment(t *testing.T) {
...@@ -524,7 +512,7 @@ func TestInvalidL2Genesis(t *testing.T) { ...@@ -524,7 +512,7 @@ func TestInvalidL2Genesis(t *testing.T) {
} }
for _, tt := range tests { for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) { t.Run(tt.name, func(t *testing.T) {
env, bundle, _ := createEnv(t, lgr, nil, broadcaster.NoopBroadcaster(), deployerAddr, localArtifactsFactory, localArtifactsFactory) env, bundle, _ := createEnv(t, lgr, nil, broadcaster.NoopBroadcaster(), deployerAddr)
intent, st := newIntent(t, l1ChainID, dk, l2ChainID1, loc, loc) intent, st := newIntent(t, l1ChainID, dk, l2ChainID1, loc, loc)
intent.Chains = append(intent.Chains, newChainIntent(t, dk, l1ChainID, l2ChainID1)) intent.Chains = append(intent.Chains, newChainIntent(t, dk, l1ChainID, l2ChainID1))
intent.DeploymentStrategy = state.DeploymentStrategyGenesis intent.DeploymentStrategy = state.DeploymentStrategyGenesis
...@@ -558,42 +546,27 @@ func setupGenesisChain(t *testing.T) (*pipeline.Env, pipeline.ArtifactsBundle, * ...@@ -558,42 +546,27 @@ func setupGenesisChain(t *testing.T) (*pipeline.Env, pipeline.ArtifactsBundle, *
loc, _ := testutil.LocalArtifacts(t) loc, _ := testutil.LocalArtifacts(t)
env, bundle, _ := createEnv(t, lgr, nil, broadcaster.NoopBroadcaster(), deployerAddr, localArtifactsFactory, localArtifactsFactory) env, bundle, _ := createEnv(t, lgr, nil, broadcaster.NoopBroadcaster(), deployerAddr)
intent, st := newIntent(t, l1ChainID, dk, l2ChainID1, loc, loc) intent, st := newIntent(t, l1ChainID, dk, l2ChainID1, loc, loc)
intent.Chains = append(intent.Chains, newChainIntent(t, dk, l1ChainID, l2ChainID1)) intent.Chains = append(intent.Chains, newChainIntent(t, dk, l1ChainID, l2ChainID1))
intent.DeploymentStrategy = state.DeploymentStrategyGenesis intent.DeploymentStrategy = state.DeploymentStrategyGenesis
return env, bundle, intent, st return env, bundle, intent, st
} }
type artifactsFactory func(t *testing.T) (*artifacts.Locator, foundry.StatDirFs)
func localArtifactsFactory(t *testing.T) (*artifacts.Locator, foundry.StatDirFs) {
return testutil.LocalArtifacts(t)
}
func taggedArtifactsFactory(tag string) artifactsFactory {
return func(t *testing.T) (*artifacts.Locator, foundry.StatDirFs) {
return testutil.ArtifactsFromURL(t, fmt.Sprintf("tag://%s", tag))
}
}
func createEnv( func createEnv(
t *testing.T, t *testing.T,
lgr log.Logger, lgr log.Logger,
l1Client *ethclient.Client, l1Client *ethclient.Client,
bcaster broadcaster.Broadcaster, bcaster broadcaster.Broadcaster,
deployerAddr common.Address, deployerAddr common.Address,
l1Factory artifactsFactory,
l2Factory artifactsFactory,
) (*pipeline.Env, pipeline.ArtifactsBundle, *script.Host) { ) (*pipeline.Env, pipeline.ArtifactsBundle, *script.Host) {
_, l1AFS := l1Factory(t) _, artifactsFS := testutil.LocalArtifacts(t)
_, l2AFS := l2Factory(t)
host, err := env.DefaultScriptHost( host, err := env.DefaultScriptHost(
bcaster, bcaster,
lgr, lgr,
deployerAddr, deployerAddr,
l1AFS, artifactsFS,
0, 0,
) )
require.NoError(t, err) require.NoError(t, err)
...@@ -608,8 +581,8 @@ func createEnv( ...@@ -608,8 +581,8 @@ func createEnv(
} }
bundle := pipeline.ArtifactsBundle{ bundle := pipeline.ArtifactsBundle{
L1: l1AFS, L1: artifactsFS,
L2: l2AFS, L2: artifactsFS,
} }
return env, bundle, host return env, bundle, host
...@@ -662,7 +635,6 @@ func newChainIntent(t *testing.T, dk *devkeys.MnemonicDevKeys, l1ChainID *big.In ...@@ -662,7 +635,6 @@ func newChainIntent(t *testing.T, dk *devkeys.MnemonicDevKeys, l1ChainID *big.In
L1ProxyAdminOwner: addrFor(t, dk, devkeys.L2ProxyAdminOwnerRole.Key(l1ChainID)), L1ProxyAdminOwner: addrFor(t, dk, devkeys.L2ProxyAdminOwnerRole.Key(l1ChainID)),
L2ProxyAdminOwner: addrFor(t, dk, devkeys.L2ProxyAdminOwnerRole.Key(l1ChainID)), L2ProxyAdminOwner: addrFor(t, dk, devkeys.L2ProxyAdminOwnerRole.Key(l1ChainID)),
SystemConfigOwner: addrFor(t, dk, devkeys.SystemConfigOwner.Key(l1ChainID)), SystemConfigOwner: addrFor(t, dk, devkeys.SystemConfigOwner.Key(l1ChainID)),
SystemConfigFeeAdmin: addrFor(t, dk, devkeys.SystemConfigFeeAdmin.Key(l1ChainID)),
UnsafeBlockSigner: addrFor(t, dk, devkeys.SequencerP2PRole.Key(l1ChainID)), UnsafeBlockSigner: addrFor(t, dk, devkeys.SequencerP2PRole.Key(l1ChainID)),
Batcher: addrFor(t, dk, devkeys.BatcherRole.Key(l1ChainID)), Batcher: addrFor(t, dk, devkeys.BatcherRole.Key(l1ChainID)),
Proposer: addrFor(t, dk, devkeys.ProposerRole.Key(l1ChainID)), Proposer: addrFor(t, dk, devkeys.ProposerRole.Key(l1ChainID)),
...@@ -767,20 +739,17 @@ func validateOPChainDeployment(t *testing.T, cg codeGetter, st *state.State, int ...@@ -767,20 +739,17 @@ func validateOPChainDeployment(t *testing.T, cg codeGetter, st *state.State, int
alloc := chainState.Allocs.Data.Accounts alloc := chainState.Allocs.Data.Accounts
chainIntent := intent.Chains[i] chainIntent := intent.Chains[i]
checkImmutableBehindProxy(t, alloc, predeploys.BaseFeeVaultAddr, chainIntent.BaseFeeVaultRecipient)
// First try to read the owner from the bytecode, which is the situation with the checkImmutableBehindProxy(t, alloc, predeploys.L1FeeVaultAddr, chainIntent.L1FeeVaultRecipient)
// Isthmus L2ProxyAdmin (on this commit). checkImmutableBehindProxy(t, alloc, predeploys.SequencerFeeVaultAddr, chainIntent.SequencerFeeVaultRecipient)
if err := checkImmutableBehindProxy(t, alloc, predeploys.ProxyAdminAddr, common.HexToAddress("0xDeaDDEaDDeAdDeAdDEAdDEaddeAddEAdDEAd0001")); err != nil { checkImmutableBehindProxy(t, alloc, predeploys.OptimismMintableERC721FactoryAddr, common.BigToHash(new(big.Int).SetUint64(intent.L1ChainID)))
t.Logf("Warning: Failed to check immutable behind proxy for L2ProxyAdmin, falling back to <=v1.6.0 storage check")
// If the bytecode check fails, fall back to reading the owner from storage. // ownership slots
// Note however that the L2ProxyAdmin owner address here (0xe59a881b2626f948f56f509f180c32428585629a) comes from the chainIntent, var addrAsSlot common.Hash
// and does not actually match the `owner()` of the L2ProxyAdmin contract deployed on Sepolia (0x2FC3ffc903729a0f03966b917003800B145F67F3). addrAsSlot.SetBytes(chainIntent.Roles.L1ProxyAdminOwner.Bytes())
// It seems the L2 state is locally constructed rather than pulled from an L2 RPC. // slot 0
var L2ProxyAdminOwner common.Hash ownerSlot := common.Hash{}
L2ProxyAdminOwner.SetBytes(chainIntent.Roles.L2ProxyAdminOwner.Bytes()) checkStorageSlot(t, alloc, predeploys.ProxyAdminAddr, ownerSlot, addrAsSlot)
checkStorageSlot(t, alloc, predeploys.ProxyAdminAddr, common.Hash{}, L2ProxyAdminOwner)
}
var defaultGovOwner common.Hash var defaultGovOwner common.Hash
defaultGovOwner.SetBytes(common.HexToAddress("0xDeaDDEaDDeAdDeAdDEAdDEaddeAddEAdDEAdDEad").Bytes()) defaultGovOwner.SetBytes(common.HexToAddress("0xDeaDDEaDDeAdDeAdDEAdDEaddeAddEAdDEAdDEad").Bytes())
checkStorageSlot(t, alloc, predeploys.GovernanceTokenAddr, common.Hash{31: 0x0a}, defaultGovOwner) checkStorageSlot(t, alloc, predeploys.GovernanceTokenAddr, common.Hash{31: 0x0a}, defaultGovOwner)
...@@ -801,23 +770,20 @@ type bytesMarshaler interface { ...@@ -801,23 +770,20 @@ type bytesMarshaler interface {
Bytes() []byte Bytes() []byte
} }
func checkImmutableBehindProxy(t *testing.T, allocations types.GenesisAlloc, proxyContract common.Address, thing bytesMarshaler) error { func checkImmutableBehindProxy(t *testing.T, allocations types.GenesisAlloc, proxyContract common.Address, thing bytesMarshaler) {
implementationAddress := getEIP1967ImplementationAddress(t, allocations, proxyContract) implementationAddress := getEIP1967ImplementationAddress(t, allocations, proxyContract)
return checkImmutable(t, allocations, implementationAddress, thing) checkImmutable(t, allocations, implementationAddress, thing)
} }
func checkImmutable(t *testing.T, allocations types.GenesisAlloc, implementationAddress common.Address, thing bytesMarshaler) error { func checkImmutable(t *testing.T, allocations types.GenesisAlloc, implementationAddress common.Address, thing bytesMarshaler) {
account, ok := allocations[implementationAddress] account, ok := allocations[implementationAddress]
if !ok { require.True(t, ok, "%s not found in allocations", implementationAddress)
return fmt.Errorf("%s not found in allocations", implementationAddress) require.NotEmpty(t, account.Code, "%s should have code", implementationAddress)
} require.True(
if len(account.Code) == 0 { t,
return fmt.Errorf("%s should have code", implementationAddress) bytes.Contains(account.Code, thing.Bytes()),
} "%s code should contain %s immutable", implementationAddress, hex.EncodeToString(thing.Bytes()),
if !bytes.Contains(account.Code, thing.Bytes()) { )
return fmt.Errorf("%s code should contain %s immutable", implementationAddress, hex.EncodeToString(thing.Bytes()))
}
return nil
} }
func checkStorageSlot(t *testing.T, allocs types.GenesisAlloc, address common.Address, slot common.Hash, expected common.Hash) { func checkStorageSlot(t *testing.T, allocs types.GenesisAlloc, address common.Address, slot common.Hash, expected common.Hash) {
......
...@@ -59,7 +59,7 @@ type opcmDeployInputV160 struct { ...@@ -59,7 +59,7 @@ type opcmDeployInputV160 struct {
type opcmRolesIsthmus struct { type opcmRolesIsthmus struct {
opcmRolesBase opcmRolesBase
SystemConfigFeeAdmin common.Address FeeAdmin common.Address
} }
type opcmDeployInputIsthmus struct { type opcmDeployInputIsthmus struct {
...@@ -136,7 +136,7 @@ func DeployOPChainInputIsthmusDeployCalldata(input DeployOPChainInputIsthmus) an ...@@ -136,7 +136,7 @@ func DeployOPChainInputIsthmusDeployCalldata(input DeployOPChainInputIsthmus) an
return opcmDeployInputIsthmus{ return opcmDeployInputIsthmus{
Roles: opcmRolesIsthmus{ Roles: opcmRolesIsthmus{
opcmRolesBase: v160Data.Roles, opcmRolesBase: v160Data.Roles,
SystemConfigFeeAdmin: input.SystemConfigFeeAdmin, FeeAdmin: input.SystemConfigFeeAdmin,
}, },
opcmDeployInputBase: v160Data.opcmDeployInputBase, opcmDeployInputBase: v160Data.opcmDeployInputBase,
} }
......
...@@ -276,7 +276,7 @@ func makeDCIIsthmus(intent *state.Intent, thisIntent *state.ChainIntent, chainID ...@@ -276,7 +276,7 @@ func makeDCIIsthmus(intent *state.Intent, thisIntent *state.ChainIntent, chainID
return opcm.DeployOPChainInputIsthmus{ return opcm.DeployOPChainInputIsthmus{
DeployOPChainInputV160: dci, DeployOPChainInputV160: dci,
SystemConfigFeeAdmin: thisIntent.Roles.SystemConfigFeeAdmin, SystemConfigFeeAdmin: common.Address{'D', 'E', 'A', 'D'},
}, nil }, nil
} }
......
...@@ -176,8 +176,6 @@ type ChainRoles struct { ...@@ -176,8 +176,6 @@ type ChainRoles struct {
SystemConfigOwner common.Address `json:"systemConfigOwner" toml:"systemConfigOwner"` SystemConfigOwner common.Address `json:"systemConfigOwner" toml:"systemConfigOwner"`
SystemConfigFeeAdmin common.Address `json:"systemConfigFeeAdmin" toml:"systemConfigFeeAdmin"`
UnsafeBlockSigner common.Address `json:"unsafeBlockSigner" toml:"unsafeBlockSigner"` UnsafeBlockSigner common.Address `json:"unsafeBlockSigner" toml:"unsafeBlockSigner"`
Batcher common.Address `json:"batcher" toml:"batcher"` Batcher common.Address `json:"batcher" toml:"batcher"`
...@@ -201,10 +199,6 @@ func (c *ChainIntent) Check() error { ...@@ -201,10 +199,6 @@ func (c *ChainIntent) Check() error {
c.Roles.SystemConfigOwner = c.Roles.L1ProxyAdminOwner c.Roles.SystemConfigOwner = c.Roles.L1ProxyAdminOwner
} }
if c.Roles.SystemConfigFeeAdmin == emptyAddress {
return fmt.Errorf("systemConfigFeeAdmin must be set")
}
if c.Roles.L2ProxyAdminOwner == emptyAddress { if c.Roles.L2ProxyAdminOwner == emptyAddress {
return fmt.Errorf("l2ProxyAdminOwner must be set") return fmt.Errorf("l2ProxyAdminOwner must be set")
} }
......
...@@ -3,35 +3,31 @@ package testutil ...@@ -3,35 +3,31 @@ package testutil
import ( import (
"context" "context"
"fmt" "fmt"
"net/url"
"path" "path"
"runtime" "runtime"
"testing" "testing"
"github.com/ethereum-optimism/optimism/op-service/testlog" artifacts2 "github.com/ethereum-optimism/optimism/op-deployer/pkg/deployer/artifacts"
"github.com/ethereum/go-ethereum/log"
"github.com/ethereum-optimism/optimism/op-deployer/pkg/deployer/artifacts"
"github.com/ethereum-optimism/optimism/op-chain-ops/foundry" "github.com/ethereum-optimism/optimism/op-chain-ops/foundry"
op_service "github.com/ethereum-optimism/optimism/op-service" op_service "github.com/ethereum-optimism/optimism/op-service"
"github.com/stretchr/testify/require" "github.com/stretchr/testify/require"
) )
func LocalArtifacts(t *testing.T) (*artifacts.Locator, foundry.StatDirFs) { func LocalArtifacts(t *testing.T) (*artifacts2.Locator, foundry.StatDirFs) {
_, testFilename, _, ok := runtime.Caller(0) _, testFilename, _, ok := runtime.Caller(0)
require.Truef(t, ok, "failed to get test filename") require.Truef(t, ok, "failed to get test filename")
monorepoDir, err := op_service.FindMonorepoRoot(testFilename) monorepoDir, err := op_service.FindMonorepoRoot(testFilename)
require.NoError(t, err) require.NoError(t, err)
artifactsDir := path.Join(monorepoDir, "packages", "contracts-bedrock", "forge-artifacts") artifactsDir := path.Join(monorepoDir, "packages", "contracts-bedrock", "forge-artifacts")
return ArtifactsFromURL(t, fmt.Sprintf("file://%s", artifactsDir)) artifactsURL, err := url.Parse(fmt.Sprintf("file://%s", artifactsDir))
} require.NoError(t, err)
loc := &artifacts2.Locator{
func ArtifactsFromURL(t *testing.T, artifactsURLStr string) (*artifacts.Locator, foundry.StatDirFs) { URL: artifactsURL,
loc := new(artifacts.Locator) }
require.NoError(t, loc.UnmarshalText([]byte(artifactsURLStr)))
progressor := artifacts.LogProgressor(testlog.Logger(t, log.LevelInfo)) artifactsFS, cleanupArtifacts, err := artifacts2.Download(context.Background(), loc, artifacts2.NoopDownloadProgressor)
artifactsFS, cleanupArtifacts, err := artifacts.Download(context.Background(), loc, progressor)
require.NoError(t, err) require.NoError(t, err)
t.Cleanup(func() { t.Cleanup(func() {
_ = cleanupArtifacts() _ = cleanupArtifacts()
......
...@@ -49,45 +49,15 @@ type SystemConfigAddresses struct { ...@@ -49,45 +49,15 @@ type SystemConfigAddresses struct {
GasPayingToken common.Address GasPayingToken common.Address
} }
// SystemConfigRoles is an auto generated low-level Go binding around an user-defined struct.
type SystemConfigRoles struct {
Owner common.Address
FeeAdmin common.Address
UnsafeBlockSigner common.Address
BatcherHash [32]byte
}
// SystemConfigMetaData contains all meta data concerning the SystemConfig contract. // SystemConfigMetaData contains all meta data concerning the SystemConfig contract.
var SystemConfigMetaData = &bind.MetaData{ var SystemConfigMetaData = &bind.MetaData{
ABI: "[{\"type\":\"constructor\",\"inputs\":[],\"stateMutability\":\"nonpayable\"},{\"type\":\"function\",\"name\":\"BATCH_INBOX_SLOT\",\"inputs\":[],\"outputs\":[{\"name\":\"\",\"type\":\"bytes32\",\"internalType\":\"bytes32\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"DISPUTE_GAME_FACTORY_SLOT\",\"inputs\":[],\"outputs\":[{\"name\":\"\",\"type\":\"bytes32\",\"internalType\":\"bytes32\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"L1_CROSS_DOMAIN_MESSENGER_SLOT\",\"inputs\":[],\"outputs\":[{\"name\":\"\",\"type\":\"bytes32\",\"internalType\":\"bytes32\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"L1_ERC_721_BRIDGE_SLOT\",\"inputs\":[],\"outputs\":[{\"name\":\"\",\"type\":\"bytes32\",\"internalType\":\"bytes32\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"L1_STANDARD_BRIDGE_SLOT\",\"inputs\":[],\"outputs\":[{\"name\":\"\",\"type\":\"bytes32\",\"internalType\":\"bytes32\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"OPTIMISM_MINTABLE_ERC20_FACTORY_SLOT\",\"inputs\":[],\"outputs\":[{\"name\":\"\",\"type\":\"bytes32\",\"internalType\":\"bytes32\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"OPTIMISM_PORTAL_SLOT\",\"inputs\":[],\"outputs\":[{\"name\":\"\",\"type\":\"bytes32\",\"internalType\":\"bytes32\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"START_BLOCK_SLOT\",\"inputs\":[],\"outputs\":[{\"name\":\"\",\"type\":\"bytes32\",\"internalType\":\"bytes32\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"UNSAFE_BLOCK_SIGNER_SLOT\",\"inputs\":[],\"outputs\":[{\"name\":\"\",\"type\":\"bytes32\",\"internalType\":\"bytes32\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"VERSION\",\"inputs\":[],\"outputs\":[{\"name\":\"\",\"type\":\"uint256\",\"internalType\":\"uint256\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"basefeeScalar\",\"inputs\":[],\"outputs\":[{\"name\":\"\",\"type\":\"uint32\",\"internalType\":\"uint32\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"batchInbox\",\"inputs\":[],\"outputs\":[{\"name\":\"addr_\",\"type\":\"address\",\"internalType\":\"address\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"batcherHash\",\"inputs\":[],\"outputs\":[{\"name\":\"\",\"type\":\"bytes32\",\"internalType\":\"bytes32\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"blobbasefeeScalar\",\"inputs\":[],\"outputs\":[{\"name\":\"\",\"type\":\"uint32\",\"internalType\":\"uint32\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"disputeGameFactory\",\"inputs\":[],\"outputs\":[{\"name\":\"addr_\",\"type\":\"address\",\"internalType\":\"address\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"eip1559Denominator\",\"inputs\":[],\"outputs\":[{\"name\":\"\",\"type\":\"uint32\",\"internalType\":\"uint32\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"eip1559Elasticity\",\"inputs\":[],\"outputs\":[{\"name\":\"\",\"type\":\"uint32\",\"internalType\":\"uint32\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"feeAdmin\",\"inputs\":[],\"outputs\":[{\"name\":\"addr_\",\"type\":\"address\",\"internalType\":\"address\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"gasLimit\",\"inputs\":[],\"outputs\":[{\"name\":\"\",\"type\":\"uint64\",\"internalType\":\"uint64\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"gasPayingToken\",\"inputs\":[],\"outputs\":[{\"name\":\"addr_\",\"type\":\"address\",\"internalType\":\"address\"},{\"name\":\"decimals_\",\"type\":\"uint8\",\"internalType\":\"uint8\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"gasPayingTokenName\",\"inputs\":[],\"outputs\":[{\"name\":\"name_\",\"type\":\"string\",\"internalType\":\"string\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"gasPayingTokenSymbol\",\"inputs\":[],\"outputs\":[{\"name\":\"symbol_\",\"type\":\"string\",\"internalType\":\"string\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"initialize\",\"inputs\":[{\"name\":\"_roles\",\"type\":\"tuple\",\"internalType\":\"structSystemConfig.Roles\",\"components\":[{\"name\":\"owner\",\"type\":\"address\",\"internalType\":\"address\"},{\"name\":\"feeAdmin\",\"type\":\"address\",\"internalType\":\"address\"},{\"name\":\"unsafeBlockSigner\",\"type\":\"address\",\"internalType\":\"address\"},{\"name\":\"batcherHash\",\"type\":\"bytes32\",\"internalType\":\"bytes32\"}]},{\"name\":\"_basefeeScalar\",\"type\":\"uint32\",\"internalType\":\"uint32\"},{\"name\":\"_blobbasefeeScalar\",\"type\":\"uint32\",\"internalType\":\"uint32\"},{\"name\":\"_gasLimit\",\"type\":\"uint64\",\"internalType\":\"uint64\"},{\"name\":\"_config\",\"type\":\"tuple\",\"internalType\":\"structIResourceMetering.ResourceConfig\",\"components\":[{\"name\":\"maxResourceLimit\",\"type\":\"uint32\",\"internalType\":\"uint32\"},{\"name\":\"elasticityMultiplier\",\"type\":\"uint8\",\"internalType\":\"uint8\"},{\"name\":\"baseFeeMaxChangeDenominator\",\"type\":\"uint8\",\"internalType\":\"uint8\"},{\"name\":\"minimumBaseFee\",\"type\":\"uint32\",\"internalType\":\"uint32\"},{\"name\":\"systemTxMaxGas\",\"type\":\"uint32\",\"internalType\":\"uint32\"},{\"name\":\"maximumBaseFee\",\"type\":\"uint128\",\"internalType\":\"uint128\"}]},{\"name\":\"_batchInbox\",\"type\":\"address\",\"internalType\":\"address\"},{\"name\":\"_addresses\",\"type\":\"tuple\",\"internalType\":\"structSystemConfig.Addresses\",\"components\":[{\"name\":\"l1CrossDomainMessenger\",\"type\":\"address\",\"internalType\":\"address\"},{\"name\":\"l1ERC721Bridge\",\"type\":\"address\",\"internalType\":\"address\"},{\"name\":\"l1StandardBridge\",\"type\":\"address\",\"internalType\":\"address\"},{\"name\":\"disputeGameFactory\",\"type\":\"address\",\"internalType\":\"address\"},{\"name\":\"optimismPortal\",\"type\":\"address\",\"internalType\":\"address\"},{\"name\":\"optimismMintableERC20Factory\",\"type\":\"address\",\"internalType\":\"address\"},{\"name\":\"gasPayingToken\",\"type\":\"address\",\"internalType\":\"address\"}]}],\"outputs\":[],\"stateMutability\":\"nonpayable\"},{\"type\":\"function\",\"name\":\"isCustomGasToken\",\"inputs\":[],\"outputs\":[{\"name\":\"\",\"type\":\"bool\",\"internalType\":\"bool\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"l1CrossDomainMessenger\",\"inputs\":[],\"outputs\":[{\"name\":\"addr_\",\"type\":\"address\",\"internalType\":\"address\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"l1ERC721Bridge\",\"inputs\":[],\"outputs\":[{\"name\":\"addr_\",\"type\":\"address\",\"internalType\":\"address\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"l1StandardBridge\",\"inputs\":[],\"outputs\":[{\"name\":\"addr_\",\"type\":\"address\",\"internalType\":\"address\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"maximumGasLimit\",\"inputs\":[],\"outputs\":[{\"name\":\"\",\"type\":\"uint64\",\"internalType\":\"uint64\"}],\"stateMutability\":\"pure\"},{\"type\":\"function\",\"name\":\"minimumGasLimit\",\"inputs\":[],\"outputs\":[{\"name\":\"\",\"type\":\"uint64\",\"internalType\":\"uint64\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"optimismMintableERC20Factory\",\"inputs\":[],\"outputs\":[{\"name\":\"addr_\",\"type\":\"address\",\"internalType\":\"address\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"optimismPortal\",\"inputs\":[],\"outputs\":[{\"name\":\"addr_\",\"type\":\"address\",\"internalType\":\"address\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"overhead\",\"inputs\":[],\"outputs\":[{\"name\":\"\",\"type\":\"uint256\",\"internalType\":\"uint256\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"owner\",\"inputs\":[],\"outputs\":[{\"name\":\"\",\"type\":\"address\",\"internalType\":\"address\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"renounceOwnership\",\"inputs\":[],\"outputs\":[],\"stateMutability\":\"nonpayable\"},{\"type\":\"function\",\"name\":\"resourceConfig\",\"inputs\":[],\"outputs\":[{\"name\":\"\",\"type\":\"tuple\",\"internalType\":\"structIResourceMetering.ResourceConfig\",\"components\":[{\"name\":\"maxResourceLimit\",\"type\":\"uint32\",\"internalType\":\"uint32\"},{\"name\":\"elasticityMultiplier\",\"type\":\"uint8\",\"internalType\":\"uint8\"},{\"name\":\"baseFeeMaxChangeDenominator\",\"type\":\"uint8\",\"internalType\":\"uint8\"},{\"name\":\"minimumBaseFee\",\"type\":\"uint32\",\"internalType\":\"uint32\"},{\"name\":\"systemTxMaxGas\",\"type\":\"uint32\",\"internalType\":\"uint32\"},{\"name\":\"maximumBaseFee\",\"type\":\"uint128\",\"internalType\":\"uint128\"}]}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"scalar\",\"inputs\":[],\"outputs\":[{\"name\":\"\",\"type\":\"uint256\",\"internalType\":\"uint256\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"setBatcherHash\",\"inputs\":[{\"name\":\"_batcherHash\",\"type\":\"bytes32\",\"internalType\":\"bytes32\"}],\"outputs\":[],\"stateMutability\":\"nonpayable\"},{\"type\":\"function\",\"name\":\"setEIP1559Params\",\"inputs\":[{\"name\":\"_denominator\",\"type\":\"uint32\",\"internalType\":\"uint32\"},{\"name\":\"_elasticity\",\"type\":\"uint32\",\"internalType\":\"uint32\"}],\"outputs\":[],\"stateMutability\":\"nonpayable\"},{\"type\":\"function\",\"name\":\"setFeeVaultConfig\",\"inputs\":[{\"name\":\"_type\",\"type\":\"uint8\",\"internalType\":\"enumTypes.ConfigType\"},{\"name\":\"_recipient\",\"type\":\"address\",\"internalType\":\"address\"},{\"name\":\"_min\",\"type\":\"uint256\",\"internalType\":\"uint256\"},{\"name\":\"_network\",\"type\":\"uint8\",\"internalType\":\"enumTypes.WithdrawalNetwork\"}],\"outputs\":[],\"stateMutability\":\"nonpayable\"},{\"type\":\"function\",\"name\":\"setGasConfig\",\"inputs\":[{\"name\":\"_overhead\",\"type\":\"uint256\",\"internalType\":\"uint256\"},{\"name\":\"_scalar\",\"type\":\"uint256\",\"internalType\":\"uint256\"}],\"outputs\":[],\"stateMutability\":\"nonpayable\"},{\"type\":\"function\",\"name\":\"setGasConfigEcotone\",\"inputs\":[{\"name\":\"_basefeeScalar\",\"type\":\"uint32\",\"internalType\":\"uint32\"},{\"name\":\"_blobbasefeeScalar\",\"type\":\"uint32\",\"internalType\":\"uint32\"}],\"outputs\":[],\"stateMutability\":\"nonpayable\"},{\"type\":\"function\",\"name\":\"setGasLimit\",\"inputs\":[{\"name\":\"_gasLimit\",\"type\":\"uint64\",\"internalType\":\"uint64\"}],\"outputs\":[],\"stateMutability\":\"nonpayable\"},{\"type\":\"function\",\"name\":\"setUnsafeBlockSigner\",\"inputs\":[{\"name\":\"_unsafeBlockSigner\",\"type\":\"address\",\"internalType\":\"address\"}],\"outputs\":[],\"stateMutability\":\"nonpayable\"},{\"type\":\"function\",\"name\":\"startBlock\",\"inputs\":[],\"outputs\":[{\"name\":\"startBlock_\",\"type\":\"uint256\",\"internalType\":\"uint256\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"transferOwnership\",\"inputs\":[{\"name\":\"newOwner\",\"type\":\"address\",\"internalType\":\"address\"}],\"outputs\":[],\"stateMutability\":\"nonpayable\"},{\"type\":\"function\",\"name\":\"unsafeBlockSigner\",\"inputs\":[],\"outputs\":[{\"name\":\"addr_\",\"type\":\"address\",\"internalType\":\"address\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"version\",\"inputs\":[],\"outputs\":[{\"name\":\"\",\"type\":\"string\",\"internalType\":\"string\"}],\"stateMutability\":\"pure\"},{\"type\":\"event\",\"name\":\"ConfigUpdate\",\"inputs\":[{\"name\":\"version\",\"type\":\"uint256\",\"indexed\":true,\"internalType\":\"uint256\"},{\"name\":\"updateType\",\"type\":\"uint8\",\"indexed\":true,\"internalType\":\"enumSystemConfig.UpdateType\"},{\"name\":\"data\",\"type\":\"bytes\",\"indexed\":false,\"internalType\":\"bytes\"}],\"anonymous\":false},{\"type\":\"event\",\"name\":\"Initialized\",\"inputs\":[{\"name\":\"version\",\"type\":\"uint8\",\"indexed\":false,\"internalType\":\"uint8\"}],\"anonymous\":false},{\"type\":\"event\",\"name\":\"OwnershipTransferred\",\"inputs\":[{\"name\":\"previousOwner\",\"type\":\"address\",\"indexed\":true,\"internalType\":\"address\"},{\"name\":\"newOwner\",\"type\":\"address\",\"indexed\":true,\"internalType\":\"address\"}],\"anonymous\":false},{\"type\":\"error\",\"name\":\"UnsafeCast\",\"inputs\":[]}]", ABI: "[{\"type\":\"constructor\",\"inputs\":[],\"stateMutability\":\"nonpayable\"},{\"type\":\"function\",\"name\":\"BATCH_INBOX_SLOT\",\"inputs\":[],\"outputs\":[{\"name\":\"\",\"type\":\"bytes32\",\"internalType\":\"bytes32\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"DISPUTE_GAME_FACTORY_SLOT\",\"inputs\":[],\"outputs\":[{\"name\":\"\",\"type\":\"bytes32\",\"internalType\":\"bytes32\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"L1_CROSS_DOMAIN_MESSENGER_SLOT\",\"inputs\":[],\"outputs\":[{\"name\":\"\",\"type\":\"bytes32\",\"internalType\":\"bytes32\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"L1_ERC_721_BRIDGE_SLOT\",\"inputs\":[],\"outputs\":[{\"name\":\"\",\"type\":\"bytes32\",\"internalType\":\"bytes32\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"L1_STANDARD_BRIDGE_SLOT\",\"inputs\":[],\"outputs\":[{\"name\":\"\",\"type\":\"bytes32\",\"internalType\":\"bytes32\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"OPTIMISM_MINTABLE_ERC20_FACTORY_SLOT\",\"inputs\":[],\"outputs\":[{\"name\":\"\",\"type\":\"bytes32\",\"internalType\":\"bytes32\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"OPTIMISM_PORTAL_SLOT\",\"inputs\":[],\"outputs\":[{\"name\":\"\",\"type\":\"bytes32\",\"internalType\":\"bytes32\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"START_BLOCK_SLOT\",\"inputs\":[],\"outputs\":[{\"name\":\"\",\"type\":\"bytes32\",\"internalType\":\"bytes32\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"UNSAFE_BLOCK_SIGNER_SLOT\",\"inputs\":[],\"outputs\":[{\"name\":\"\",\"type\":\"bytes32\",\"internalType\":\"bytes32\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"VERSION\",\"inputs\":[],\"outputs\":[{\"name\":\"\",\"type\":\"uint256\",\"internalType\":\"uint256\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"basefeeScalar\",\"inputs\":[],\"outputs\":[{\"name\":\"\",\"type\":\"uint32\",\"internalType\":\"uint32\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"batchInbox\",\"inputs\":[],\"outputs\":[{\"name\":\"addr_\",\"type\":\"address\",\"internalType\":\"address\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"batcherHash\",\"inputs\":[],\"outputs\":[{\"name\":\"\",\"type\":\"bytes32\",\"internalType\":\"bytes32\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"blobbasefeeScalar\",\"inputs\":[],\"outputs\":[{\"name\":\"\",\"type\":\"uint32\",\"internalType\":\"uint32\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"disputeGameFactory\",\"inputs\":[],\"outputs\":[{\"name\":\"addr_\",\"type\":\"address\",\"internalType\":\"address\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"eip1559Denominator\",\"inputs\":[],\"outputs\":[{\"name\":\"\",\"type\":\"uint32\",\"internalType\":\"uint32\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"eip1559Elasticity\",\"inputs\":[],\"outputs\":[{\"name\":\"\",\"type\":\"uint32\",\"internalType\":\"uint32\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"gasLimit\",\"inputs\":[],\"outputs\":[{\"name\":\"\",\"type\":\"uint64\",\"internalType\":\"uint64\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"gasPayingToken\",\"inputs\":[],\"outputs\":[{\"name\":\"addr_\",\"type\":\"address\",\"internalType\":\"address\"},{\"name\":\"decimals_\",\"type\":\"uint8\",\"internalType\":\"uint8\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"gasPayingTokenName\",\"inputs\":[],\"outputs\":[{\"name\":\"name_\",\"type\":\"string\",\"internalType\":\"string\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"gasPayingTokenSymbol\",\"inputs\":[],\"outputs\":[{\"name\":\"symbol_\",\"type\":\"string\",\"internalType\":\"string\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"initialize\",\"inputs\":[{\"name\":\"_owner\",\"type\":\"address\",\"internalType\":\"address\"},{\"name\":\"_basefeeScalar\",\"type\":\"uint32\",\"internalType\":\"uint32\"},{\"name\":\"_blobbasefeeScalar\",\"type\":\"uint32\",\"internalType\":\"uint32\"},{\"name\":\"_batcherHash\",\"type\":\"bytes32\",\"internalType\":\"bytes32\"},{\"name\":\"_gasLimit\",\"type\":\"uint64\",\"internalType\":\"uint64\"},{\"name\":\"_unsafeBlockSigner\",\"type\":\"address\",\"internalType\":\"address\"},{\"name\":\"_config\",\"type\":\"tuple\",\"internalType\":\"structIResourceMetering.ResourceConfig\",\"components\":[{\"name\":\"maxResourceLimit\",\"type\":\"uint32\",\"internalType\":\"uint32\"},{\"name\":\"elasticityMultiplier\",\"type\":\"uint8\",\"internalType\":\"uint8\"},{\"name\":\"baseFeeMaxChangeDenominator\",\"type\":\"uint8\",\"internalType\":\"uint8\"},{\"name\":\"minimumBaseFee\",\"type\":\"uint32\",\"internalType\":\"uint32\"},{\"name\":\"systemTxMaxGas\",\"type\":\"uint32\",\"internalType\":\"uint32\"},{\"name\":\"maximumBaseFee\",\"type\":\"uint128\",\"internalType\":\"uint128\"}]},{\"name\":\"_batchInbox\",\"type\":\"address\",\"internalType\":\"address\"},{\"name\":\"_addresses\",\"type\":\"tuple\",\"internalType\":\"structSystemConfig.Addresses\",\"components\":[{\"name\":\"l1CrossDomainMessenger\",\"type\":\"address\",\"internalType\":\"address\"},{\"name\":\"l1ERC721Bridge\",\"type\":\"address\",\"internalType\":\"address\"},{\"name\":\"l1StandardBridge\",\"type\":\"address\",\"internalType\":\"address\"},{\"name\":\"disputeGameFactory\",\"type\":\"address\",\"internalType\":\"address\"},{\"name\":\"optimismPortal\",\"type\":\"address\",\"internalType\":\"address\"},{\"name\":\"optimismMintableERC20Factory\",\"type\":\"address\",\"internalType\":\"address\"},{\"name\":\"gasPayingToken\",\"type\":\"address\",\"internalType\":\"address\"}]}],\"outputs\":[],\"stateMutability\":\"nonpayable\"},{\"type\":\"function\",\"name\":\"isCustomGasToken\",\"inputs\":[],\"outputs\":[{\"name\":\"\",\"type\":\"bool\",\"internalType\":\"bool\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"l1CrossDomainMessenger\",\"inputs\":[],\"outputs\":[{\"name\":\"addr_\",\"type\":\"address\",\"internalType\":\"address\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"l1ERC721Bridge\",\"inputs\":[],\"outputs\":[{\"name\":\"addr_\",\"type\":\"address\",\"internalType\":\"address\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"l1StandardBridge\",\"inputs\":[],\"outputs\":[{\"name\":\"addr_\",\"type\":\"address\",\"internalType\":\"address\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"maximumGasLimit\",\"inputs\":[],\"outputs\":[{\"name\":\"\",\"type\":\"uint64\",\"internalType\":\"uint64\"}],\"stateMutability\":\"pure\"},{\"type\":\"function\",\"name\":\"minimumGasLimit\",\"inputs\":[],\"outputs\":[{\"name\":\"\",\"type\":\"uint64\",\"internalType\":\"uint64\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"optimismMintableERC20Factory\",\"inputs\":[],\"outputs\":[{\"name\":\"addr_\",\"type\":\"address\",\"internalType\":\"address\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"optimismPortal\",\"inputs\":[],\"outputs\":[{\"name\":\"addr_\",\"type\":\"address\",\"internalType\":\"address\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"overhead\",\"inputs\":[],\"outputs\":[{\"name\":\"\",\"type\":\"uint256\",\"internalType\":\"uint256\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"owner\",\"inputs\":[],\"outputs\":[{\"name\":\"\",\"type\":\"address\",\"internalType\":\"address\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"renounceOwnership\",\"inputs\":[],\"outputs\":[],\"stateMutability\":\"nonpayable\"},{\"type\":\"function\",\"name\":\"resourceConfig\",\"inputs\":[],\"outputs\":[{\"name\":\"\",\"type\":\"tuple\",\"internalType\":\"structIResourceMetering.ResourceConfig\",\"components\":[{\"name\":\"maxResourceLimit\",\"type\":\"uint32\",\"internalType\":\"uint32\"},{\"name\":\"elasticityMultiplier\",\"type\":\"uint8\",\"internalType\":\"uint8\"},{\"name\":\"baseFeeMaxChangeDenominator\",\"type\":\"uint8\",\"internalType\":\"uint8\"},{\"name\":\"minimumBaseFee\",\"type\":\"uint32\",\"internalType\":\"uint32\"},{\"name\":\"systemTxMaxGas\",\"type\":\"uint32\",\"internalType\":\"uint32\"},{\"name\":\"maximumBaseFee\",\"type\":\"uint128\",\"internalType\":\"uint128\"}]}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"scalar\",\"inputs\":[],\"outputs\":[{\"name\":\"\",\"type\":\"uint256\",\"internalType\":\"uint256\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"setBatcherHash\",\"inputs\":[{\"name\":\"_batcherHash\",\"type\":\"bytes32\",\"internalType\":\"bytes32\"}],\"outputs\":[],\"stateMutability\":\"nonpayable\"},{\"type\":\"function\",\"name\":\"setEIP1559Params\",\"inputs\":[{\"name\":\"_denominator\",\"type\":\"uint32\",\"internalType\":\"uint32\"},{\"name\":\"_elasticity\",\"type\":\"uint32\",\"internalType\":\"uint32\"}],\"outputs\":[],\"stateMutability\":\"nonpayable\"},{\"type\":\"function\",\"name\":\"setGasConfig\",\"inputs\":[{\"name\":\"_overhead\",\"type\":\"uint256\",\"internalType\":\"uint256\"},{\"name\":\"_scalar\",\"type\":\"uint256\",\"internalType\":\"uint256\"}],\"outputs\":[],\"stateMutability\":\"nonpayable\"},{\"type\":\"function\",\"name\":\"setGasConfigEcotone\",\"inputs\":[{\"name\":\"_basefeeScalar\",\"type\":\"uint32\",\"internalType\":\"uint32\"},{\"name\":\"_blobbasefeeScalar\",\"type\":\"uint32\",\"internalType\":\"uint32\"}],\"outputs\":[],\"stateMutability\":\"nonpayable\"},{\"type\":\"function\",\"name\":\"setGasLimit\",\"inputs\":[{\"name\":\"_gasLimit\",\"type\":\"uint64\",\"internalType\":\"uint64\"}],\"outputs\":[],\"stateMutability\":\"nonpayable\"},{\"type\":\"function\",\"name\":\"setUnsafeBlockSigner\",\"inputs\":[{\"name\":\"_unsafeBlockSigner\",\"type\":\"address\",\"internalType\":\"address\"}],\"outputs\":[],\"stateMutability\":\"nonpayable\"},{\"type\":\"function\",\"name\":\"startBlock\",\"inputs\":[],\"outputs\":[{\"name\":\"startBlock_\",\"type\":\"uint256\",\"internalType\":\"uint256\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"transferOwnership\",\"inputs\":[{\"name\":\"newOwner\",\"type\":\"address\",\"internalType\":\"address\"}],\"outputs\":[],\"stateMutability\":\"nonpayable\"},{\"type\":\"function\",\"name\":\"unsafeBlockSigner\",\"inputs\":[],\"outputs\":[{\"name\":\"addr_\",\"type\":\"address\",\"internalType\":\"address\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"version\",\"inputs\":[],\"outputs\":[{\"name\":\"\",\"type\":\"string\",\"internalType\":\"string\"}],\"stateMutability\":\"pure\"},{\"type\":\"event\",\"name\":\"ConfigUpdate\",\"inputs\":[{\"name\":\"version\",\"type\":\"uint256\",\"indexed\":true,\"internalType\":\"uint256\"},{\"name\":\"updateType\",\"type\":\"uint8\",\"indexed\":true,\"internalType\":\"enumSystemConfig.UpdateType\"},{\"name\":\"data\",\"type\":\"bytes\",\"indexed\":false,\"internalType\":\"bytes\"}],\"anonymous\":false},{\"type\":\"event\",\"name\":\"Initialized\",\"inputs\":[{\"name\":\"version\",\"type\":\"uint8\",\"indexed\":false,\"internalType\":\"uint8\"}],\"anonymous\":false},{\"type\":\"event\",\"name\":\"OwnershipTransferred\",\"inputs\":[{\"name\":\"previousOwner\",\"type\":\"address\",\"indexed\":true,\"internalType\":\"address\"},{\"name\":\"newOwner\",\"type\":\"address\",\"indexed\":true,\"internalType\":\"address\"}],\"anonymous\":false}]",
Bin: "0x60806040523480156200001157600080fd5b506200005a6200004360017fa11ee3ab75b40e88a0105e935d17cd36c8faee0138320d776c411291bdbbb1a062000130565b60001b6000196200006a60201b6200119d1760201c565b620000646200006e565b62000156565b9055565b600054610100900460ff1615620000db5760405162461bcd60e51b815260206004820152602760248201527f496e697469616c697a61626c653a20636f6e747261637420697320696e697469604482015266616c697a696e6760c81b606482015260840160405180910390fd5b60005460ff90811610156200012e576000805460ff191660ff9081179091556040519081527f7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb38474024989060200160405180910390a15b565b6000828210156200015157634e487b7160e01b600052601160045260246000fd5b500390565b612fd880620001666000396000f3fe608060405234801561001057600080fd5b50600436106103155760003560e01c8063a7119869116101a7578063dac6e63a116100ee578063f2fde38b11610097578063f8c68de011610071578063f8c68de01461076f578063fd32aa0f14610777578063ffa1ad741461077f57600080fd5b8063f2fde38b1461073f578063f45e65d814610752578063f68016b71461075b57600080fd5b8063e81b2c6d116100c8578063e81b2c6d1461070e578063ec70751714610717578063f2b4e6171461073757600080fd5b8063dac6e63a146106f6578063e0e2016d146106fe578063e2a3285c1461070657600080fd5b8063c4e8ddfa11610150578063cc731b021161012a578063cc731b02146105aa578063d220a9e0146106de578063d8444715146106ee57600080fd5b8063c4e8ddfa14610577578063c9b26f611461057f578063c9ff2d161461059257600080fd5b8063be4be78311610181578063be4be78314610520578063bfb14fb714610533578063c0fd4b411461056457600080fd5b8063a7119869146104fd578063b40a817c14610505578063bc49ce5f1461051857600080fd5b806330a402c01161026b578063550fcdc9116102145780638da5cb5b116101ee5780638da5cb5b146104c4578063935f029e146104e25780639b7d7f0a146104f557600080fd5b8063550fcdc9146104ac5780635d73369c146104b4578063715018a6146104bc57600080fd5b80634add321d116102455780634add321d1461043b5780634f16540b1461044357806354fd4d501461046a57600080fd5b806330a402c0146103f55780634397dfef146103fd57806348cd4cb11461043357600080fd5b806318d13918116102cd57806321326849116102a757806321326849146103b757806321d7fde5146103cf57806322b4dded146103e257600080fd5b806318d139181461039257806319f5cea8146103a75780631fd19ee1146103af57600080fd5b80630a49cb03116102fe5780630a49cb03146103625780630ae14b1b1461036a5780630c18c1621461038957600080fd5b806306c926571461031a578063078f29cf14610335575b600080fd5b610322610787565b6040519081526020015b60405180910390f35b61033d6107b5565b60405173ffffffffffffffffffffffffffffffffffffffff909116815260200161032c565b61033d6107ee565b630bebc2005b60405167ffffffffffffffff909116815260200161032c565b61032260655481565b6103a56103a03660046128f3565b61081e565b005b610322610832565b61033d61085d565b6103bf610887565b604051901515815260200161032c565b6103a56103dd366004612929565b6108c6565b6103a56103f0366004612b4c565b6108dc565b61033d610d21565b610405610d4b565b6040805173ffffffffffffffffffffffffffffffffffffffff909316835260ff90911660208301520161032c565b610322610d5f565b610370610d8f565b6103227f65a7ed542fb37fe237fdfbdd70b31598523fe5b32879e307bae27a0bd9581c0881565b60408051808201909152600c81527f322e332e302d626574612e36000000000000000000000000000000000000000060208201525b60405161032c9190612c93565b61049f610db5565b610322610dbf565b6103a5610dea565b60335473ffffffffffffffffffffffffffffffffffffffff1661033d565b6103a56104f0366004612ca6565b610dfe565b61033d610e10565b61033d610e40565b6103a5610513366004612cc8565b610e70565b610322610e81565b6103a561052e366004612ce3565b610eac565b60685461054f9068010000000000000000900463ffffffff1681565b60405163ffffffff909116815260200161032c565b6103a5610572366004612929565b610f80565b61033d610f92565b6103a561058d366004612d3c565b610fc2565b606a5461054f90640100000000900463ffffffff1681565b61066e6040805160c081018252600080825260208201819052918101829052606081018290526080810182905260a0810191909152506040805160c08101825260695463ffffffff8082168352640100000000820460ff9081166020850152650100000000008304169383019390935266010000000000008104831660608301526a0100000000000000000000810490921660808201526e0100000000000000000000000000009091046fffffffffffffffffffffffffffffffff1660a082015290565b60405161032c9190600060c08201905063ffffffff80845116835260ff602085015116602084015260ff6040850151166040840152806060850151166060840152806080850151166080840152506fffffffffffffffffffffffffffffffff60a08401511660a083015292915050565b606a5461054f9063ffffffff1681565b61049f610fd3565b61033d610fdd565b61032261100d565b610322611038565b61032260675481565b60685461054f906c01000000000000000000000000900463ffffffff1681565b61033d611063565b6103a561074d3660046128f3565b611093565b61032260665481565b6068546103709067ffffffffffffffff1681565b610322611147565b610322611172565b610322600081565b6107b260017fa04c5bb938ca6fc46d95553abf0a76345ce3e722a30bf4f74928b8e7d852320d612d84565b81565b60006107e96107e560017f9904ba90dde5696cda05c9e0dab5cbaa0fea005ace4d11218a02ac668dad6377612d84565b5490565b905090565b60006107e96107e560017f4b6c74f9e688cb39801f2112c14a8c57232a3fc5202e1444126d4bce86eb19ad612d84565b6108266111a1565b61082f81611222565b50565b6107b260017f46adcbebc6be8ce551740c29c47c8798210f23f7f4086c41752944352568d5a8612d84565b60006107e97f65a7ed542fb37fe237fdfbdd70b31598523fe5b32879e307bae27a0bd9581c085490565b600080610892610d4b565b5073ffffffffffffffffffffffffffffffffffffffff1673eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee141592915050565b6108ce6111a1565b6108d882826112df565b5050565b600054610100900460ff16158080156108fc5750600054600160ff909116105b806109165750303b158015610916575060005460ff166001145b6109a7576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602e60248201527f496e697469616c697a61626c653a20636f6e747261637420697320616c72656160448201527f647920696e697469616c697a656400000000000000000000000000000000000060648201526084015b60405180910390fd5b600080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff001660011790558015610a0557600080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00ff166101001790555b610a0d61141e565b8751610a1890611093565b610a2588606001516114bd565b610a2f87876112df565b610a38856114e5565b60408801517f65a7ed542fb37fe237fdfbdd70b31598523fe5b32879e307bae27a0bd9581c085560208801517f5a12cb4aeab79fd7e76814330f3e0732946417b36fa088add63d298d3c0f7a3f55610ab9610ab460017f71ac12829d66ee73d8d95bff50b3589745ce57edae70a3fb111a2342464dc598612d84565b849055565b610af0610ae760017f4b6c74f9e688cb39801f2112c14a8c57232a3fc5202e1444126d4bce86eb19ad612d84565b60808401519055565b610b27610b1e60017f52322a25d9f59ea17656545543306b7aef62bc0cc53a0e65ccfa0c75b97aa907612d84565b60608401519055565b610b5e610b5560017fa04c5bb938ca6fc46d95553abf0a76345ce3e722a30bf4f74928b8e7d852320d612d84565b60a08401519055565b610b95610b8c60017f383f291819e6d54073bc9a648251d97421076bdd101933c0c022219ce9580637612d84565b8351600461163b565b610bcf610bc360017f46adcbebc6be8ce551740c29c47c8798210f23f7f4086c41752944352568d5a8612d84565b6020840151600561163b565b610c09610bfd60017f9904ba90dde5696cda05c9e0dab5cbaa0fea005ace4d11218a02ac668dad6377612d84565b6040840151600661163b565b610c116116f2565b610c19611784565b610c268260c001516117ec565b610c2f84611ae0565b610c37610d8f565b67ffffffffffffffff168567ffffffffffffffff161015610cb4576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601f60248201527f53797374656d436f6e6669673a20676173206c696d697420746f6f206c6f7700604482015260640161099e565b8015610d1757600080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00ff169055604051600181527f7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb38474024989060200160405180910390a15b5050505050505050565b60006107e97f5a12cb4aeab79fd7e76814330f3e0732946417b36fa088add63d298d3c0f7a3f5490565b600080610d56611f54565b90939092509050565b60006107e96107e560017fa11ee3ab75b40e88a0105e935d17cd36c8faee0138320d776c411291bdbbb1a0612d84565b6069546000906107e99063ffffffff6a0100000000000000000000820481169116612d9b565b60606107e9611fd1565b6107b260017f383f291819e6d54073bc9a648251d97421076bdd101933c0c022219ce9580637612d84565b610df26111a1565b610dfc6000612092565b565b610e066111a1565b6108d88282612109565b60006107e96107e560017fa04c5bb938ca6fc46d95553abf0a76345ce3e722a30bf4f74928b8e7d852320d612d84565b60006107e96107e560017f383f291819e6d54073bc9a648251d97421076bdd101933c0c022219ce9580637612d84565b610e786111a1565b61082f816114e5565b6107b260017f71ac12829d66ee73d8d95bff50b3589745ce57edae70a3fb111a2342464dc598612d84565b610eb4610d21565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614610f6e576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602960248201527f53797374656d436f6e6669673a2063616c6c6572206973206e6f74207468652060448201527f6665652061646d696e0000000000000000000000000000000000000000000000606482015260840161099e565b610f7a848484846121df565b50505050565b610f886111a1565b6108d88282612353565b60006107e96107e560017f46adcbebc6be8ce551740c29c47c8798210f23f7f4086c41752944352568d5a8612d84565b610fca6111a1565b61082f816114bd565b60606107e9612525565b60006107e96107e560017f71ac12829d66ee73d8d95bff50b3589745ce57edae70a3fb111a2342464dc598612d84565b6107b260017fa11ee3ab75b40e88a0105e935d17cd36c8faee0138320d776c411291bdbbb1a0612d84565b6107b260017f52322a25d9f59ea17656545543306b7aef62bc0cc53a0e65ccfa0c75b97aa907612d84565b60006107e96107e560017f52322a25d9f59ea17656545543306b7aef62bc0cc53a0e65ccfa0c75b97aa907612d84565b61109b6111a1565b73ffffffffffffffffffffffffffffffffffffffff811661113e576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602660248201527f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160448201527f6464726573730000000000000000000000000000000000000000000000000000606482015260840161099e565b61082f81612092565b6107b260017f9904ba90dde5696cda05c9e0dab5cbaa0fea005ace4d11218a02ac668dad6377612d84565b6107b260017f4b6c74f9e688cb39801f2112c14a8c57232a3fc5202e1444126d4bce86eb19ad612d84565b9055565b60335473ffffffffffffffffffffffffffffffffffffffff163314610dfc576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572604482015260640161099e565b61124b7f65a7ed542fb37fe237fdfbdd70b31598523fe5b32879e307bae27a0bd9581c08829055565b6040805173ffffffffffffffffffffffffffffffffffffffff8316602082015260009101604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0818403018152919052905060035b60007f1d2b0bda21d56b8bd12d4f94ebacffdfb35f5e226f84b461103bb8beab6353be836040516112d39190612c93565b60405180910390a35050565b606880547fffffffffffffffffffffffffffffffff0000000000000000ffffffffffffffff166801000000000000000063ffffffff8581169182027fffffffffffffffffffffffffffffffff00000000ffffffffffffffffffffffff16929092176c0100000000000000000000000092851692909202919091179091557f0100000000000000000000000000000000000000000000000000000000000000602083811b67ffffffff000000001690921717606681905560655460408051938401919091528201526000906060015b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0818403018152919052905060015b60007f1d2b0bda21d56b8bd12d4f94ebacffdfb35f5e226f84b461103bb8beab6353be836040516114119190612c93565b60405180910390a3505050565b600054610100900460ff166114b5576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602b60248201527f496e697469616c697a61626c653a20636f6e7472616374206973206e6f74206960448201527f6e697469616c697a696e67000000000000000000000000000000000000000000606482015260840161099e565b610dfc6125db565b60678190556040805160208082018490528251808303909101815290820190915260006112a2565b6114ed610d8f565b67ffffffffffffffff168167ffffffffffffffff16101561156a576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601f60248201527f53797374656d436f6e6669673a20676173206c696d697420746f6f206c6f7700604482015260640161099e565b630bebc20067ffffffffffffffff821611156115e2576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820181905260248201527f53797374656d436f6e6669673a20676173206c696d697420746f6f2068696768604482015260640161099e565b606880547fffffffffffffffffffffffffffffffffffffffffffffffff00000000000000001667ffffffffffffffff831690811790915560408051602080820193909352815180820390930183528101905260026112a2565b8183556116466107ee565b73ffffffffffffffffffffffffffffffffffffffff1663c0012163828460405160200161168f919073ffffffffffffffffffffffffffffffffffffffff91909116815260200190565b6040516020818303038152906040526040518363ffffffff1660e01b81526004016116bb929190612df6565b600060405180830381600087803b1580156116d557600080fd5b505af11580156116e9573d6000803e3d6000fd5b50505050505050565b6116fa6107ee565b73ffffffffffffffffffffffffffffffffffffffff1663c001216360074660405160200161172a91815260200190565b6040516020818303038152906040526040518363ffffffff1660e01b8152600401611756929190612df6565b600060405180830381600087803b15801561177057600080fd5b505af1158015610f7a573d6000803e3d6000fd5b6117b26107e560017fa11ee3ab75b40e88a0105e935d17cd36c8faee0138320d776c411291bdbbb1a0612d84565b600003610dfc57610dfc6117e760017fa11ee3ab75b40e88a0105e935d17cd36c8faee0138320d776c411291bdbbb1a0612d84565b439055565b73ffffffffffffffffffffffffffffffffffffffff81161580159061183b575073ffffffffffffffffffffffffffffffffffffffff811673eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee14155b801561184c575061184a610887565b155b1561082f57601260ff168173ffffffffffffffffffffffffffffffffffffffff1663313ce5676040518163ffffffff1660e01b8152600401602060405180830381865afa1580156118a1573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906118c59190612e4e565b60ff1614611955576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602e60248201527f53797374656d436f6e6669673a2062616420646563696d616c73206f6620676160448201527f7320706179696e6720746f6b656e000000000000000000000000000000000000606482015260840161099e565b60006119f08273ffffffffffffffffffffffffffffffffffffffff166306fdde036040518163ffffffff1660e01b8152600401600060405180830381865afa1580156119a5573d6000803e3d6000fd5b505050506040513d6000823e601f3d9081017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe01682016040526119eb9190810190612e6b565b61267b565b90506000611a428373ffffffffffffffffffffffffffffffffffffffff166395d89b416040518163ffffffff1660e01b8152600401600060405180830381865afa1580156119a5573d6000803e3d6000fd5b9050611a51836012848461271e565b611a596107ee565b6040805173ffffffffffffffffffffffffffffffffffffffff86811660208301526012828401526060820186905260808083018690528351808403909101815260a08301938490527fc001216300000000000000000000000000000000000000000000000000000000909352929092169163c0012163916116bb916000919060a401612df6565b8060a001516fffffffffffffffffffffffffffffffff16816060015163ffffffff161115611b90576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603560248201527f53797374656d436f6e6669673a206d696e206261736520666565206d7573742060448201527f6265206c657373207468616e206d617820626173650000000000000000000000606482015260840161099e565b6001816040015160ff1611611c27576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602f60248201527f53797374656d436f6e6669673a2064656e6f6d696e61746f72206d757374206260448201527f65206c6172676572207468616e20310000000000000000000000000000000000606482015260840161099e565b6068546080820151825167ffffffffffffffff90921691611c489190612f36565b63ffffffff161115611cb6576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601f60248201527f53797374656d436f6e6669673a20676173206c696d697420746f6f206c6f7700604482015260640161099e565b6000816020015160ff1611611d4d576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602f60248201527f53797374656d436f6e6669673a20656c6173746963697479206d756c7469706c60448201527f6965722063616e6e6f7420626520300000000000000000000000000000000000606482015260840161099e565b8051602082015163ffffffff82169160ff90911690611d6d908290612f55565b611d779190612f9f565b63ffffffff1614611e0a576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603760248201527f53797374656d436f6e6669673a20707265636973696f6e206c6f73732077697460448201527f6820746172676574207265736f75726365206c696d6974000000000000000000606482015260840161099e565b805160698054602084015160408501516060860151608087015160a09097015163ffffffff9687167fffffffffffffffffffffffffffffffffffffffffffffffffffffff00000000009095169490941764010000000060ff94851602177fffffffffffffffffffffffffffffffffffffffffffff0000000000ffffffffff166501000000000093909216929092027fffffffffffffffffffffffffffffffffffffffffffff00000000ffffffffffff1617660100000000000091851691909102177fffff0000000000000000000000000000000000000000ffffffffffffffffffff166a010000000000000000000093909416929092027fffff00000000000000000000000000000000ffffffffffffffffffffffffffff16929092176e0100000000000000000000000000006fffffffffffffffffffffffffffffffff90921691909102179055565b60008080611f866107e560017f04adb1412b2ddc16fcc0d4538d5c8f07cf9c83abecc6b41f6f69037b708fbcec612d84565b73ffffffffffffffffffffffffffffffffffffffff81169350905082611fc5575073eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee92601292509050565b60a081901c9150509091565b60606000611fdd611f54565b5090507fffffffffffffffffffffffff111111111111111111111111111111111111111273ffffffffffffffffffffffffffffffffffffffff82160161205657505060408051808201909152600381527f4554480000000000000000000000000000000000000000000000000000000000602082015290565b61208c6120876107e560017fa48b38a4b44951360fbdcbfaaeae5ed6ae92585412e9841b70ec72ed8cd05764612d84565b6127ea565b91505090565b6033805473ffffffffffffffffffffffffffffffffffffffff8381167fffffffffffffffffffffffff0000000000000000000000000000000000000000831681179093556040519116919082907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e090600090a35050565b7fff000000000000000000000000000000000000000000000000000000000000008116156121b9576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602160248201527f53797374656d436f6e6669673a207363616c61722065786365656473206d617860448201527f2e00000000000000000000000000000000000000000000000000000000000000606482015260840161099e565b6065829055606681905560408051602081018490529081018290526000906060016113ad565b60018460098111156121f3576121f3612dc7565b14806122105750600284600981111561220e5761220e612dc7565b145b8061222c5750600384600981111561222a5761222a612dc7565b145b6122b8576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603a60248201527f53797374656d436f6e6669673a20436f6e66696754797065206973206973206e60448201527f6f74206120466565205661756c7420436f6e6669672074797065000000000000606482015260840161099e565b6122c06107ee565b73ffffffffffffffffffffffffffffffffffffffff1663c0012163856122e786868661281e565b6040516020016122f991815260200190565b6040516020818303038152906040526040518363ffffffff1660e01b8152600401612325929190612df6565b600060405180830381600087803b15801561233f57600080fd5b505af1158015610d17573d6000803e3d6000fd5b60018263ffffffff1610156123ea576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602660248201527f53797374656d436f6e6669673a2064656e6f6d696e61746f72206d757374206260448201527f65203e3d20310000000000000000000000000000000000000000000000000000606482015260840161099e565b60018163ffffffff161015612481576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602560248201527f53797374656d436f6e6669673a20656c6173746963697479206d75737420626560448201527f203e3d2031000000000000000000000000000000000000000000000000000000606482015260840161099e565b606a805463ffffffff83811664010000000081027fffffffffffffffffffffffffffffffffffffffffffffffff000000000000000090931691861691909117919091179091556040516000916124ee91602086811b67ffffffff0000000016909217910190815260200190565b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0818403018152919052905060046113e0565b60606000612531611f54565b5090507fffffffffffffffffffffffff111111111111111111111111111111111111111273ffffffffffffffffffffffffffffffffffffffff8216016125aa57505060408051808201909152600581527f4574686572000000000000000000000000000000000000000000000000000000602082015290565b61208c6120876107e560017f657c3582c29b3176614e3a33ddd1ec48352696a04e92b3c0566d72010fa8863d612d84565b600054610100900460ff16612672576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602b60248201527f496e697469616c697a61626c653a20636f6e7472616374206973206e6f74206960448201527f6e697469616c697a696e67000000000000000000000000000000000000000000606482015260840161099e565b610dfc33612092565b600060208251111561270f576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603660248201527f476173506179696e67546f6b656e3a20737472696e672063616e6e6f7420626560448201527f2067726561746572207468616e20333220627974657300000000000000000000606482015260840161099e565b612718826128a1565b92915050565b61278461274c60017f04adb1412b2ddc16fcc0d4538d5c8f07cf9c83abecc6b41f6f69037b708fbcec612d84565b74ff000000000000000000000000000000000000000060a086901b1673ffffffffffffffffffffffffffffffffffffffff8716179055565b6127b76127b260017f657c3582c29b3176614e3a33ddd1ec48352696a04e92b3c0566d72010fa8863d612d84565b839055565b610f7a6127e560017fa48b38a4b44951360fbdcbfaaeae5ed6ae92585412e9841b70ec72ed8cd05764612d84565b829055565b60405160005b82811a15612800576001016127f0565b80825260208201838152600082820152505060408101604052919050565b60006affffffffffffffffffffff831115612865576040517fc4bd89a900000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b8373ffffffffffffffffffffffffffffffffffffffff1660a084901b60f884600181111561289557612895612dc7565b901b1717949350505050565b8051602181106128b95763ec92f9a36000526004601cfd5b9081015160209190910360031b1b90565b803573ffffffffffffffffffffffffffffffffffffffff811681146128ee57600080fd5b919050565b60006020828403121561290557600080fd5b61290e826128ca565b9392505050565b803563ffffffff811681146128ee57600080fd5b6000806040838503121561293c57600080fd5b61294583612915565b915061295360208401612915565b90509250929050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b6040516080810167ffffffffffffffff811182821017156129ae576129ae61295c565b60405290565b803567ffffffffffffffff811681146128ee57600080fd5b60ff8116811461082f57600080fd5b600060c082840312156129ed57600080fd5b60405160c0810181811067ffffffffffffffff82111715612a1057612a1061295c565b604052905080612a1f83612915565b81526020830135612a2f816129cc565b60208201526040830135612a42816129cc565b6040820152612a5360608401612915565b6060820152612a6460808401612915565b608082015260a08301356fffffffffffffffffffffffffffffffff81168114612a8c57600080fd5b60a0919091015292915050565b600060e08284031215612aab57600080fd5b60405160e0810181811067ffffffffffffffff82111715612ace57612ace61295c565b604052905080612add836128ca565b8152612aeb602084016128ca565b6020820152612afc604084016128ca565b6040820152612b0d606084016128ca565b6060820152612b1e608084016128ca565b6080820152612b2f60a084016128ca565b60a0820152612b4060c084016128ca565b60c08201525092915050565b60008060008060008060008789036102a0811215612b6957600080fd5b6080811215612b7757600080fd5b50612b8061298b565b612b89896128ca565b8152612b9760208a016128ca565b6020820152612ba860408a016128ca565b6040820152606089810135908201529650612bc560808901612915565b9550612bd360a08901612915565b9450612be160c089016129b4565b9350612bf08960e08a016129db565b9250612bff6101a089016128ca565b9150612c0f896101c08a01612a99565b905092959891949750929550565b60005b83811015612c38578181015183820152602001612c20565b83811115610f7a5750506000910152565b60008151808452612c61816020860160208601612c1d565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0169290920160200192915050565b60208152600061290e6020830184612c49565b60008060408385031215612cb957600080fd5b50508035926020909101359150565b600060208284031215612cda57600080fd5b61290e826129b4565b60008060008060808587031215612cf957600080fd5b8435600a8110612d0857600080fd5b9350612d16602086016128ca565b925060408501359150606085013560028110612d3157600080fd5b939692955090935050565b600060208284031215612d4e57600080fd5b5035919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b600082821015612d9657612d96612d55565b500390565b600067ffffffffffffffff808316818516808303821115612dbe57612dbe612d55565b01949350505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602160045260246000fd5b6000600a8410612e2f577f4e487b7100000000000000000000000000000000000000000000000000000000600052602160045260246000fd5b83825260406020830152612e466040830184612c49565b949350505050565b600060208284031215612e6057600080fd5b815161290e816129cc565b600060208284031215612e7d57600080fd5b815167ffffffffffffffff80821115612e9557600080fd5b818401915084601f830112612ea957600080fd5b815181811115612ebb57612ebb61295c565b604051601f82017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0908116603f01168101908382118183101715612f0157612f0161295c565b81604052828152876020848701011115612f1a57600080fd5b612f2b836020830160208801612c1d565b979650505050505050565b600063ffffffff808316818516808303821115612dbe57612dbe612d55565b600063ffffffff80841680612f93577f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b92169190910492915050565b600063ffffffff80831681851681830481118215151615612fc257612fc2612d55565b0294935050505056fea164736f6c634300080f000a",
} }
// SystemConfigABI is the input ABI used to generate the binding from. // SystemConfigABI is the input ABI used to generate the binding from.
// Deprecated: Use SystemConfigMetaData.ABI instead. // Deprecated: Use SystemConfigMetaData.ABI instead.
var SystemConfigABI = SystemConfigMetaData.ABI var SystemConfigABI = SystemConfigMetaData.ABI
// SystemConfigBin is the compiled bytecode used for deploying new contracts.
// Deprecated: Use SystemConfigMetaData.Bin instead.
var SystemConfigBin = SystemConfigMetaData.Bin
// DeploySystemConfig deploys a new Ethereum contract, binding an instance of SystemConfig to it.
func DeploySystemConfig(auth *bind.TransactOpts, backend bind.ContractBackend) (common.Address, *types.Transaction, *SystemConfig, error) {
parsed, err := SystemConfigMetaData.GetAbi()
if err != nil {
return common.Address{}, nil, nil, err
}
if parsed == nil {
return common.Address{}, nil, nil, errors.New("GetABI returned nil")
}
address, tx, contract, err := bind.DeployContract(auth, *parsed, common.FromHex(SystemConfigBin), backend)
if err != nil {
return common.Address{}, nil, nil, err
}
return address, tx, &SystemConfig{SystemConfigCaller: SystemConfigCaller{contract: contract}, SystemConfigTransactor: SystemConfigTransactor{contract: contract}, SystemConfigFilterer: SystemConfigFilterer{contract: contract}}, nil
}
// SystemConfig is an auto generated Go binding around an Ethereum contract. // SystemConfig is an auto generated Go binding around an Ethereum contract.
type SystemConfig struct { type SystemConfig struct {
SystemConfigCaller // Read-only binding to the contract SystemConfigCaller // Read-only binding to the contract
...@@ -757,37 +727,6 @@ func (_SystemConfig *SystemConfigCallerSession) Eip1559Elasticity() (uint32, err ...@@ -757,37 +727,6 @@ func (_SystemConfig *SystemConfigCallerSession) Eip1559Elasticity() (uint32, err
return _SystemConfig.Contract.Eip1559Elasticity(&_SystemConfig.CallOpts) return _SystemConfig.Contract.Eip1559Elasticity(&_SystemConfig.CallOpts)
} }
// FeeAdmin is a free data retrieval call binding the contract method 0x30a402c0.
//
// Solidity: function feeAdmin() view returns(address addr_)
func (_SystemConfig *SystemConfigCaller) FeeAdmin(opts *bind.CallOpts) (common.Address, error) {
var out []interface{}
err := _SystemConfig.contract.Call(opts, &out, "feeAdmin")
if err != nil {
return *new(common.Address), err
}
out0 := *abi.ConvertType(out[0], new(common.Address)).(*common.Address)
return out0, err
}
// FeeAdmin is a free data retrieval call binding the contract method 0x30a402c0.
//
// Solidity: function feeAdmin() view returns(address addr_)
func (_SystemConfig *SystemConfigSession) FeeAdmin() (common.Address, error) {
return _SystemConfig.Contract.FeeAdmin(&_SystemConfig.CallOpts)
}
// FeeAdmin is a free data retrieval call binding the contract method 0x30a402c0.
//
// Solidity: function feeAdmin() view returns(address addr_)
func (_SystemConfig *SystemConfigCallerSession) FeeAdmin() (common.Address, error) {
return _SystemConfig.Contract.FeeAdmin(&_SystemConfig.CallOpts)
}
// GasLimit is a free data retrieval call binding the contract method 0xf68016b7. // GasLimit is a free data retrieval call binding the contract method 0xf68016b7.
// //
// Solidity: function gasLimit() view returns(uint64) // Solidity: function gasLimit() view returns(uint64)
...@@ -1391,25 +1330,25 @@ func (_SystemConfig *SystemConfigCallerSession) Version() (string, error) { ...@@ -1391,25 +1330,25 @@ func (_SystemConfig *SystemConfigCallerSession) Version() (string, error) {
return _SystemConfig.Contract.Version(&_SystemConfig.CallOpts) return _SystemConfig.Contract.Version(&_SystemConfig.CallOpts)
} }
// Initialize is a paid mutator transaction binding the contract method 0x22b4dded. // Initialize is a paid mutator transaction binding the contract method 0xdb9040fa.
// //
// Solidity: function initialize((address,address,address,bytes32) _roles, uint32 _basefeeScalar, uint32 _blobbasefeeScalar, uint64 _gasLimit, (uint32,uint8,uint8,uint32,uint32,uint128) _config, address _batchInbox, (address,address,address,address,address,address,address) _addresses) returns() // Solidity: function initialize(address _owner, uint32 _basefeeScalar, uint32 _blobbasefeeScalar, bytes32 _batcherHash, uint64 _gasLimit, address _unsafeBlockSigner, (uint32,uint8,uint8,uint32,uint32,uint128) _config, address _batchInbox, (address,address,address,address,address,address,address) _addresses) returns()
func (_SystemConfig *SystemConfigTransactor) Initialize(opts *bind.TransactOpts, _roles SystemConfigRoles, _basefeeScalar uint32, _blobbasefeeScalar uint32, _gasLimit uint64, _config IResourceMeteringResourceConfig, _batchInbox common.Address, _addresses SystemConfigAddresses) (*types.Transaction, error) { func (_SystemConfig *SystemConfigTransactor) Initialize(opts *bind.TransactOpts, _owner common.Address, _basefeeScalar uint32, _blobbasefeeScalar uint32, _batcherHash [32]byte, _gasLimit uint64, _unsafeBlockSigner common.Address, _config IResourceMeteringResourceConfig, _batchInbox common.Address, _addresses SystemConfigAddresses) (*types.Transaction, error) {
return _SystemConfig.contract.Transact(opts, "initialize", _roles, _basefeeScalar, _blobbasefeeScalar, _gasLimit, _config, _batchInbox, _addresses) return _SystemConfig.contract.Transact(opts, "initialize", _owner, _basefeeScalar, _blobbasefeeScalar, _batcherHash, _gasLimit, _unsafeBlockSigner, _config, _batchInbox, _addresses)
} }
// Initialize is a paid mutator transaction binding the contract method 0x22b4dded. // Initialize is a paid mutator transaction binding the contract method 0xdb9040fa.
// //
// Solidity: function initialize((address,address,address,bytes32) _roles, uint32 _basefeeScalar, uint32 _blobbasefeeScalar, uint64 _gasLimit, (uint32,uint8,uint8,uint32,uint32,uint128) _config, address _batchInbox, (address,address,address,address,address,address,address) _addresses) returns() // Solidity: function initialize(address _owner, uint32 _basefeeScalar, uint32 _blobbasefeeScalar, bytes32 _batcherHash, uint64 _gasLimit, address _unsafeBlockSigner, (uint32,uint8,uint8,uint32,uint32,uint128) _config, address _batchInbox, (address,address,address,address,address,address,address) _addresses) returns()
func (_SystemConfig *SystemConfigSession) Initialize(_roles SystemConfigRoles, _basefeeScalar uint32, _blobbasefeeScalar uint32, _gasLimit uint64, _config IResourceMeteringResourceConfig, _batchInbox common.Address, _addresses SystemConfigAddresses) (*types.Transaction, error) { func (_SystemConfig *SystemConfigSession) Initialize(_owner common.Address, _basefeeScalar uint32, _blobbasefeeScalar uint32, _batcherHash [32]byte, _gasLimit uint64, _unsafeBlockSigner common.Address, _config IResourceMeteringResourceConfig, _batchInbox common.Address, _addresses SystemConfigAddresses) (*types.Transaction, error) {
return _SystemConfig.Contract.Initialize(&_SystemConfig.TransactOpts, _roles, _basefeeScalar, _blobbasefeeScalar, _gasLimit, _config, _batchInbox, _addresses) return _SystemConfig.Contract.Initialize(&_SystemConfig.TransactOpts, _owner, _basefeeScalar, _blobbasefeeScalar, _batcherHash, _gasLimit, _unsafeBlockSigner, _config, _batchInbox, _addresses)
} }
// Initialize is a paid mutator transaction binding the contract method 0x22b4dded. // Initialize is a paid mutator transaction binding the contract method 0xdb9040fa.
// //
// Solidity: function initialize((address,address,address,bytes32) _roles, uint32 _basefeeScalar, uint32 _blobbasefeeScalar, uint64 _gasLimit, (uint32,uint8,uint8,uint32,uint32,uint128) _config, address _batchInbox, (address,address,address,address,address,address,address) _addresses) returns() // Solidity: function initialize(address _owner, uint32 _basefeeScalar, uint32 _blobbasefeeScalar, bytes32 _batcherHash, uint64 _gasLimit, address _unsafeBlockSigner, (uint32,uint8,uint8,uint32,uint32,uint128) _config, address _batchInbox, (address,address,address,address,address,address,address) _addresses) returns()
func (_SystemConfig *SystemConfigTransactorSession) Initialize(_roles SystemConfigRoles, _basefeeScalar uint32, _blobbasefeeScalar uint32, _gasLimit uint64, _config IResourceMeteringResourceConfig, _batchInbox common.Address, _addresses SystemConfigAddresses) (*types.Transaction, error) { func (_SystemConfig *SystemConfigTransactorSession) Initialize(_owner common.Address, _basefeeScalar uint32, _blobbasefeeScalar uint32, _batcherHash [32]byte, _gasLimit uint64, _unsafeBlockSigner common.Address, _config IResourceMeteringResourceConfig, _batchInbox common.Address, _addresses SystemConfigAddresses) (*types.Transaction, error) {
return _SystemConfig.Contract.Initialize(&_SystemConfig.TransactOpts, _roles, _basefeeScalar, _blobbasefeeScalar, _gasLimit, _config, _batchInbox, _addresses) return _SystemConfig.Contract.Initialize(&_SystemConfig.TransactOpts, _owner, _basefeeScalar, _blobbasefeeScalar, _batcherHash, _gasLimit, _unsafeBlockSigner, _config, _batchInbox, _addresses)
} }
// RenounceOwnership is a paid mutator transaction binding the contract method 0x715018a6. // RenounceOwnership is a paid mutator transaction binding the contract method 0x715018a6.
...@@ -1475,27 +1414,6 @@ func (_SystemConfig *SystemConfigTransactorSession) SetEIP1559Params(_denominato ...@@ -1475,27 +1414,6 @@ func (_SystemConfig *SystemConfigTransactorSession) SetEIP1559Params(_denominato
return _SystemConfig.Contract.SetEIP1559Params(&_SystemConfig.TransactOpts, _denominator, _elasticity) return _SystemConfig.Contract.SetEIP1559Params(&_SystemConfig.TransactOpts, _denominator, _elasticity)
} }
// SetFeeVaultConfig is a paid mutator transaction binding the contract method 0xbe4be783.
//
// Solidity: function setFeeVaultConfig(uint8 _type, address _recipient, uint256 _min, uint8 _network) returns()
func (_SystemConfig *SystemConfigTransactor) SetFeeVaultConfig(opts *bind.TransactOpts, _type uint8, _recipient common.Address, _min *big.Int, _network uint8) (*types.Transaction, error) {
return _SystemConfig.contract.Transact(opts, "setFeeVaultConfig", _type, _recipient, _min, _network)
}
// SetFeeVaultConfig is a paid mutator transaction binding the contract method 0xbe4be783.
//
// Solidity: function setFeeVaultConfig(uint8 _type, address _recipient, uint256 _min, uint8 _network) returns()
func (_SystemConfig *SystemConfigSession) SetFeeVaultConfig(_type uint8, _recipient common.Address, _min *big.Int, _network uint8) (*types.Transaction, error) {
return _SystemConfig.Contract.SetFeeVaultConfig(&_SystemConfig.TransactOpts, _type, _recipient, _min, _network)
}
// SetFeeVaultConfig is a paid mutator transaction binding the contract method 0xbe4be783.
//
// Solidity: function setFeeVaultConfig(uint8 _type, address _recipient, uint256 _min, uint8 _network) returns()
func (_SystemConfig *SystemConfigTransactorSession) SetFeeVaultConfig(_type uint8, _recipient common.Address, _min *big.Int, _network uint8) (*types.Transaction, error) {
return _SystemConfig.Contract.SetFeeVaultConfig(&_SystemConfig.TransactOpts, _type, _recipient, _min, _network)
}
// SetGasConfig is a paid mutator transaction binding the contract method 0x935f029e. // SetGasConfig is a paid mutator transaction binding the contract method 0x935f029e.
// //
// Solidity: function setGasConfig(uint256 _overhead, uint256 _scalar) returns() // Solidity: function setGasConfig(uint256 _overhead, uint256 _scalar) returns()
......
...@@ -159,21 +159,18 @@ func setCustomGasToken(t *testing.T, cfg e2esys.SystemConfig, sys *e2esys.System ...@@ -159,21 +159,18 @@ func setCustomGasToken(t *testing.T, cfg e2esys.SystemConfig, sys *e2esys.System
require.NoError(t, err) require.NoError(t, err)
// Get existing parameters from SystemConfigProxy contract // Get existing parameters from SystemConfigProxy contract
roles := bindings.SystemConfigRoles{} owner, err := systemConfig.Owner(&bind.CallOpts{})
roles.Owner, err = systemConfig.Owner(&bind.CallOpts{})
require.NoError(t, err)
roles.FeeAdmin, err = systemConfig.FeeAdmin(&bind.CallOpts{})
require.NoError(t, err)
roles.UnsafeBlockSigner, err = systemConfig.UnsafeBlockSigner(&bind.CallOpts{})
require.NoError(t, err)
roles.BatcherHash, err = systemConfig.BatcherHash(&bind.CallOpts{})
require.NoError(t, err) require.NoError(t, err)
basefeeScalar, err := systemConfig.BasefeeScalar(&bind.CallOpts{}) basefeeScalar, err := systemConfig.BasefeeScalar(&bind.CallOpts{})
require.NoError(t, err) require.NoError(t, err)
blobbasefeeScalar, err := systemConfig.BlobbasefeeScalar(&bind.CallOpts{}) blobbasefeeScalar, err := systemConfig.BlobbasefeeScalar(&bind.CallOpts{})
require.NoError(t, err) require.NoError(t, err)
batcherHash, err := systemConfig.BatcherHash(&bind.CallOpts{})
require.NoError(t, err)
gasLimit, err := systemConfig.GasLimit(&bind.CallOpts{}) gasLimit, err := systemConfig.GasLimit(&bind.CallOpts{})
require.NoError(t, err) require.NoError(t, err)
unsafeBlockSigner, err := systemConfig.UnsafeBlockSigner(&bind.CallOpts{})
require.NoError(t, err)
resourceConfig, err := systemConfig.ResourceConfig(&bind.CallOpts{}) resourceConfig, err := systemConfig.ResourceConfig(&bind.CallOpts{})
require.NoError(t, err) require.NoError(t, err)
batchInbox, err := systemConfig.BatchInbox(&bind.CallOpts{}) batchInbox, err := systemConfig.BatchInbox(&bind.CallOpts{})
...@@ -231,10 +228,12 @@ func setCustomGasToken(t *testing.T, cfg e2esys.SystemConfig, sys *e2esys.System ...@@ -231,10 +228,12 @@ func setCustomGasToken(t *testing.T, cfg e2esys.SystemConfig, sys *e2esys.System
waitForTx(t, tx, err, l1Client) waitForTx(t, tx, err, l1Client)
// Reinitialise with existing initializer values but with custom gas token set // Reinitialise with existing initializer values but with custom gas token set
tx, err = systemConfig.Initialize(deployerOpts, roles, tx, err = systemConfig.Initialize(deployerOpts, owner,
basefeeScalar, basefeeScalar,
blobbasefeeScalar, blobbasefeeScalar,
batcherHash,
gasLimit, gasLimit,
unsafeBlockSigner,
resourceConfig, resourceConfig,
batchInbox, batchInbox,
addresses) addresses)
......
...@@ -4,14 +4,14 @@ GasBenchMark_L1BlockInterop_SetValuesInterop:test_setL1BlockValuesInterop_benchm ...@@ -4,14 +4,14 @@ GasBenchMark_L1BlockInterop_SetValuesInterop:test_setL1BlockValuesInterop_benchm
GasBenchMark_L1BlockInterop_SetValuesInterop_Warm:test_setL1BlockValuesInterop_benchmark() (gas: 5099) GasBenchMark_L1BlockInterop_SetValuesInterop_Warm:test_setL1BlockValuesInterop_benchmark() (gas: 5099)
GasBenchMark_L1Block_SetValuesEcotone:test_setL1BlockValuesEcotone_benchmark() (gas: 158531) GasBenchMark_L1Block_SetValuesEcotone:test_setL1BlockValuesEcotone_benchmark() (gas: 158531)
GasBenchMark_L1Block_SetValuesEcotone_Warm:test_setL1BlockValuesEcotone_benchmark() (gas: 7597) GasBenchMark_L1Block_SetValuesEcotone_Warm:test_setL1BlockValuesEcotone_benchmark() (gas: 7597)
GasBenchMark_L1CrossDomainMessenger:test_sendMessage_benchmark_0() (gas: 367239) GasBenchMark_L1CrossDomainMessenger:test_sendMessage_benchmark_0() (gas: 369280)
GasBenchMark_L1CrossDomainMessenger:test_sendMessage_benchmark_1() (gas: 2965379) GasBenchMark_L1CrossDomainMessenger:test_sendMessage_benchmark_1() (gas: 2967420)
GasBenchMark_L1StandardBridge_Deposit:test_depositERC20_benchmark_0() (gas: 560245) GasBenchMark_L1StandardBridge_Deposit:test_depositERC20_benchmark_0() (gas: 564398)
GasBenchMark_L1StandardBridge_Deposit:test_depositERC20_benchmark_1() (gas: 4072288) GasBenchMark_L1StandardBridge_Deposit:test_depositERC20_benchmark_1() (gas: 4076613)
GasBenchMark_L1StandardBridge_Deposit:test_depositETH_benchmark_0() (gas: 462746) GasBenchMark_L1StandardBridge_Deposit:test_depositETH_benchmark_0() (gas: 467098)
GasBenchMark_L1StandardBridge_Deposit:test_depositETH_benchmark_1() (gas: 3508450) GasBenchMark_L1StandardBridge_Deposit:test_depositETH_benchmark_1() (gas: 3512802)
GasBenchMark_L1StandardBridge_Finalize:test_finalizeETHWithdrawal_benchmark() (gas: 70492) GasBenchMark_L1StandardBridge_Finalize:test_finalizeETHWithdrawal_benchmark() (gas: 72664)
GasBenchMark_L2OutputOracle:test_proposeL2Output_benchmark() (gas: 92973) GasBenchMark_L2OutputOracle:test_proposeL2Output_benchmark() (gas: 92973)
GasBenchMark_OptimismPortal:test_depositTransaction_benchmark() (gas: 68366) GasBenchMark_OptimismPortal:test_depositTransaction_benchmark() (gas: 68422)
GasBenchMark_OptimismPortal:test_depositTransaction_benchmark_1() (gas: 68930) GasBenchMark_OptimismPortal:test_depositTransaction_benchmark_1() (gas: 68986)
GasBenchMark_OptimismPortal:test_proveWithdrawalTransaction_benchmark() (gas: 155655) GasBenchMark_OptimismPortal:test_proveWithdrawalTransaction_benchmark() (gas: 155610)
\ No newline at end of file \ No newline at end of file
...@@ -27,7 +27,6 @@ ...@@ -27,7 +27,6 @@
"sequencerFeeVaultWithdrawalNetwork": 0, "sequencerFeeVaultWithdrawalNetwork": 0,
"proxyAdminOwner": "0xa0Ee7A142d267C1f36714E4a8F75612F20a79720", "proxyAdminOwner": "0xa0Ee7A142d267C1f36714E4a8F75612F20a79720",
"finalSystemOwner": "0xa0Ee7A142d267C1f36714E4a8F75612F20a79720", "finalSystemOwner": "0xa0Ee7A142d267C1f36714E4a8F75612F20a79720",
"systemConfigFeeAdmin": "0xa0Ee7A142d267C1f36714E4a8F75612F20a79720",
"superchainConfigGuardian": "0xa0Ee7A142d267C1f36714E4a8F75612F20a79720", "superchainConfigGuardian": "0xa0Ee7A142d267C1f36714E4a8F75612F20a79720",
"finalizationPeriodSeconds": 2, "finalizationPeriodSeconds": 2,
"fundDevAccounts": true, "fundDevAccounts": true,
......
{ {
"finalSystemOwner": "0x9965507D1a55bcC2695C58ba16FB37d819B0A4dc", "finalSystemOwner": "0x9965507D1a55bcC2695C58ba16FB37d819B0A4dc",
"systemConfigFeeAdmin": "0x976EA74026E726554dB657fA54763abd0C3a0aa9",
"superchainConfigGuardian": "0x9965507D1a55bcC2695C58ba16FB37d819B0A4dc", "superchainConfigGuardian": "0x9965507D1a55bcC2695C58ba16FB37d819B0A4dc",
"proxyAdminOwner": "0x9965507D1a55bcC2695C58ba16FB37d819B0A4dc", "proxyAdminOwner": "0x9965507D1a55bcC2695C58ba16FB37d819B0A4dc",
"l1StartingBlockTag": "earliest", "l1StartingBlockTag": "earliest",
......
...@@ -76,8 +76,8 @@ runs = 256 ...@@ -76,8 +76,8 @@ runs = 256
depth = 32 depth = 32
[profile.ciheavy] [profile.ciheavy]
# temp reduce fuzz runs for 1 pr
# fuzz = { runs = 20000 } # fuzz = { runs = 20000 }
# temporary reduce fuzz runs to unblock CI
fuzz = { runs = 200 } fuzz = { runs = 200 }
[profile.ciheavy.invariant] [profile.ciheavy.invariant]
......
...@@ -47,6 +47,7 @@ abstract contract Artifacts { ...@@ -47,6 +47,7 @@ abstract contract Artifacts {
/// @notice Setup function. The arguments here /// @notice Setup function. The arguments here
function setUp() public virtual { function setUp() public virtual {
deploymentOutfile = Config.deploymentOutfile(); deploymentOutfile = Config.deploymentOutfile();
console.log("Writing artifact to %s", deploymentOutfile);
ForgeArtifacts.ensurePath(deploymentOutfile); ForgeArtifacts.ensurePath(deploymentOutfile);
uint256 chainId = Config.chainID(); uint256 chainId = Config.chainID();
...@@ -182,6 +183,7 @@ abstract contract Artifacts { ...@@ -182,6 +183,7 @@ abstract contract Artifacts {
/// @param _name The name of the deployment. /// @param _name The name of the deployment.
/// @param _deployed The address of the deployment. /// @param _deployed The address of the deployment.
function save(string memory _name, address _deployed) public { function save(string memory _name, address _deployed) public {
console.log("Saving %s: %s", _name, _deployed);
if (bytes(_name).length == 0) { if (bytes(_name).length == 0) {
revert InvalidDeployment("EmptyName"); revert InvalidDeployment("EmptyName");
} }
......
...@@ -8,28 +8,27 @@ import { EIP1967Helper } from "test/mocks/EIP1967Helper.sol"; ...@@ -8,28 +8,27 @@ import { EIP1967Helper } from "test/mocks/EIP1967Helper.sol";
// Scripts // Scripts
import { Deployer } from "scripts/deploy/Deployer.sol"; import { Deployer } from "scripts/deploy/Deployer.sol";
import { Config, OutputMode, OutputModeUtils, Fork, ForkUtils, LATEST_FORK } from "scripts/libraries/Config.sol"; import { Config, OutputMode, OutputModeUtils, Fork, ForkUtils, LATEST_FORK } from "scripts/libraries/Config.sol";
import { DeployConfig } from "scripts/deploy/DeployConfig.s.sol";
import { Process } from "scripts/libraries/Process.sol"; import { Process } from "scripts/libraries/Process.sol";
import { SetPreinstalls } from "scripts/SetPreinstalls.s.sol"; import { SetPreinstalls } from "scripts/SetPreinstalls.s.sol";
// Contracts
import { SequencerFeeVault } from "src/L2/SequencerFeeVault.sol";
import { BaseFeeVault } from "src/L2/BaseFeeVault.sol";
import { L1FeeVault } from "src/L2/L1FeeVault.sol";
import { OptimismSuperchainERC20Beacon } from "src/L2/OptimismSuperchainERC20Beacon.sol";
import { OptimismMintableERC721Factory } from "src/L2/OptimismMintableERC721Factory.sol";
import { GovernanceToken } from "src/governance/GovernanceToken.sol";
import { DeployUtils } from "scripts/libraries/DeployUtils.sol"; import { DeployUtils } from "scripts/libraries/DeployUtils.sol";
// Libraries // Libraries
import { Predeploys } from "src/libraries/Predeploys.sol"; import { Predeploys } from "src/libraries/Predeploys.sol";
import { Preinstalls } from "src/libraries/Preinstalls.sol"; import { Preinstalls } from "src/libraries/Preinstalls.sol";
import { Constants } from "src/libraries/Constants.sol";
import { Encoding } from "src/libraries/Encoding.sol";
import { Types } from "src/libraries/Types.sol"; import { Types } from "src/libraries/Types.sol";
// Interfaces // Interfaces
import { ISequencerFeeVault } from "src/L2/interfaces/ISequencerFeeVault.sol";
import { IBaseFeeVault } from "src/L2/interfaces/IBaseFeeVault.sol";
import { IL1FeeVault } from "src/L2/interfaces/IL1FeeVault.sol";
import { IOptimismMintableERC721Factory } from "src/universal/interfaces/IOptimismMintableERC721Factory.sol";
import { IGovernanceToken } from "src/governance/interfaces/IGovernanceToken.sol"; import { IGovernanceToken } from "src/governance/interfaces/IGovernanceToken.sol";
import { IOptimismMintableERC20Factory } from "src/universal/interfaces/IOptimismMintableERC20Factory.sol";
import { IL2StandardBridge } from "src/L2/interfaces/IL2StandardBridge.sol";
import { IL2ERC721Bridge } from "src/L2/interfaces/IL2ERC721Bridge.sol";
import { IStandardBridge } from "src/universal/interfaces/IStandardBridge.sol";
import { ICrossDomainMessenger } from "src/universal/interfaces/ICrossDomainMessenger.sol";
import { IL2CrossDomainMessenger } from "src/L2/interfaces/IL2CrossDomainMessenger.sol";
import { IGasPriceOracle } from "src/L2/interfaces/IGasPriceOracle.sol"; import { IGasPriceOracle } from "src/L2/interfaces/IGasPriceOracle.sol";
import { IL1Block } from "src/L2/interfaces/IL1Block.sol"; import { IL1Block } from "src/L2/interfaces/IL1Block.sol";
...@@ -111,12 +110,7 @@ contract L2Genesis is Deployer { ...@@ -111,12 +110,7 @@ contract L2Genesis is Deployer {
/// Sets the precompiles, proxies, and the implementation accounts to be `vm.dumpState` /// Sets the precompiles, proxies, and the implementation accounts to be `vm.dumpState`
/// to generate a L2 genesis alloc. /// to generate a L2 genesis alloc.
function runWithStateDump() public { function runWithStateDump() public {
runWithOptions({ runWithOptions(Config.outputMode(), cfg.fork(), artifactDependencies());
_mode: Config.outputMode(),
_fork: Config.fork(),
_populateNetworkConfig: true,
_l1Dependencies: artifactDependencies()
});
} }
/// @notice Alias for `runWithStateDump` so that no `--sig` needs to be specified. /// @notice Alias for `runWithStateDump` so that no `--sig` needs to be specified.
...@@ -126,72 +120,45 @@ contract L2Genesis is Deployer { ...@@ -126,72 +120,45 @@ contract L2Genesis is Deployer {
/// @notice This is used by op-e2e to have a version of the L2 allocs for each upgrade. /// @notice This is used by op-e2e to have a version of the L2 allocs for each upgrade.
function runWithAllUpgrades() public { function runWithAllUpgrades() public {
console.log("L2Genesis: runWithAllUpgrades"); runWithOptions(OutputMode.ALL, LATEST_FORK, artifactDependencies());
runWithOptions({
_mode: OutputMode.ALL,
_fork: LATEST_FORK,
_populateNetworkConfig: true,
_l1Dependencies: artifactDependencies()
});
} }
/// @notice This is used by new experimental interop deploy tooling. /// @notice This is used by new experimental interop deploy tooling.
function runWithEnv() public { function runWithEnv() public {
// The setUp() is skipped (since we insert a custom DeployConfig, and do not use Artifacts) // The setUp() is skipped (since we insert a custom DeployConfig, and do not use Artifacts)
deployer = makeAddr("deployer"); deployer = makeAddr("deployer");
runWithOptions({ runWithOptions(
_mode: OutputMode.NONE, OutputMode.NONE,
_fork: Config.fork(), Config.fork(),
_populateNetworkConfig: false, L1Dependencies({
_l1Dependencies: L1Dependencies({
l1CrossDomainMessengerProxy: payable(vm.envAddress("L2GENESIS_L1CrossDomainMessengerProxy")), l1CrossDomainMessengerProxy: payable(vm.envAddress("L2GENESIS_L1CrossDomainMessengerProxy")),
l1StandardBridgeProxy: payable(vm.envAddress("L2GENESIS_L1StandardBridgeProxy")), l1StandardBridgeProxy: payable(vm.envAddress("L2GENESIS_L1StandardBridgeProxy")),
l1ERC721BridgeProxy: payable(vm.envAddress("L2GENESIS_L1ERC721BridgeProxy")) l1ERC721BridgeProxy: payable(vm.envAddress("L2GENESIS_L1ERC721BridgeProxy"))
}) })
}); );
} }
/// @notice This is used by foundry tests to enable the latest fork with the /// @notice This is used by foundry tests to enable the latest fork with the
/// given L1 dependencies. /// given L1 dependencies.
function runWithLatestLocal(L1Dependencies memory _l1Dependencies) public { function runWithLatestLocal(L1Dependencies memory _l1Dependencies) public {
runWithOptions({ runWithOptions(OutputMode.NONE, LATEST_FORK, _l1Dependencies);
_mode: OutputMode.NONE,
_fork: LATEST_FORK,
_populateNetworkConfig: true,
_l1Dependencies: _l1Dependencies
});
} }
/// @notice Build the L2 genesis. /// @notice Build the L2 genesis.
/// @param _mode The mode to run the script in. function runWithOptions(OutputMode _mode, Fork _fork, L1Dependencies memory _l1Dependencies) public {
/// @param _fork The fork to build the genesis for.
/// @param _populateNetworkConfig If true, the L1 Block contract will be populated with network specific
/// configuration. Otherwise, the standard genesis will be built.
function runWithOptions(
OutputMode _mode,
Fork _fork,
bool _populateNetworkConfig,
L1Dependencies memory _l1Dependencies
)
public
{
console.log("L2Genesis: outputMode: %s, fork: %s", _mode.toString(), _fork.toString()); console.log("L2Genesis: outputMode: %s, fork: %s", _mode.toString(), _fork.toString());
vm.startPrank(deployer); vm.startPrank(deployer);
vm.chainId(cfg.l2ChainID()); vm.chainId(cfg.l2ChainID());
dealEthToPrecompiles(); dealEthToPrecompiles();
setPredeployProxies(); setPredeployProxies();
setPredeployImplementations(); setPredeployImplementations(_l1Dependencies);
setPreinstalls(); setPreinstalls();
if (cfg.fundDevAccounts()) { if (cfg.fundDevAccounts()) {
fundDevAccounts(); fundDevAccounts();
} }
vm.stopPrank(); vm.stopPrank();
if (_populateNetworkConfig) {
_setNetworkConfig(_l1Dependencies, cfg);
}
if (writeForkGenesisAllocs(_fork, Fork.DELTA, _mode)) { if (writeForkGenesisAllocs(_fork, Fork.DELTA, _mode)) {
return; return;
} }
...@@ -215,59 +182,6 @@ contract L2Genesis is Deployer { ...@@ -215,59 +182,6 @@ contract L2Genesis is Deployer {
if (writeForkGenesisAllocs(_fork, Fork.HOLOCENE, _mode)) { if (writeForkGenesisAllocs(_fork, Fork.HOLOCENE, _mode)) {
return; return;
} }
if (writeForkGenesisAllocs(_fork, Fork.ISTHMUS, _mode)) {
return;
}
}
/// @notice Sets network-specific configuration in the L1Block contract
/// @param _l1Dependencies The L1 contract dependencies needed for configuration
function _setNetworkConfig(L1Dependencies memory _l1Dependencies, DeployConfig _config) internal {
console.log("L2Genesis: Modify the standard L2 genesis with network specific configuration");
vm.startPrank(Constants.DEPOSITOR_ACCOUNT);
IL1Block(Predeploys.L1_BLOCK_ATTRIBUTES).setConfig(
Types.ConfigType.L1_ERC_721_BRIDGE_ADDRESS, abi.encode(_l1Dependencies.l1ERC721BridgeProxy)
);
IL1Block(Predeploys.L1_BLOCK_ATTRIBUTES).setConfig(
Types.ConfigType.L1_CROSS_DOMAIN_MESSENGER_ADDRESS, abi.encode(_l1Dependencies.l1CrossDomainMessengerProxy)
);
IL1Block(Predeploys.L1_BLOCK_ATTRIBUTES).setConfig(
Types.ConfigType.L1_STANDARD_BRIDGE_ADDRESS, abi.encode(_l1Dependencies.l1StandardBridgeProxy)
);
IL1Block(Predeploys.L1_BLOCK_ATTRIBUTES).setConfig(
Types.ConfigType.REMOTE_CHAIN_ID, abi.encode(_config.l1ChainID())
);
bytes32 sequencerFeeVaultConfig = Encoding.encodeFeeVaultConfig({
_recipient: _config.sequencerFeeVaultRecipient(),
_amount: _config.sequencerFeeVaultMinimumWithdrawalAmount(),
_network: Types.WithdrawalNetwork(_config.sequencerFeeVaultWithdrawalNetwork())
});
IL1Block(Predeploys.L1_BLOCK_ATTRIBUTES).setConfig(
Types.ConfigType.SEQUENCER_FEE_VAULT_CONFIG, abi.encode(sequencerFeeVaultConfig)
);
bytes32 baseFeeVaultConfig = Encoding.encodeFeeVaultConfig({
_recipient: _config.baseFeeVaultRecipient(),
_amount: _config.baseFeeVaultMinimumWithdrawalAmount(),
_network: Types.WithdrawalNetwork(_config.baseFeeVaultWithdrawalNetwork())
});
IL1Block(Predeploys.L1_BLOCK_ATTRIBUTES).setConfig(
Types.ConfigType.BASE_FEE_VAULT_CONFIG, abi.encode(baseFeeVaultConfig)
);
bytes32 l1FeeVaultConfig = Encoding.encodeFeeVaultConfig({
_recipient: _config.l1FeeVaultRecipient(),
_amount: _config.l1FeeVaultMinimumWithdrawalAmount(),
_network: Types.WithdrawalNetwork(_config.l1FeeVaultWithdrawalNetwork())
});
IL1Block(Predeploys.L1_BLOCK_ATTRIBUTES).setConfig(
Types.ConfigType.L1_FEE_VAULT_CONFIG, abi.encode(l1FeeVaultConfig)
);
vm.stopPrank();
} }
function writeForkGenesisAllocs(Fork _latest, Fork _current, OutputMode _mode) internal returns (bool isLatest_) { function writeForkGenesisAllocs(Fork _latest, Fork _current, OutputMode _mode) internal returns (bool isLatest_) {
...@@ -327,20 +241,24 @@ contract L2Genesis is Deployer { ...@@ -327,20 +241,24 @@ contract L2Genesis is Deployer {
/// @notice Sets all the implementations for the predeploy proxies. For contracts without proxies, /// @notice Sets all the implementations for the predeploy proxies. For contracts without proxies,
/// sets the deployed bytecode at their expected predeploy address. /// sets the deployed bytecode at their expected predeploy address.
/// LEGACY_ERC20_ETH and L1_MESSAGE_SENDER are deprecated and are not set. /// LEGACY_ERC20_ETH and L1_MESSAGE_SENDER are deprecated and are not set.
function setPredeployImplementations() internal { function setPredeployImplementations(L1Dependencies memory _l1Dependencies) internal {
console.log("Setting predeploy implementations with L1 contract dependencies:");
console.log("- L1CrossDomainMessengerProxy: %s", _l1Dependencies.l1CrossDomainMessengerProxy);
console.log("- L1StandardBridgeProxy: %s", _l1Dependencies.l1StandardBridgeProxy);
console.log("- L1ERC721BridgeProxy: %s", _l1Dependencies.l1ERC721BridgeProxy);
setLegacyMessagePasser(); // 0 setLegacyMessagePasser(); // 0
// 01: legacy, not used in OP-Stack // 01: legacy, not used in OP-Stack
setDeployerWhitelist(); // 2 setDeployerWhitelist(); // 2
// 3,4,5: legacy, not used in OP-Stack. // 3,4,5: legacy, not used in OP-Stack.
setWETH(); // 6: WETH (not behind a proxy) setWETH(); // 6: WETH (not behind a proxy)
setL2CrossDomainMessenger(); // 7 setL2CrossDomainMessenger(_l1Dependencies.l1CrossDomainMessengerProxy); // 7
// 8,9,A,B,C,D,E: legacy, not used in OP-Stack. // 8,9,A,B,C,D,E: legacy, not used in OP-Stack.
setGasPriceOracle(); // f setGasPriceOracle(); // f
setL2StandardBridge(); // 10 setL2StandardBridge(_l1Dependencies.l1StandardBridgeProxy); // 10
setSequencerFeeVault(); // 11 setSequencerFeeVault(); // 11
setOptimismMintableERC20Factory(); // 12 setOptimismMintableERC20Factory(); // 12
setL1BlockNumber(); // 13 setL1BlockNumber(); // 13
setL2ERC721Bridge(); // 14 setL2ERC721Bridge(_l1Dependencies.l1ERC721BridgeProxy); // 14
setL1Block(); // 15 setL1Block(); // 15
setL2ToL1MessagePasser(); // 16 setL2ToL1MessagePasser(); // 16
setOptimismMintableERC721Factory(); // 17 setOptimismMintableERC721Factory(); // 17
...@@ -366,9 +284,12 @@ contract L2Genesis is Deployer { ...@@ -366,9 +284,12 @@ contract L2Genesis is Deployer {
// Note the ProxyAdmin implementation itself is behind a proxy that owns itself. // Note the ProxyAdmin implementation itself is behind a proxy that owns itself.
address impl = _setImplementationCode(Predeploys.PROXY_ADMIN); address impl = _setImplementationCode(Predeploys.PROXY_ADMIN);
// update the proxy to not be uninitialized (although not standard initialize pattern)
bytes32 _ownerSlot = bytes32(0); bytes32 _ownerSlot = bytes32(0);
vm.store(impl, _ownerSlot, bytes32(uint256(0xdead)));
// there is no initialize() function, so we just set the storage manually.
vm.store(Predeploys.PROXY_ADMIN, _ownerSlot, bytes32(uint256(uint160(cfg.proxyAdminOwner()))));
// update the proxy to not be uninitialized (although not standard initialize pattern)
vm.store(impl, _ownerSlot, bytes32(uint256(uint160(cfg.proxyAdminOwner()))));
} }
function setL2ToL1MessagePasser() public { function setL2ToL1MessagePasser() public {
...@@ -376,40 +297,102 @@ contract L2Genesis is Deployer { ...@@ -376,40 +297,102 @@ contract L2Genesis is Deployer {
} }
/// @notice This predeploy is following the safety invariant #1. /// @notice This predeploy is following the safety invariant #1.
function setL2CrossDomainMessenger() public { function setL2CrossDomainMessenger(address payable _l1CrossDomainMessengerProxy) public {
_setImplementationCode(Predeploys.L2_CROSS_DOMAIN_MESSENGER); address impl = _setImplementationCode(Predeploys.L2_CROSS_DOMAIN_MESSENGER);
IL2CrossDomainMessenger(impl).initialize({ _l1CrossDomainMessenger: ICrossDomainMessenger(address(0)) });
IL2CrossDomainMessenger(Predeploys.L2_CROSS_DOMAIN_MESSENGER).initialize({
_l1CrossDomainMessenger: ICrossDomainMessenger(_l1CrossDomainMessengerProxy)
});
} }
/// @notice This predeploy is following the safety invariant #1. /// @notice This predeploy is following the safety invariant #1.
function setL2StandardBridge() public { function setL2StandardBridge(address payable _l1StandardBridgeProxy) public {
address impl;
if (cfg.useInterop()) { if (cfg.useInterop()) {
string memory cname = "L2StandardBridgeInterop"; string memory cname = "L2StandardBridgeInterop";
address impl = Predeploys.predeployToCodeNamespace(Predeploys.L2_STANDARD_BRIDGE); impl = Predeploys.predeployToCodeNamespace(Predeploys.L2_STANDARD_BRIDGE);
console.log("Setting %s implementation at: %s", cname, impl); console.log("Setting %s implementation at: %s", cname, impl);
vm.etch(impl, vm.getDeployedCode(string.concat(cname, ".sol:", cname))); vm.etch(impl, vm.getDeployedCode(string.concat(cname, ".sol:", cname)));
} else { } else {
_setImplementationCode(Predeploys.L2_STANDARD_BRIDGE); impl = _setImplementationCode(Predeploys.L2_STANDARD_BRIDGE);
} }
IL2StandardBridge(payable(impl)).initialize({ _otherBridge: IStandardBridge(payable(address(0))) });
IL2StandardBridge(payable(Predeploys.L2_STANDARD_BRIDGE)).initialize({
_otherBridge: IStandardBridge(_l1StandardBridgeProxy)
});
} }
/// @notice This predeploy is following the safety invariant #1. /// @notice This predeploy is following the safety invariant #1.
function setL2ERC721Bridge() public { function setL2ERC721Bridge(address payable _l1ERC721BridgeProxy) public {
_setImplementationCode(Predeploys.L2_ERC721_BRIDGE); address impl = _setImplementationCode(Predeploys.L2_ERC721_BRIDGE);
IL2ERC721Bridge(impl).initialize({ _l1ERC721Bridge: payable(address(0)) });
IL2ERC721Bridge(Predeploys.L2_ERC721_BRIDGE).initialize({ _l1ERC721Bridge: payable(_l1ERC721BridgeProxy) });
} }
/// @notice This predeploy is following the safety invariant #2, /// @notice This predeploy is following the safety invariant #2,
function setSequencerFeeVault() public { function setSequencerFeeVault() public {
_setImplementationCode(Predeploys.SEQUENCER_FEE_WALLET); ISequencerFeeVault vault = ISequencerFeeVault(
DeployUtils.create1(
"SequencerFeeVault",
DeployUtils.encodeConstructor(
abi.encodeCall(
ISequencerFeeVault.__constructor__,
(
cfg.sequencerFeeVaultRecipient(),
cfg.sequencerFeeVaultMinimumWithdrawalAmount(),
Types.WithdrawalNetwork(cfg.sequencerFeeVaultWithdrawalNetwork())
)
)
)
)
);
address impl = Predeploys.predeployToCodeNamespace(Predeploys.SEQUENCER_FEE_WALLET);
console.log("Setting %s implementation at: %s", "SequencerFeeVault", impl);
vm.etch(impl, address(vault).code);
/// Reset so its not included state dump
vm.etch(address(vault), "");
vm.resetNonce(address(vault));
} }
/// @notice This predeploy is following the safety invariant #1. /// @notice This predeploy is following the safety invariant #1.
function setOptimismMintableERC20Factory() public { function setOptimismMintableERC20Factory() public {
_setImplementationCode(Predeploys.OPTIMISM_MINTABLE_ERC20_FACTORY); address impl = _setImplementationCode(Predeploys.OPTIMISM_MINTABLE_ERC20_FACTORY);
IOptimismMintableERC20Factory(impl).initialize({ _bridge: address(0) });
IOptimismMintableERC20Factory(Predeploys.OPTIMISM_MINTABLE_ERC20_FACTORY).initialize({
_bridge: Predeploys.L2_STANDARD_BRIDGE
});
} }
/// @notice This predeploy is following the safety invariant #2, /// @notice This predeploy is following the safety invariant #2,
function setOptimismMintableERC721Factory() public { function setOptimismMintableERC721Factory() public {
_setImplementationCode(Predeploys.OPTIMISM_MINTABLE_ERC721_FACTORY); IOptimismMintableERC721Factory factory = IOptimismMintableERC721Factory(
DeployUtils.create1(
"OptimismMintableERC721Factory",
DeployUtils.encodeConstructor(
abi.encodeCall(
IOptimismMintableERC721Factory.__constructor__, (Predeploys.L2_ERC721_BRIDGE, cfg.l1ChainID())
)
)
)
);
address impl = Predeploys.predeployToCodeNamespace(Predeploys.OPTIMISM_MINTABLE_ERC721_FACTORY);
console.log("Setting %s implementation at: %s", "OptimismMintableERC721Factory", impl);
vm.etch(impl, address(factory).code);
/// Reset so its not included state dump
vm.etch(address(factory), "");
vm.resetNonce(address(factory));
} }
/// @notice This predeploy is following the safety invariant #1. /// @notice This predeploy is following the safety invariant #1.
...@@ -456,12 +439,56 @@ contract L2Genesis is Deployer { ...@@ -456,12 +439,56 @@ contract L2Genesis is Deployer {
/// @notice This predeploy is following the safety invariant #2. /// @notice This predeploy is following the safety invariant #2.
function setBaseFeeVault() public { function setBaseFeeVault() public {
_setImplementationCode(Predeploys.BASE_FEE_VAULT); IBaseFeeVault vault = IBaseFeeVault(
DeployUtils.create1(
"BaseFeeVault",
DeployUtils.encodeConstructor(
abi.encodeCall(
IBaseFeeVault.__constructor__,
(
cfg.baseFeeVaultRecipient(),
cfg.baseFeeVaultMinimumWithdrawalAmount(),
Types.WithdrawalNetwork(cfg.baseFeeVaultWithdrawalNetwork())
)
)
)
)
);
address impl = Predeploys.predeployToCodeNamespace(Predeploys.BASE_FEE_VAULT);
console.log("Setting %s implementation at: %s", "BaseFeeVault", impl);
vm.etch(impl, address(vault).code);
/// Reset so its not included state dump
vm.etch(address(vault), "");
vm.resetNonce(address(vault));
} }
/// @notice This predeploy is following the safety invariant #2. /// @notice This predeploy is following the safety invariant #2.
function setL1FeeVault() public { function setL1FeeVault() public {
_setImplementationCode(Predeploys.L1_FEE_VAULT); IL1FeeVault vault = IL1FeeVault(
DeployUtils.create1(
"L1FeeVault",
DeployUtils.encodeConstructor(
abi.encodeCall(
IL1FeeVault.__constructor__,
(
cfg.l1FeeVaultRecipient(),
cfg.l1FeeVaultMinimumWithdrawalAmount(),
Types.WithdrawalNetwork(cfg.l1FeeVaultWithdrawalNetwork())
)
)
)
)
);
address impl = Predeploys.predeployToCodeNamespace(Predeploys.L1_FEE_VAULT);
console.log("Setting %s implementation at: %s", "L1FeeVault", impl);
vm.etch(impl, address(vault).code);
/// Reset so its not included state dump
vm.etch(address(vault), "");
vm.resetNonce(address(vault));
} }
/// @notice This predeploy is following the safety invariant #2. /// @notice This predeploy is following the safety invariant #2.
......
...@@ -13,7 +13,6 @@ import { ISystemConfigInterop } from "src/L1/interfaces/ISystemConfigInterop.sol ...@@ -13,7 +13,6 @@ import { ISystemConfigInterop } from "src/L1/interfaces/ISystemConfigInterop.sol
import { Constants } from "src/libraries/Constants.sol"; import { Constants } from "src/libraries/Constants.sol";
import { Predeploys } from "src/libraries/Predeploys.sol"; import { Predeploys } from "src/libraries/Predeploys.sol";
import { Types } from "scripts/libraries/Types.sol"; import { Types } from "scripts/libraries/Types.sol";
import { DeployUtils } from "scripts/libraries/DeployUtils.sol";
// Interfaces // Interfaces
import { IResourceMetering } from "src/L1/interfaces/IResourceMetering.sol"; import { IResourceMetering } from "src/L1/interfaces/IResourceMetering.sol";
...@@ -41,7 +40,8 @@ library ChainAssertions { ...@@ -41,7 +40,8 @@ library ChainAssertions {
function postDeployAssertions( function postDeployAssertions(
Types.ContractSet memory _prox, Types.ContractSet memory _prox,
DeployConfig _cfg, DeployConfig _cfg,
uint256 _l2OutputOracleStartingTimestamp uint256 _l2OutputOracleStartingTimestamp,
Vm _vm
) )
internal internal
view view
...@@ -52,7 +52,7 @@ library ChainAssertions { ...@@ -52,7 +52,7 @@ library ChainAssertions {
require(keccak256(abi.encode(rcfg)) == keccak256(abi.encode(dflt))); require(keccak256(abi.encode(rcfg)) == keccak256(abi.encode(dflt)));
checkSystemConfig({ _contracts: _prox, _cfg: _cfg, _isProxy: true }); checkSystemConfig({ _contracts: _prox, _cfg: _cfg, _isProxy: true });
checkL1CrossDomainMessenger({ _contracts: _prox, _isProxy: true }); checkL1CrossDomainMessenger({ _contracts: _prox, _vm: _vm, _isProxy: true });
checkL1StandardBridge({ _contracts: _prox, _isProxy: true }); checkL1StandardBridge({ _contracts: _prox, _isProxy: true });
checkL2OutputOracle({ checkL2OutputOracle({
_contracts: _prox, _contracts: _prox,
...@@ -77,7 +77,7 @@ library ChainAssertions { ...@@ -77,7 +77,7 @@ library ChainAssertions {
); );
// Check that the contract is initialized // Check that the contract is initialized
DeployUtils.assertInitialized({ _contractAddress: address(config), _slot: 0, _offset: 0 }); assertInitializedSlotIsSet({ _contractAddress: address(config), _slot: 0, _offset: 0 });
IResourceMetering.ResourceConfig memory resourceConfig = config.resourceConfig(); IResourceMetering.ResourceConfig memory resourceConfig = config.resourceConfig();
...@@ -109,18 +109,18 @@ library ChainAssertions { ...@@ -109,18 +109,18 @@ library ChainAssertions {
require(config.optimismPortal() == _contracts.OptimismPortal, "CHECK-SCFG-200"); require(config.optimismPortal() == _contracts.OptimismPortal, "CHECK-SCFG-200");
require(config.optimismMintableERC20Factory() == _contracts.OptimismMintableERC20Factory, "CHECK-SCFG-210"); require(config.optimismMintableERC20Factory() == _contracts.OptimismMintableERC20Factory, "CHECK-SCFG-210");
} else { } else {
require(config.owner() == address(0), "CHECK-SCFG-220"); require(config.owner() == address(0xdead), "CHECK-SCFG-220");
require(config.overhead() == 0, "CHECK-SCFG-230"); require(config.overhead() == 0, "CHECK-SCFG-230");
require(config.scalar() == 0, "CHECK-SCFG-240"); require(config.scalar() == uint256(0x01) << 248, "CHECK-SCFG-240"); // version 1
require(config.basefeeScalar() == 0, "CHECK-SCFG-250"); require(config.basefeeScalar() == 0, "CHECK-SCFG-250");
require(config.blobbasefeeScalar() == 0, "CHECK-SCFG-260"); require(config.blobbasefeeScalar() == 0, "CHECK-SCFG-260");
require(config.batcherHash() == bytes32(0), "CHECK-SCFG-270"); require(config.batcherHash() == bytes32(0), "CHECK-SCFG-270");
require(config.gasLimit() == 0, "CHECK-SCFG-280"); require(config.gasLimit() == 1, "CHECK-SCFG-280");
require(config.unsafeBlockSigner() == address(0), "CHECK-SCFG-290"); require(config.unsafeBlockSigner() == address(0), "CHECK-SCFG-290");
// Check _config // Check _config
require(resourceConfig.maxResourceLimit == 0, "CHECK-SCFG-300"); require(resourceConfig.maxResourceLimit == 1, "CHECK-SCFG-300");
require(resourceConfig.elasticityMultiplier == 0, "CHECK-SCFG-310"); require(resourceConfig.elasticityMultiplier == 1, "CHECK-SCFG-310");
require(resourceConfig.baseFeeMaxChangeDenominator == 0, "CHECK-SCFG-320"); require(resourceConfig.baseFeeMaxChangeDenominator == 2, "CHECK-SCFG-320");
require(resourceConfig.systemTxMaxGas == 0, "CHECK-SCFG-330"); require(resourceConfig.systemTxMaxGas == 0, "CHECK-SCFG-330");
require(resourceConfig.minimumBaseFee == 0, "CHECK-SCFG-340"); require(resourceConfig.minimumBaseFee == 0, "CHECK-SCFG-340");
require(resourceConfig.maximumBaseFee == 0, "CHECK-SCFG-350"); require(resourceConfig.maximumBaseFee == 0, "CHECK-SCFG-350");
...@@ -163,7 +163,7 @@ library ChainAssertions { ...@@ -163,7 +163,7 @@ library ChainAssertions {
} }
/// @notice Asserts that the L1CrossDomainMessenger is setup correctly /// @notice Asserts that the L1CrossDomainMessenger is setup correctly
function checkL1CrossDomainMessenger(Types.ContractSet memory _contracts, bool _isProxy) internal view { function checkL1CrossDomainMessenger(Types.ContractSet memory _contracts, Vm _vm, bool _isProxy) internal view {
IL1CrossDomainMessenger messenger = IL1CrossDomainMessenger(_contracts.L1CrossDomainMessenger); IL1CrossDomainMessenger messenger = IL1CrossDomainMessenger(_contracts.L1CrossDomainMessenger);
console.log( console.log(
"Running chain assertions on the L1CrossDomainMessenger %s at %s", "Running chain assertions on the L1CrossDomainMessenger %s at %s",
...@@ -173,7 +173,7 @@ library ChainAssertions { ...@@ -173,7 +173,7 @@ library ChainAssertions {
require(address(messenger) != address(0), "CHECK-L1XDM-10"); require(address(messenger) != address(0), "CHECK-L1XDM-10");
// Check that the contract is initialized // Check that the contract is initialized
DeployUtils.assertInitialized({ _contractAddress: address(messenger), _slot: 250, _offset: 0 }); assertInitializedSlotIsSet({ _contractAddress: address(messenger), _slot: 0, _offset: 20 });
require(address(messenger.OTHER_MESSENGER()) == Predeploys.L2_CROSS_DOMAIN_MESSENGER, "CHECK-L1XDM-20"); require(address(messenger.OTHER_MESSENGER()) == Predeploys.L2_CROSS_DOMAIN_MESSENGER, "CHECK-L1XDM-20");
require(address(messenger.otherMessenger()) == Predeploys.L2_CROSS_DOMAIN_MESSENGER, "CHECK-L1XDM-30"); require(address(messenger.otherMessenger()) == Predeploys.L2_CROSS_DOMAIN_MESSENGER, "CHECK-L1XDM-30");
...@@ -182,6 +182,8 @@ library ChainAssertions { ...@@ -182,6 +182,8 @@ library ChainAssertions {
require(address(messenger.PORTAL()) == _contracts.OptimismPortal, "CHECK-L1XDM-40"); require(address(messenger.PORTAL()) == _contracts.OptimismPortal, "CHECK-L1XDM-40");
require(address(messenger.portal()) == _contracts.OptimismPortal, "CHECK-L1XDM-50"); require(address(messenger.portal()) == _contracts.OptimismPortal, "CHECK-L1XDM-50");
require(address(messenger.superchainConfig()) == _contracts.SuperchainConfig, "CHECK-L1XDM-60"); require(address(messenger.superchainConfig()) == _contracts.SuperchainConfig, "CHECK-L1XDM-60");
bytes32 xdmSenderSlot = _vm.load(address(messenger), bytes32(uint256(204)));
require(address(uint160(uint256(xdmSenderSlot))) == Constants.DEFAULT_L2_SENDER, "CHECK-L1XDM-70");
} else { } else {
require(address(messenger.PORTAL()) == address(0), "CHECK-L1XDM-80"); require(address(messenger.PORTAL()) == address(0), "CHECK-L1XDM-80");
require(address(messenger.portal()) == address(0), "CHECK-L1XDM-90"); require(address(messenger.portal()) == address(0), "CHECK-L1XDM-90");
...@@ -200,7 +202,7 @@ library ChainAssertions { ...@@ -200,7 +202,7 @@ library ChainAssertions {
require(address(bridge) != address(0), "CHECK-L1SB-10"); require(address(bridge) != address(0), "CHECK-L1SB-10");
// Check that the contract is initialized // Check that the contract is initialized
DeployUtils.assertInitialized({ _contractAddress: address(bridge), _slot: 49, _offset: 0 }); assertInitializedSlotIsSet({ _contractAddress: address(bridge), _slot: 0, _offset: 0 });
if (_isProxy) { if (_isProxy) {
require(address(bridge.MESSENGER()) == _contracts.L1CrossDomainMessenger, "CHECK-L1SB-20"); require(address(bridge.MESSENGER()) == _contracts.L1CrossDomainMessenger, "CHECK-L1SB-20");
...@@ -235,7 +237,7 @@ library ChainAssertions { ...@@ -235,7 +237,7 @@ library ChainAssertions {
require(address(factory) != address(0), "CHECK-DG-10"); require(address(factory) != address(0), "CHECK-DG-10");
// Check that the contract is initialized // Check that the contract is initialized
DeployUtils.assertInitialized({ _contractAddress: address(factory), _slot: 0, _offset: 0 }); assertInitializedSlotIsSet({ _contractAddress: address(factory), _slot: 0, _offset: 0 });
// The same check is made for both proxy and implementation // The same check is made for both proxy and implementation
require(factory.owner() == _expectedOwner, "CHECK-DG-20"); require(factory.owner() == _expectedOwner, "CHECK-DG-20");
...@@ -275,7 +277,7 @@ library ChainAssertions { ...@@ -275,7 +277,7 @@ library ChainAssertions {
require(address(weth) != address(0), "CHECK-DWETH-10"); require(address(weth) != address(0), "CHECK-DWETH-10");
// Check that the contract is initialized // Check that the contract is initialized
DeployUtils.assertInitialized({ _contractAddress: address(weth), _slot: 0, _offset: 0 }); assertInitializedSlotIsSet({ _contractAddress: address(weth), _slot: 0, _offset: 0 });
if (_isProxy) { if (_isProxy) {
require(weth.owner() == _expectedOwner, "CHECK-DWETH-20"); require(weth.owner() == _expectedOwner, "CHECK-DWETH-20");
...@@ -306,7 +308,7 @@ library ChainAssertions { ...@@ -306,7 +308,7 @@ library ChainAssertions {
require(address(weth) != address(0), "CHECK-PDWETH-10"); require(address(weth) != address(0), "CHECK-PDWETH-10");
// Check that the contract is initialized // Check that the contract is initialized
DeployUtils.assertInitialized({ _contractAddress: address(weth), _slot: 0, _offset: 0 }); assertInitializedSlotIsSet({ _contractAddress: address(weth), _slot: 0, _offset: 0 });
if (_isProxy) { if (_isProxy) {
require(weth.owner() == _expectedOwner, "CHECK-PDWETH-20"); require(weth.owner() == _expectedOwner, "CHECK-PDWETH-20");
...@@ -337,7 +339,7 @@ library ChainAssertions { ...@@ -337,7 +339,7 @@ library ChainAssertions {
require(address(oracle) != address(0), "CHECK-L2OO-10"); require(address(oracle) != address(0), "CHECK-L2OO-10");
// Check that the contract is initialized // Check that the contract is initialized
DeployUtils.assertInitialized({ _contractAddress: address(oracle), _slot: 0, _offset: 0 }); assertInitializedSlotIsSet({ _contractAddress: address(oracle), _slot: 0, _offset: 0 });
if (_isProxy) { if (_isProxy) {
require(oracle.SUBMISSION_INTERVAL() == _cfg.l2OutputOracleSubmissionInterval(), "CHECK-L2OO-20"); require(oracle.SUBMISSION_INTERVAL() == _cfg.l2OutputOracleSubmissionInterval(), "CHECK-L2OO-20");
...@@ -379,7 +381,7 @@ library ChainAssertions { ...@@ -379,7 +381,7 @@ library ChainAssertions {
require(address(factory) != address(0), "CHECK-MERC20F-10"); require(address(factory) != address(0), "CHECK-MERC20F-10");
// Check that the contract is initialized // Check that the contract is initialized
DeployUtils.assertInitialized({ _contractAddress: address(factory), _slot: 51, _offset: 0 }); assertInitializedSlotIsSet({ _contractAddress: address(factory), _slot: 0, _offset: 0 });
if (_isProxy) { if (_isProxy) {
require(factory.BRIDGE() == _contracts.L1StandardBridge, "CHECK-MERC20F-10"); require(factory.BRIDGE() == _contracts.L1StandardBridge, "CHECK-MERC20F-10");
...@@ -402,7 +404,7 @@ library ChainAssertions { ...@@ -402,7 +404,7 @@ library ChainAssertions {
require(address(bridge) != address(0), "CHECK-L1ERC721B-10"); require(address(bridge) != address(0), "CHECK-L1ERC721B-10");
// Check that the contract is initialized // Check that the contract is initialized
DeployUtils.assertInitialized({ _contractAddress: address(bridge) }); assertInitializedSlotIsSet({ _contractAddress: address(bridge), _slot: 0, _offset: 0 });
require(address(bridge.OTHER_BRIDGE()) == Predeploys.L2_ERC721_BRIDGE, "CHECK-L1ERC721B-10"); require(address(bridge.OTHER_BRIDGE()) == Predeploys.L2_ERC721_BRIDGE, "CHECK-L1ERC721B-10");
require(address(bridge.otherBridge()) == Predeploys.L2_ERC721_BRIDGE, "CHECK-L1ERC721B-20"); require(address(bridge.otherBridge()) == Predeploys.L2_ERC721_BRIDGE, "CHECK-L1ERC721B-20");
...@@ -429,7 +431,7 @@ library ChainAssertions { ...@@ -429,7 +431,7 @@ library ChainAssertions {
require(address(portal) != address(0), "CHECK-OP-10"); require(address(portal) != address(0), "CHECK-OP-10");
// Check that the contract is initialized // Check that the contract is initialized
DeployUtils.assertInitialized({ _contractAddress: address(portal), _slot: 0, _offset: 0 }); assertInitializedSlotIsSet({ _contractAddress: address(portal), _slot: 0, _offset: 0 });
address guardian = _cfg.superchainConfigGuardian(); address guardian = _cfg.superchainConfigGuardian();
if (guardian.code.length == 0) { if (guardian.code.length == 0) {
...@@ -469,7 +471,7 @@ library ChainAssertions { ...@@ -469,7 +471,7 @@ library ChainAssertions {
require(address(portal) != address(0), "CHECK-OP2-10"); require(address(portal) != address(0), "CHECK-OP2-10");
// Check that the contract is initialized // Check that the contract is initialized
DeployUtils.assertInitialized({ _contractAddress: address(portal), _slot: 0, _offset: 0 }); assertInitializedSlotIsSet({ _contractAddress: address(portal), _slot: 0, _offset: 0 });
address guardian = _cfg.superchainConfigGuardian(); address guardian = _cfg.superchainConfigGuardian();
if (guardian.code.length == 0) { if (guardian.code.length == 0) {
...@@ -512,7 +514,7 @@ library ChainAssertions { ...@@ -512,7 +514,7 @@ library ChainAssertions {
require(address(versions) != address(0), "CHECK-PV-10"); require(address(versions) != address(0), "CHECK-PV-10");
// Check that the contract is initialized // Check that the contract is initialized
DeployUtils.assertInitialized({ _contractAddress: address(versions), _slot: 0, _offset: 0 }); assertInitializedSlotIsSet({ _contractAddress: address(versions), _slot: 0, _offset: 0 });
if (_isProxy) { if (_isProxy) {
require(versions.owner() == _cfg.finalSystemOwner(), "CHECK-PV-20"); require(versions.owner() == _cfg.finalSystemOwner(), "CHECK-PV-20");
...@@ -544,7 +546,7 @@ library ChainAssertions { ...@@ -544,7 +546,7 @@ library ChainAssertions {
require(address(superchainConfig) != address(0), "CHECK-SC-10"); require(address(superchainConfig) != address(0), "CHECK-SC-10");
// Check that the contract is initialized // Check that the contract is initialized
DeployUtils.assertInitialized({ _contractAddress: address(superchainConfig), _slot: 0, _offset: 0 }); assertInitializedSlotIsSet({ _contractAddress: address(superchainConfig), _slot: 0, _offset: 0 });
if (_isProxy) { if (_isProxy) {
require(superchainConfig.guardian() == _cfg.superchainConfigGuardian(), "CHECK-SC-20"); require(superchainConfig.guardian() == _cfg.superchainConfigGuardian(), "CHECK-SC-20");
...@@ -566,7 +568,7 @@ library ChainAssertions { ...@@ -566,7 +568,7 @@ library ChainAssertions {
require(address(opcm) != address(0), "CHECK-OPCM-10"); require(address(opcm) != address(0), "CHECK-OPCM-10");
// Check that the contract is initialized // Check that the contract is initialized
DeployUtils.assertInitialized({ _contractAddress: address(opcm), _slot: 0, _offset: 0 }); assertInitializedSlotIsSet({ _contractAddress: address(opcm), _slot: 0, _offset: 0 });
// These values are immutable so are shared by the proxy and implementation // These values are immutable so are shared by the proxy and implementation
require(address(opcm.superchainConfig()) == address(_contracts.SuperchainConfig), "CHECK-OPCM-30"); require(address(opcm.superchainConfig()) == address(_contracts.SuperchainConfig), "CHECK-OPCM-30");
...@@ -574,4 +576,15 @@ library ChainAssertions { ...@@ -574,4 +576,15 @@ library ChainAssertions {
// TODO: Add assertions for blueprints and setters? // TODO: Add assertions for blueprints and setters?
} }
/// @dev Asserts that for a given contract the value of a storage slot at an offset is 1 or 0xff.
/// A call to `initialize` will set it to 1 and a call to _disableInitializers will set it to 0xff.
function assertInitializedSlotIsSet(address _contractAddress, uint256 _slot, uint256 _offset) internal view {
bytes32 slotVal = vm.load(_contractAddress, bytes32(_slot));
uint8 val = uint8((uint256(slotVal) >> (_offset * 8)) & 0xFF);
require(
val == uint8(1) || val == uint8(0xff),
"ChainAssertions: storage value is not 1 or 0xff at the given slot and offset"
);
}
} }
...@@ -155,7 +155,7 @@ contract Deploy is Deployer { ...@@ -155,7 +155,7 @@ contract Deploy is Deployer {
DelayedWETH: getAddress("DelayedWETHProxy"), DelayedWETH: getAddress("DelayedWETHProxy"),
PermissionedDelayedWETH: getAddress("PermissionedDelayedWETHProxy"), PermissionedDelayedWETH: getAddress("PermissionedDelayedWETHProxy"),
AnchorStateRegistry: getAddress("AnchorStateRegistryProxy"), AnchorStateRegistry: getAddress("AnchorStateRegistryProxy"),
OptimismMintableERC20Factory: getAddress("L1OptimismMintableERC20FactoryProxy"), OptimismMintableERC20Factory: getAddress("OptimismMintableERC20FactoryProxy"),
OptimismPortal: getAddress("OptimismPortalProxy"), OptimismPortal: getAddress("OptimismPortalProxy"),
OptimismPortal2: getAddress("OptimismPortalProxy"), OptimismPortal2: getAddress("OptimismPortalProxy"),
SystemConfig: getAddress("SystemConfigProxy"), SystemConfig: getAddress("SystemConfigProxy"),
...@@ -176,7 +176,7 @@ contract Deploy is Deployer { ...@@ -176,7 +176,7 @@ contract Deploy is Deployer {
DelayedWETH: getAddress("DelayedWETH"), DelayedWETH: getAddress("DelayedWETH"),
PermissionedDelayedWETH: getAddress("PermissionedDelayedWETH"), PermissionedDelayedWETH: getAddress("PermissionedDelayedWETH"),
AnchorStateRegistry: getAddress("AnchorStateRegistry"), AnchorStateRegistry: getAddress("AnchorStateRegistry"),
OptimismMintableERC20Factory: getAddress("L1OptimismMintableERC20Factory"), OptimismMintableERC20Factory: getAddress("OptimismMintableERC20Factory"),
OptimismPortal: getAddress("OptimismPortal"), OptimismPortal: getAddress("OptimismPortal"),
OptimismPortal2: getAddress("OptimismPortal2"), OptimismPortal2: getAddress("OptimismPortal2"),
SystemConfig: getAddress("SystemConfig"), SystemConfig: getAddress("SystemConfig"),
...@@ -398,9 +398,7 @@ contract Deploy is Deployer { ...@@ -398,9 +398,7 @@ contract Deploy is Deployer {
} }
save("L1CrossDomainMessenger", address(dio.l1CrossDomainMessengerImpl())); save("L1CrossDomainMessenger", address(dio.l1CrossDomainMessengerImpl()));
// Save under both names for backwards compatibility
save("OptimismMintableERC20Factory", address(dio.optimismMintableERC20FactoryImpl())); save("OptimismMintableERC20Factory", address(dio.optimismMintableERC20FactoryImpl()));
save("L1OptimismMintableERC20Factory", address(dio.optimismMintableERC20FactoryImpl()));
save("SystemConfig", address(dio.systemConfigImpl())); save("SystemConfig", address(dio.systemConfigImpl()));
save("L1StandardBridge", address(dio.l1StandardBridgeImpl())); save("L1StandardBridge", address(dio.l1StandardBridgeImpl()));
save("L1ERC721Bridge", address(dio.l1ERC721BridgeImpl())); save("L1ERC721Bridge", address(dio.l1ERC721BridgeImpl()));
...@@ -415,7 +413,7 @@ contract Deploy is Deployer { ...@@ -415,7 +413,7 @@ contract Deploy is Deployer {
save("OPContractsManager", address(dio.opcmImpl())); save("OPContractsManager", address(dio.opcmImpl()));
Types.ContractSet memory contracts = _impls(); Types.ContractSet memory contracts = _impls();
ChainAssertions.checkL1CrossDomainMessenger({ _contracts: contracts, _isProxy: false }); ChainAssertions.checkL1CrossDomainMessenger({ _contracts: contracts, _vm: vm, _isProxy: false });
ChainAssertions.checkL1StandardBridge({ _contracts: contracts, _isProxy: false }); ChainAssertions.checkL1StandardBridge({ _contracts: contracts, _isProxy: false });
ChainAssertions.checkL1ERC721Bridge({ _contracts: contracts, _isProxy: false }); ChainAssertions.checkL1ERC721Bridge({ _contracts: contracts, _isProxy: false });
ChainAssertions.checkOptimismPortal2({ _contracts: contracts, _cfg: cfg, _isProxy: false }); ChainAssertions.checkOptimismPortal2({ _contracts: contracts, _cfg: cfg, _isProxy: false });
...@@ -458,9 +456,7 @@ contract Deploy is Deployer { ...@@ -458,9 +456,7 @@ contract Deploy is Deployer {
save("AddressManager", address(deployOutput.addressManager)); save("AddressManager", address(deployOutput.addressManager));
save("L1ERC721BridgeProxy", address(deployOutput.l1ERC721BridgeProxy)); save("L1ERC721BridgeProxy", address(deployOutput.l1ERC721BridgeProxy));
save("SystemConfigProxy", address(deployOutput.systemConfigProxy)); save("SystemConfigProxy", address(deployOutput.systemConfigProxy));
// Save under both names for backwards compatibility
save("OptimismMintableERC20FactoryProxy", address(deployOutput.optimismMintableERC20FactoryProxy)); save("OptimismMintableERC20FactoryProxy", address(deployOutput.optimismMintableERC20FactoryProxy));
save("L1OptimismMintableERC20FactoryProxy", address(deployOutput.optimismMintableERC20FactoryProxy));
save("L1StandardBridgeProxy", address(deployOutput.l1StandardBridgeProxy)); save("L1StandardBridgeProxy", address(deployOutput.l1StandardBridgeProxy));
save("L1CrossDomainMessengerProxy", address(deployOutput.l1CrossDomainMessengerProxy)); save("L1CrossDomainMessengerProxy", address(deployOutput.l1CrossDomainMessengerProxy));
...@@ -827,15 +823,12 @@ contract Deploy is Deployer { ...@@ -827,15 +823,12 @@ contract Deploy is Deployer {
_data: abi.encodeCall( _data: abi.encodeCall(
ISystemConfig.initialize, ISystemConfig.initialize,
( (
ISystemConfig.Roles({ cfg.finalSystemOwner(),
owner: cfg.finalSystemOwner(),
feeAdmin: cfg.systemConfigFeeAdmin(),
unsafeBlockSigner: cfg.p2pSequencerAddress(),
batcherHash: batcherHash
}),
cfg.basefeeScalar(), cfg.basefeeScalar(),
cfg.blobbasefeeScalar(), cfg.blobbasefeeScalar(),
batcherHash,
uint64(cfg.l2GenesisBlockGasLimit()), uint64(cfg.l2GenesisBlockGasLimit()),
cfg.p2pSequencerAddress(),
Constants.DEFAULT_RESOURCE_CONFIG(), Constants.DEFAULT_RESOURCE_CONFIG(),
cfg.batchInboxAddress(), cfg.batchInboxAddress(),
ISystemConfig.Addresses({ ISystemConfig.Addresses({
...@@ -844,7 +837,7 @@ contract Deploy is Deployer { ...@@ -844,7 +837,7 @@ contract Deploy is Deployer {
l1StandardBridge: mustGetAddress("L1StandardBridgeProxy"), l1StandardBridge: mustGetAddress("L1StandardBridgeProxy"),
disputeGameFactory: mustGetAddress("DisputeGameFactoryProxy"), disputeGameFactory: mustGetAddress("DisputeGameFactoryProxy"),
optimismPortal: mustGetAddress("OptimismPortalProxy"), optimismPortal: mustGetAddress("OptimismPortalProxy"),
optimismMintableERC20Factory: mustGetAddress("L1OptimismMintableERC20FactoryProxy"), optimismMintableERC20Factory: mustGetAddress("OptimismMintableERC20FactoryProxy"),
gasPayingToken: customGasTokenAddress gasPayingToken: customGasTokenAddress
}) })
) )
...@@ -1271,8 +1264,7 @@ contract Deploy is Deployer { ...@@ -1271,8 +1264,7 @@ contract Deploy is Deployer {
batcher: cfg.batchSenderAddress(), batcher: cfg.batchSenderAddress(),
unsafeBlockSigner: cfg.p2pSequencerAddress(), unsafeBlockSigner: cfg.p2pSequencerAddress(),
proposer: cfg.l2OutputOracleProposer(), proposer: cfg.l2OutputOracleProposer(),
challenger: cfg.l2OutputOracleChallenger(), challenger: cfg.l2OutputOracleChallenger()
systemConfigFeeAdmin: cfg.systemConfigFeeAdmin()
}), }),
basefeeScalar: cfg.basefeeScalar(), basefeeScalar: cfg.basefeeScalar(),
blobBasefeeScalar: cfg.blobbasefeeScalar(), blobBasefeeScalar: cfg.blobbasefeeScalar(),
......
...@@ -86,7 +86,6 @@ contract DeployConfig is Script { ...@@ -86,7 +86,6 @@ contract DeployConfig is Script {
uint256 public daResolveWindow; uint256 public daResolveWindow;
uint256 public daBondSize; uint256 public daBondSize;
uint256 public daResolverRefundPercentage; uint256 public daResolverRefundPercentage;
address public systemConfigFeeAdmin;
bool public useCustomGasToken; bool public useCustomGasToken;
address public customGasTokenAddress; address public customGasTokenAddress;
...@@ -102,7 +101,6 @@ contract DeployConfig is Script { ...@@ -102,7 +101,6 @@ contract DeployConfig is Script {
} }
finalSystemOwner = stdJson.readAddress(_json, "$.finalSystemOwner"); finalSystemOwner = stdJson.readAddress(_json, "$.finalSystemOwner");
systemConfigFeeAdmin = stdJson.readAddress(_json, "$.systemConfigFeeAdmin");
superchainConfigGuardian = stdJson.readAddress(_json, "$.superchainConfigGuardian"); superchainConfigGuardian = stdJson.readAddress(_json, "$.superchainConfigGuardian");
l1ChainID = stdJson.readUint(_json, "$.l1ChainID"); l1ChainID = stdJson.readUint(_json, "$.l1ChainID");
l2ChainID = stdJson.readUint(_json, "$.l2ChainID"); l2ChainID = stdJson.readUint(_json, "$.l2ChainID");
......
...@@ -29,8 +29,7 @@ import { ISystemConfig } from "src/L1/interfaces/ISystemConfig.sol"; ...@@ -29,8 +29,7 @@ import { ISystemConfig } from "src/L1/interfaces/ISystemConfig.sol";
import { IL1CrossDomainMessenger } from "src/L1/interfaces/IL1CrossDomainMessenger.sol"; import { IL1CrossDomainMessenger } from "src/L1/interfaces/IL1CrossDomainMessenger.sol";
import { IL1ERC721Bridge } from "src/L1/interfaces/IL1ERC721Bridge.sol"; import { IL1ERC721Bridge } from "src/L1/interfaces/IL1ERC721Bridge.sol";
import { IL1StandardBridge } from "src/L1/interfaces/IL1StandardBridge.sol"; import { IL1StandardBridge } from "src/L1/interfaces/IL1StandardBridge.sol";
import { IL1OptimismMintableERC20Factory as IOptimismMintableERC20Factory } from import { IOptimismMintableERC20Factory } from "src/universal/interfaces/IOptimismMintableERC20Factory.sol";
"src/L1/interfaces/IL1OptimismMintableERC20Factory.sol";
import { OPContractsManagerInterop } from "src/L1/OPContractsManagerInterop.sol"; import { OPContractsManagerInterop } from "src/L1/OPContractsManagerInterop.sol";
import { IOptimismPortalInterop } from "src/L1/interfaces/IOptimismPortalInterop.sol"; import { IOptimismPortalInterop } from "src/L1/interfaces/IOptimismPortalInterop.sol";
...@@ -371,19 +370,19 @@ contract DeployImplementationsOutput is BaseDeployIO { ...@@ -371,19 +370,19 @@ contract DeployImplementationsOutput is BaseDeployIO {
DeployUtils.assertInitialized({ _contractAddress: address(systemConfig), _slot: 0, _offset: 0 }); DeployUtils.assertInitialized({ _contractAddress: address(systemConfig), _slot: 0, _offset: 0 });
require(systemConfig.owner() == address(0), "SYSCON-10"); require(systemConfig.owner() == address(0xdead), "SYSCON-10");
require(systemConfig.overhead() == 0, "SYSCON-20"); require(systemConfig.overhead() == 0, "SYSCON-20");
require(systemConfig.scalar() == 0, "SYSCON-30"); require(systemConfig.scalar() == uint256(0x01) << 248, "SYSCON-30");
require(systemConfig.basefeeScalar() == 0, "SYSCON-40"); require(systemConfig.basefeeScalar() == 0, "SYSCON-40");
require(systemConfig.blobbasefeeScalar() == 0, "SYSCON-50"); require(systemConfig.blobbasefeeScalar() == 0, "SYSCON-50");
require(systemConfig.batcherHash() == bytes32(0), "SYSCON-60"); require(systemConfig.batcherHash() == bytes32(0), "SYSCON-60");
require(systemConfig.gasLimit() == 0, "SYSCON-70"); require(systemConfig.gasLimit() == 1, "SYSCON-70");
require(systemConfig.unsafeBlockSigner() == address(0), "SYSCON-80"); require(systemConfig.unsafeBlockSigner() == address(0), "SYSCON-80");
IResourceMetering.ResourceConfig memory resourceConfig = systemConfig.resourceConfig(); IResourceMetering.ResourceConfig memory resourceConfig = systemConfig.resourceConfig();
require(resourceConfig.maxResourceLimit == 0, "SYSCON-90"); require(resourceConfig.maxResourceLimit == 1, "SYSCON-90");
require(resourceConfig.elasticityMultiplier == 0, "SYSCON-100"); require(resourceConfig.elasticityMultiplier == 1, "SYSCON-100");
require(resourceConfig.baseFeeMaxChangeDenominator == 0, "SYSCON-110"); require(resourceConfig.baseFeeMaxChangeDenominator == 2, "SYSCON-110");
require(resourceConfig.systemTxMaxGas == 0, "SYSCON-120"); require(resourceConfig.systemTxMaxGas == 0, "SYSCON-120");
require(resourceConfig.minimumBaseFee == 0, "SYSCON-130"); require(resourceConfig.minimumBaseFee == 0, "SYSCON-130");
require(resourceConfig.maximumBaseFee == 0, "SYSCON-140"); require(resourceConfig.maximumBaseFee == 0, "SYSCON-140");
...@@ -401,7 +400,7 @@ contract DeployImplementationsOutput is BaseDeployIO { ...@@ -401,7 +400,7 @@ contract DeployImplementationsOutput is BaseDeployIO {
function assertValidL1CrossDomainMessengerImpl(DeployImplementationsInput) internal view { function assertValidL1CrossDomainMessengerImpl(DeployImplementationsInput) internal view {
IL1CrossDomainMessenger messenger = l1CrossDomainMessengerImpl(); IL1CrossDomainMessenger messenger = l1CrossDomainMessengerImpl();
DeployUtils.assertInitialized({ _contractAddress: address(messenger), _slot: 250, _offset: 0 }); DeployUtils.assertInitialized({ _contractAddress: address(messenger), _slot: 0, _offset: 20 });
require(address(messenger.OTHER_MESSENGER()) == Predeploys.L2_CROSS_DOMAIN_MESSENGER, "L1xDM-10"); require(address(messenger.OTHER_MESSENGER()) == Predeploys.L2_CROSS_DOMAIN_MESSENGER, "L1xDM-10");
require(address(messenger.otherMessenger()) == Predeploys.L2_CROSS_DOMAIN_MESSENGER, "L1xDM-20"); require(address(messenger.otherMessenger()) == Predeploys.L2_CROSS_DOMAIN_MESSENGER, "L1xDM-20");
...@@ -409,15 +408,14 @@ contract DeployImplementationsOutput is BaseDeployIO { ...@@ -409,15 +408,14 @@ contract DeployImplementationsOutput is BaseDeployIO {
require(address(messenger.portal()) == address(0), "L1xDM-40"); require(address(messenger.portal()) == address(0), "L1xDM-40");
require(address(messenger.superchainConfig()) == address(0), "L1xDM-50"); require(address(messenger.superchainConfig()) == address(0), "L1xDM-50");
// TODO: vm.expectRevert is not supported by op-chain-ops, so we can't check this yet. bytes32 xdmSenderSlot = vm.load(address(messenger), bytes32(uint256(204)));
// vm.expectRevert("CrossDomainMessenger: xDomainMessageSender is not set"); require(address(uint160(uint256(xdmSenderSlot))) == Constants.DEFAULT_L2_SENDER, "L1xDM-60");
// messenger.xDomainMessageSender();
} }
function assertValidL1ERC721BridgeImpl(DeployImplementationsInput) internal view { function assertValidL1ERC721BridgeImpl(DeployImplementationsInput) internal view {
IL1ERC721Bridge bridge = l1ERC721BridgeImpl(); IL1ERC721Bridge bridge = l1ERC721BridgeImpl();
DeployUtils.assertInitialized({ _contractAddress: address(bridge) }); DeployUtils.assertInitialized({ _contractAddress: address(bridge), _slot: 0, _offset: 0 });
require(address(bridge.OTHER_BRIDGE()) == Predeploys.L2_ERC721_BRIDGE, "L721B-10"); require(address(bridge.OTHER_BRIDGE()) == Predeploys.L2_ERC721_BRIDGE, "L721B-10");
require(address(bridge.otherBridge()) == Predeploys.L2_ERC721_BRIDGE, "L721B-20"); require(address(bridge.otherBridge()) == Predeploys.L2_ERC721_BRIDGE, "L721B-20");
...@@ -429,7 +427,7 @@ contract DeployImplementationsOutput is BaseDeployIO { ...@@ -429,7 +427,7 @@ contract DeployImplementationsOutput is BaseDeployIO {
function assertValidL1StandardBridgeImpl(DeployImplementationsInput) internal view { function assertValidL1StandardBridgeImpl(DeployImplementationsInput) internal view {
IL1StandardBridge bridge = l1StandardBridgeImpl(); IL1StandardBridge bridge = l1StandardBridgeImpl();
DeployUtils.assertInitialized({ _contractAddress: address(bridge), _slot: 49, _offset: 0 }); DeployUtils.assertInitialized({ _contractAddress: address(bridge), _slot: 0, _offset: 0 });
require(address(bridge.MESSENGER()) == address(0), "L1SB-10"); require(address(bridge.MESSENGER()) == address(0), "L1SB-10");
require(address(bridge.messenger()) == address(0), "L1SB-20"); require(address(bridge.messenger()) == address(0), "L1SB-20");
...@@ -441,7 +439,7 @@ contract DeployImplementationsOutput is BaseDeployIO { ...@@ -441,7 +439,7 @@ contract DeployImplementationsOutput is BaseDeployIO {
function assertValidOptimismMintableERC20FactoryImpl(DeployImplementationsInput) internal view { function assertValidOptimismMintableERC20FactoryImpl(DeployImplementationsInput) internal view {
IOptimismMintableERC20Factory factory = optimismMintableERC20FactoryImpl(); IOptimismMintableERC20Factory factory = optimismMintableERC20FactoryImpl();
DeployUtils.assertInitialized({ _contractAddress: address(factory), _slot: 51, _offset: 0 }); DeployUtils.assertInitialized({ _contractAddress: address(factory), _slot: 0, _offset: 0 });
require(address(factory.BRIDGE()) == address(0), "MERC20F-10"); require(address(factory.BRIDGE()) == address(0), "MERC20F-10");
require(address(factory.bridge()) == address(0), "MERC20F-20"); require(address(factory.bridge()) == address(0), "MERC20F-20");
...@@ -790,7 +788,7 @@ contract DeployImplementations is Script { ...@@ -790,7 +788,7 @@ contract DeployImplementations is Script {
vm.broadcast(msg.sender); vm.broadcast(msg.sender);
impl = IOptimismMintableERC20Factory( impl = IOptimismMintableERC20Factory(
DeployUtils.create1({ DeployUtils.create1({
_name: "L1OptimismMintableERC20Factory", _name: "OptimismMintableERC20Factory",
_args: DeployUtils.encodeConstructor(abi.encodeCall(IOptimismMintableERC20Factory.__constructor__, ())) _args: DeployUtils.encodeConstructor(abi.encodeCall(IOptimismMintableERC20Factory.__constructor__, ()))
}) })
); );
...@@ -798,7 +796,7 @@ contract DeployImplementations is Script { ...@@ -798,7 +796,7 @@ contract DeployImplementations is Script {
revert(string.concat("DeployImplementations: failed to deploy release ", release)); revert(string.concat("DeployImplementations: failed to deploy release ", release));
} }
vm.label(address(impl), "L1OptimismMintableERC20FactoryImpl"); vm.label(address(impl), "OptimismMintableERC20FactoryImpl");
_dio.set(_dio.optimismMintableERC20FactoryImpl.selector, address(impl)); _dio.set(_dio.optimismMintableERC20FactoryImpl.selector, address(impl));
} }
......
...@@ -38,7 +38,6 @@ import { IOptimismMintableERC20Factory } from "src/universal/interfaces/IOptimis ...@@ -38,7 +38,6 @@ import { IOptimismMintableERC20Factory } from "src/universal/interfaces/IOptimis
contract DeployOPChainInput is BaseDeployIO { contract DeployOPChainInput is BaseDeployIO {
address internal _opChainProxyAdminOwner; address internal _opChainProxyAdminOwner;
address internal _systemConfigOwner; address internal _systemConfigOwner;
address internal _systemConfigFeeAdmin;
address internal _batcher; address internal _batcher;
address internal _unsafeBlockSigner; address internal _unsafeBlockSigner;
address internal _proposer; address internal _proposer;
...@@ -65,7 +64,6 @@ contract DeployOPChainInput is BaseDeployIO { ...@@ -65,7 +64,6 @@ contract DeployOPChainInput is BaseDeployIO {
require(_addr != address(0), "DeployOPChainInput: cannot set zero address"); require(_addr != address(0), "DeployOPChainInput: cannot set zero address");
if (_sel == this.opChainProxyAdminOwner.selector) _opChainProxyAdminOwner = _addr; if (_sel == this.opChainProxyAdminOwner.selector) _opChainProxyAdminOwner = _addr;
else if (_sel == this.systemConfigOwner.selector) _systemConfigOwner = _addr; else if (_sel == this.systemConfigOwner.selector) _systemConfigOwner = _addr;
else if (_sel == this.systemConfigFeeAdmin.selector) _systemConfigFeeAdmin = _addr;
else if (_sel == this.batcher.selector) _batcher = _addr; else if (_sel == this.batcher.selector) _batcher = _addr;
else if (_sel == this.unsafeBlockSigner.selector) _unsafeBlockSigner = _addr; else if (_sel == this.unsafeBlockSigner.selector) _unsafeBlockSigner = _addr;
else if (_sel == this.proposer.selector) _proposer = _addr; else if (_sel == this.proposer.selector) _proposer = _addr;
...@@ -125,11 +123,6 @@ contract DeployOPChainInput is BaseDeployIO { ...@@ -125,11 +123,6 @@ contract DeployOPChainInput is BaseDeployIO {
return _systemConfigOwner; return _systemConfigOwner;
} }
function systemConfigFeeAdmin() public view returns (address) {
require(_systemConfigFeeAdmin != address(0), "DeployOPChainInput: not set");
return _systemConfigFeeAdmin;
}
function batcher() public view returns (address) { function batcher() public view returns (address) {
require(_batcher != address(0), "DeployOPChainInput: not set"); require(_batcher != address(0), "DeployOPChainInput: not set");
return _batcher; return _batcher;
...@@ -362,8 +355,7 @@ contract DeployOPChain is Script { ...@@ -362,8 +355,7 @@ contract DeployOPChain is Script {
batcher: _doi.batcher(), batcher: _doi.batcher(),
unsafeBlockSigner: _doi.unsafeBlockSigner(), unsafeBlockSigner: _doi.unsafeBlockSigner(),
proposer: _doi.proposer(), proposer: _doi.proposer(),
challenger: _doi.challenger(), challenger: _doi.challenger()
systemConfigFeeAdmin: _doi.systemConfigFeeAdmin()
}); });
OPContractsManager.DeployInput memory deployInput = OPContractsManager.DeployInput({ OPContractsManager.DeployInput memory deployInput = OPContractsManager.DeployInput({
roles: roles, roles: roles,
...@@ -580,7 +572,7 @@ contract DeployOPChain is Script { ...@@ -580,7 +572,7 @@ contract DeployOPChain is Script {
function assertValidL1CrossDomainMessenger(DeployOPChainInput _doi, DeployOPChainOutput _doo) internal { function assertValidL1CrossDomainMessenger(DeployOPChainInput _doi, DeployOPChainOutput _doo) internal {
IL1CrossDomainMessenger messenger = _doo.l1CrossDomainMessengerProxy(); IL1CrossDomainMessenger messenger = _doo.l1CrossDomainMessengerProxy();
DeployUtils.assertInitialized({ _contractAddress: address(messenger), _slot: 250, _offset: 0 }); DeployUtils.assertInitialized({ _contractAddress: address(messenger), _slot: 0, _offset: 20 });
require(address(messenger.OTHER_MESSENGER()) == Predeploys.L2_CROSS_DOMAIN_MESSENGER, "L1xDM-10"); require(address(messenger.OTHER_MESSENGER()) == Predeploys.L2_CROSS_DOMAIN_MESSENGER, "L1xDM-10");
require(address(messenger.otherMessenger()) == Predeploys.L2_CROSS_DOMAIN_MESSENGER, "L1xDM-20"); require(address(messenger.otherMessenger()) == Predeploys.L2_CROSS_DOMAIN_MESSENGER, "L1xDM-20");
...@@ -589,16 +581,15 @@ contract DeployOPChain is Script { ...@@ -589,16 +581,15 @@ contract DeployOPChain is Script {
require(address(messenger.portal()) == address(_doo.optimismPortalProxy()), "L1xDM-40"); require(address(messenger.portal()) == address(_doo.optimismPortalProxy()), "L1xDM-40");
require(address(messenger.superchainConfig()) == address(_doi.opcmProxy().superchainConfig()), "L1xDM-50"); require(address(messenger.superchainConfig()) == address(_doi.opcmProxy().superchainConfig()), "L1xDM-50");
// TODO: vm.expectRevert is not supported by op-chain-ops, so we can't check this yet. bytes32 xdmSenderSlot = vm.load(address(messenger), bytes32(uint256(204)));
// vm.expectRevert("CrossDomainMessenger: xDomainMessageSender is not set"); require(address(uint160(uint256(xdmSenderSlot))) == Constants.DEFAULT_L2_SENDER, "L1xDM-60");
// messenger.xDomainMessageSender();
} }
function assertValidL1StandardBridge(DeployOPChainInput _doi, DeployOPChainOutput _doo) internal { function assertValidL1StandardBridge(DeployOPChainInput _doi, DeployOPChainOutput _doo) internal {
IL1StandardBridge bridge = _doo.l1StandardBridgeProxy(); IL1StandardBridge bridge = _doo.l1StandardBridgeProxy();
IL1CrossDomainMessenger messenger = _doo.l1CrossDomainMessengerProxy(); IL1CrossDomainMessenger messenger = _doo.l1CrossDomainMessengerProxy();
DeployUtils.assertInitialized({ _contractAddress: address(bridge), _slot: 49, _offset: 0 }); DeployUtils.assertInitialized({ _contractAddress: address(bridge), _slot: 0, _offset: 0 });
require(address(bridge.MESSENGER()) == address(messenger), "L1SB-10"); require(address(bridge.MESSENGER()) == address(messenger), "L1SB-10");
require(address(bridge.messenger()) == address(messenger), "L1SB-20"); require(address(bridge.messenger()) == address(messenger), "L1SB-20");
...@@ -610,7 +601,7 @@ contract DeployOPChain is Script { ...@@ -610,7 +601,7 @@ contract DeployOPChain is Script {
function assertValidOptimismMintableERC20Factory(DeployOPChainInput, DeployOPChainOutput _doo) internal { function assertValidOptimismMintableERC20Factory(DeployOPChainInput, DeployOPChainOutput _doo) internal {
IOptimismMintableERC20Factory factory = _doo.optimismMintableERC20FactoryProxy(); IOptimismMintableERC20Factory factory = _doo.optimismMintableERC20FactoryProxy();
DeployUtils.assertInitialized({ _contractAddress: address(factory), _slot: 51, _offset: 0 }); DeployUtils.assertInitialized({ _contractAddress: address(factory), _slot: 0, _offset: 0 });
require(factory.BRIDGE() == address(_doo.l1StandardBridgeProxy()), "MERC20F-10"); require(factory.BRIDGE() == address(_doo.l1StandardBridgeProxy()), "MERC20F-10");
require(factory.bridge() == address(_doo.l1StandardBridgeProxy()), "MERC20F-20"); require(factory.bridge() == address(_doo.l1StandardBridgeProxy()), "MERC20F-20");
...@@ -619,7 +610,7 @@ contract DeployOPChain is Script { ...@@ -619,7 +610,7 @@ contract DeployOPChain is Script {
function assertValidL1ERC721Bridge(DeployOPChainInput _doi, DeployOPChainOutput _doo) internal { function assertValidL1ERC721Bridge(DeployOPChainInput _doi, DeployOPChainOutput _doo) internal {
IL1ERC721Bridge bridge = _doo.l1ERC721BridgeProxy(); IL1ERC721Bridge bridge = _doo.l1ERC721BridgeProxy();
DeployUtils.assertInitialized({ _contractAddress: address(bridge) }); DeployUtils.assertInitialized({ _contractAddress: address(bridge), _slot: 0, _offset: 0 });
require(address(bridge.OTHER_BRIDGE()) == Predeploys.L2_ERC721_BRIDGE, "L721B-10"); require(address(bridge.OTHER_BRIDGE()) == Predeploys.L2_ERC721_BRIDGE, "L721B-10");
require(address(bridge.otherBridge()) == Predeploys.L2_ERC721_BRIDGE, "L721B-20"); require(address(bridge.otherBridge()) == Predeploys.L2_ERC721_BRIDGE, "L721B-20");
......
...@@ -359,7 +359,6 @@ contract DeploySuperchain is Script { ...@@ -359,7 +359,6 @@ contract DeploySuperchain is Script {
function deployAndInitializeSuperchainConfig(DeploySuperchainInput _dsi, DeploySuperchainOutput _dso) public { function deployAndInitializeSuperchainConfig(DeploySuperchainInput _dsi, DeploySuperchainOutput _dso) public {
address guardian = _dsi.guardian(); address guardian = _dsi.guardian();
address upgrader = _dsi.superchainProxyAdminOwner();
bool paused = _dsi.paused(); bool paused = _dsi.paused();
IProxyAdmin superchainProxyAdmin = _dso.superchainProxyAdmin(); IProxyAdmin superchainProxyAdmin = _dso.superchainProxyAdmin();
...@@ -377,7 +376,7 @@ contract DeploySuperchain is Script { ...@@ -377,7 +376,7 @@ contract DeploySuperchain is Script {
superchainProxyAdmin.upgradeAndCall( superchainProxyAdmin.upgradeAndCall(
payable(address(superchainConfigProxy)), payable(address(superchainConfigProxy)),
address(superchainConfigImpl), address(superchainConfigImpl),
abi.encodeCall(ISuperchainConfig.initialize, (guardian, upgrader, paused)) abi.encodeCall(ISuperchainConfig.initialize, (guardian, paused))
); );
vm.stopBroadcast(); vm.stopBroadcast();
......
...@@ -34,11 +34,10 @@ enum Fork { ...@@ -34,11 +34,10 @@ enum Fork {
ECOTONE, ECOTONE,
FJORD, FJORD,
GRANITE, GRANITE,
HOLOCENE, HOLOCENE
ISTHMUS
} }
Fork constant LATEST_FORK = Fork.ISTHMUS; Fork constant LATEST_FORK = Fork.HOLOCENE;
library ForkUtils { library ForkUtils {
function toString(Fork _fork) internal pure returns (string memory) { function toString(Fork _fork) internal pure returns (string memory) {
...@@ -54,8 +53,6 @@ library ForkUtils { ...@@ -54,8 +53,6 @@ library ForkUtils {
return "granite"; return "granite";
} else if (_fork == Fork.HOLOCENE) { } else if (_fork == Fork.HOLOCENE) {
return "holocene"; return "holocene";
} else if (_fork == Fork.ISTHMUS) {
return "isthmus";
} else { } else {
return "unknown"; return "unknown";
} }
...@@ -171,8 +168,6 @@ library Config { ...@@ -171,8 +168,6 @@ library Config {
return Fork.GRANITE; return Fork.GRANITE;
} else if (forkHash == keccak256(bytes("holocene"))) { } else if (forkHash == keccak256(bytes("holocene"))) {
return Fork.HOLOCENE; return Fork.HOLOCENE;
} else if (forkHash == keccak256(bytes("isthmus"))) {
return Fork.ISTHMUS;
} else { } else {
revert(string.concat("Config: unknown fork: ", forkStr)); revert(string.concat("Config: unknown fork: ", forkStr));
} }
......
...@@ -351,11 +351,6 @@ library DeployUtils { ...@@ -351,11 +351,6 @@ library DeployUtils {
} }
} }
/// @notice The unstructured storage slot that is used for v5 openzeppelin initializable. Computed as:
/// keccak256(abi.encode(uint256(keccak256("openzeppelin.storage.Initializable")) - 1)) &
/// ~bytes32(uint256(0xff))
bytes32 internal constant INITIALIZABLE_STORAGE = 0xf0c57e16840df040f15088dc2f81fe391c3923bec73e23a9662efc9c229c6a00;
/// @notice Asserts that for a given contract the value of a storage slot at an offset is 1 or /// @notice Asserts that for a given contract the value of a storage slot at an offset is 1 or
/// `type(uint8).max`. The value is set to 1 when a contract is initialized, and set to /// `type(uint8).max`. The value is set to 1 when a contract is initialized, and set to
/// `type(uint8).max` when `_disableInitializers` is called. /// `type(uint8).max` when `_disableInitializers` is called.
...@@ -367,9 +362,4 @@ library DeployUtils { ...@@ -367,9 +362,4 @@ library DeployUtils {
"DeployUtils: value at the given slot and offset does not indicate initialization" "DeployUtils: value at the given slot and offset does not indicate initialization"
); );
} }
/// @notice Asserts that the contract has been initialized, assuming that it is using openzeppelin v5 initializable.
function assertInitialized(address _contractAddress) internal view {
assertInitialized({ _contractAddress: _contractAddress, _slot: uint256(INITIALIZABLE_STORAGE), _offset: 0 });
}
} }
...@@ -5,7 +5,6 @@ import { Vm } from "forge-std/Vm.sol"; ...@@ -5,7 +5,6 @@ import { Vm } from "forge-std/Vm.sol";
import { stdJson } from "forge-std/StdJson.sol"; import { stdJson } from "forge-std/StdJson.sol";
import { LibString } from "@solady/utils/LibString.sol"; import { LibString } from "@solady/utils/LibString.sol";
import { Executables } from "scripts/libraries/Executables.sol"; import { Executables } from "scripts/libraries/Executables.sol";
import { DeployUtils } from "scripts/libraries/DeployUtils.sol";
import { Process } from "scripts/libraries/Process.sol"; import { Process } from "scripts/libraries/Process.sol";
/// @notice Contains information about a storage slot. Mirrors the layout of the storage /// @notice Contains information about a storage slot. Mirrors the layout of the storage
...@@ -191,19 +190,6 @@ library ForgeArtifacts { ...@@ -191,19 +190,6 @@ library ForgeArtifacts {
function getInitializedSlot(string memory _contractName) internal returns (StorageSlot memory slot_) { function getInitializedSlot(string memory _contractName) internal returns (StorageSlot memory slot_) {
string memory storageLayout = getStorageLayout(_contractName); string memory storageLayout = getStorageLayout(_contractName);
// Contracts that use oz v5 should be here
if (LibString.eq(_contractName, "L1ERC721Bridge")) {
StorageSlot memory slot = StorageSlot({
astId: 0,
_contract: _contractName,
label: "_initialized",
offset: 0,
slot: vm.toString(DeployUtils.INITIALIZABLE_STORAGE),
_type: "bool"
});
return slot;
}
// FaultDisputeGame and PermissionedDisputeGame use a different name for the initialized storage slot. // FaultDisputeGame and PermissionedDisputeGame use a different name for the initialized storage slot.
string memory slotName = "_initialized"; string memory slotName = "_initialized";
string memory slotType = "t_uint8"; string memory slotType = "t_uint8";
...@@ -228,10 +214,7 @@ library ForgeArtifacts { ...@@ -228,10 +214,7 @@ library ForgeArtifacts {
slotType, slotType,
"\")'" "\")'"
); );
bytes memory rawSlot = vm.parseJson(string(Process.run(command)));
bytes memory result = Process.run(command);
require(result.length > 0, string.concat("ForgeArtifacts: ", _contractName, "is not initializable"));
bytes memory rawSlot = vm.parseJson(string(result));
slot_ = abi.decode(rawSlot, (StorageSlot)); slot_ = abi.decode(rawSlot, (StorageSlot));
} }
......
...@@ -8,60 +8,56 @@ ...@@ -8,60 +8,56 @@
"sourceCodeHash": "0x30e83a535ef27b2e900c831c4e1a4ec2750195350011c4fdacda1da9db2d167b" "sourceCodeHash": "0x30e83a535ef27b2e900c831c4e1a4ec2750195350011c4fdacda1da9db2d167b"
}, },
"src/L1/L1CrossDomainMessenger.sol": { "src/L1/L1CrossDomainMessenger.sol": {
"initCodeHash": "0x8d0351b1c13be9e53ba9d3c6174e0ef0ae5c37cfdf31da446533548f5c56553a", "initCodeHash": "0x2e9cb3ceb5e55341b311f0666ef7655df4fafae75afdfbcd701cd9c9b2b017d5",
"sourceCodeHash": "0x5b00fc7b2450c008cefb283779237f7402722182eb9e5210439d5a01359dc38f" "sourceCodeHash": "0x848ec3774be17bcc8ba65a23d08e35e979b3f39f9d2ac8a810188f945c69c9ea"
}, },
"src/L1/L1ERC721Bridge.sol": { "src/L1/L1ERC721Bridge.sol": {
"initCodeHash": "0x19542aad97e146219d4d3cdcfb29f8f1591815731c51216e8424e754556a21a0", "initCodeHash": "0xb3bf093ea83a24574a6093bebf5b2aea707355ed8d6702b2b5eb292e75b6ae42",
"sourceCodeHash": "0x71fc58927450aa7f6e97688e7a5ecbfadfa235a26523d4c540183647ccbf7fdf" "sourceCodeHash": "0x289de9f40898b6305deecc6b60cdf566aa6c6a1444f713c3a0af23ea7878207e"
},
"src/L1/L1OptimismMintableERC20Factory.sol": {
"initCodeHash": "0xc6b0a84d485c8503bd1ce077fbfa5533ad1f6a001feab31d9c21948d02d47827",
"sourceCodeHash": "0x9432cd22e23347f4b397706b4eb28ee4eaba481f4914d2d685d77c413963326d"
}, },
"src/L1/L1StandardBridge.sol": { "src/L1/L1StandardBridge.sol": {
"initCodeHash": "0x0a17e22cb56c915bf1aaf3a61ac28de2dca4f2122ba57fe597a3dd612e245478", "initCodeHash": "0x802f72745bb9a82dc049377bb9cf6b58f35aec388aeb957b28a5e14f28d91bc1",
"sourceCodeHash": "0xa706c8d55d1e34a86d42a113cd486ccb809a36ff956cf32fbcb839ca2cdfbf0b" "sourceCodeHash": "0x24b784645b065a5393a2115a078d67f91eb09afd5e70baf81daf975381f16155"
}, },
"src/L1/L2OutputOracle.sol": { "src/L1/L2OutputOracle.sol": {
"initCodeHash": "0x1182bfb87c4ab399b912ca7fe18cdbf4b24c414e078fb0a55bd3c44d442d3ed1", "initCodeHash": "0x1182bfb87c4ab399b912ca7fe18cdbf4b24c414e078fb0a55bd3c44d442d3ed1",
"sourceCodeHash": "0x4132ff37d267cb12224b75ea806c0aa7d25407b0d66ce526d7fcda8f7d223882" "sourceCodeHash": "0x4132ff37d267cb12224b75ea806c0aa7d25407b0d66ce526d7fcda8f7d223882"
}, },
"src/L1/OPContractsManager.sol": { "src/L1/OPContractsManager.sol": {
"initCodeHash": "0xa6e3fda99d87e69c3a2d2b1efb2f419cae75b1f2a0295548f5f2db84432dd9c4", "initCodeHash": "0xd58cb3978affc5c1457cdd498ff8420c90aef804d4c3b62cf42ab2691986d6d2",
"sourceCodeHash": "0x647ec3500bca93169dd5384919c6787238da40ffd53fc5d1c3b7c61701a9d398" "sourceCodeHash": "0x7bfa6eff76176649fe600303cd60009a0f6e282cbaec55836b5ea1f8875cbeb5"
}, },
"src/L1/OptimismPortal.sol": { "src/L1/OptimismPortal.sol": {
"initCodeHash": "0x25c4212bac52f172b193cb3c36376074f239491d53c0d83c5081df7042cd02f8", "initCodeHash": "0x152167cfa18635ae4918a6eb3371a599cfa084418c0a652799cdb48bfc0ee0cc",
"sourceCodeHash": "0x6300532cb22fd9848bf54891c3a48003c7108470199a200d082b740c91e0a017" "sourceCodeHash": "0xbe34b82900d02f71bb0949818eabe49531f7e0d8d8bae01f6dac4a296530d1aa"
}, },
"src/L1/OptimismPortal2.sol": { "src/L1/OptimismPortal2.sol": {
"initCodeHash": "0x8e6c808992ea90f28feb12338309ff512876163ed4409a1dca6184475ab4a136", "initCodeHash": "0x218358b48f640b3fcb2d239f00dc1cd3b11517ad46c8e1efa44953d38da63540",
"sourceCodeHash": "0xedc1819877c3263c43a27c5077363691ce0839fa8e61b8d000a0ba9998bf1905" "sourceCodeHash": "0x66ac1212760db53a2bb1839e4cd17dc071d9273b8e6fb80646b79e91b3371c1a"
}, },
"src/L1/OptimismPortalInterop.sol": { "src/L1/OptimismPortalInterop.sol": {
"initCodeHash": "0xcda63947d6fb33478b7bdc6f20a983061b3ff9d77a7c64a6b7141af08b79fd60", "initCodeHash": "0x39f66ac74341ec235fbdd0d79546283210bd8ac35a2ab2c4bd36c9722ce18411",
"sourceCodeHash": "0x3731c4ac1c5784b92934d3f84d8eba70321b4c6b379a9349aa4c620da6c5a7d8" "sourceCodeHash": "0xbb98144285b9530e336f957d10b20363b350876597e30fd34821940896a2bae8"
}, },
"src/L1/ProtocolVersions.sol": { "src/L1/ProtocolVersions.sol": {
"initCodeHash": "0xefd4806e8737716d5d2022ca2e9e9fba0a0cb5714b026166b58e472222c7d15f", "initCodeHash": "0xefd4806e8737716d5d2022ca2e9e9fba0a0cb5714b026166b58e472222c7d15f",
"sourceCodeHash": "0x15205131bf420aa6d03c558bb75dd49cd7439caed7ccdcbfd89c4170a48c94f5" "sourceCodeHash": "0x15205131bf420aa6d03c558bb75dd49cd7439caed7ccdcbfd89c4170a48c94f5"
}, },
"src/L1/SuperchainConfig.sol": { "src/L1/SuperchainConfig.sol": {
"initCodeHash": "0x37b2cabf25e5717ec9961bdb084b3a35ffd403c867361b106ea5e47345bc7ba9", "initCodeHash": "0xfca12d9016c746e5c275b186e0ca40cfd65cf45a5665aab7589a669fea3abb47",
"sourceCodeHash": "0xbd02a2297b9088c29070bf910ec306dd31d8d185007afaaf7743435493b0ede6" "sourceCodeHash": "0x39489a85bc3a5c8560f82d41b31bf7fe22f5b648f4ed538f61695a73092ea9eb"
}, },
"src/L1/SystemConfig.sol": { "src/L1/SystemConfig.sol": {
"initCodeHash": "0xc2961b2de5e12fc7f8079bb462ee9ca605940ab6072b531b5fa173dd3d3af407", "initCodeHash": "0x429058f75d97fa7a7d0166b59830909bc722324feefc40f2b41419d6335d3f37",
"sourceCodeHash": "0xa699d0715f3016f3acb3e3971d8560c280340a0c87e8a0a07ab80160e612c196" "sourceCodeHash": "0x5ca776041a4ddc0d28ec55db7012d669481cd4601b0e71dbd3493a67b8a7e5a5"
}, },
"src/L1/SystemConfigInterop.sol": { "src/L1/SystemConfigInterop.sol": {
"initCodeHash": "0x2f5b58ef3db81ee004e69069d231de7c108920105edafad5e0fcf8a897201d5d", "initCodeHash": "0x277a61dcabed81a15739a8e9ed50615252bcc687cebea852e00191d0a1fbe11f",
"sourceCodeHash": "0x5c996568f655a7467e9de456b39eed7dbfde46d53a609f56b7369940fef0e1ea" "sourceCodeHash": "0x38361a4f70a19e1b7819e933932a0c9fd2bcebaaebcbc7942f5c00dfaa2c28df"
}, },
"src/L2/BaseFeeVault.sol": { "src/L2/BaseFeeVault.sol": {
"initCodeHash": "0x2eded104b7c98ea055dbd02a19ed967f5341ba169056425522ef2b3ce4b3300e", "initCodeHash": "0xbf49824cf37e201181484a8a423fcad8f504dc925921a2b28e83398197858dec",
"sourceCodeHash": "0x8428d0a173d3d58327aebc5585f1a62e3929ed56324a224e15b88bd1bca31348" "sourceCodeHash": "0x983e8e248c61e362ba6a01dd2e217a535c9bb828dc0b4421f5f27e0577f2e14c"
}, },
"src/L2/CrossL2Inbox.sol": { "src/L2/CrossL2Inbox.sol": {
"initCodeHash": "0x31ecaebf368ab3333e80c6dc004b3c9f9a31f813c3138ab388bb3eead9f1b4ee", "initCodeHash": "0x31ecaebf368ab3333e80c6dc004b3c9f9a31f813c3138ab388bb3eead9f1b4ee",
...@@ -72,68 +68,60 @@ ...@@ -72,68 +68,60 @@
"sourceCodeHash": "0x0b6afdc52d1ae88d9e4bbb5dc00920e7a6bd1e9d6595bfdbae64874190f39df0" "sourceCodeHash": "0x0b6afdc52d1ae88d9e4bbb5dc00920e7a6bd1e9d6595bfdbae64874190f39df0"
}, },
"src/L2/GasPriceOracle.sol": { "src/L2/GasPriceOracle.sol": {
"initCodeHash": "0x83d50e3b34cd1b4de32f1cced28796b07aefc526cc17ceb1903ad55f4abc90b7", "initCodeHash": "0x7e8c2b42e10187ad649c0bf70c5688c2a4af3c412bacaec87d63c3f93ae4cfef",
"sourceCodeHash": "0x64109614b3813b0f6003bcfada1bdbdba733c623aa7b935b9e51753f1c60ed6a" "sourceCodeHash": "0xa12ce15ded3cca681b2fc9facaebbb45d740dd6f9c9496333c1c46689c9a2d99"
}, },
"src/L2/L1Block.sol": { "src/L2/L1Block.sol": {
"initCodeHash": "0xdd942ad49044ca92b46f39f5035995628c2c8b10c1060c0a59b65cdc20176832", "initCodeHash": "0xa919d2aa76a7ecdfd076e2b1dbece499cc85706075f16eb6fa7b1a0fa7b38c1b",
"sourceCodeHash": "0x4c6be03e3eddc17810a65e475c1c7dc1e5a15fe4c1c6d9b8ab17b3323d06e405" "sourceCodeHash": "0x692cfcbc06dba6328f6e5c6b500741df04e4bdf730b2069aeb5d168355ea7b6f"
}, },
"src/L2/L1BlockInterop.sol": { "src/L2/L1BlockInterop.sol": {
"initCodeHash": "0xfab767c50aff6bd9d232605c7016afaee34e36647142ea952fea57c98b860c2e", "initCodeHash": "0x62e9cc59daaf72066ac20597a666db33e9a7b3f7be71a3d47ea4841a9aca9d07",
"sourceCodeHash": "0xc220f197eb6aec98554fc72f68f95578a20f201a4780cada28832d21ae4d816b" "sourceCodeHash": "0xe57627347366d74029a0d24f0b45d7b9cf82b81c94681d0f633d5e5c37c8de4a"
}, },
"src/L2/L1FeeVault.sol": { "src/L2/L1FeeVault.sol": {
"initCodeHash": "0xffd78f3c10c018ec77c3ede7599f76ad23433cc1f18794e47eb73ed5f3460dda", "initCodeHash": "0xbf49824cf37e201181484a8a423fcad8f504dc925921a2b28e83398197858dec",
"sourceCodeHash": "0x52cec09ff02282b9e7adef9f770cbc1f31682d41aece1749ba7b4ff14528eb1b" "sourceCodeHash": "0xc7cda130f2bb3648e04d5a480082aa1789e16456c1280954d822b05d30100b2d"
}, },
"src/L2/L2CrossDomainMessenger.sol": { "src/L2/L2CrossDomainMessenger.sol": {
"initCodeHash": "0x9d478585dbebd5bf03e4d7a735bc5f64006e2ff99d62fc08c2202c5483005d5a", "initCodeHash": "0xc496495496b96ea0eaf417c5e56b295836c12db3e6aafe2e607563e7a50b5b65",
"sourceCodeHash": "0x0726b306b41eaf326e19f0d6d1c8a9dbdc8efb2baa449e8fca5954a7b31f79c7" "sourceCodeHash": "0x56edf0f36366326a92722ae3c7502bce3d80b2ee5e354181dc09ba801437a488"
}, },
"src/L2/L2ERC721Bridge.sol": { "src/L2/L2ERC721Bridge.sol": {
"initCodeHash": "0xc83703c9b18f7e4dcdbaf327894e36bf1edfbd39f9e55c5546f2f2deedf7689f", "initCodeHash": "0xaed0528e8b81817a0c3b41513c02e7fd678f58e34b98f02ea33d5a770a064c2f",
"sourceCodeHash": "0x69e4394ac1cabc4c2cbf64988fc234f47c0750af720875ed2dbd339b752f6b87" "sourceCodeHash": "0xf8569c75b801f38f8a5a41e94e90f159ddc5f5412804b26e3e564755a50631b8"
},
"src/L2/L2OptimismMintableERC20Factory.sol": {
"initCodeHash": "0xb4411155cd6bf9ce710cbce80aaf7a5c8d4b509cfb3b6eca1ff1bcb9eee76013",
"sourceCodeHash": "0xb2330d5ef6c7eecc14745d5a2122daa105f2630f811548c203e5bca4a91787ec"
}, },
"src/L2/L2StandardBridge.sol": { "src/L2/L2StandardBridge.sol": {
"initCodeHash": "0xf6a2658d9fbda6959cff4af0ae3891534fdfdc2685c6f7210bb124ba6553d5a3", "initCodeHash": "0xcb4aa19f0cd43a35cb5c65f26c3cfd7c41f1d1e5bcc15aef6096d385df7272c9",
"sourceCodeHash": "0x909e93976c2d9b419a52ce131d86aad5de9c0e8fe6bf1d5afc7257c1d9524871" "sourceCodeHash": "0x89771b53b7f6e64d943afb2a4bf15395efcf20d5302b76a18e52fa7cce8cdc56"
}, },
"src/L2/L2StandardBridgeInterop.sol": { "src/L2/L2StandardBridgeInterop.sol": {
"initCodeHash": "0x26c04ae665855e91fc12e995bc9436b63415068da90d694f4a9f070db80027b2", "initCodeHash": "0xc4eaece28d2cfca3c51247c3cce320a167a83c7fd13aea5736549d2b25e0b139",
"sourceCodeHash": "0x0ca6d8900a02c213acca44c8cb56df816fa1bebd6903a9ea6d4c21525c936c12" "sourceCodeHash": "0x9e80044adf5f83c30b520ee153b75be5a152081c9e1271e7e618ecfccd1fb4ac"
}, },
"src/L2/L2ToL1MessagePasser.sol": { "src/L2/L2ToL1MessagePasser.sol": {
"initCodeHash": "0x13fe3729beb9ed966c97bef09acb9fe5043fe651d453145073d05f2567fa988d", "initCodeHash": "0x13fe3729beb9ed966c97bef09acb9fe5043fe651d453145073d05f2567fa988d",
"sourceCodeHash": "0xd08a2e6514dbd44e16aa312a1b27b2841a9eab5622cbd05a39c30f543fad673c" "sourceCodeHash": "0xd08a2e6514dbd44e16aa312a1b27b2841a9eab5622cbd05a39c30f543fad673c"
}, },
"src/L2/L2ToL2CrossDomainMessenger.sol": { "src/L2/L2ToL2CrossDomainMessenger.sol": {
"initCodeHash": "0x8db6e86984e2501a4281765a9eaeafc0fe1d15c7bb802bbc15d5221a907be526", "initCodeHash": "0x2a1a1ee4f47175ce661ee8e4e50cfa879b082dcb5278b1d66ddda00ed77bb744",
"sourceCodeHash": "0x00e6d19b377aad27dfc8bf759dbc052fcc708d17e2a56453988ccc97e838399d" "sourceCodeHash": "0xa76133db7f449ae742f9ba988ad86ccb5672475f61298b9fefe411b63b63e9f6"
},
"src/L2/OptimismMintableERC721Factory.sol": {
"initCodeHash": "0xc66a3211c520beb0e3da3ce78c0f307bf4397365f147e45d31650d15678e42b2",
"sourceCodeHash": "0x35b725198c3780182408ccc76dc877b29659508592befde437754c69af7d7b5f"
}, },
"src/L2/OptimismSuperchainERC20.sol": { "src/L2/OptimismSuperchainERC20.sol": {
"initCodeHash": "0x529f3756a365a8f225d7debdd15c474c1338c8973bb65a1aad98f85753f74722", "initCodeHash": "0x5bc5824030ecdb531e1f615d207cb73cdaa702e198769445d0ddbe717271eba9",
"sourceCodeHash": "0xf68baaee0a09ea51d5a4e821df79976c0914369ebc8e5fd27bbbf89072254fc8" "sourceCodeHash": "0x0819c9411a155dca592d19b60c4176954202e4fe5d632a4ffbf88d465461252c"
}, },
"src/L2/OptimismSuperchainERC20Beacon.sol": { "src/L2/OptimismSuperchainERC20Beacon.sol": {
"initCodeHash": "0xb032e99f5c205c8b474da89887e350277cdd05b99ee28374b97bfae18ef7a72c", "initCodeHash": "0x23dba3ceb9e58646695c306996c9e15251ac79acc6339c1a93d10a4c79da6dab",
"sourceCodeHash": "0xe8753177e8491152eb3ecbed42d5232ae545091a116f23d104a4f9621711fbda" "sourceCodeHash": "0xf4379e49665823c877f5732f35068435ce06e2394fce6910a5e113d16cdc9f95"
}, },
"src/L2/OptimismSuperchainERC20Factory.sol": { "src/L2/OptimismSuperchainERC20Factory.sol": {
"initCodeHash": "0xe6a098346699c3df248050fc3301197661d391f8e4849a93f00afeac17cae317", "initCodeHash": "0x18a362c57f08b611db98dfde96121385e938f995c84e3547c1c03fd49f9db2fd",
"sourceCodeHash": "0x1e8380bdce27292f805ddc85fec0db5bc60fbe3fd9e0bcbd146c103062ed459a" "sourceCodeHash": "0x450cd89d0aae7bbc85ff57a14a6d3468c24c6743f25943f6d895d34b1456c456"
}, },
"src/L2/SequencerFeeVault.sol": { "src/L2/SequencerFeeVault.sol": {
"initCodeHash": "0x4f0017a0b906cb949ebb5931cebe00130109a4e9bb453d77b470982de5b996fb", "initCodeHash": "0xcaadbf08057b5d47f7704257e9385a29e42a7a08c818646d109c5952d3d35218",
"sourceCodeHash": "0x8d71ff1b7d5c758ff15137c0ab1411e4abe8d91bc4fab28c981a767f6323b426" "sourceCodeHash": "0x05bbc6039e5a9ff38987e7b9b89c69e2ee8aa4b7ca20dd002ea1bbd3d70f27f3"
}, },
"src/L2/SuperchainERC20.sol": { "src/L2/SuperchainERC20.sol": {
"initCodeHash": "0xc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470", "initCodeHash": "0xc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470",
...@@ -144,12 +132,12 @@ ...@@ -144,12 +132,12 @@
"sourceCodeHash": "0x617aa994f659c5d8ebd54128d994f86f5b175ceca095b024b8524a7898e8ae62" "sourceCodeHash": "0x617aa994f659c5d8ebd54128d994f86f5b175ceca095b024b8524a7898e8ae62"
}, },
"src/L2/SuperchainWETH.sol": { "src/L2/SuperchainWETH.sol": {
"initCodeHash": "0xb74ce648b49e3b7885a3252ff32aeb71e8cb515558f516c0dd61f1cf22028edc", "initCodeHash": "0x5aef986a7c9c102b1e9b3068e2a2b66adce0a71dd5f39e03694622bf494f8d97",
"sourceCodeHash": "0x095de6eeb2cd06937b3fe014392048bc494cb5ca7a4a5fd5519141a80eae3a76" "sourceCodeHash": "0xa62101a23b860e97f393027c898082a1c73d50679eceb6c6793844af29702359"
}, },
"src/L2/WETH.sol": { "src/L2/WETH.sol": {
"initCodeHash": "0x480d4f8dbec1b0d3211bccbbdfb69796f3e90c784f724b1bbfd4703b0aafdeba", "initCodeHash": "0x17ea1b1c5d5a622d51c2961fde886a5498de63584e654ed1d69ee80dddbe0b17",
"sourceCodeHash": "0x59a210accdd484cf00e63042cde4687e1c87ef9dbafa5fe2e081dee8e6563621" "sourceCodeHash": "0x0fa0633a769e73f5937514c0003ba7947a1c275bbe5b85d78879c42f0ed8895b"
}, },
"src/cannon/MIPS.sol": { "src/cannon/MIPS.sol": {
"initCodeHash": "0xa3cbf121bad13c00227ea4fef128853d9a86b7ec9158de894f99b58d38d7630a", "initCodeHash": "0xa3cbf121bad13c00227ea4fef128853d9a86b7ec9158de894f99b58d38d7630a",
...@@ -227,9 +215,17 @@ ...@@ -227,9 +215,17 @@
"initCodeHash": "0x9cd677275b175812f1d5f90a127dbf7b3592714fd842a7a0de3988d716ca3eac", "initCodeHash": "0x9cd677275b175812f1d5f90a127dbf7b3592714fd842a7a0de3988d716ca3eac",
"sourceCodeHash": "0x5611d8082f68af566554d7f09640b4b1f0e3efee4da1372b68fc7fc538a35ac7" "sourceCodeHash": "0x5611d8082f68af566554d7f09640b4b1f0e3efee4da1372b68fc7fc538a35ac7"
}, },
"src/universal/OptimismMintableERC20Factory.sol": {
"initCodeHash": "0x03ad07bd7f89a29f1850fa8b5d377daf0e1d5aef6cb458a127df520549e8e8e6",
"sourceCodeHash": "0xdb6ec93782a4a217475195507740794a4f5553b9032e7ba31dc48b81f579a940"
},
"src/universal/OptimismMintableERC721.sol": { "src/universal/OptimismMintableERC721.sol": {
"initCodeHash": "0x406ff004414b60852afe6ee6783ac03157ebcbe7e4787740a94576594fdfe912", "initCodeHash": "0x8aa309f2676d5267b6c9e411f88dc6e4badce414b8d66b330df3f60e9836380e",
"sourceCodeHash": "0x8b4292d7556907b597d9fd3ccd5bcd8b8d61bf8e32c5a7a33d4de2557414c830" "sourceCodeHash": "0x03bf7ad4d2b751bdead9930fc8f89b8e55d40dd4b2f5670fd339e87ae81f8b49"
},
"src/universal/OptimismMintableERC721Factory.sol": {
"initCodeHash": "0x5ea977ba35558c3b75bebe28900548c763d205e40d6cf7660292b8e96bf3aea8",
"sourceCodeHash": "0x063ca3a0a2e3c592173af6157e383b5aaeff752000f98648a5c71260bb26590a"
}, },
"src/universal/StorageSetter.sol": { "src/universal/StorageSetter.sol": {
"initCodeHash": "0x21b3059e9b13b330f76d02b61f61dcfa3abf3517a0b56afa0895c4b8291740bf", "initCodeHash": "0x21b3059e9b13b330f76d02b61f61dcfa3abf3517a0b56afa0895c4b8291740bf",
......
[ [
{
"inputs": [
{
"internalType": "address",
"name": "_recipient",
"type": "address"
},
{
"internalType": "uint256",
"name": "_minWithdrawalAmount",
"type": "uint256"
},
{
"internalType": "enum Types.WithdrawalNetwork",
"name": "_withdrawalNetwork",
"type": "uint8"
}
],
"stateMutability": "nonpayable",
"type": "constructor"
},
{ {
"stateMutability": "payable", "stateMutability": "payable",
"type": "receive" "type": "receive"
...@@ -35,30 +56,7 @@ ...@@ -35,30 +56,7 @@
"outputs": [ "outputs": [
{ {
"internalType": "enum Types.WithdrawalNetwork", "internalType": "enum Types.WithdrawalNetwork",
"name": "withdrawalNetwork_", "name": "",
"type": "uint8"
}
],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [],
"name": "config",
"outputs": [
{
"internalType": "address",
"name": "recipient_",
"type": "address"
},
{
"internalType": "uint256",
"name": "amount_",
"type": "uint256"
},
{
"internalType": "enum Types.WithdrawalNetwork",
"name": "withdrawalNetwork_",
"type": "uint8" "type": "uint8"
} }
], ],
...@@ -130,7 +128,7 @@ ...@@ -130,7 +128,7 @@
"outputs": [ "outputs": [
{ {
"internalType": "enum Types.WithdrawalNetwork", "internalType": "enum Types.WithdrawalNetwork",
"name": "withdrawalNetwork_", "name": "network_",
"type": "uint8" "type": "uint8"
} }
], ],
......
...@@ -121,25 +121,6 @@ ...@@ -121,25 +121,6 @@
"stateMutability": "view", "stateMutability": "view",
"type": "function" "type": "function"
}, },
{
"inputs": [
{
"internalType": "enum Types.ConfigType",
"name": "_type",
"type": "uint8"
}
],
"name": "getConfig",
"outputs": [
{
"internalType": "bytes",
"name": "data_",
"type": "bytes"
}
],
"stateMutability": "view",
"type": "function"
},
{ {
"inputs": [], "inputs": [],
"name": "hash", "name": "hash",
...@@ -166,19 +147,6 @@ ...@@ -166,19 +147,6 @@
"stateMutability": "view", "stateMutability": "view",
"type": "function" "type": "function"
}, },
{
"inputs": [],
"name": "isIsthmus",
"outputs": [
{
"internalType": "bool",
"name": "",
"type": "bool"
}
],
"stateMutability": "view",
"type": "function"
},
{ {
"inputs": [], "inputs": [],
"name": "l1FeeOverhead", "name": "l1FeeOverhead",
...@@ -231,24 +199,6 @@ ...@@ -231,24 +199,6 @@
"stateMutability": "view", "stateMutability": "view",
"type": "function" "type": "function"
}, },
{
"inputs": [
{
"internalType": "enum Types.ConfigType",
"name": "_type",
"type": "uint8"
},
{
"internalType": "bytes",
"name": "_value",
"type": "bytes"
}
],
"name": "setConfig",
"outputs": [],
"stateMutability": "nonpayable",
"type": "function"
},
{ {
"inputs": [ "inputs": [
{ {
...@@ -277,13 +227,6 @@ ...@@ -277,13 +227,6 @@
"stateMutability": "nonpayable", "stateMutability": "nonpayable",
"type": "function" "type": "function"
}, },
{
"inputs": [],
"name": "setIsthmus",
"outputs": [],
"stateMutability": "nonpayable",
"type": "function"
},
{ {
"inputs": [ "inputs": [
{ {
...@@ -400,10 +343,5 @@ ...@@ -400,10 +343,5 @@
"inputs": [], "inputs": [],
"name": "NotDepositor", "name": "NotDepositor",
"type": "error" "type": "error"
},
{
"inputs": [],
"name": "UnsafeCast",
"type": "error"
} }
] ]
\ No newline at end of file
...@@ -141,25 +141,6 @@ ...@@ -141,25 +141,6 @@
"stateMutability": "view", "stateMutability": "view",
"type": "function" "type": "function"
}, },
{
"inputs": [
{
"internalType": "enum Types.ConfigType",
"name": "_type",
"type": "uint8"
}
],
"name": "getConfig",
"outputs": [
{
"internalType": "bytes",
"name": "data_",
"type": "bytes"
}
],
"stateMutability": "view",
"type": "function"
},
{ {
"inputs": [], "inputs": [],
"name": "hash", "name": "hash",
...@@ -218,19 +199,6 @@ ...@@ -218,19 +199,6 @@
"stateMutability": "view", "stateMutability": "view",
"type": "function" "type": "function"
}, },
{
"inputs": [],
"name": "isIsthmus",
"outputs": [
{
"internalType": "bool",
"name": "",
"type": "bool"
}
],
"stateMutability": "view",
"type": "function"
},
{ {
"inputs": [], "inputs": [],
"name": "l1FeeOverhead", "name": "l1FeeOverhead",
...@@ -286,7 +254,7 @@ ...@@ -286,7 +254,7 @@
{ {
"inputs": [ "inputs": [
{ {
"internalType": "enum Types.ConfigType", "internalType": "enum ConfigType",
"name": "_type", "name": "_type",
"type": "uint8" "type": "uint8"
}, },
...@@ -329,13 +297,6 @@ ...@@ -329,13 +297,6 @@
"stateMutability": "nonpayable", "stateMutability": "nonpayable",
"type": "function" "type": "function"
}, },
{
"inputs": [],
"name": "setIsthmus",
"outputs": [],
"stateMutability": "nonpayable",
"type": "function"
},
{ {
"inputs": [ "inputs": [
{ {
...@@ -510,10 +471,5 @@ ...@@ -510,10 +471,5 @@
"inputs": [], "inputs": [],
"name": "NotDepositor", "name": "NotDepositor",
"type": "error" "type": "error"
},
{
"inputs": [],
"name": "UnsafeCast",
"type": "error"
} }
] ]
\ No newline at end of file
...@@ -223,7 +223,7 @@ ...@@ -223,7 +223,7 @@
"type": "address" "type": "address"
} }
], ],
"stateMutability": "pure", "stateMutability": "view",
"type": "function" "type": "function"
}, },
{ {
......
...@@ -209,7 +209,7 @@ ...@@ -209,7 +209,7 @@
"type": "address" "type": "address"
} }
], ],
"stateMutability": "pure", "stateMutability": "view",
"type": "function" "type": "function"
}, },
{ {
...@@ -342,22 +342,12 @@ ...@@ -342,22 +342,12 @@
"inputs": [ "inputs": [
{ {
"indexed": false, "indexed": false,
"internalType": "uint64", "internalType": "uint8",
"name": "version", "name": "version",
"type": "uint64" "type": "uint8"
} }
], ],
"name": "Initialized", "name": "Initialized",
"type": "event" "type": "event"
},
{
"inputs": [],
"name": "InvalidInitialization",
"type": "error"
},
{
"inputs": [],
"name": "NotInitializing",
"type": "error"
} }
] ]
\ No newline at end of file
[ [
{
"inputs": [
{
"internalType": "address",
"name": "_recipient",
"type": "address"
},
{
"internalType": "uint256",
"name": "_minWithdrawalAmount",
"type": "uint256"
},
{
"internalType": "enum Types.WithdrawalNetwork",
"name": "_withdrawalNetwork",
"type": "uint8"
}
],
"stateMutability": "nonpayable",
"type": "constructor"
},
{ {
"stateMutability": "payable", "stateMutability": "payable",
"type": "receive" "type": "receive"
...@@ -35,30 +56,7 @@ ...@@ -35,30 +56,7 @@
"outputs": [ "outputs": [
{ {
"internalType": "enum Types.WithdrawalNetwork", "internalType": "enum Types.WithdrawalNetwork",
"name": "withdrawalNetwork_", "name": "",
"type": "uint8"
}
],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [],
"name": "config",
"outputs": [
{
"internalType": "address",
"name": "recipient_",
"type": "address"
},
{
"internalType": "uint256",
"name": "amount_",
"type": "uint256"
},
{
"internalType": "enum Types.WithdrawalNetwork",
"name": "withdrawalNetwork_",
"type": "uint8" "type": "uint8"
} }
], ],
...@@ -130,7 +128,7 @@ ...@@ -130,7 +128,7 @@
"outputs": [ "outputs": [
{ {
"internalType": "enum Types.WithdrawalNetwork", "internalType": "enum Types.WithdrawalNetwork",
"name": "withdrawalNetwork_", "name": "network_",
"type": "uint8" "type": "uint8"
} }
], ],
......
...@@ -26,7 +26,7 @@ ...@@ -26,7 +26,7 @@
"name": "OTHER_BRIDGE", "name": "OTHER_BRIDGE",
"outputs": [ "outputs": [
{ {
"internalType": "contract IStandardBridge", "internalType": "contract StandardBridge",
"name": "", "name": "",
"type": "address" "type": "address"
} }
...@@ -447,7 +447,7 @@ ...@@ -447,7 +447,7 @@
"type": "address" "type": "address"
} }
], ],
"stateMutability": "pure", "stateMutability": "view",
"type": "function" "type": "function"
}, },
{ {
...@@ -468,12 +468,12 @@ ...@@ -468,12 +468,12 @@
"name": "otherBridge", "name": "otherBridge",
"outputs": [ "outputs": [
{ {
"internalType": "contract IStandardBridge", "internalType": "contract StandardBridge",
"name": "", "name": "",
"type": "address" "type": "address"
} }
], ],
"stateMutability": "pure", "stateMutability": "view",
"type": "function" "type": "function"
}, },
{ {
......
[ [
{
"inputs": [],
"stateMutability": "nonpayable",
"type": "constructor"
},
{ {
"inputs": [], "inputs": [],
"name": "MESSAGE_VERSION", "name": "MESSAGE_VERSION",
...@@ -159,6 +164,19 @@ ...@@ -159,6 +164,19 @@
"stateMutability": "view", "stateMutability": "view",
"type": "function" "type": "function"
}, },
{
"inputs": [
{
"internalType": "contract CrossDomainMessenger",
"name": "_l1CrossDomainMessenger",
"type": "address"
}
],
"name": "initialize",
"outputs": [],
"stateMutability": "nonpayable",
"type": "function"
},
{ {
"inputs": [], "inputs": [],
"name": "l1CrossDomainMessenger", "name": "l1CrossDomainMessenger",
...@@ -330,6 +348,19 @@ ...@@ -330,6 +348,19 @@
"name": "FailedRelayedMessage", "name": "FailedRelayedMessage",
"type": "event" "type": "event"
}, },
{
"anonymous": false,
"inputs": [
{
"indexed": false,
"internalType": "uint8",
"name": "version",
"type": "uint8"
}
],
"name": "Initialized",
"type": "event"
},
{ {
"anonymous": false, "anonymous": false,
"inputs": [ "inputs": [
......
[ [
{
"inputs": [],
"stateMutability": "nonpayable",
"type": "constructor"
},
{ {
"inputs": [], "inputs": [],
"name": "MESSENGER", "name": "MESSENGER",
...@@ -134,6 +139,19 @@ ...@@ -134,6 +139,19 @@
"stateMutability": "nonpayable", "stateMutability": "nonpayable",
"type": "function" "type": "function"
}, },
{
"inputs": [
{
"internalType": "address payable",
"name": "_l1ERC721Bridge",
"type": "address"
}
],
"name": "initialize",
"outputs": [],
"stateMutability": "nonpayable",
"type": "function"
},
{ {
"inputs": [], "inputs": [],
"name": "messenger", "name": "messenger",
...@@ -144,7 +162,7 @@ ...@@ -144,7 +162,7 @@
"type": "address" "type": "address"
} }
], ],
"stateMutability": "pure", "stateMutability": "view",
"type": "function" "type": "function"
}, },
{ {
...@@ -271,5 +289,18 @@ ...@@ -271,5 +289,18 @@
], ],
"name": "ERC721BridgeInitiated", "name": "ERC721BridgeInitiated",
"type": "event" "type": "event"
},
{
"anonymous": false,
"inputs": [
{
"indexed": false,
"internalType": "uint8",
"name": "version",
"type": "uint8"
}
],
"name": "Initialized",
"type": "event"
} }
] ]
\ No newline at end of file
[
{
"inputs": [],
"name": "BRIDGE",
"outputs": [
{
"internalType": "address",
"name": "",
"type": "address"
}
],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [],
"name": "bridge",
"outputs": [
{
"internalType": "address",
"name": "",
"type": "address"
}
],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [
{
"internalType": "address",
"name": "_remoteToken",
"type": "address"
},
{
"internalType": "string",
"name": "_name",
"type": "string"
},
{
"internalType": "string",
"name": "_symbol",
"type": "string"
}
],
"name": "createOptimismMintableERC20",
"outputs": [
{
"internalType": "address",
"name": "",
"type": "address"
}
],
"stateMutability": "nonpayable",
"type": "function"
},
{
"inputs": [
{
"internalType": "address",
"name": "_remoteToken",
"type": "address"
},
{
"internalType": "string",
"name": "_name",
"type": "string"
},
{
"internalType": "string",
"name": "_symbol",
"type": "string"
},
{
"internalType": "uint8",
"name": "_decimals",
"type": "uint8"
}
],
"name": "createOptimismMintableERC20WithDecimals",
"outputs": [
{
"internalType": "address",
"name": "",
"type": "address"
}
],
"stateMutability": "nonpayable",
"type": "function"
},
{
"inputs": [
{
"internalType": "address",
"name": "_remoteToken",
"type": "address"
},
{
"internalType": "string",
"name": "_name",
"type": "string"
},
{
"internalType": "string",
"name": "_symbol",
"type": "string"
}
],
"name": "createStandardL2Token",
"outputs": [
{
"internalType": "address",
"name": "",
"type": "address"
}
],
"stateMutability": "nonpayable",
"type": "function"
},
{
"inputs": [
{
"internalType": "address",
"name": "",
"type": "address"
}
],
"name": "deployments",
"outputs": [
{
"internalType": "address",
"name": "",
"type": "address"
}
],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [],
"name": "version",
"outputs": [
{
"internalType": "string",
"name": "",
"type": "string"
}
],
"stateMutability": "view",
"type": "function"
},
{
"anonymous": false,
"inputs": [
{
"indexed": true,
"internalType": "address",
"name": "localToken",
"type": "address"
},
{
"indexed": true,
"internalType": "address",
"name": "remoteToken",
"type": "address"
},
{
"indexed": false,
"internalType": "address",
"name": "deployer",
"type": "address"
}
],
"name": "OptimismMintableERC20Created",
"type": "event"
},
{
"anonymous": false,
"inputs": [
{
"indexed": true,
"internalType": "address",
"name": "remoteToken",
"type": "address"
},
{
"indexed": true,
"internalType": "address",
"name": "localToken",
"type": "address"
}
],
"name": "StandardL2TokenCreated",
"type": "event"
}
]
\ No newline at end of file
[
{
"inputs": [],
"stateMutability": "nonpayable",
"type": "constructor"
},
{
"inputs": [],
"name": "addressManager",
"outputs": [
{
"internalType": "contract IAddressManager",
"name": "",
"type": "address"
}
],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [
{
"internalType": "address payable",
"name": "_proxy",
"type": "address"
},
{
"internalType": "address",
"name": "_newAdmin",
"type": "address"
}
],
"name": "changeProxyAdmin",
"outputs": [],
"stateMutability": "nonpayable",
"type": "function"
},
{
"inputs": [
{
"internalType": "address payable",
"name": "_proxy",
"type": "address"
}
],
"name": "getProxyAdmin",
"outputs": [
{
"internalType": "address",
"name": "",
"type": "address"
}
],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [
{
"internalType": "address",
"name": "_proxy",
"type": "address"
}
],
"name": "getProxyImplementation",
"outputs": [
{
"internalType": "address",
"name": "",
"type": "address"
}
],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [
{
"internalType": "address",
"name": "",
"type": "address"
}
],
"name": "implementationName",
"outputs": [
{
"internalType": "string",
"name": "",
"type": "string"
}
],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [],
"name": "isUpgrading",
"outputs": [
{
"internalType": "bool",
"name": "",
"type": "bool"
}
],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [],
"name": "owner",
"outputs": [
{
"internalType": "address",
"name": "",
"type": "address"
}
],
"stateMutability": "pure",
"type": "function"
},
{
"inputs": [
{
"internalType": "address",
"name": "",
"type": "address"
}
],
"name": "proxyType",
"outputs": [
{
"internalType": "enum ProxyAdmin.ProxyType",
"name": "",
"type": "uint8"
}
],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [],
"name": "renounceOwnership",
"outputs": [],
"stateMutability": "nonpayable",
"type": "function"
},
{
"inputs": [
{
"internalType": "string",
"name": "_name",
"type": "string"
},
{
"internalType": "address",
"name": "_address",
"type": "address"
}
],
"name": "setAddress",
"outputs": [],
"stateMutability": "nonpayable",
"type": "function"
},
{
"inputs": [
{
"internalType": "contract IAddressManager",
"name": "_address",
"type": "address"
}
],
"name": "setAddressManager",
"outputs": [],
"stateMutability": "nonpayable",
"type": "function"
},
{
"inputs": [
{
"internalType": "address",
"name": "_address",
"type": "address"
},
{
"internalType": "string",
"name": "_name",
"type": "string"
}
],
"name": "setImplementationName",
"outputs": [],
"stateMutability": "nonpayable",
"type": "function"
},
{
"inputs": [
{
"internalType": "address",
"name": "_address",
"type": "address"
},
{
"internalType": "enum ProxyAdmin.ProxyType",
"name": "_type",
"type": "uint8"
}
],
"name": "setProxyType",
"outputs": [],
"stateMutability": "nonpayable",
"type": "function"
},
{
"inputs": [
{
"internalType": "bool",
"name": "_upgrading",
"type": "bool"
}
],
"name": "setUpgrading",
"outputs": [],
"stateMutability": "nonpayable",
"type": "function"
},
{
"inputs": [
{
"internalType": "address",
"name": "newOwner",
"type": "address"
}
],
"name": "transferOwnership",
"outputs": [],
"stateMutability": "nonpayable",
"type": "function"
},
{
"inputs": [
{
"internalType": "address payable",
"name": "_proxy",
"type": "address"
},
{
"internalType": "address",
"name": "_implementation",
"type": "address"
}
],
"name": "upgrade",
"outputs": [],
"stateMutability": "nonpayable",
"type": "function"
},
{
"inputs": [
{
"internalType": "address payable",
"name": "_proxy",
"type": "address"
},
{
"internalType": "address",
"name": "_implementation",
"type": "address"
},
{
"internalType": "bytes",
"name": "_data",
"type": "bytes"
}
],
"name": "upgradeAndCall",
"outputs": [],
"stateMutability": "payable",
"type": "function"
},
{
"anonymous": false,
"inputs": [
{
"indexed": true,
"internalType": "address",
"name": "previousOwner",
"type": "address"
},
{
"indexed": true,
"internalType": "address",
"name": "newOwner",
"type": "address"
}
],
"name": "OwnershipTransferred",
"type": "event"
}
]
\ No newline at end of file
[ [
{
"inputs": [],
"stateMutability": "nonpayable",
"type": "constructor"
},
{ {
"stateMutability": "payable", "stateMutability": "payable",
"type": "receive" "type": "receive"
...@@ -21,7 +26,7 @@ ...@@ -21,7 +26,7 @@
"name": "OTHER_BRIDGE", "name": "OTHER_BRIDGE",
"outputs": [ "outputs": [
{ {
"internalType": "contract IStandardBridge", "internalType": "contract StandardBridge",
"name": "", "name": "",
"type": "address" "type": "address"
} }
...@@ -231,6 +236,19 @@ ...@@ -231,6 +236,19 @@
"stateMutability": "payable", "stateMutability": "payable",
"type": "function" "type": "function"
}, },
{
"inputs": [
{
"internalType": "contract StandardBridge",
"name": "_otherBridge",
"type": "address"
}
],
"name": "initialize",
"outputs": [],
"stateMutability": "nonpayable",
"type": "function"
},
{ {
"inputs": [], "inputs": [],
"name": "l1TokenBridge", "name": "l1TokenBridge",
...@@ -254,7 +272,7 @@ ...@@ -254,7 +272,7 @@
"type": "address" "type": "address"
} }
], ],
"stateMutability": "pure", "stateMutability": "view",
"type": "function" "type": "function"
}, },
{ {
...@@ -262,7 +280,7 @@ ...@@ -262,7 +280,7 @@
"name": "otherBridge", "name": "otherBridge",
"outputs": [ "outputs": [
{ {
"internalType": "contract IStandardBridge", "internalType": "contract StandardBridge",
"name": "", "name": "",
"type": "address" "type": "address"
} }
...@@ -548,6 +566,19 @@ ...@@ -548,6 +566,19 @@
"name": "ETHBridgeInitiated", "name": "ETHBridgeInitiated",
"type": "event" "type": "event"
}, },
{
"anonymous": false,
"inputs": [
{
"indexed": false,
"internalType": "uint8",
"name": "version",
"type": "uint8"
}
],
"name": "Initialized",
"type": "event"
},
{ {
"anonymous": false, "anonymous": false,
"inputs": [ "inputs": [
......
...@@ -21,7 +21,7 @@ ...@@ -21,7 +21,7 @@
"name": "OTHER_BRIDGE", "name": "OTHER_BRIDGE",
"outputs": [ "outputs": [
{ {
"internalType": "contract IStandardBridge", "internalType": "contract StandardBridge",
"name": "", "name": "",
"type": "address" "type": "address"
} }
...@@ -254,6 +254,19 @@ ...@@ -254,6 +254,19 @@
"stateMutability": "payable", "stateMutability": "payable",
"type": "function" "type": "function"
}, },
{
"inputs": [
{
"internalType": "contract StandardBridge",
"name": "_otherBridge",
"type": "address"
}
],
"name": "initialize",
"outputs": [],
"stateMutability": "nonpayable",
"type": "function"
},
{ {
"inputs": [], "inputs": [],
"name": "l1TokenBridge", "name": "l1TokenBridge",
...@@ -277,7 +290,7 @@ ...@@ -277,7 +290,7 @@
"type": "address" "type": "address"
} }
], ],
"stateMutability": "pure", "stateMutability": "view",
"type": "function" "type": "function"
}, },
{ {
...@@ -285,7 +298,7 @@ ...@@ -285,7 +298,7 @@
"name": "otherBridge", "name": "otherBridge",
"outputs": [ "outputs": [
{ {
"internalType": "contract IStandardBridge", "internalType": "contract StandardBridge",
"name": "", "name": "",
"type": "address" "type": "address"
} }
...@@ -602,6 +615,19 @@ ...@@ -602,6 +615,19 @@
"name": "ETHBridgeInitiated", "name": "ETHBridgeInitiated",
"type": "event" "type": "event"
}, },
{
"anonymous": false,
"inputs": [
{
"indexed": false,
"internalType": "uint8",
"name": "version",
"type": "uint8"
}
],
"name": "Initialized",
"type": "event"
},
{ {
"anonymous": false, "anonymous": false,
"inputs": [ "inputs": [
......
...@@ -137,11 +137,6 @@ ...@@ -137,11 +137,6 @@
"internalType": "address", "internalType": "address",
"name": "challenger", "name": "challenger",
"type": "address" "type": "address"
},
{
"internalType": "address",
"name": "systemConfigFeeAdmin",
"type": "address"
} }
], ],
"internalType": "struct OPContractsManager.Roles", "internalType": "struct OPContractsManager.Roles",
......
...@@ -137,11 +137,6 @@ ...@@ -137,11 +137,6 @@
"internalType": "address", "internalType": "address",
"name": "challenger", "name": "challenger",
"type": "address" "type": "address"
},
{
"internalType": "address",
"name": "systemConfigFeeAdmin",
"type": "address"
} }
], ],
"internalType": "struct OPContractsManager.Roles", "internalType": "struct OPContractsManager.Roles",
......
...@@ -2,7 +2,7 @@ ...@@ -2,7 +2,7 @@
{ {
"inputs": [ "inputs": [
{ {
"internalType": "contract IL2ERC721Bridge", "internalType": "address",
"name": "_bridge", "name": "_bridge",
"type": "address" "type": "address"
}, },
...@@ -35,7 +35,7 @@ ...@@ -35,7 +35,7 @@
"name": "BRIDGE", "name": "BRIDGE",
"outputs": [ "outputs": [
{ {
"internalType": "contract IL2ERC721Bridge", "internalType": "address",
"name": "", "name": "",
"type": "address" "type": "address"
} }
...@@ -124,7 +124,7 @@ ...@@ -124,7 +124,7 @@
"name": "bridge", "name": "bridge",
"outputs": [ "outputs": [
{ {
"internalType": "contract IL2ERC721Bridge", "internalType": "address",
"name": "", "name": "",
"type": "address" "type": "address"
} }
......
[ [
{
"inputs": [
{
"internalType": "address",
"name": "_bridge",
"type": "address"
},
{
"internalType": "uint256",
"name": "_remoteChainId",
"type": "uint256"
}
],
"stateMutability": "nonpayable",
"type": "constructor"
},
{ {
"inputs": [], "inputs": [],
"name": "BRIDGE", "name": "BRIDGE",
"outputs": [ "outputs": [
{ {
"internalType": "contract IL2ERC721Bridge", "internalType": "address",
"name": "", "name": "",
"type": "address" "type": "address"
} }
], ],
"stateMutability": "pure", "stateMutability": "view",
"type": "function" "type": "function"
}, },
{ {
...@@ -30,12 +46,12 @@ ...@@ -30,12 +46,12 @@
"name": "bridge", "name": "bridge",
"outputs": [ "outputs": [
{ {
"internalType": "contract IL2ERC721Bridge", "internalType": "address",
"name": "", "name": "",
"type": "address" "type": "address"
} }
], ],
"stateMutability": "pure", "stateMutability": "view",
"type": "function" "type": "function"
}, },
{ {
...@@ -88,7 +104,7 @@ ...@@ -88,7 +104,7 @@
}, },
{ {
"inputs": [], "inputs": [],
"name": "remoteChainId", "name": "remoteChainID",
"outputs": [ "outputs": [
{ {
"internalType": "uint256", "internalType": "uint256",
......
...@@ -413,17 +413,27 @@ ...@@ -413,17 +413,27 @@
{ {
"inputs": [ "inputs": [
{ {
"internalType": "enum Types.ConfigType", "internalType": "address",
"name": "_type", "name": "_token",
"type": "address"
},
{
"internalType": "uint8",
"name": "_decimals",
"type": "uint8" "type": "uint8"
}, },
{ {
"internalType": "bytes", "internalType": "bytes32",
"name": "_value", "name": "_name",
"type": "bytes" "type": "bytes32"
},
{
"internalType": "bytes32",
"name": "_symbol",
"type": "bytes32"
} }
], ],
"name": "setConfig", "name": "setGasPayingToken",
"outputs": [], "outputs": [],
"stateMutability": "nonpayable", "stateMutability": "nonpayable",
"type": "function" "type": "function"
......
...@@ -605,17 +605,27 @@ ...@@ -605,17 +605,27 @@
{ {
"inputs": [ "inputs": [
{ {
"internalType": "enum Types.ConfigType", "internalType": "address",
"name": "_type", "name": "_token",
"type": "address"
},
{
"internalType": "uint8",
"name": "_decimals",
"type": "uint8" "type": "uint8"
}, },
{ {
"internalType": "bytes", "internalType": "bytes32",
"name": "_value", "name": "_name",
"type": "bytes" "type": "bytes32"
},
{
"internalType": "bytes32",
"name": "_symbol",
"type": "bytes32"
} }
], ],
"name": "setConfig", "name": "setGasPayingToken",
"outputs": [], "outputs": [],
"stateMutability": "nonpayable", "stateMutability": "nonpayable",
"type": "function" "type": "function"
...@@ -659,24 +669,6 @@ ...@@ -659,24 +669,6 @@
"stateMutability": "view", "stateMutability": "view",
"type": "function" "type": "function"
}, },
{
"inputs": [
{
"internalType": "uint32",
"name": "_gasLimit",
"type": "uint32"
},
{
"internalType": "bytes",
"name": "_calldata",
"type": "bytes"
}
],
"name": "upgrade",
"outputs": [],
"stateMutability": "nonpayable",
"type": "function"
},
{ {
"inputs": [], "inputs": [],
"name": "version", "name": "version",
......
...@@ -605,7 +605,7 @@ ...@@ -605,7 +605,7 @@
{ {
"inputs": [ "inputs": [
{ {
"internalType": "enum Types.ConfigType", "internalType": "enum ConfigType",
"name": "_type", "name": "_type",
"type": "uint8" "type": "uint8"
}, },
...@@ -620,6 +620,34 @@ ...@@ -620,6 +620,34 @@
"stateMutability": "nonpayable", "stateMutability": "nonpayable",
"type": "function" "type": "function"
}, },
{
"inputs": [
{
"internalType": "address",
"name": "_token",
"type": "address"
},
{
"internalType": "uint8",
"name": "_decimals",
"type": "uint8"
},
{
"internalType": "bytes32",
"name": "_name",
"type": "bytes32"
},
{
"internalType": "bytes32",
"name": "_symbol",
"type": "bytes32"
}
],
"name": "setGasPayingToken",
"outputs": [],
"stateMutability": "nonpayable",
"type": "function"
},
{ {
"inputs": [ "inputs": [
{ {
...@@ -659,24 +687,6 @@ ...@@ -659,24 +687,6 @@
"stateMutability": "view", "stateMutability": "view",
"type": "function" "type": "function"
}, },
{
"inputs": [
{
"internalType": "uint32",
"name": "_gasLimit",
"type": "uint32"
},
{
"internalType": "bytes",
"name": "_calldata",
"type": "bytes"
}
],
"name": "upgrade",
"outputs": [],
"stateMutability": "nonpayable",
"type": "function"
},
{ {
"inputs": [], "inputs": [],
"name": "version", "name": "version",
......
[ [
{
"inputs": [
{
"internalType": "address",
"name": "_recipient",
"type": "address"
},
{
"internalType": "uint256",
"name": "_minWithdrawalAmount",
"type": "uint256"
},
{
"internalType": "enum Types.WithdrawalNetwork",
"name": "_withdrawalNetwork",
"type": "uint8"
}
],
"stateMutability": "nonpayable",
"type": "constructor"
},
{ {
"stateMutability": "payable", "stateMutability": "payable",
"type": "receive" "type": "receive"
...@@ -35,30 +56,7 @@ ...@@ -35,30 +56,7 @@
"outputs": [ "outputs": [
{ {
"internalType": "enum Types.WithdrawalNetwork", "internalType": "enum Types.WithdrawalNetwork",
"name": "withdrawalNetwork_", "name": "",
"type": "uint8"
}
],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [],
"name": "config",
"outputs": [
{
"internalType": "address",
"name": "recipient_",
"type": "address"
},
{
"internalType": "uint256",
"name": "amount_",
"type": "uint256"
},
{
"internalType": "enum Types.WithdrawalNetwork",
"name": "withdrawalNetwork_",
"type": "uint8" "type": "uint8"
} }
], ],
...@@ -71,7 +69,7 @@ ...@@ -71,7 +69,7 @@
"outputs": [ "outputs": [
{ {
"internalType": "address", "internalType": "address",
"name": "recipient_", "name": "",
"type": "address" "type": "address"
} }
], ],
...@@ -143,7 +141,7 @@ ...@@ -143,7 +141,7 @@
"outputs": [ "outputs": [
{ {
"internalType": "enum Types.WithdrawalNetwork", "internalType": "enum Types.WithdrawalNetwork",
"name": "withdrawalNetwork_", "name": "network_",
"type": "uint8" "type": "uint8"
} }
], ],
......
...@@ -30,19 +30,6 @@ ...@@ -30,19 +30,6 @@
"stateMutability": "view", "stateMutability": "view",
"type": "function" "type": "function"
}, },
{
"inputs": [],
"name": "UPGRADER_SLOT",
"outputs": [
{
"internalType": "bytes32",
"name": "",
"type": "bytes32"
}
],
"stateMutability": "view",
"type": "function"
},
{ {
"inputs": [], "inputs": [],
"name": "guardian", "name": "guardian",
...@@ -63,11 +50,6 @@ ...@@ -63,11 +50,6 @@
"name": "_guardian", "name": "_guardian",
"type": "address" "type": "address"
}, },
{
"internalType": "address",
"name": "_upgrader",
"type": "address"
},
{ {
"internalType": "bool", "internalType": "bool",
"name": "_paused", "name": "_paused",
...@@ -112,19 +94,6 @@ ...@@ -112,19 +94,6 @@
"stateMutability": "nonpayable", "stateMutability": "nonpayable",
"type": "function" "type": "function"
}, },
{
"inputs": [],
"name": "upgrader",
"outputs": [
{
"internalType": "address",
"name": "upgrader_",
"type": "address"
}
],
"stateMutability": "view",
"type": "function"
},
{ {
"inputs": [], "inputs": [],
"name": "version", "name": "version",
......
...@@ -225,19 +225,6 @@ ...@@ -225,19 +225,6 @@
"stateMutability": "view", "stateMutability": "view",
"type": "function" "type": "function"
}, },
{
"inputs": [],
"name": "feeAdmin",
"outputs": [
{
"internalType": "address",
"name": "addr_",
"type": "address"
}
],
"stateMutability": "view",
"type": "function"
},
{ {
"inputs": [], "inputs": [],
"name": "gasLimit", "name": "gasLimit",
...@@ -297,33 +284,11 @@ ...@@ -297,33 +284,11 @@
}, },
{ {
"inputs": [ "inputs": [
{
"components": [
{ {
"internalType": "address", "internalType": "address",
"name": "owner", "name": "_owner",
"type": "address" "type": "address"
}, },
{
"internalType": "address",
"name": "feeAdmin",
"type": "address"
},
{
"internalType": "address",
"name": "unsafeBlockSigner",
"type": "address"
},
{
"internalType": "bytes32",
"name": "batcherHash",
"type": "bytes32"
}
],
"internalType": "struct SystemConfig.Roles",
"name": "_roles",
"type": "tuple"
},
{ {
"internalType": "uint32", "internalType": "uint32",
"name": "_basefeeScalar", "name": "_basefeeScalar",
...@@ -334,11 +299,21 @@ ...@@ -334,11 +299,21 @@
"name": "_blobbasefeeScalar", "name": "_blobbasefeeScalar",
"type": "uint32" "type": "uint32"
}, },
{
"internalType": "bytes32",
"name": "_batcherHash",
"type": "bytes32"
},
{ {
"internalType": "uint64", "internalType": "uint64",
"name": "_gasLimit", "name": "_gasLimit",
"type": "uint64" "type": "uint64"
}, },
{
"internalType": "address",
"name": "_unsafeBlockSigner",
"type": "address"
},
{ {
"components": [ "components": [
{ {
...@@ -655,34 +630,6 @@ ...@@ -655,34 +630,6 @@
"stateMutability": "nonpayable", "stateMutability": "nonpayable",
"type": "function" "type": "function"
}, },
{
"inputs": [
{
"internalType": "enum Types.ConfigType",
"name": "_type",
"type": "uint8"
},
{
"internalType": "address",
"name": "_recipient",
"type": "address"
},
{
"internalType": "uint256",
"name": "_min",
"type": "uint256"
},
{
"internalType": "enum Types.WithdrawalNetwork",
"name": "_network",
"type": "uint8"
}
],
"name": "setFeeVaultConfig",
"outputs": [],
"stateMutability": "nonpayable",
"type": "function"
},
{ {
"inputs": [ "inputs": [
{ {
...@@ -853,10 +800,5 @@ ...@@ -853,10 +800,5 @@
], ],
"name": "OwnershipTransferred", "name": "OwnershipTransferred",
"type": "event" "type": "event"
},
{
"inputs": [],
"name": "UnsafeCast",
"type": "error"
} }
] ]
\ No newline at end of file
...@@ -246,19 +246,6 @@ ...@@ -246,19 +246,6 @@
"stateMutability": "view", "stateMutability": "view",
"type": "function" "type": "function"
}, },
{
"inputs": [],
"name": "feeAdmin",
"outputs": [
{
"internalType": "address",
"name": "addr_",
"type": "address"
}
],
"stateMutability": "view",
"type": "function"
},
{ {
"inputs": [], "inputs": [],
"name": "gasLimit", "name": "gasLimit",
...@@ -318,33 +305,11 @@ ...@@ -318,33 +305,11 @@
}, },
{ {
"inputs": [ "inputs": [
{
"components": [
{ {
"internalType": "address", "internalType": "address",
"name": "owner", "name": "_owner",
"type": "address" "type": "address"
}, },
{
"internalType": "address",
"name": "feeAdmin",
"type": "address"
},
{
"internalType": "address",
"name": "unsafeBlockSigner",
"type": "address"
},
{
"internalType": "bytes32",
"name": "batcherHash",
"type": "bytes32"
}
],
"internalType": "struct SystemConfig.Roles",
"name": "_roles",
"type": "tuple"
},
{ {
"internalType": "uint32", "internalType": "uint32",
"name": "_basefeeScalar", "name": "_basefeeScalar",
...@@ -355,11 +320,21 @@ ...@@ -355,11 +320,21 @@
"name": "_blobbasefeeScalar", "name": "_blobbasefeeScalar",
"type": "uint32" "type": "uint32"
}, },
{
"internalType": "bytes32",
"name": "_batcherHash",
"type": "bytes32"
},
{ {
"internalType": "uint64", "internalType": "uint64",
"name": "_gasLimit", "name": "_gasLimit",
"type": "uint64" "type": "uint64"
}, },
{
"internalType": "address",
"name": "_unsafeBlockSigner",
"type": "address"
},
{ {
"components": [ "components": [
{ {
...@@ -443,6 +418,11 @@ ...@@ -443,6 +418,11 @@
"internalType": "struct SystemConfig.Addresses", "internalType": "struct SystemConfig.Addresses",
"name": "_addresses", "name": "_addresses",
"type": "tuple" "type": "tuple"
},
{
"internalType": "address",
"name": "_dependencyManager",
"type": "address"
} }
], ],
"name": "initialize", "name": "initialize",
...@@ -452,33 +432,11 @@ ...@@ -452,33 +432,11 @@
}, },
{ {
"inputs": [ "inputs": [
{
"components": [
{
"internalType": "address",
"name": "owner",
"type": "address"
},
{ {
"internalType": "address", "internalType": "address",
"name": "feeAdmin", "name": "_owner",
"type": "address" "type": "address"
}, },
{
"internalType": "address",
"name": "unsafeBlockSigner",
"type": "address"
},
{
"internalType": "bytes32",
"name": "batcherHash",
"type": "bytes32"
}
],
"internalType": "struct SystemConfig.Roles",
"name": "_roles",
"type": "tuple"
},
{ {
"internalType": "uint32", "internalType": "uint32",
"name": "_basefeeScalar", "name": "_basefeeScalar",
...@@ -489,11 +447,21 @@ ...@@ -489,11 +447,21 @@
"name": "_blobbasefeeScalar", "name": "_blobbasefeeScalar",
"type": "uint32" "type": "uint32"
}, },
{
"internalType": "bytes32",
"name": "_batcherHash",
"type": "bytes32"
},
{ {
"internalType": "uint64", "internalType": "uint64",
"name": "_gasLimit", "name": "_gasLimit",
"type": "uint64" "type": "uint64"
}, },
{
"internalType": "address",
"name": "_unsafeBlockSigner",
"type": "address"
},
{ {
"components": [ "components": [
{ {
...@@ -577,11 +545,6 @@ ...@@ -577,11 +545,6 @@
"internalType": "struct SystemConfig.Addresses", "internalType": "struct SystemConfig.Addresses",
"name": "_addresses", "name": "_addresses",
"type": "tuple" "type": "tuple"
},
{
"internalType": "address",
"name": "_dependencyManager",
"type": "address"
} }
], ],
"name": "initialize", "name": "initialize",
...@@ -828,34 +791,6 @@ ...@@ -828,34 +791,6 @@
"stateMutability": "nonpayable", "stateMutability": "nonpayable",
"type": "function" "type": "function"
}, },
{
"inputs": [
{
"internalType": "enum Types.ConfigType",
"name": "_type",
"type": "uint8"
},
{
"internalType": "address",
"name": "_recipient",
"type": "address"
},
{
"internalType": "uint256",
"name": "_min",
"type": "uint256"
},
{
"internalType": "enum Types.WithdrawalNetwork",
"name": "_network",
"type": "uint8"
}
],
"name": "setFeeVaultConfig",
"outputs": [],
"stateMutability": "nonpayable",
"type": "function"
},
{ {
"inputs": [ "inputs": [
{ {
...@@ -1026,10 +961,5 @@ ...@@ -1026,10 +961,5 @@
], ],
"name": "OwnershipTransferred", "name": "OwnershipTransferred",
"type": "event" "type": "event"
},
{
"inputs": [],
"name": "UnsafeCast",
"type": "error"
} }
] ]
\ No newline at end of file
[
{
"bytes": "20",
"label": "spacer_0_0_20",
"offset": 0,
"slot": "0",
"type": "address"
}
]
\ No newline at end of file
[
{
"bytes": "1600",
"label": "spacer_1_0_1600",
"offset": 0,
"slot": "0",
"type": "uint256[50]"
},
{
"bytes": "20",
"label": "spacer_51_0_20",
"offset": 0,
"slot": "50",
"type": "address"
},
{
"bytes": "1568",
"label": "spacer_52_0_1568",
"offset": 0,
"slot": "51",
"type": "uint256[49]"
},
{
"bytes": "1",
"label": "spacer_101_0_1",
"offset": 0,
"slot": "100",
"type": "bool"
},
{
"bytes": "1568",
"label": "spacer_102_0_1568",
"offset": 0,
"slot": "101",
"type": "uint256[49]"
},
{
"bytes": "32",
"label": "spacer_151_0_32",
"offset": 0,
"slot": "150",
"type": "uint256"
},
{
"bytes": "1568",
"label": "spacer_152_0_1568",
"offset": 0,
"slot": "151",
"type": "uint256[49]"
},
{
"bytes": "32",
"label": "spacer_201_0_32",
"offset": 0,
"slot": "200",
"type": "mapping(bytes32 => bool)"
},
{
"bytes": "32",
"label": "spacer_202_0_32",
"offset": 0,
"slot": "201",
"type": "mapping(bytes32 => bool)"
}
]
\ No newline at end of file
...@@ -75,12 +75,5 @@ ...@@ -75,12 +75,5 @@
"offset": 0, "offset": 0,
"slot": "7", "slot": "7",
"type": "uint256" "type": "uint256"
},
{
"bytes": "1",
"label": "isIsthmus",
"offset": 0,
"slot": "8",
"type": "bool"
} }
] ]
\ No newline at end of file
...@@ -76,18 +76,11 @@ ...@@ -76,18 +76,11 @@
"slot": "7", "slot": "7",
"type": "uint256" "type": "uint256"
}, },
{
"bytes": "1",
"label": "isIsthmus",
"offset": 0,
"slot": "8",
"type": "bool"
},
{ {
"bytes": "64", "bytes": "64",
"label": "dependencySet", "label": "dependencySet",
"offset": 0, "offset": 0,
"slot": "9", "slot": "8",
"type": "struct EnumerableSet.UintSet" "type": "struct EnumerableSet.UintSet"
} }
] ]
\ No newline at end of file
...@@ -7,11 +7,18 @@ ...@@ -7,11 +7,18 @@
"type": "address" "type": "address"
}, },
{ {
"bytes": "12", "bytes": "1",
"label": "spacer_0_20_12", "label": "_initialized",
"offset": 20, "offset": 20,
"slot": "0", "slot": "0",
"type": "bytes12" "type": "uint8"
},
{
"bytes": "1",
"label": "_initializing",
"offset": 21,
"slot": "0",
"type": "bool"
}, },
{ {
"bytes": "1600", "bytes": "1600",
...@@ -85,10 +92,10 @@ ...@@ -85,10 +92,10 @@
}, },
{ {
"bytes": "20", "bytes": "20",
"label": "spacer_204_0_20", "label": "xDomainMsgSender",
"offset": 0, "offset": 0,
"slot": "204", "slot": "204",
"type": "bytes20" "type": "address"
}, },
{ {
"bytes": "30", "bytes": "30",
...@@ -106,52 +113,17 @@ ...@@ -106,52 +113,17 @@
}, },
{ {
"bytes": "20", "bytes": "20",
"label": "spacer_207_0_20", "label": "otherMessenger",
"offset": 0, "offset": 0,
"slot": "207", "slot": "207",
"type": "address" "type": "contract CrossDomainMessenger"
},
{
"bytes": "20",
"label": "xDomainMsgSender",
"offset": 0,
"slot": "208",
"type": "address"
}, },
{ {
"bytes": "12", "bytes": "1376",
"label": "spacer_208_20_12",
"offset": 20,
"slot": "208",
"type": "bytes12"
},
{
"bytes": "1312",
"label": "__gap", "label": "__gap",
"offset": 0, "offset": 0,
"slot": "209", "slot": "208",
"type": "uint256[41]" "type": "uint256[43]"
},
{
"bytes": "1",
"label": "_initialized",
"offset": 0,
"slot": "250",
"type": "uint8"
},
{
"bytes": "1",
"label": "_initializing",
"offset": 1,
"slot": "250",
"type": "bool"
},
{
"bytes": "30",
"label": "spacer_250_2_30",
"offset": 2,
"slot": "250",
"type": "bytes30"
}, },
{ {
"bytes": "20", "bytes": "20",
......
[ [
{ {
"bytes": "32", "bytes": "1",
"label": "spacer_0_0_32", "label": "_initialized",
"offset": 0, "offset": 0,
"slot": "0", "slot": "0",
"type": "bytes32" "type": "uint8"
},
{
"bytes": "1",
"label": "_initializing",
"offset": 1,
"slot": "0",
"type": "bool"
},
{
"bytes": "30",
"label": "spacer_0_2_30",
"offset": 2,
"slot": "0",
"type": "bytes30"
}, },
{ {
"bytes": "20", "bytes": "20",
"label": "spacer_1_0_20", "label": "messenger",
"offset": 0, "offset": 0,
"slot": "1", "slot": "1",
"type": "address" "type": "contract ICrossDomainMessenger"
}, },
{ {
"bytes": "20", "bytes": "20",
"label": "spacer_2_0_20", "label": "otherBridge",
"offset": 0, "offset": 0,
"slot": "2", "slot": "2",
"type": "address" "type": "contract ERC721Bridge"
}, },
{ {
"bytes": "1472", "bytes": "1472",
...@@ -40,12 +54,5 @@ ...@@ -40,12 +54,5 @@
"offset": 0, "offset": 0,
"slot": "50", "slot": "50",
"type": "contract ISuperchainConfig" "type": "contract ISuperchainConfig"
},
{
"bytes": "20",
"label": "crossDomainMessenger",
"offset": 0,
"slot": "51",
"type": "contract ICrossDomainMessenger"
} }
] ]
\ No newline at end of file
[ [
{ {
"bytes": "32", "bytes": "1",
"label": "spacer_0_0_32", "label": "_initialized",
"offset": 0, "offset": 0,
"slot": "0", "slot": "0",
"type": "bytes32" "type": "uint8"
},
{
"bytes": "1",
"label": "_initializing",
"offset": 1,
"slot": "0",
"type": "bool"
},
{
"bytes": "30",
"label": "spacer_0_2_30",
"offset": 2,
"slot": "0",
"type": "bytes30"
}, },
{ {
"bytes": "20", "bytes": "20",
...@@ -22,45 +36,24 @@ ...@@ -22,45 +36,24 @@
}, },
{ {
"bytes": "20", "bytes": "20",
"label": "spacer_3_0_20", "label": "messenger",
"offset": 0, "offset": 0,
"slot": "3", "slot": "3",
"type": "address" "type": "contract ICrossDomainMessenger"
}, },
{ {
"bytes": "20", "bytes": "20",
"label": "spacer_4_0_20", "label": "otherBridge",
"offset": 0, "offset": 0,
"slot": "4", "slot": "4",
"type": "address" "type": "contract StandardBridge"
}, },
{ {
"bytes": "1408", "bytes": "1440",
"label": "__gap", "label": "__gap",
"offset": 0, "offset": 0,
"slot": "5", "slot": "5",
"type": "uint256[44]" "type": "uint256[45]"
},
{
"bytes": "1",
"label": "_initialized",
"offset": 0,
"slot": "49",
"type": "uint8"
},
{
"bytes": "1",
"label": "_initializing",
"offset": 1,
"slot": "49",
"type": "bool"
},
{
"bytes": "30",
"label": "spacer_49_2_30",
"offset": 2,
"slot": "49",
"type": "bytes30"
}, },
{ {
"bytes": "20", "bytes": "20",
...@@ -75,12 +68,5 @@ ...@@ -75,12 +68,5 @@
"offset": 0, "offset": 0,
"slot": "51", "slot": "51",
"type": "contract ISystemConfig" "type": "contract ISystemConfig"
},
{
"bytes": "20",
"label": "crossDomainMessenger",
"offset": 0,
"slot": "52",
"type": "contract ICrossDomainMessenger"
} }
] ]
\ No newline at end of file
...@@ -7,11 +7,18 @@ ...@@ -7,11 +7,18 @@
"type": "address" "type": "address"
}, },
{ {
"bytes": "12", "bytes": "1",
"label": "spacer_0_20_12", "label": "_initialized",
"offset": 20, "offset": 20,
"slot": "0", "slot": "0",
"type": "bytes12" "type": "uint8"
},
{
"bytes": "1",
"label": "_initializing",
"offset": 21,
"slot": "0",
"type": "bool"
}, },
{ {
"bytes": "1600", "bytes": "1600",
...@@ -85,10 +92,10 @@ ...@@ -85,10 +92,10 @@
}, },
{ {
"bytes": "20", "bytes": "20",
"label": "spacer_204_0_20", "label": "xDomainMsgSender",
"offset": 0, "offset": 0,
"slot": "204", "slot": "204",
"type": "bytes20" "type": "address"
}, },
{ {
"bytes": "30", "bytes": "30",
...@@ -106,30 +113,16 @@ ...@@ -106,30 +113,16 @@
}, },
{ {
"bytes": "20", "bytes": "20",
"label": "spacer_207_0_20", "label": "otherMessenger",
"offset": 0, "offset": 0,
"slot": "207", "slot": "207",
"type": "address" "type": "contract CrossDomainMessenger"
}, },
{ {
"bytes": "20", "bytes": "1376",
"label": "xDomainMsgSender",
"offset": 0,
"slot": "208",
"type": "address"
},
{
"bytes": "12",
"label": "spacer_208_20_12",
"offset": 20,
"slot": "208",
"type": "bytes12"
},
{
"bytes": "1312",
"label": "__gap", "label": "__gap",
"offset": 0, "offset": 0,
"slot": "209", "slot": "208",
"type": "uint256[41]" "type": "uint256[43]"
} }
] ]
\ No newline at end of file
[ [
{ {
"bytes": "32", "bytes": "1",
"label": "spacer_0_0_32", "label": "_initialized",
"offset": 0, "offset": 0,
"slot": "0", "slot": "0",
"type": "bytes32" "type": "uint8"
},
{
"bytes": "1",
"label": "_initializing",
"offset": 1,
"slot": "0",
"type": "bool"
},
{
"bytes": "30",
"label": "spacer_0_2_30",
"offset": 2,
"slot": "0",
"type": "bytes30"
}, },
{ {
"bytes": "20", "bytes": "20",
"label": "spacer_1_0_20", "label": "messenger",
"offset": 0, "offset": 0,
"slot": "1", "slot": "1",
"type": "address" "type": "contract ICrossDomainMessenger"
}, },
{ {
"bytes": "20", "bytes": "20",
"label": "spacer_2_0_20", "label": "otherBridge",
"offset": 0, "offset": 0,
"slot": "2", "slot": "2",
"type": "address" "type": "contract ERC721Bridge"
}, },
{ {
"bytes": "1472", "bytes": "1472",
......
[
{
"bytes": "32",
"label": "spacer_0_0_32",
"offset": 0,
"slot": "0",
"type": "bytes32"
},
{
"bytes": "32",
"label": "spacer_1_0_32",
"offset": 0,
"slot": "1",
"type": "bytes32"
},
{
"bytes": "32",
"label": "deployments",
"offset": 0,
"slot": "2",
"type": "mapping(address => address)"
},
{
"bytes": "1536",
"label": "__gap",
"offset": 0,
"slot": "3",
"type": "uint256[48]"
}
]
\ No newline at end of file
[
{
"bytes": "20",
"label": "_owner",
"offset": 0,
"slot": "0",
"type": "address"
},
{
"bytes": "32",
"label": "proxyType",
"offset": 0,
"slot": "1",
"type": "mapping(address => enum ProxyAdmin.ProxyType)"
},
{
"bytes": "32",
"label": "implementationName",
"offset": 0,
"slot": "2",
"type": "mapping(address => string)"
},
{
"bytes": "20",
"label": "addressManager",
"offset": 0,
"slot": "3",
"type": "contract IAddressManager"
},
{
"bytes": "1",
"label": "upgrading",
"offset": 20,
"slot": "3",
"type": "bool"
}
]
\ No newline at end of file
[ [
{ {
"bytes": "32", "bytes": "1",
"label": "spacer_0_0_32", "label": "_initialized",
"offset": 0, "offset": 0,
"slot": "0", "slot": "0",
"type": "bytes32" "type": "uint8"
},
{
"bytes": "1",
"label": "_initializing",
"offset": 1,
"slot": "0",
"type": "bool"
},
{
"bytes": "30",
"label": "spacer_0_2_30",
"offset": 2,
"slot": "0",
"type": "bytes30"
}, },
{ {
"bytes": "20", "bytes": "20",
...@@ -22,23 +36,23 @@ ...@@ -22,23 +36,23 @@
}, },
{ {
"bytes": "20", "bytes": "20",
"label": "spacer_3_0_20", "label": "messenger",
"offset": 0, "offset": 0,
"slot": "3", "slot": "3",
"type": "address" "type": "contract ICrossDomainMessenger"
}, },
{ {
"bytes": "20", "bytes": "20",
"label": "spacer_4_0_20", "label": "otherBridge",
"offset": 0, "offset": 0,
"slot": "4", "slot": "4",
"type": "address" "type": "contract StandardBridge"
}, },
{ {
"bytes": "1408", "bytes": "1440",
"label": "__gap", "label": "__gap",
"offset": 0, "offset": 0,
"slot": "5", "slot": "5",
"type": "uint256[44]" "type": "uint256[45]"
} }
] ]
\ No newline at end of file
[ [
{ {
"bytes": "32", "bytes": "1",
"label": "spacer_0_0_32", "label": "_initialized",
"offset": 0, "offset": 0,
"slot": "0", "slot": "0",
"type": "bytes32" "type": "uint8"
},
{
"bytes": "1",
"label": "_initializing",
"offset": 1,
"slot": "0",
"type": "bool"
},
{
"bytes": "30",
"label": "spacer_0_2_30",
"offset": 2,
"slot": "0",
"type": "bytes30"
}, },
{ {
"bytes": "20", "bytes": "20",
...@@ -22,23 +36,23 @@ ...@@ -22,23 +36,23 @@
}, },
{ {
"bytes": "20", "bytes": "20",
"label": "spacer_3_0_20", "label": "messenger",
"offset": 0, "offset": 0,
"slot": "3", "slot": "3",
"type": "address" "type": "contract ICrossDomainMessenger"
}, },
{ {
"bytes": "20", "bytes": "20",
"label": "spacer_4_0_20", "label": "otherBridge",
"offset": 0, "offset": 0,
"slot": "4", "slot": "4",
"type": "address" "type": "contract StandardBridge"
}, },
{ {
"bytes": "1408", "bytes": "1440",
"label": "__gap", "label": "__gap",
"offset": 0, "offset": 0,
"slot": "5", "slot": "5",
"type": "uint256[44]" "type": "uint256[45]"
} }
] ]
\ No newline at end of file
[ [
{
"bytes": "32",
"label": "spacer_0_0_32",
"offset": 0,
"slot": "0",
"type": "bytes32"
},
{
"bytes": "32",
"label": "spacer_1_0_32",
"offset": 0,
"slot": "1",
"type": "bytes32"
},
{
"bytes": "32",
"label": "deployments",
"offset": 0,
"slot": "2",
"type": "mapping(address => address)"
},
{
"bytes": "1536",
"label": "__gap",
"offset": 0,
"slot": "3",
"type": "uint256[48]"
},
{ {
"bytes": "1", "bytes": "1",
"label": "_initialized", "label": "_initialized",
"offset": 0, "offset": 0,
"slot": "51", "slot": "0",
"type": "uint8" "type": "uint8"
}, },
{ {
"bytes": "1", "bytes": "1",
"label": "_initializing", "label": "_initializing",
"offset": 1, "offset": 1,
"slot": "51", "slot": "0",
"type": "bool" "type": "bool"
}, },
{ {
"bytes": "30", "bytes": "30",
"label": "spacer_51_2_30", "label": "spacer_0_2_30",
"offset": 2, "offset": 2,
"slot": "51", "slot": "0",
"type": "bytes30" "type": "bytes30"
}, },
{ {
"bytes": "20", "bytes": "20",
"label": "standardBridge", "label": "bridge",
"offset": 0, "offset": 0,
"slot": "52", "slot": "1",
"type": "address" "type": "address"
},
{
"bytes": "32",
"label": "deployments",
"offset": 0,
"slot": "2",
"type": "mapping(address => address)"
},
{
"bytes": "1536",
"label": "__gap",
"offset": 0,
"slot": "3",
"type": "uint256[48]"
} }
] ]
\ No newline at end of file
...@@ -3,7 +3,6 @@ pragma solidity 0.8.15; ...@@ -3,7 +3,6 @@ pragma solidity 0.8.15;
// Contracts // Contracts
import { CrossDomainMessenger } from "src/universal/CrossDomainMessenger.sol"; import { CrossDomainMessenger } from "src/universal/CrossDomainMessenger.sol";
import { Initializable } from "@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol";
// Libraries // Libraries
import { Predeploys } from "src/libraries/Predeploys.sol"; import { Predeploys } from "src/libraries/Predeploys.sol";
...@@ -19,10 +18,7 @@ import { IOptimismPortal } from "src/L1/interfaces/IOptimismPortal.sol"; ...@@ -19,10 +18,7 @@ import { IOptimismPortal } from "src/L1/interfaces/IOptimismPortal.sol";
/// @notice The L1CrossDomainMessenger is a message passing interface between L1 and L2 responsible /// @notice The L1CrossDomainMessenger is a message passing interface between L1 and L2 responsible
/// for sending and receiving data on the L1 side. Users are encouraged to use this /// for sending and receiving data on the L1 side. Users are encouraged to use this
/// interface instead of interacting with lower-level contracts directly. /// interface instead of interacting with lower-level contracts directly.
contract L1CrossDomainMessenger is CrossDomainMessenger, ISemver, Initializable { contract L1CrossDomainMessenger is CrossDomainMessenger, ISemver {
/// @notice Spacer to give the initializer a full slot, to avoid offsetting the superchainConfig slot.
bytes30 private spacer_250_2_30;
/// @notice Contract of the SuperchainConfig. /// @notice Contract of the SuperchainConfig.
ISuperchainConfig public superchainConfig; ISuperchainConfig public superchainConfig;
...@@ -34,12 +30,16 @@ contract L1CrossDomainMessenger is CrossDomainMessenger, ISemver, Initializable ...@@ -34,12 +30,16 @@ contract L1CrossDomainMessenger is CrossDomainMessenger, ISemver, Initializable
ISystemConfig public systemConfig; ISystemConfig public systemConfig;
/// @notice Semantic version. /// @notice Semantic version.
/// @custom:semver 2.4.1-beta.3 /// @custom:semver 2.4.1-beta.2
string public constant version = "2.4.1-beta.3"; string public constant version = "2.4.1-beta.2";
/// @notice Constructs the L1CrossDomainMessenger contract. /// @notice Constructs the L1CrossDomainMessenger contract.
constructor() CrossDomainMessenger() { constructor() CrossDomainMessenger() {
_disableInitializers(); initialize({
_superchainConfig: ISuperchainConfig(address(0)),
_portal: IOptimismPortal(payable(address(0))),
_systemConfig: ISystemConfig(address(0))
});
} }
/// @notice Initializes the contract. /// @notice Initializes the contract.
...@@ -57,12 +57,7 @@ contract L1CrossDomainMessenger is CrossDomainMessenger, ISemver, Initializable ...@@ -57,12 +57,7 @@ contract L1CrossDomainMessenger is CrossDomainMessenger, ISemver, Initializable
superchainConfig = _superchainConfig; superchainConfig = _superchainConfig;
portal = _portal; portal = _portal;
systemConfig = _systemConfig; systemConfig = _systemConfig;
} __CrossDomainMessenger_init({ _otherMessenger: CrossDomainMessenger(Predeploys.L2_CROSS_DOMAIN_MESSENGER) });
/// @notice Getter function for the other messenger.
/// @return Contract of the messenger on the other network.
function otherMessenger() public pure override returns (CrossDomainMessenger) {
return CrossDomainMessenger(Predeploys.L2_CROSS_DOMAIN_MESSENGER);
} }
/// @inheritdoc CrossDomainMessenger /// @inheritdoc CrossDomainMessenger
...@@ -91,7 +86,7 @@ contract L1CrossDomainMessenger is CrossDomainMessenger, ISemver, Initializable ...@@ -91,7 +86,7 @@ contract L1CrossDomainMessenger is CrossDomainMessenger, ISemver, Initializable
/// @inheritdoc CrossDomainMessenger /// @inheritdoc CrossDomainMessenger
function _isOtherMessenger() internal view override returns (bool) { function _isOtherMessenger() internal view override returns (bool) {
return msg.sender == address(portal) && portal.l2Sender() == address(otherMessenger()); return msg.sender == address(portal) && portal.l2Sender() == address(otherMessenger);
} }
/// @inheritdoc CrossDomainMessenger /// @inheritdoc CrossDomainMessenger
......
// SPDX-License-Identifier: MIT // SPDX-License-Identifier: MIT
pragma solidity 0.8.25; pragma solidity 0.8.15;
// Contracts // Contracts
import { ERC721Bridge } from "src/universal/ERC721Bridge.sol"; import { ERC721Bridge } from "src/universal/ERC721Bridge.sol";
import { Initializable } from "@openzeppelin/contracts-v5/proxy/utils/Initializable.sol";
// Libraries // Libraries
import { Predeploys } from "src/libraries/Predeploys.sol"; import { Predeploys } from "src/libraries/Predeploys.sol";
...@@ -20,7 +19,7 @@ import { IL2ERC721Bridge } from "src/L2/interfaces/IL2ERC721Bridge.sol"; ...@@ -20,7 +19,7 @@ import { IL2ERC721Bridge } from "src/L2/interfaces/IL2ERC721Bridge.sol";
/// @notice The L1 ERC721 bridge is a contract which works together with the L2 ERC721 bridge to /// @notice The L1 ERC721 bridge is a contract which works together with the L2 ERC721 bridge to
/// make it possible to transfer ERC721 tokens from Ethereum to Optimism. This contract /// make it possible to transfer ERC721 tokens from Ethereum to Optimism. This contract
/// acts as an escrow for ERC721 tokens deposited into L2. /// acts as an escrow for ERC721 tokens deposited into L2.
contract L1ERC721Bridge is ERC721Bridge, Initializable, ISemver { contract L1ERC721Bridge is ERC721Bridge, ISemver {
/// @notice Mapping of L1 token to L2 token to ID to boolean, indicating if the given L1 token /// @notice Mapping of L1 token to L2 token to ID to boolean, indicating if the given L1 token
/// by ID was deposited for a given L2 token. /// by ID was deposited for a given L2 token.
mapping(address => mapping(address => mapping(uint256 => bool))) public deposits; mapping(address => mapping(address => mapping(uint256 => bool))) public deposits;
...@@ -28,16 +27,13 @@ contract L1ERC721Bridge is ERC721Bridge, Initializable, ISemver { ...@@ -28,16 +27,13 @@ contract L1ERC721Bridge is ERC721Bridge, Initializable, ISemver {
/// @notice Address of the SuperchainConfig contract. /// @notice Address of the SuperchainConfig contract.
ISuperchainConfig public superchainConfig; ISuperchainConfig public superchainConfig;
/// @notice Contract of the CrossDomainMessenger on this chain.
ICrossDomainMessenger internal crossDomainMessenger;
/// @notice Semantic version. /// @notice Semantic version.
/// @custom:semver 2.1.1-beta.3 /// @custom:semver 2.2.0-beta.1
string public constant version = "2.1.1-beta.3"; string public constant version = "2.2.0-beta.1";
/// @notice Constructs the L1ERC721Bridge contract. /// @notice Constructs the L1ERC721Bridge contract.
constructor() ERC721Bridge() { constructor() ERC721Bridge() {
_disableInitializers(); initialize({ _messenger: ICrossDomainMessenger(address(0)), _superchainConfig: ISuperchainConfig(address(0)) });
} }
/// @notice Initializes the contract. /// @notice Initializes the contract.
...@@ -45,19 +41,7 @@ contract L1ERC721Bridge is ERC721Bridge, Initializable, ISemver { ...@@ -45,19 +41,7 @@ contract L1ERC721Bridge is ERC721Bridge, Initializable, ISemver {
/// @param _superchainConfig Contract of the SuperchainConfig contract on this network. /// @param _superchainConfig Contract of the SuperchainConfig contract on this network.
function initialize(ICrossDomainMessenger _messenger, ISuperchainConfig _superchainConfig) public initializer { function initialize(ICrossDomainMessenger _messenger, ISuperchainConfig _superchainConfig) public initializer {
superchainConfig = _superchainConfig; superchainConfig = _superchainConfig;
crossDomainMessenger = _messenger; __ERC721Bridge_init({ _messenger: _messenger, _otherBridge: ERC721Bridge(payable(Predeploys.L2_ERC721_BRIDGE)) });
}
/// @notice Getter function for the CrossDomainMessenger contract on this chain.
/// @return Contract of the CrossDomainMessenger on this chain.
function messenger() public view override returns (ICrossDomainMessenger) {
return ICrossDomainMessenger(crossDomainMessenger);
}
/// @notice Getter function for the other bridge.
/// @return Contract of the bridge on the other network.
function otherBridge() public pure override returns (ERC721Bridge) {
return ERC721Bridge(payable(Predeploys.L2_ERC721_BRIDGE));
} }
/// @inheritdoc ERC721Bridge /// @inheritdoc ERC721Bridge
...@@ -132,7 +116,7 @@ contract L1ERC721Bridge is ERC721Bridge, Initializable, ISemver { ...@@ -132,7 +116,7 @@ contract L1ERC721Bridge is ERC721Bridge, Initializable, ISemver {
IERC721(_localToken).transferFrom({ from: _from, to: address(this), tokenId: _tokenId }); IERC721(_localToken).transferFrom({ from: _from, to: address(this), tokenId: _tokenId });
// Send calldata into L2 // Send calldata into L2
messenger().sendMessage({ _target: address(otherBridge()), _message: message, _minGasLimit: _minGasLimit }); messenger.sendMessage({ _target: address(otherBridge), _message: message, _minGasLimit: _minGasLimit });
emit ERC721BridgeInitiated(_localToken, _remoteToken, _from, _to, _tokenId, _extraData); emit ERC721BridgeInitiated(_localToken, _remoteToken, _from, _to, _tokenId, _extraData);
} }
} }
// SPDX-License-Identifier: MIT
pragma solidity 0.8.15;
import { OptimismMintableERC20Factory } from "src/universal/OptimismMintableERC20Factory.sol";
import { Initializable } from "@openzeppelin/contracts/proxy/utils/Initializable.sol";
/// @custom:proxied true
/// @title L1OptimismMintableERC20Factory
/// @notice Allows users to create L1 tokens that represent L2 native tokens.
contract L1OptimismMintableERC20Factory is OptimismMintableERC20Factory, Initializable {
/// @custom:semver 1.3.1-beta.5
/// @notice Semantic version.
/// The semver MUST be bumped any time that there is a change in
/// the OptimismMintableERC20 token contract since this contract
/// is responsible for deploying OptimismMintableERC20 contracts.
string public constant version = "1.3.1-beta.5";
/// @custom:spacer
/// @notice Spacer to fill the remainder of the _initialized slot, preventing the standardBridge
/// address from being packed with it.
bytes30 private spacer_51_2_30;
/// @notice Address of the bridge on this domain.
address internal standardBridge;
constructor() {
_disableInitializers();
}
/// @notice Initializes the contract.
/// @param _bridge Contract of the bridge on this domain.
function initialize(address _bridge) public initializer {
standardBridge = _bridge;
}
/// @notice Getter function for the bridge contract.
/// @return Contract of the bridge on this domain.
function bridge() public view virtual override returns (address) {
return standardBridge;
}
}
...@@ -3,16 +3,15 @@ pragma solidity 0.8.15; ...@@ -3,16 +3,15 @@ pragma solidity 0.8.15;
// Contracts // Contracts
import { StandardBridge } from "src/universal/StandardBridge.sol"; import { StandardBridge } from "src/universal/StandardBridge.sol";
// Libraries // Libraries
import { Predeploys } from "src/libraries/Predeploys.sol"; import { Predeploys } from "src/libraries/Predeploys.sol";
// Interfaces // Interfaces
import { ISemver } from "src/universal/interfaces/ISemver.sol"; import { ISemver } from "src/universal/interfaces/ISemver.sol";
import { ICrossDomainMessenger } from "src/universal/interfaces/ICrossDomainMessenger.sol"; import { ICrossDomainMessenger } from "src/universal/interfaces/ICrossDomainMessenger.sol";
import { IStandardBridge } from "src/universal/interfaces/IStandardBridge.sol";
import { ISuperchainConfig } from "src/L1/interfaces/ISuperchainConfig.sol"; import { ISuperchainConfig } from "src/L1/interfaces/ISuperchainConfig.sol";
import { ISystemConfig } from "src/L1/interfaces/ISystemConfig.sol"; import { ISystemConfig } from "src/L1/interfaces/ISystemConfig.sol";
import { Initializable } from "@openzeppelin/contracts/proxy/utils/Initializable.sol";
/// @custom:proxied true /// @custom:proxied true
/// @title L1StandardBridge /// @title L1StandardBridge
...@@ -24,7 +23,7 @@ import { Initializable } from "@openzeppelin/contracts/proxy/utils/Initializable ...@@ -24,7 +23,7 @@ import { Initializable } from "@openzeppelin/contracts/proxy/utils/Initializable
/// NOTE: this contract is not intended to support all variations of ERC20 tokens. Examples /// NOTE: this contract is not intended to support all variations of ERC20 tokens. Examples
/// of some token types that may not be properly supported by this contract include, but are /// of some token types that may not be properly supported by this contract include, but are
/// not limited to: tokens with transfer fees, rebasing tokens, and tokens with blocklists. /// not limited to: tokens with transfer fees, rebasing tokens, and tokens with blocklists.
contract L1StandardBridge is StandardBridge, ISemver, Initializable { contract L1StandardBridge is StandardBridge, ISemver {
/// @custom:legacy /// @custom:legacy
/// @notice Emitted whenever a deposit of ETH from L1 into L2 is initiated. /// @notice Emitted whenever a deposit of ETH from L1 into L2 is initiated.
/// @param from Address of the depositor. /// @param from Address of the depositor.
...@@ -76,13 +75,8 @@ contract L1StandardBridge is StandardBridge, ISemver, Initializable { ...@@ -76,13 +75,8 @@ contract L1StandardBridge is StandardBridge, ISemver, Initializable {
); );
/// @notice Semantic version. /// @notice Semantic version.
/// @custom:semver 2.2.1-beta.3 /// @custom:semver 2.2.1-beta.2
string public constant version = "2.2.1-beta.3"; string public constant version = "2.2.1-beta.2";
/// @custom:spacer
/// @notice Spacer to fill the remainder of the _initialized slot, preventing the superchainConfig
/// address from being packed with it.
bytes30 private spacer_49_2_30;
/// @notice Address of the SuperchainConfig contract. /// @notice Address of the SuperchainConfig contract.
ISuperchainConfig public superchainConfig; ISuperchainConfig public superchainConfig;
...@@ -90,12 +84,13 @@ contract L1StandardBridge is StandardBridge, ISemver, Initializable { ...@@ -90,12 +84,13 @@ contract L1StandardBridge is StandardBridge, ISemver, Initializable {
/// @notice Address of the SystemConfig contract. /// @notice Address of the SystemConfig contract.
ISystemConfig public systemConfig; ISystemConfig public systemConfig;
/// @notice Contract for the CrossDomainMessenger on this network.
ICrossDomainMessenger internal crossDomainMessenger;
/// @notice Constructs the L1StandardBridge contract. /// @notice Constructs the L1StandardBridge contract.
constructor() StandardBridge() { constructor() StandardBridge() {
_disableInitializers(); initialize({
_messenger: ICrossDomainMessenger(address(0)),
_superchainConfig: ISuperchainConfig(address(0)),
_systemConfig: ISystemConfig(address(0))
});
} }
/// @notice Initializer. /// @notice Initializer.
...@@ -111,19 +106,10 @@ contract L1StandardBridge is StandardBridge, ISemver, Initializable { ...@@ -111,19 +106,10 @@ contract L1StandardBridge is StandardBridge, ISemver, Initializable {
{ {
superchainConfig = _superchainConfig; superchainConfig = _superchainConfig;
systemConfig = _systemConfig; systemConfig = _systemConfig;
crossDomainMessenger = _messenger; __StandardBridge_init({
} _messenger: _messenger,
_otherBridge: StandardBridge(payable(Predeploys.L2_STANDARD_BRIDGE))
/// @notice Returns the contract of the bridge on the other chain. });
/// @return Contract of the bridge on the other chain.
function otherBridge() public pure override returns (IStandardBridge) {
return IStandardBridge(payable(Predeploys.L2_STANDARD_BRIDGE));
}
/// @notice Getter function for the messenger contract.
/// @return Contract of the messenger on this domain.
function messenger() public view override returns (ICrossDomainMessenger) {
return ICrossDomainMessenger(crossDomainMessenger);
} }
/// @inheritdoc StandardBridge /// @inheritdoc StandardBridge
...@@ -255,8 +241,8 @@ contract L1StandardBridge is StandardBridge, ISemver, Initializable { ...@@ -255,8 +241,8 @@ contract L1StandardBridge is StandardBridge, ISemver, Initializable {
/// @custom:legacy /// @custom:legacy
/// @notice Retrieves the access of the corresponding L2 bridge contract. /// @notice Retrieves the access of the corresponding L2 bridge contract.
/// @return Address of the corresponding L2 bridge contract. /// @return Address of the corresponding L2 bridge contract.
function l2TokenBridge() external pure returns (address) { function l2TokenBridge() external view returns (address) {
return address(otherBridge()); return address(otherBridge);
} }
/// @notice Internal function for initiating an ETH deposit. /// @notice Internal function for initiating an ETH deposit.
......
...@@ -46,7 +46,6 @@ contract OPContractsManager is ISemver, Initializable { ...@@ -46,7 +46,6 @@ contract OPContractsManager is ISemver, Initializable {
address unsafeBlockSigner; address unsafeBlockSigner;
address proposer; address proposer;
address challenger; address challenger;
address systemConfigFeeAdmin;
} }
/// @notice The full set of inputs to deploy a new OP Stack chain. /// @notice The full set of inputs to deploy a new OP Stack chain.
...@@ -130,8 +129,8 @@ contract OPContractsManager is ISemver, Initializable { ...@@ -130,8 +129,8 @@ contract OPContractsManager is ISemver, Initializable {
// -------- Constants and Variables -------- // -------- Constants and Variables --------
/// @custom:semver 1.0.0-beta.21 /// @custom:semver 1.0.0-beta.20
string public constant version = "1.0.0-beta.21"; string public constant version = "1.0.0-beta.20";
/// @notice Represents the interface version so consumers know how to decode the DeployOutput struct /// @notice Represents the interface version so consumers know how to decode the DeployOutput struct
/// that's emitted in the `Deployed` event. Whenever that struct changes, a new version should be used. /// that's emitted in the `Deployed` event. Whenever that struct changes, a new version should be used.
...@@ -255,7 +254,7 @@ contract OPContractsManager is ISemver, Initializable { ...@@ -255,7 +254,7 @@ contract OPContractsManager is ISemver, Initializable {
output.systemConfigProxy = output.systemConfigProxy =
ISystemConfig(deployProxy(l2ChainId, output.opChainProxyAdmin, saltMixer, "SystemConfig")); ISystemConfig(deployProxy(l2ChainId, output.opChainProxyAdmin, saltMixer, "SystemConfig"));
output.optimismMintableERC20FactoryProxy = IOptimismMintableERC20Factory( output.optimismMintableERC20FactoryProxy = IOptimismMintableERC20Factory(
deployProxy(l2ChainId, output.opChainProxyAdmin, saltMixer, "L1OptimismMintableERC20Factory") deployProxy(l2ChainId, output.opChainProxyAdmin, saltMixer, "OptimismMintableERC20Factory")
); );
output.disputeGameFactoryProxy = output.disputeGameFactoryProxy =
IDisputeGameFactory(deployProxy(l2ChainId, output.opChainProxyAdmin, saltMixer, "DisputeGameFactory")); IDisputeGameFactory(deployProxy(l2ChainId, output.opChainProxyAdmin, saltMixer, "DisputeGameFactory"));
...@@ -469,15 +468,12 @@ contract OPContractsManager is ISemver, Initializable { ...@@ -469,15 +468,12 @@ contract OPContractsManager is ISemver, Initializable {
return abi.encodeWithSelector( return abi.encodeWithSelector(
_selector, _selector,
ISystemConfig.Roles({ _input.roles.systemConfigOwner,
owner: _input.roles.systemConfigOwner,
feeAdmin: _input.roles.systemConfigFeeAdmin,
unsafeBlockSigner: _input.roles.unsafeBlockSigner,
batcherHash: bytes32(uint256(uint160(_input.roles.batcher)))
}),
_input.basefeeScalar, _input.basefeeScalar,
_input.blobBasefeeScalar, _input.blobBasefeeScalar,
bytes32(uint256(uint160(_input.roles.batcher))), // batcherHash
_input.gasLimit, _input.gasLimit,
_input.roles.unsafeBlockSigner,
referenceResourceConfig, referenceResourceConfig,
chainIdToBatchInboxAddress(_input.l2ChainId), chainIdToBatchInboxAddress(_input.l2ChainId),
opChainAddrs opChainAddrs
...@@ -491,15 +487,12 @@ contract OPContractsManager is ISemver, Initializable { ...@@ -491,15 +487,12 @@ contract OPContractsManager is ISemver, Initializable {
return abi.encodeWithSelector( return abi.encodeWithSelector(
_selector, _selector,
ISystemConfig.Roles({ _input.roles.systemConfigOwner,
owner: _input.roles.systemConfigOwner,
feeAdmin: _input.roles.systemConfigFeeAdmin,
unsafeBlockSigner: _input.roles.unsafeBlockSigner,
batcherHash: bytes32(uint256(uint160(_input.roles.batcher)))
}),
_input.basefeeScalar, _input.basefeeScalar,
_input.blobBasefeeScalar, _input.blobBasefeeScalar,
bytes32(uint256(uint160(_input.roles.batcher))), // batcherHash
_input.gasLimit, _input.gasLimit,
_input.roles.unsafeBlockSigner,
referenceResourceConfig, referenceResourceConfig,
chainIdToBatchInboxAddress(_input.l2ChainId), chainIdToBatchInboxAddress(_input.l2ChainId),
opChainAddrs opChainAddrs
......
...@@ -41,15 +41,12 @@ contract OPContractsManagerInterop is OPContractsManager { ...@@ -41,15 +41,12 @@ contract OPContractsManagerInterop is OPContractsManager {
return abi.encodeWithSelector( return abi.encodeWithSelector(
_selector, _selector,
ISystemConfig.Roles({ _input.roles.systemConfigOwner,
owner: _input.roles.systemConfigOwner,
feeAdmin: _input.roles.systemConfigFeeAdmin,
unsafeBlockSigner: _input.roles.unsafeBlockSigner,
batcherHash: bytes32(uint256(uint160(_input.roles.batcher)))
}),
_input.basefeeScalar, _input.basefeeScalar,
_input.blobBasefeeScalar, _input.blobBasefeeScalar,
bytes32(uint256(uint160(_input.roles.batcher))), // batcherHash
_input.gasLimit, _input.gasLimit,
_input.roles.unsafeBlockSigner,
referenceResourceConfig, referenceResourceConfig,
chainIdToBatchInboxAddress(_input.l2ChainId), chainIdToBatchInboxAddress(_input.l2ChainId),
opChainAddrs, opChainAddrs,
......
...@@ -146,9 +146,9 @@ contract OptimismPortal is Initializable, ResourceMetering, ISemver { ...@@ -146,9 +146,9 @@ contract OptimismPortal is Initializable, ResourceMetering, ISemver {
} }
/// @notice Semantic version. /// @notice Semantic version.
/// @custom:semver 2.8.1-beta.5 /// @custom:semver 2.8.1-beta.4
function version() public pure virtual returns (string memory) { function version() public pure virtual returns (string memory) {
return "2.8.1-beta.5"; return "2.8.1-beta.4";
} }
/// @notice Constructs the OptimismPortal contract. /// @notice Constructs the OptimismPortal contract.
...@@ -584,17 +584,17 @@ contract OptimismPortal is Initializable, ResourceMetering, ISemver { ...@@ -584,17 +584,17 @@ contract OptimismPortal is Initializable, ResourceMetering, ISemver {
emit TransactionDeposited(from, _to, DEPOSIT_VERSION, opaqueData); emit TransactionDeposited(from, _to, DEPOSIT_VERSION, opaqueData);
} }
/// @notice Sets static configuration options for the L2 system. /// @notice Sets the gas paying token for the L2 system. This token is used as the
/// @param _type Type of configuration to set. /// L2 native asset. Only the SystemConfig contract can call this function.
/// @param _value Encoded value of the configuration. function setGasPayingToken(address _token, uint8 _decimals, bytes32 _name, bytes32 _symbol) external {
function setConfig(Types.ConfigType _type, bytes memory _value) external {
if (msg.sender != address(systemConfig)) revert Unauthorized(); if (msg.sender != address(systemConfig)) revert Unauthorized();
// Set L2 deposit gas as used without paying burning gas. Ensures that deposits cannot use too much L2 gas. // Set L2 deposit gas as used without paying burning gas. Ensures that deposits cannot use too much L2 gas.
// This value must be large enough to cover the cost of calling `L1Block.setConfig`. // This value must be large enough to cover the cost of calling `L1Block.setGasPayingToken`.
useGas(SYSTEM_DEPOSIT_GAS_LIMIT); useGas(SYSTEM_DEPOSIT_GAS_LIMIT);
// Emit the special deposit transaction directly that sets the config in the L1Block predeploy contract. // Emit the special deposit transaction directly that sets the gas paying
// token in the L1Block predeploy contract.
emit TransactionDeposited( emit TransactionDeposited(
Constants.DEPOSITOR_ACCOUNT, Constants.DEPOSITOR_ACCOUNT,
Predeploys.L1_BLOCK_ATTRIBUTES, Predeploys.L1_BLOCK_ATTRIBUTES,
...@@ -604,7 +604,7 @@ contract OptimismPortal is Initializable, ResourceMetering, ISemver { ...@@ -604,7 +604,7 @@ contract OptimismPortal is Initializable, ResourceMetering, ISemver {
uint256(0), // value uint256(0), // value
uint64(SYSTEM_DEPOSIT_GAS_LIMIT), // gasLimit uint64(SYSTEM_DEPOSIT_GAS_LIMIT), // gasLimit
false, // isCreation, false, // isCreation,
abi.encodeCall(IL1Block.setConfig, (_type, _value)) abi.encodeCall(IL1Block.setGasPayingToken, (_token, _decimals, _name, _symbol))
) )
); );
} }
......
...@@ -183,9 +183,9 @@ contract OptimismPortal2 is Initializable, ResourceMetering, ISemver { ...@@ -183,9 +183,9 @@ contract OptimismPortal2 is Initializable, ResourceMetering, ISemver {
} }
/// @notice Semantic version. /// @notice Semantic version.
/// @custom:semver 3.11.0-beta.7 /// @custom:semver 3.11.0-beta.6
function version() public pure virtual returns (string memory) { function version() public pure virtual returns (string memory) {
return "3.11.0-beta.7"; return "3.11.0-beta.6";
} }
/// @notice Constructs the OptimismPortal contract. /// @notice Constructs the OptimismPortal contract.
...@@ -605,17 +605,17 @@ contract OptimismPortal2 is Initializable, ResourceMetering, ISemver { ...@@ -605,17 +605,17 @@ contract OptimismPortal2 is Initializable, ResourceMetering, ISemver {
emit TransactionDeposited(from, _to, DEPOSIT_VERSION, opaqueData); emit TransactionDeposited(from, _to, DEPOSIT_VERSION, opaqueData);
} }
/// @notice Sets static configuration options for the L2 system. /// @notice Sets the gas paying token for the L2 system. This token is used as the
/// @param _type Type of configuration to set. /// L2 native asset. Only the SystemConfig contract can call this function.
/// @param _value Encoded value of the configuration. function setGasPayingToken(address _token, uint8 _decimals, bytes32 _name, bytes32 _symbol) external {
function setConfig(Types.ConfigType _type, bytes memory _value) external {
if (msg.sender != address(systemConfig)) revert Unauthorized(); if (msg.sender != address(systemConfig)) revert Unauthorized();
// Set L2 deposit gas as used without paying burning gas. Ensures that deposits cannot use too much L2 gas. // Set L2 deposit gas as used without paying burning gas. Ensures that deposits cannot use too much L2 gas.
// This value must be large enough to cover the cost of calling `L1Block.setConfig`. // This value must be large enough to cover the cost of calling `L1Block.setGasPayingToken`.
useGas(SYSTEM_DEPOSIT_GAS_LIMIT); useGas(SYSTEM_DEPOSIT_GAS_LIMIT);
// Emit the special deposit transaction directly that sets the config in the L1Block predeploy contract. // Emit the special deposit transaction directly that sets the gas paying
// token in the L1Block predeploy contract.
emit TransactionDeposited( emit TransactionDeposited(
Constants.DEPOSITOR_ACCOUNT, Constants.DEPOSITOR_ACCOUNT,
Predeploys.L1_BLOCK_ATTRIBUTES, Predeploys.L1_BLOCK_ATTRIBUTES,
...@@ -625,30 +625,7 @@ contract OptimismPortal2 is Initializable, ResourceMetering, ISemver { ...@@ -625,30 +625,7 @@ contract OptimismPortal2 is Initializable, ResourceMetering, ISemver {
uint256(0), // value uint256(0), // value
uint64(SYSTEM_DEPOSIT_GAS_LIMIT), // gasLimit uint64(SYSTEM_DEPOSIT_GAS_LIMIT), // gasLimit
false, // isCreation, false, // isCreation,
abi.encodeCall(IL1Block.setConfig, (_type, _value)) abi.encodeCall(IL1Block.setGasPayingToken, (_token, _decimals, _name, _symbol))
)
);
}
/// @notice Calls the L2ProxyAdmin as the DEPOSITOR_ACCOUNT. This function can be used
/// to upgrade the predeploys on L2. Only callable by the upgrader role on the
/// SuperchainConfig.
function upgrade(uint32 _gasLimit, bytes memory _calldata) external {
if (msg.sender != superchainConfig.upgrader()) revert Unauthorized();
useGas(_gasLimit);
// Emit the special deposit transaction which calls to the L2 Proxy Admin
emit TransactionDeposited(
Constants.DEPOSITOR_ACCOUNT,
Predeploys.PROXY_ADMIN,
DEPOSIT_VERSION,
abi.encodePacked(
uint256(0), // mint
uint256(0), // value
uint64(_gasLimit), // gasLimit
false, // isCreation,
_calldata // data
) )
); );
} }
......
...@@ -3,6 +3,12 @@ pragma solidity 0.8.15; ...@@ -3,6 +3,12 @@ pragma solidity 0.8.15;
// Contracts // Contracts
import { OptimismPortal2 } from "src/L1/OptimismPortal2.sol"; import { OptimismPortal2 } from "src/L1/OptimismPortal2.sol";
import { L1BlockInterop, ConfigType } from "src/L2/L1BlockInterop.sol";
// Libraries
import { Predeploys } from "src/libraries/Predeploys.sol";
import { Constants } from "src/libraries/Constants.sol";
import { Unauthorized } from "src/libraries/PortalErrors.sol";
/// @custom:proxied true /// @custom:proxied true
/// @title OptimismPortalInterop /// @title OptimismPortalInterop
...@@ -17,8 +23,33 @@ contract OptimismPortalInterop is OptimismPortal2 { ...@@ -17,8 +23,33 @@ contract OptimismPortalInterop is OptimismPortal2 {
OptimismPortal2(_proofMaturityDelaySeconds, _disputeGameFinalityDelaySeconds) OptimismPortal2(_proofMaturityDelaySeconds, _disputeGameFinalityDelaySeconds)
{ } { }
/// @custom:semver +interop-beta.3 /// @custom:semver +interop-beta.2
function version() public pure override returns (string memory) { function version() public pure override returns (string memory) {
return string.concat(super.version(), "+interop-beta.3"); return string.concat(super.version(), "+interop-beta.2");
}
/// @notice Sets static configuration options for the L2 system.
/// @param _type Type of configuration to set.
/// @param _value Encoded value of the configuration.
function setConfig(ConfigType _type, bytes memory _value) external {
if (msg.sender != address(systemConfig)) revert Unauthorized();
// Set L2 deposit gas as used without paying burning gas. Ensures that deposits cannot use too much L2 gas.
// This value must be large enough to cover the cost of calling `L1Block.setConfig`.
useGas(SYSTEM_DEPOSIT_GAS_LIMIT);
// Emit the special deposit transaction directly that sets the config in the L1Block predeploy contract.
emit TransactionDeposited(
Constants.DEPOSITOR_ACCOUNT,
Predeploys.L1_BLOCK_ATTRIBUTES,
DEPOSIT_VERSION,
abi.encodePacked(
uint256(0), // mint
uint256(0), // value
uint64(SYSTEM_DEPOSIT_GAS_LIMIT), // gasLimit
false, // isCreation,
abi.encodeCall(L1BlockInterop.setConfig, (_type, _value))
)
);
} }
} }
...@@ -12,10 +12,8 @@ import { Storage } from "src/libraries/Storage.sol"; ...@@ -12,10 +12,8 @@ import { Storage } from "src/libraries/Storage.sol";
contract SuperchainConfig is Initializable, ISemver { contract SuperchainConfig is Initializable, ISemver {
/// @notice Enum representing different types of updates. /// @notice Enum representing different types of updates.
/// @custom:value GUARDIAN Represents an update to the guardian. /// @custom:value GUARDIAN Represents an update to the guardian.
/// @custom:value UPGRADER Represents an update to the upgrader.
enum UpdateType { enum UpdateType {
GUARDIAN, GUARDIAN
UPGRADER
} }
/// @notice Whether or not the Superchain is paused. /// @notice Whether or not the Superchain is paused.
...@@ -25,10 +23,6 @@ contract SuperchainConfig is Initializable, ISemver { ...@@ -25,10 +23,6 @@ contract SuperchainConfig is Initializable, ISemver {
/// It can only be modified by an upgrade. /// It can only be modified by an upgrade.
bytes32 public constant GUARDIAN_SLOT = bytes32(uint256(keccak256("superchainConfig.guardian")) - 1); bytes32 public constant GUARDIAN_SLOT = bytes32(uint256(keccak256("superchainConfig.guardian")) - 1);
/// @notice The address of the upgrader, which can faciliate upgrades of L2 predeploys.
/// . It can only be modified by an upgrade.
bytes32 public constant UPGRADER_SLOT = bytes32(uint256(keccak256("superchainConfig.upgrader")) - 1);
/// @notice Emitted when the pause is triggered. /// @notice Emitted when the pause is triggered.
/// @param identifier A string helping to identify provenance of the pause transaction. /// @param identifier A string helping to identify provenance of the pause transaction.
event Paused(string identifier); event Paused(string identifier);
...@@ -42,20 +36,19 @@ contract SuperchainConfig is Initializable, ISemver { ...@@ -42,20 +36,19 @@ contract SuperchainConfig is Initializable, ISemver {
event ConfigUpdate(UpdateType indexed updateType, bytes data); event ConfigUpdate(UpdateType indexed updateType, bytes data);
/// @notice Semantic version. /// @notice Semantic version.
/// @custom:semver 1.1.1-beta.2 /// @custom:semver 1.1.1-beta.1
string public constant version = "1.1.1-beta.2"; string public constant version = "1.1.1-beta.1";
/// @notice Constructs the SuperchainConfig contract. /// @notice Constructs the SuperchainConfig contract.
constructor() { constructor() {
_disableInitializers(); initialize({ _guardian: address(0), _paused: false });
} }
/// @notice Initializer. /// @notice Initializer.
/// @param _guardian Address of the guardian, can pause the OptimismPortal. /// @param _guardian Address of the guardian, can pause the OptimismPortal.
/// @param _paused Initial paused status. /// @param _paused Initial paused status.
function initialize(address _guardian, address _upgrader, bool _paused) public initializer { function initialize(address _guardian, bool _paused) public initializer {
_setGuardian(_guardian); _setGuardian(_guardian);
_setUpgrader(_upgrader);
if (_paused) { if (_paused) {
_pause("Initializer paused"); _pause("Initializer paused");
} }
...@@ -66,11 +59,6 @@ contract SuperchainConfig is Initializable, ISemver { ...@@ -66,11 +59,6 @@ contract SuperchainConfig is Initializable, ISemver {
guardian_ = Storage.getAddress(GUARDIAN_SLOT); guardian_ = Storage.getAddress(GUARDIAN_SLOT);
} }
/// @notice Getter for the upgrader address.
function upgrader() public view returns (address upgrader_) {
upgrader_ = Storage.getAddress(UPGRADER_SLOT);
}
/// @notice Getter for the current paused status. /// @notice Getter for the current paused status.
function paused() public view returns (bool paused_) { function paused() public view returns (bool paused_) {
paused_ = Storage.getBool(PAUSED_SLOT); paused_ = Storage.getBool(PAUSED_SLOT);
...@@ -104,12 +92,4 @@ contract SuperchainConfig is Initializable, ISemver { ...@@ -104,12 +92,4 @@ contract SuperchainConfig is Initializable, ISemver {
Storage.setAddress(GUARDIAN_SLOT, _guardian); Storage.setAddress(GUARDIAN_SLOT, _guardian);
emit ConfigUpdate(UpdateType.GUARDIAN, abi.encode(_guardian)); emit ConfigUpdate(UpdateType.GUARDIAN, abi.encode(_guardian));
} }
/// @notice Sets the upgrader address. This is only callable during initialization, so an upgrade
/// will be required to change the upgrader.
/// @param _upgrader The new upgrader address.
function _setUpgrader(address _upgrader) internal {
Storage.setAddress(UPGRADER_SLOT, _upgrader);
emit ConfigUpdate(UpdateType.UPGRADER, abi.encode(_upgrader));
}
} }
...@@ -4,18 +4,15 @@ pragma solidity 0.8.15; ...@@ -4,18 +4,15 @@ pragma solidity 0.8.15;
// Contracts // Contracts
import { OwnableUpgradeable } from "@openzeppelin/contracts-upgradeable/access/OwnableUpgradeable.sol"; import { OwnableUpgradeable } from "@openzeppelin/contracts-upgradeable/access/OwnableUpgradeable.sol";
import { ERC20 } from "@openzeppelin/contracts/token/ERC20/ERC20.sol"; import { ERC20 } from "@openzeppelin/contracts/token/ERC20/ERC20.sol";
import { StaticConfig } from "src/libraries/StaticConfig.sol";
import { Encoding } from "src/libraries/Encoding.sol";
// Libraries // Libraries
import { Storage } from "src/libraries/Storage.sol"; import { Storage } from "src/libraries/Storage.sol";
import { Constants } from "src/libraries/Constants.sol"; import { Constants } from "src/libraries/Constants.sol";
import { GasPayingToken, IGasToken } from "src/libraries/GasPayingToken.sol"; import { GasPayingToken, IGasToken } from "src/libraries/GasPayingToken.sol";
import { Types } from "src/libraries/Types.sol";
// Interfaces // Interfaces
import { ISemver } from "src/universal/interfaces/ISemver.sol"; import { ISemver } from "src/universal/interfaces/ISemver.sol";
import { IOptimismPortal2 as IOptimismPortal } from "src/L1/interfaces/IOptimismPortal2.sol"; import { IOptimismPortal } from "src/L1/interfaces/IOptimismPortal.sol";
import { IResourceMetering } from "src/L1/interfaces/IResourceMetering.sol"; import { IResourceMetering } from "src/L1/interfaces/IResourceMetering.sol";
/// @custom:proxied true /// @custom:proxied true
...@@ -51,18 +48,6 @@ contract SystemConfig is OwnableUpgradeable, ISemver, IGasToken { ...@@ -51,18 +48,6 @@ contract SystemConfig is OwnableUpgradeable, ISemver, IGasToken {
address gasPayingToken; address gasPayingToken;
} }
/// @notice Struct representing the roles of the system.
/// @notice The owner (chain operator) of the system.
/// @notice The fee admin of the system.
/// @notice The unsafe block signer of the system.
/// @notice The batcher hash of the system.
struct Roles {
address owner;
address feeAdmin;
address unsafeBlockSigner;
bytes32 batcherHash;
}
/// @notice Version identifier, used for upgrades. /// @notice Version identifier, used for upgrades.
uint256 public constant VERSION = 0; uint256 public constant VERSION = 0;
...@@ -76,9 +61,6 @@ contract SystemConfig is OwnableUpgradeable, ISemver, IGasToken { ...@@ -76,9 +61,6 @@ contract SystemConfig is OwnableUpgradeable, ISemver, IGasToken {
/// but it is better to be safe than sorry. /// but it is better to be safe than sorry.
bytes32 public constant UNSAFE_BLOCK_SIGNER_SLOT = keccak256("systemconfig.unsafeblocksigner"); bytes32 public constant UNSAFE_BLOCK_SIGNER_SLOT = keccak256("systemconfig.unsafeblocksigner");
/// @notice Storage slot that the feeAdmin address is stored at.
bytes32 internal constant FEE_ADMIN_SLOT = keccak256("systemconfig.feeadmin");
/// @notice Storage slot that the L1CrossDomainMessenger address is stored at. /// @notice Storage slot that the L1CrossDomainMessenger address is stored at.
bytes32 public constant L1_CROSS_DOMAIN_MESSENGER_SLOT = bytes32 public constant L1_CROSS_DOMAIN_MESSENGER_SLOT =
bytes32(uint256(keccak256("systemconfig.l1crossdomainmessenger")) - 1); bytes32(uint256(keccak256("systemconfig.l1crossdomainmessenger")) - 1);
...@@ -155,9 +137,9 @@ contract SystemConfig is OwnableUpgradeable, ISemver, IGasToken { ...@@ -155,9 +137,9 @@ contract SystemConfig is OwnableUpgradeable, ISemver, IGasToken {
event ConfigUpdate(uint256 indexed version, UpdateType indexed updateType, bytes data); event ConfigUpdate(uint256 indexed version, UpdateType indexed updateType, bytes data);
/// @notice Semantic version. /// @notice Semantic version.
/// @custom:semver 2.3.0-beta.6 /// @custom:semver 2.3.0-beta.5
function version() public pure virtual returns (string memory) { function version() public pure virtual returns (string memory) {
return "2.3.0-beta.6"; return "2.3.0-beta.5";
} }
/// @notice Constructs the SystemConfig contract. Cannot set /// @notice Constructs the SystemConfig contract. Cannot set
...@@ -165,28 +147,55 @@ contract SystemConfig is OwnableUpgradeable, ISemver, IGasToken { ...@@ -165,28 +147,55 @@ contract SystemConfig is OwnableUpgradeable, ISemver, IGasToken {
/// implementation, so set it to `address(0xdEaD)` /// implementation, so set it to `address(0xdEaD)`
/// @dev START_BLOCK_SLOT is set to type(uint256).max here so that it will be a dead value /// @dev START_BLOCK_SLOT is set to type(uint256).max here so that it will be a dead value
/// in the singleton and is skipped by initialize when setting the start block. /// in the singleton and is skipped by initialize when setting the start block.
/// _disableInitializers is called to prevent the need to make calls during the constructor
/// if initialize is called directly.
constructor() { constructor() {
Storage.setUint(START_BLOCK_SLOT, type(uint256).max); Storage.setUint(START_BLOCK_SLOT, type(uint256).max);
_disableInitializers(); initialize({
_owner: address(0xdEaD),
_basefeeScalar: 0,
_blobbasefeeScalar: 0,
_batcherHash: bytes32(0),
_gasLimit: 1,
_unsafeBlockSigner: address(0),
_config: IResourceMetering.ResourceConfig({
maxResourceLimit: 1,
elasticityMultiplier: 1,
baseFeeMaxChangeDenominator: 2,
minimumBaseFee: 0,
systemTxMaxGas: 0,
maximumBaseFee: 0
}),
_batchInbox: address(0),
_addresses: SystemConfig.Addresses({
l1CrossDomainMessenger: address(0),
l1ERC721Bridge: address(0),
l1StandardBridge: address(0),
disputeGameFactory: address(0),
optimismPortal: address(0),
optimismMintableERC20Factory: address(0),
gasPayingToken: address(0)
})
});
} }
/// @notice Initializer. /// @notice Initializer.
/// The resource config must be set before the require check. /// The resource config must be set before the require check.
/// @param _roles Initial roles. /// @param _owner Initial owner of the contract.
/// @param _basefeeScalar Initial basefee scalar value. /// @param _basefeeScalar Initial basefee scalar value.
/// @param _blobbasefeeScalar Initial blobbasefee scalar value. /// @param _blobbasefeeScalar Initial blobbasefee scalar value.
/// @param _batcherHash Initial batcher hash.
/// @param _gasLimit Initial gas limit. /// @param _gasLimit Initial gas limit.
/// @param _unsafeBlockSigner Initial unsafe block signer address.
/// @param _config Initial ResourceConfig. /// @param _config Initial ResourceConfig.
/// @param _batchInbox Batch inbox address. An identifier for the op-node to find /// @param _batchInbox Batch inbox address. An identifier for the op-node to find
/// canonical data. /// canonical data.
/// @param _addresses Set of L1 contract addresses. These should be the proxies. /// @param _addresses Set of L1 contract addresses. These should be the proxies.
function initialize( function initialize(
Roles memory _roles, address _owner,
uint32 _basefeeScalar, uint32 _basefeeScalar,
uint32 _blobbasefeeScalar, uint32 _blobbasefeeScalar,
bytes32 _batcherHash,
uint64 _gasLimit, uint64 _gasLimit,
address _unsafeBlockSigner,
IResourceMetering.ResourceConfig memory _config, IResourceMetering.ResourceConfig memory _config,
address _batchInbox, address _batchInbox,
SystemConfig.Addresses memory _addresses SystemConfig.Addresses memory _addresses
...@@ -195,58 +204,29 @@ contract SystemConfig is OwnableUpgradeable, ISemver, IGasToken { ...@@ -195,58 +204,29 @@ contract SystemConfig is OwnableUpgradeable, ISemver, IGasToken {
initializer initializer
{ {
__Ownable_init(); __Ownable_init();
transferOwnership(_roles.owner); transferOwnership(_owner);
// These are set in ascending order of their UpdateTypes. // These are set in ascending order of their UpdateTypes.
_setBatcherHash(_roles.batcherHash); _setBatcherHash(_batcherHash);
_setGasConfigEcotone({ _basefeeScalar: _basefeeScalar, _blobbasefeeScalar: _blobbasefeeScalar }); _setGasConfigEcotone({ _basefeeScalar: _basefeeScalar, _blobbasefeeScalar: _blobbasefeeScalar });
_setGasLimit(_gasLimit); _setGasLimit(_gasLimit);
Storage.setAddress(UNSAFE_BLOCK_SIGNER_SLOT, _roles.unsafeBlockSigner); Storage.setAddress(UNSAFE_BLOCK_SIGNER_SLOT, _unsafeBlockSigner);
Storage.setAddress(FEE_ADMIN_SLOT, _roles.feeAdmin);
Storage.setAddress(BATCH_INBOX_SLOT, _batchInbox); Storage.setAddress(BATCH_INBOX_SLOT, _batchInbox);
Storage.setAddress(L1_CROSS_DOMAIN_MESSENGER_SLOT, _addresses.l1CrossDomainMessenger);
Storage.setAddress(OPTIMISM_PORTAL_SLOT, _addresses.optimismPortal); Storage.setAddress(L1_ERC_721_BRIDGE_SLOT, _addresses.l1ERC721Bridge);
Storage.setAddress(L1_STANDARD_BRIDGE_SLOT, _addresses.l1StandardBridge);
Storage.setAddress(DISPUTE_GAME_FACTORY_SLOT, _addresses.disputeGameFactory); Storage.setAddress(DISPUTE_GAME_FACTORY_SLOT, _addresses.disputeGameFactory);
Storage.setAddress(OPTIMISM_PORTAL_SLOT, _addresses.optimismPortal);
Storage.setAddress(OPTIMISM_MINTABLE_ERC20_FACTORY_SLOT, _addresses.optimismMintableERC20Factory); Storage.setAddress(OPTIMISM_MINTABLE_ERC20_FACTORY_SLOT, _addresses.optimismMintableERC20Factory);
_setGasPayingToken(_addresses.gasPayingToken);
_setAddress(
L1_CROSS_DOMAIN_MESSENGER_SLOT,
_addresses.l1CrossDomainMessenger,
Types.ConfigType.L1_CROSS_DOMAIN_MESSENGER_ADDRESS
);
_setAddress(L1_ERC_721_BRIDGE_SLOT, _addresses.l1ERC721Bridge, Types.ConfigType.L1_ERC_721_BRIDGE_ADDRESS);
_setAddress(L1_STANDARD_BRIDGE_SLOT, _addresses.l1StandardBridge, Types.ConfigType.L1_STANDARD_BRIDGE_ADDRESS);
_setRemoteChainId();
_setStartBlock(); _setStartBlock();
_setGasPayingToken(_addresses.gasPayingToken);
// TODO: set fee vault config calls
_setResourceConfig(_config); _setResourceConfig(_config);
require(_gasLimit >= minimumGasLimit(), "SystemConfig: gas limit too low"); require(_gasLimit >= minimumGasLimit(), "SystemConfig: gas limit too low");
} }
/// @notice Internal setter for L1 system addresses that need to be legible from within L2.
/// @param _slot The local storage slot that the address should be stored in.
/// @param _addr The address of the L1 based system address.
/// @param _type The ConfigType that represents what the address is.
function _setAddress(bytes32 _slot, address _addr, Types.ConfigType _type) internal {
Storage.setAddress(_slot, _addr);
IOptimismPortal(payable(optimismPortal())).setConfig({ _type: _type, _value: abi.encode(_addr) });
}
/// @notice Internal setter for the base chain's chain id. This allows for the
/// base chain's chain id to be legible from within the parent chain.
/// In the case of an L2, this would be the L1 chain id.
function _setRemoteChainId() internal {
IOptimismPortal(payable(optimismPortal())).setConfig({
_type: Types.ConfigType.REMOTE_CHAIN_ID,
_value: abi.encode(block.chainid)
});
}
/// @notice Returns the minimum L2 gas limit that can be safely set for the system to /// @notice Returns the minimum L2 gas limit that can be safely set for the system to
/// operate. The L2 gas limit must be larger than or equal to the amount of /// operate. The L2 gas limit must be larger than or equal to the amount of
/// gas that is allocated for deposits per block plus the amount of gas that /// gas that is allocated for deposits per block plus the amount of gas that
...@@ -273,12 +253,6 @@ contract SystemConfig is OwnableUpgradeable, ISemver, IGasToken { ...@@ -273,12 +253,6 @@ contract SystemConfig is OwnableUpgradeable, ISemver, IGasToken {
addr_ = Storage.getAddress(UNSAFE_BLOCK_SIGNER_SLOT); addr_ = Storage.getAddress(UNSAFE_BLOCK_SIGNER_SLOT);
} }
/// @notice High level getter for the fee admin address.
/// @return addr_ Address of the fee admin.
function feeAdmin() public view returns (address addr_) {
addr_ = Storage.getAddress(FEE_ADMIN_SLOT);
}
/// @notice Getter for the L1CrossDomainMessenger address. /// @notice Getter for the L1CrossDomainMessenger address.
function l1CrossDomainMessenger() external view returns (address addr_) { function l1CrossDomainMessenger() external view returns (address addr_) {
addr_ = Storage.getAddress(L1_CROSS_DOMAIN_MESSENGER_SLOT); addr_ = Storage.getAddress(L1_CROSS_DOMAIN_MESSENGER_SLOT);
...@@ -346,7 +320,7 @@ contract SystemConfig is OwnableUpgradeable, ISemver, IGasToken { ...@@ -346,7 +320,7 @@ contract SystemConfig is OwnableUpgradeable, ISemver, IGasToken {
/// to set the token address. This prevents the token address from being changed /// to set the token address. This prevents the token address from being changed
/// and makes it explicitly opt-in to use custom gas token. /// and makes it explicitly opt-in to use custom gas token.
/// @param _token Address of the gas paying token. /// @param _token Address of the gas paying token.
function _setGasPayingToken(address _token) internal { function _setGasPayingToken(address _token) internal virtual {
if (_token != address(0) && _token != Constants.ETHER && !isCustomGasToken()) { if (_token != address(0) && _token != Constants.ETHER && !isCustomGasToken()) {
require( require(
ERC20(_token).decimals() == GAS_PAYING_TOKEN_DECIMALS, "SystemConfig: bad decimals of gas paying token" ERC20(_token).decimals() == GAS_PAYING_TOKEN_DECIMALS, "SystemConfig: bad decimals of gas paying token"
...@@ -354,17 +328,14 @@ contract SystemConfig is OwnableUpgradeable, ISemver, IGasToken { ...@@ -354,17 +328,14 @@ contract SystemConfig is OwnableUpgradeable, ISemver, IGasToken {
bytes32 name = GasPayingToken.sanitize(ERC20(_token).name()); bytes32 name = GasPayingToken.sanitize(ERC20(_token).name());
bytes32 symbol = GasPayingToken.sanitize(ERC20(_token).symbol()); bytes32 symbol = GasPayingToken.sanitize(ERC20(_token).symbol());
// Set the gas paying token in storage and call the OptimismPortal. // Set the gas paying token in storage and in the OptimismPortal.
GasPayingToken.set({ _token: _token, _decimals: GAS_PAYING_TOKEN_DECIMALS, _name: name, _symbol: symbol }); GasPayingToken.set({ _token: _token, _decimals: GAS_PAYING_TOKEN_DECIMALS, _name: name, _symbol: symbol });
IOptimismPortal(payable(optimismPortal())).setConfig( IOptimismPortal(payable(optimismPortal())).setGasPayingToken({
Types.ConfigType.GAS_PAYING_TOKEN,
StaticConfig.encodeSetGasPayingToken({
_token: _token, _token: _token,
_decimals: GAS_PAYING_TOKEN_DECIMALS, _decimals: GAS_PAYING_TOKEN_DECIMALS,
_name: name, _name: name,
_symbol: symbol _symbol: symbol
}) });
);
} }
} }
...@@ -445,47 +416,6 @@ contract SystemConfig is OwnableUpgradeable, ISemver, IGasToken { ...@@ -445,47 +416,6 @@ contract SystemConfig is OwnableUpgradeable, ISemver, IGasToken {
_setGasLimit(_gasLimit); _setGasLimit(_gasLimit);
} }
/// @notice Setter for the FeeVault predeploy configuration.
/// @param _type The FeeVault type.
/// @param _recipient Address that should receive the funds.
/// @param _min Minimum withdrawal amount allowed to be processed.
/// @param _network The network in which the fees should be withdrawn to.
function setFeeVaultConfig(
Types.ConfigType _type,
address _recipient,
uint256 _min,
Types.WithdrawalNetwork _network
)
external
{
require(msg.sender == feeAdmin(), "SystemConfig: caller is not the fee admin");
_setFeeVaultConfig(_type, _recipient, _min, _network);
}
/// @notice Internal function for setting the FeeVault config by type.
/// @param _type The FeeVault type
/// @param _recipient Address that should receive the funds.
/// @param _min Minimum withdrawal amount allowed to be processed.
/// @param _network The network in which the fees should be withdrawn to.
function _setFeeVaultConfig(
Types.ConfigType _type,
address _recipient,
uint256 _min,
Types.WithdrawalNetwork _network
)
internal
{
require(
_type == Types.ConfigType.BASE_FEE_VAULT_CONFIG || _type == Types.ConfigType.L1_FEE_VAULT_CONFIG
|| _type == Types.ConfigType.SEQUENCER_FEE_VAULT_CONFIG,
"SystemConfig: ConfigType is is not a Fee Vault Config type"
);
IOptimismPortal(payable(optimismPortal())).setConfig({
_type: _type,
_value: abi.encode(Encoding.encodeFeeVaultConfig(_recipient, _min, _network))
});
}
/// @notice Internal function for updating the L2 gas limit. /// @notice Internal function for updating the L2 gas limit.
/// @param _gasLimit New gas limit. /// @param _gasLimit New gas limit.
function _setGasLimit(uint64 _gasLimit) internal { function _setGasLimit(uint64 _gasLimit) internal {
...@@ -562,9 +492,6 @@ contract SystemConfig is OwnableUpgradeable, ISemver, IGasToken { ...@@ -562,9 +492,6 @@ contract SystemConfig is OwnableUpgradeable, ISemver, IGasToken {
"SystemConfig: precision loss with target resource limit" "SystemConfig: precision loss with target resource limit"
); );
// TODO: maxResourceLimit must be large enough to handle the SystemConfig.initialize
// call
_resourceConfig = _config; _resourceConfig = _config;
} }
} }
...@@ -2,13 +2,16 @@ ...@@ -2,13 +2,16 @@
pragma solidity 0.8.15; pragma solidity 0.8.15;
// Contracts // Contracts
import { ERC20 } from "@openzeppelin/contracts/token/ERC20/ERC20.sol";
import { IOptimismPortalInterop as IOptimismPortal } from "src/L1/interfaces/IOptimismPortalInterop.sol"; import { IOptimismPortalInterop as IOptimismPortal } from "src/L1/interfaces/IOptimismPortalInterop.sol";
import { SystemConfig } from "src/L1/SystemConfig.sol"; import { SystemConfig } from "src/L1/SystemConfig.sol";
import { ConfigType } from "src/L2/L1BlockInterop.sol";
// Libraries // Libraries
import { Constants } from "src/libraries/Constants.sol";
import { GasPayingToken } from "src/libraries/GasPayingToken.sol";
import { StaticConfig } from "src/libraries/StaticConfig.sol"; import { StaticConfig } from "src/libraries/StaticConfig.sol";
import { Storage } from "src/libraries/Storage.sol"; import { Storage } from "src/libraries/Storage.sol";
import { Types } from "src/libraries/Types.sol";
// Interfaces // Interfaces
import { IResourceMetering } from "src/L1/interfaces/IResourceMetering.sol"; import { IResourceMetering } from "src/L1/interfaces/IResourceMetering.sol";
...@@ -25,20 +28,24 @@ contract SystemConfigInterop is SystemConfig { ...@@ -25,20 +28,24 @@ contract SystemConfigInterop is SystemConfig {
0x1708e077affb93e89be2665fb0fb72581be66f84dc00d25fed755ae911905b1c; 0x1708e077affb93e89be2665fb0fb72581be66f84dc00d25fed755ae911905b1c;
/// @notice Initializer. /// @notice Initializer.
/// @param _roles Initial roles. /// @param _owner Initial owner of the contract.
/// @param _basefeeScalar Initial basefee scalar value. /// @param _basefeeScalar Initial basefee scalar value.
/// @param _blobbasefeeScalar Initial blobbasefee scalar value. /// @param _blobbasefeeScalar Initial blobbasefee scalar value.
/// @param _batcherHash Initial batcher hash.
/// @param _gasLimit Initial gas limit. /// @param _gasLimit Initial gas limit.
/// @param _unsafeBlockSigner Initial unsafe block signer address.
/// @param _config Initial ResourceConfig. /// @param _config Initial ResourceConfig.
/// @param _batchInbox Batch inbox address. An identifier for the op-node to find /// @param _batchInbox Batch inbox address. An identifier for the op-node to find
/// canonical data. /// canonical data.
/// @param _addresses Set of L1 contract addresses. These should be the proxies. /// @param _addresses Set of L1 contract addresses. These should be the proxies.
/// @param _dependencyManager The addressed allowed to add/remove from the dependency set /// @param _dependencyManager The addressed allowed to add/remove from the dependency set
function initialize( function initialize(
SystemConfig.Roles memory _roles, address _owner,
uint32 _basefeeScalar, uint32 _basefeeScalar,
uint32 _blobbasefeeScalar, uint32 _blobbasefeeScalar,
bytes32 _batcherHash,
uint64 _gasLimit, uint64 _gasLimit,
address _unsafeBlockSigner,
IResourceMetering.ResourceConfig memory _config, IResourceMetering.ResourceConfig memory _config,
address _batchInbox, address _batchInbox,
SystemConfig.Addresses memory _addresses, SystemConfig.Addresses memory _addresses,
...@@ -48,10 +55,12 @@ contract SystemConfigInterop is SystemConfig { ...@@ -48,10 +55,12 @@ contract SystemConfigInterop is SystemConfig {
{ {
// This method has an initializer modifier, and will revert if already initialized. // This method has an initializer modifier, and will revert if already initialized.
initialize({ initialize({
_roles: _roles, _owner: _owner,
_basefeeScalar: _basefeeScalar, _basefeeScalar: _basefeeScalar,
_blobbasefeeScalar: _blobbasefeeScalar, _blobbasefeeScalar: _blobbasefeeScalar,
_batcherHash: _batcherHash,
_gasLimit: _gasLimit, _gasLimit: _gasLimit,
_unsafeBlockSigner: _unsafeBlockSigner,
_config: _config, _config: _config,
_batchInbox: _batchInbox, _batchInbox: _batchInbox,
_addresses: _addresses _addresses: _addresses
...@@ -59,9 +68,38 @@ contract SystemConfigInterop is SystemConfig { ...@@ -59,9 +68,38 @@ contract SystemConfigInterop is SystemConfig {
Storage.setAddress(DEPENDENCY_MANAGER_SLOT, _dependencyManager); Storage.setAddress(DEPENDENCY_MANAGER_SLOT, _dependencyManager);
} }
/// @custom:semver +interop-beta.4 /// @custom:semver +interop-beta.3
function version() public pure override returns (string memory) { function version() public pure override returns (string memory) {
return string.concat(super.version(), "+interop-beta.4"); return string.concat(super.version(), "+interop-beta.3");
}
/// @notice Internal setter for the gas paying token address, includes validation.
/// The token must not already be set and must be non zero and not the ether address
/// to set the token address. This prevents the token address from being changed
/// and makes it explicitly opt-in to use custom gas token. Additionally,
/// OptimismPortal's address must be non zero, since otherwise the call to set the
/// config for the gas paying token to OptimismPortal will fail.
/// @param _token Address of the gas paying token.
function _setGasPayingToken(address _token) internal override {
if (_token != address(0) && _token != Constants.ETHER && !isCustomGasToken()) {
require(
ERC20(_token).decimals() == GAS_PAYING_TOKEN_DECIMALS, "SystemConfig: bad decimals of gas paying token"
);
bytes32 name = GasPayingToken.sanitize(ERC20(_token).name());
bytes32 symbol = GasPayingToken.sanitize(ERC20(_token).symbol());
// Set the gas paying token in storage and in the OptimismPortal.
GasPayingToken.set({ _token: _token, _decimals: GAS_PAYING_TOKEN_DECIMALS, _name: name, _symbol: symbol });
IOptimismPortal(payable(optimismPortal())).setConfig(
ConfigType.SET_GAS_PAYING_TOKEN,
StaticConfig.encodeSetGasPayingToken({
_token: _token,
_decimals: GAS_PAYING_TOKEN_DECIMALS,
_name: name,
_symbol: symbol
})
);
}
} }
/// @notice Adds a chain to the interop dependency set. Can only be called by the dependency manager. /// @notice Adds a chain to the interop dependency set. Can only be called by the dependency manager.
...@@ -69,7 +107,7 @@ contract SystemConfigInterop is SystemConfig { ...@@ -69,7 +107,7 @@ contract SystemConfigInterop is SystemConfig {
function addDependency(uint256 _chainId) external { function addDependency(uint256 _chainId) external {
require(msg.sender == dependencyManager(), "SystemConfig: caller is not the dependency manager"); require(msg.sender == dependencyManager(), "SystemConfig: caller is not the dependency manager");
IOptimismPortal(payable(optimismPortal())).setConfig( IOptimismPortal(payable(optimismPortal())).setConfig(
Types.ConfigType.ADD_DEPENDENCY, StaticConfig.encodeAddDependency(_chainId) ConfigType.ADD_DEPENDENCY, StaticConfig.encodeAddDependency(_chainId)
); );
} }
...@@ -78,7 +116,7 @@ contract SystemConfigInterop is SystemConfig { ...@@ -78,7 +116,7 @@ contract SystemConfigInterop is SystemConfig {
function removeDependency(uint256 _chainId) external { function removeDependency(uint256 _chainId) external {
require(msg.sender == dependencyManager(), "SystemConfig: caller is not the dependency manager"); require(msg.sender == dependencyManager(), "SystemConfig: caller is not the dependency manager");
IOptimismPortal(payable(optimismPortal())).setConfig( IOptimismPortal(payable(optimismPortal())).setConfig(
Types.ConfigType.REMOVE_DEPENDENCY, StaticConfig.encodeRemoveDependency(_chainId) ConfigType.REMOVE_DEPENDENCY, StaticConfig.encodeRemoveDependency(_chainId)
); );
} }
......
...@@ -7,8 +7,6 @@ import { IOptimismPortal } from "src/L1/interfaces/IOptimismPortal.sol"; ...@@ -7,8 +7,6 @@ import { IOptimismPortal } from "src/L1/interfaces/IOptimismPortal.sol";
import { ISystemConfig } from "src/L1/interfaces/ISystemConfig.sol"; import { ISystemConfig } from "src/L1/interfaces/ISystemConfig.sol";
interface IL1CrossDomainMessenger is ICrossDomainMessenger { interface IL1CrossDomainMessenger is ICrossDomainMessenger {
event Initialized(uint8 version);
function PORTAL() external view returns (IOptimismPortal); function PORTAL() external view returns (IOptimismPortal);
function initialize( function initialize(
ISuperchainConfig _superchainConfig, ISuperchainConfig _superchainConfig,
...@@ -16,8 +14,6 @@ interface IL1CrossDomainMessenger is ICrossDomainMessenger { ...@@ -16,8 +14,6 @@ interface IL1CrossDomainMessenger is ICrossDomainMessenger {
ISystemConfig _systemConfig ISystemConfig _systemConfig
) )
external; external;
function OTHER_MESSENGER() external view returns (ICrossDomainMessenger);
function otherMessenger() external pure returns (ICrossDomainMessenger);
function portal() external view returns (IOptimismPortal); function portal() external view returns (IOptimismPortal);
function superchainConfig() external view returns (ISuperchainConfig); function superchainConfig() external view returns (ISuperchainConfig);
function systemConfig() external view returns (ISystemConfig); function systemConfig() external view returns (ISystemConfig);
......
...@@ -6,11 +6,6 @@ import { ICrossDomainMessenger } from "src/universal/interfaces/ICrossDomainMess ...@@ -6,11 +6,6 @@ import { ICrossDomainMessenger } from "src/universal/interfaces/ICrossDomainMess
import { ISuperchainConfig } from "src/L1/interfaces/ISuperchainConfig.sol"; import { ISuperchainConfig } from "src/L1/interfaces/ISuperchainConfig.sol";
interface IL1ERC721Bridge is IERC721Bridge { interface IL1ERC721Bridge is IERC721Bridge {
error InvalidInitialization();
error NotInitializing();
event Initialized(uint64 version);
function bridgeERC721( function bridgeERC721(
address _localToken, address _localToken,
address _remoteToken, address _remoteToken,
...@@ -39,7 +34,6 @@ interface IL1ERC721Bridge is IERC721Bridge { ...@@ -39,7 +34,6 @@ interface IL1ERC721Bridge is IERC721Bridge {
) )
external; external;
function initialize(ICrossDomainMessenger _messenger, ISuperchainConfig _superchainConfig) external; function initialize(ICrossDomainMessenger _messenger, ISuperchainConfig _superchainConfig) external;
function otherBridge() external pure returns (IERC721Bridge);
function paused() external view returns (bool); function paused() external view returns (bool);
function superchainConfig() external view returns (ISuperchainConfig); function superchainConfig() external view returns (ISuperchainConfig);
function version() external view returns (string memory); function version() external view returns (string memory);
......
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;
interface IL1OptimismMintableERC20Factory {
event Initialized(uint8 version);
event OptimismMintableERC20Created(address indexed localToken, address indexed remoteToken, address deployer);
event StandardL2TokenCreated(address indexed remoteToken, address indexed localToken);
function BRIDGE() external view returns (address);
function bridge() external view returns (address);
function createOptimismMintableERC20(
address _remoteToken,
string memory _name,
string memory _symbol
)
external
returns (address);
function createOptimismMintableERC20WithDecimals(
address _remoteToken,
string memory _name,
string memory _symbol,
uint8 _decimals
)
external
returns (address);
function createStandardL2Token(
address _remoteToken,
string memory _name,
string memory _symbol
)
external
returns (address);
function deployments(address) external view returns (address);
function initialize(address _bridge) external;
function version() external view returns (string memory);
function __constructor__() external;
}
...@@ -25,7 +25,6 @@ interface IL1StandardBridge is IStandardBridge { ...@@ -25,7 +25,6 @@ interface IL1StandardBridge is IStandardBridge {
); );
event ETHDepositInitiated(address indexed from, address indexed to, uint256 amount, bytes extraData); event ETHDepositInitiated(address indexed from, address indexed to, uint256 amount, bytes extraData);
event ETHWithdrawalFinalized(address indexed from, address indexed to, uint256 amount, bytes extraData); event ETHWithdrawalFinalized(address indexed from, address indexed to, uint256 amount, bytes extraData);
event Initialized(uint8 version);
function depositERC20( function depositERC20(
address _l1Token, address _l1Token,
...@@ -69,9 +68,7 @@ interface IL1StandardBridge is IStandardBridge { ...@@ -69,9 +68,7 @@ interface IL1StandardBridge is IStandardBridge {
ISystemConfig _systemConfig ISystemConfig _systemConfig
) )
external; external;
function l2TokenBridge() external pure returns (address); function l2TokenBridge() external view returns (address);
function OTHER_BRIDGE() external view returns (IStandardBridge);
function otherBridge() external pure returns (IStandardBridge);
function superchainConfig() external view returns (ISuperchainConfig); function superchainConfig() external view returns (ISuperchainConfig);
function systemConfig() external view returns (ISystemConfig); function systemConfig() external view returns (ISystemConfig);
function version() external view returns (string memory); function version() external view returns (string memory);
......
...@@ -5,7 +5,6 @@ import { Types } from "src/libraries/Types.sol"; ...@@ -5,7 +5,6 @@ import { Types } from "src/libraries/Types.sol";
import { ISystemConfig } from "src/L1/interfaces/ISystemConfig.sol"; import { ISystemConfig } from "src/L1/interfaces/ISystemConfig.sol";
import { ISuperchainConfig } from "src/L1/interfaces/ISuperchainConfig.sol"; import { ISuperchainConfig } from "src/L1/interfaces/ISuperchainConfig.sol";
import { IL2OutputOracle } from "src/L1/interfaces/IL2OutputOracle.sol"; import { IL2OutputOracle } from "src/L1/interfaces/IL2OutputOracle.sol";
import { Types } from "src/libraries/Types.sol";
interface IOptimismPortal { interface IOptimismPortal {
error BadTarget(); error BadTarget();
...@@ -79,9 +78,9 @@ interface IOptimismPortal { ...@@ -79,9 +78,9 @@ interface IOptimismPortal {
external external
view view
returns (bytes32 outputRoot, uint128 timestamp, uint128 l2OutputIndex); // nosemgrep returns (bytes32 outputRoot, uint128 timestamp, uint128 l2OutputIndex); // nosemgrep
function setGasPayingToken(address _token, uint8 _decimals, bytes32 _name, bytes32 _symbol) external;
function superchainConfig() external view returns (ISuperchainConfig); function superchainConfig() external view returns (ISuperchainConfig);
function systemConfig() external view returns (ISystemConfig); function systemConfig() external view returns (ISystemConfig);
function setConfig(Types.ConfigType _type, bytes memory _value) external;
function version() external pure returns (string memory); function version() external pure returns (string memory);
function __constructor__() external; function __constructor__() external;
......
...@@ -7,7 +7,6 @@ import { IDisputeGame } from "src/dispute/interfaces/IDisputeGame.sol"; ...@@ -7,7 +7,6 @@ import { IDisputeGame } from "src/dispute/interfaces/IDisputeGame.sol";
import { IDisputeGameFactory } from "src/dispute/interfaces/IDisputeGameFactory.sol"; import { IDisputeGameFactory } from "src/dispute/interfaces/IDisputeGameFactory.sol";
import { ISystemConfig } from "src/L1/interfaces/ISystemConfig.sol"; import { ISystemConfig } from "src/L1/interfaces/ISystemConfig.sol";
import { ISuperchainConfig } from "src/L1/interfaces/ISuperchainConfig.sol"; import { ISuperchainConfig } from "src/L1/interfaces/ISuperchainConfig.sol";
import { Types } from "src/libraries/Types.sol";
interface IOptimismPortal2 { interface IOptimismPortal2 {
error AlreadyFinalized(); error AlreadyFinalized();
...@@ -109,12 +108,11 @@ interface IOptimismPortal2 { ...@@ -109,12 +108,11 @@ interface IOptimismPortal2 {
returns (IDisputeGame disputeGameProxy, uint64 timestamp); // nosemgrep returns (IDisputeGame disputeGameProxy, uint64 timestamp); // nosemgrep
function respectedGameType() external view returns (GameType); function respectedGameType() external view returns (GameType);
function respectedGameTypeUpdatedAt() external view returns (uint64); function respectedGameTypeUpdatedAt() external view returns (uint64);
function setGasPayingToken(address _token, uint8 _decimals, bytes32 _name, bytes32 _symbol) external;
function setRespectedGameType(GameType _gameType) external; function setRespectedGameType(GameType _gameType) external;
function superchainConfig() external view returns (ISuperchainConfig); function superchainConfig() external view returns (ISuperchainConfig);
function systemConfig() external view returns (ISystemConfig); function systemConfig() external view returns (ISystemConfig);
function version() external pure returns (string memory); function version() external pure returns (string memory);
function setConfig(Types.ConfigType _type, bytes memory _value) external;
function upgrade(uint32 _gasLimit, bytes memory _calldata) external;
function __constructor__(uint256 _proofMaturityDelaySeconds, uint256 _disputeGameFinalityDelaySeconds) external; function __constructor__(uint256 _proofMaturityDelaySeconds, uint256 _disputeGameFinalityDelaySeconds) external;
} }
...@@ -7,6 +7,7 @@ import { IDisputeGame } from "src/dispute/interfaces/IDisputeGame.sol"; ...@@ -7,6 +7,7 @@ import { IDisputeGame } from "src/dispute/interfaces/IDisputeGame.sol";
import { IDisputeGameFactory } from "src/dispute/interfaces/IDisputeGameFactory.sol"; import { IDisputeGameFactory } from "src/dispute/interfaces/IDisputeGameFactory.sol";
import { ISystemConfig } from "src/L1/interfaces/ISystemConfig.sol"; import { ISystemConfig } from "src/L1/interfaces/ISystemConfig.sol";
import { ISuperchainConfig } from "src/L1/interfaces/ISuperchainConfig.sol"; import { ISuperchainConfig } from "src/L1/interfaces/ISuperchainConfig.sol";
import { ConfigType } from "src/L2/L1BlockInterop.sol";
interface IOptimismPortalInterop { interface IOptimismPortalInterop {
error AlreadyFinalized(); error AlreadyFinalized();
...@@ -108,11 +109,11 @@ interface IOptimismPortalInterop { ...@@ -108,11 +109,11 @@ interface IOptimismPortalInterop {
returns (IDisputeGame disputeGameProxy, uint64 timestamp); // nosemgrep returns (IDisputeGame disputeGameProxy, uint64 timestamp); // nosemgrep
function respectedGameType() external view returns (GameType); function respectedGameType() external view returns (GameType);
function respectedGameTypeUpdatedAt() external view returns (uint64); function respectedGameTypeUpdatedAt() external view returns (uint64);
function setConfig(Types.ConfigType _type, bytes memory _value) external; function setConfig(ConfigType _type, bytes memory _value) external;
function setGasPayingToken(address _token, uint8 _decimals, bytes32 _name, bytes32 _symbol) external;
function setRespectedGameType(GameType _gameType) external; function setRespectedGameType(GameType _gameType) external;
function superchainConfig() external view returns (ISuperchainConfig); function superchainConfig() external view returns (ISuperchainConfig);
function systemConfig() external view returns (ISystemConfig); function systemConfig() external view returns (ISystemConfig);
function upgrade(uint32 _gasLimit, bytes memory _calldata) external;
function version() external pure returns (string memory); function version() external pure returns (string memory);
function __constructor__(uint256 _proofMaturityDelaySeconds, uint256 _disputeGameFinalityDelaySeconds) external; function __constructor__(uint256 _proofMaturityDelaySeconds, uint256 _disputeGameFinalityDelaySeconds) external;
......
...@@ -13,10 +13,8 @@ interface ISuperchainConfig { ...@@ -13,10 +13,8 @@ interface ISuperchainConfig {
function GUARDIAN_SLOT() external view returns (bytes32); function GUARDIAN_SLOT() external view returns (bytes32);
function PAUSED_SLOT() external view returns (bytes32); function PAUSED_SLOT() external view returns (bytes32);
function UPGRADER_SLOT() external view returns (bytes32);
function guardian() external view returns (address guardian_); function guardian() external view returns (address guardian_);
function upgrader() external view returns (address upgrader_); function initialize(address _guardian, bool _paused) external;
function initialize(address _guardian, address _upgrader, bool _paused) external;
function pause(string memory _identifier) external; function pause(string memory _identifier) external;
function paused() external view returns (bool paused_); function paused() external view returns (bool paused_);
function unpause() external; function unpause() external;
......
...@@ -2,12 +2,9 @@ ...@@ -2,12 +2,9 @@
pragma solidity ^0.8.0; pragma solidity ^0.8.0;
import { IResourceMetering } from "src/L1/interfaces/IResourceMetering.sol"; import { IResourceMetering } from "src/L1/interfaces/IResourceMetering.sol";
import { Types } from "src/libraries/Types.sol";
/// @notice This interface corresponds to the Custom Gas Token version of the SystemConfig contract. /// @notice This interface corresponds to the Custom Gas Token version of the SystemConfig contract.
interface ISystemConfig { interface ISystemConfig {
error UnsafeCast();
enum UpdateType { enum UpdateType {
BATCHER, BATCHER,
FEE_SCALARS, FEE_SCALARS,
...@@ -26,13 +23,6 @@ interface ISystemConfig { ...@@ -26,13 +23,6 @@ interface ISystemConfig {
address gasPayingToken; address gasPayingToken;
} }
struct Roles {
address owner;
address feeAdmin;
address unsafeBlockSigner;
bytes32 batcherHash;
}
event ConfigUpdate(uint256 indexed version, UpdateType indexed updateType, bytes data); event ConfigUpdate(uint256 indexed version, UpdateType indexed updateType, bytes data);
event Initialized(uint8 version); event Initialized(uint8 version);
event OwnershipTransferred(address indexed previousOwner, address indexed newOwner); event OwnershipTransferred(address indexed previousOwner, address indexed newOwner);
...@@ -59,10 +49,12 @@ interface ISystemConfig { ...@@ -59,10 +49,12 @@ interface ISystemConfig {
function gasPayingTokenName() external view returns (string memory name_); function gasPayingTokenName() external view returns (string memory name_);
function gasPayingTokenSymbol() external view returns (string memory symbol_); function gasPayingTokenSymbol() external view returns (string memory symbol_);
function initialize( function initialize(
Roles memory _roles, address _owner,
uint32 _basefeeScalar, uint32 _basefeeScalar,
uint32 _blobbasefeeScalar, uint32 _blobbasefeeScalar,
bytes32 _batcherHash,
uint64 _gasLimit, uint64 _gasLimit,
address _unsafeBlockSigner,
IResourceMetering.ResourceConfig memory _config, IResourceMetering.ResourceConfig memory _config,
address _batchInbox, address _batchInbox,
Addresses memory _addresses Addresses memory _addresses
...@@ -78,18 +70,10 @@ interface ISystemConfig { ...@@ -78,18 +70,10 @@ interface ISystemConfig {
function optimismPortal() external view returns (address addr_); function optimismPortal() external view returns (address addr_);
function overhead() external view returns (uint256); function overhead() external view returns (uint256);
function owner() external view returns (address); function owner() external view returns (address);
function feeAdmin() external view returns (address addr_);
function renounceOwnership() external; function renounceOwnership() external;
function resourceConfig() external view returns (IResourceMetering.ResourceConfig memory); function resourceConfig() external view returns (IResourceMetering.ResourceConfig memory);
function scalar() external view returns (uint256); function scalar() external view returns (uint256);
function setBatcherHash(bytes32 _batcherHash) external; function setBatcherHash(bytes32 _batcherHash) external;
function setFeeVaultConfig(
Types.ConfigType _type,
address _recipient,
uint256 _min,
Types.WithdrawalNetwork _network
)
external;
function setGasConfig(uint256 _overhead, uint256 _scalar) external; function setGasConfig(uint256 _overhead, uint256 _scalar) external;
function setGasConfigEcotone(uint32 _basefeeScalar, uint32 _blobbasefeeScalar) external; function setGasConfigEcotone(uint32 _basefeeScalar, uint32 _blobbasefeeScalar) external;
function setGasLimit(uint64 _gasLimit) external; function setGasLimit(uint64 _gasLimit) external;
......
...@@ -40,7 +40,6 @@ interface ISystemConfigInterop { ...@@ -40,7 +40,6 @@ interface ISystemConfigInterop {
function optimismPortal() external view returns (address addr_); function optimismPortal() external view returns (address addr_);
function overhead() external view returns (uint256); function overhead() external view returns (uint256);
function owner() external view returns (address); function owner() external view returns (address);
function feeAdmin() external view returns (address);
function renounceOwnership() external; function renounceOwnership() external;
function resourceConfig() external view returns (IResourceMetering.ResourceConfig memory); function resourceConfig() external view returns (IResourceMetering.ResourceConfig memory);
function scalar() external view returns (uint256); function scalar() external view returns (uint256);
...@@ -58,10 +57,12 @@ interface ISystemConfigInterop { ...@@ -58,10 +57,12 @@ interface ISystemConfigInterop {
function removeDependency(uint256 _chainId) external; function removeDependency(uint256 _chainId) external;
function dependencyManager() external view returns (address); function dependencyManager() external view returns (address);
function initialize( function initialize(
ISystemConfig.Roles memory _roles, address _owner,
uint32 _basefeeScalar, uint32 _basefeeScalar,
uint32 _blobbasefeeScalar, uint32 _blobbasefeeScalar,
bytes32 _batcherHash,
uint64 _gasLimit, uint64 _gasLimit,
address _unsafeBlockSigner,
IResourceMetering.ResourceConfig memory _config, IResourceMetering.ResourceConfig memory _config,
address _batchInbox, address _batchInbox,
ISystemConfig.Addresses memory _addresses, ISystemConfig.Addresses memory _addresses,
......
...@@ -3,8 +3,8 @@ pragma solidity 0.8.15; ...@@ -3,8 +3,8 @@ pragma solidity 0.8.15;
import { ISemver } from "src/universal/interfaces/ISemver.sol"; import { ISemver } from "src/universal/interfaces/ISemver.sol";
import { FeeVault } from "src/L2/FeeVault.sol"; import { FeeVault } from "src/L2/FeeVault.sol";
import { Types } from "src/libraries/Types.sol"; import { Types } from "src/libraries/Types.sol";
import { Encoding } from "src/libraries/Encoding.sol";
/// @custom:proxied true /// @custom:proxied true
/// @custom:predeploy 0x4200000000000000000000000000000000000019 /// @custom:predeploy 0x4200000000000000000000000000000000000019
...@@ -12,20 +12,18 @@ import { Encoding } from "src/libraries/Encoding.sol"; ...@@ -12,20 +12,18 @@ import { Encoding } from "src/libraries/Encoding.sol";
/// @notice The BaseFeeVault accumulates the base fee that is paid by transactions. /// @notice The BaseFeeVault accumulates the base fee that is paid by transactions.
contract BaseFeeVault is FeeVault, ISemver { contract BaseFeeVault is FeeVault, ISemver {
/// @notice Semantic version. /// @notice Semantic version.
/// @custom:semver 1.5.0-beta.4 /// @custom:semver 1.5.0-beta.3
string public constant version = "1.5.0-beta.4"; string public constant version = "1.5.0-beta.3";
/// @notice Returns the FeeVault config /// @notice Constructs the BaseFeeVault contract.
/// @return recipient_ Wallet that will receive the fees. /// @param _recipient Wallet that will receive the fees.
/// @return amount_ Minimum balance for withdrawals. /// @param _minWithdrawalAmount Minimum balance for withdrawals.
/// @return withdrawalNetwork_ Network which the recipient will receive fees on. /// @param _withdrawalNetwork Network which the recipient will receive fees on.
function config() constructor(
public address _recipient,
view uint256 _minWithdrawalAmount,
override Types.WithdrawalNetwork _withdrawalNetwork
returns (address recipient_, uint256 amount_, Types.WithdrawalNetwork withdrawalNetwork_) )
{ FeeVault(_recipient, _minWithdrawalAmount, _withdrawalNetwork)
bytes memory data = L1_BLOCK().getConfig(Types.ConfigType.BASE_FEE_VAULT_CONFIG); { }
(recipient_, amount_, withdrawalNetwork_) = Encoding.decodeFeeVaultConfig(abi.decode(data, (bytes32)));
}
} }
...@@ -4,7 +4,6 @@ pragma solidity 0.8.15; ...@@ -4,7 +4,6 @@ pragma solidity 0.8.15;
// Libraries // Libraries
import { SafeCall } from "src/libraries/SafeCall.sol"; import { SafeCall } from "src/libraries/SafeCall.sol";
import { Predeploys } from "src/libraries/Predeploys.sol"; import { Predeploys } from "src/libraries/Predeploys.sol";
import { IL1Block } from "src/L2/interfaces/IL1Block.sol";
// Interfaces // Interfaces
import { IL2ToL1MessagePasser } from "src/L2/interfaces/IL2ToL1MessagePasser.sol"; import { IL2ToL1MessagePasser } from "src/L2/interfaces/IL2ToL1MessagePasser.sol";
...@@ -16,15 +15,27 @@ import { Types } from "src/libraries/Types.sol"; ...@@ -16,15 +15,27 @@ import { Types } from "src/libraries/Types.sol";
/// @notice The FeeVault contract contains the basic logic for the various different vault contracts /// @notice The FeeVault contract contains the basic logic for the various different vault contracts
/// used to hold fee revenue generated by the L2 system. /// used to hold fee revenue generated by the L2 system.
abstract contract FeeVault { abstract contract FeeVault {
/// @notice Minimum balance before a withdrawal can be triggered.
/// Use the `minWithdrawalAmount()` getter as this is deprecated
/// and is subject to be removed in the future.
/// @custom:legacy
uint256 public immutable MIN_WITHDRAWAL_AMOUNT;
/// @notice Account that will receive the fees. Can be located on L1 or L2.
/// Use the `recipient()` getter as this is deprecated
/// and is subject to be removed in the future.
/// @custom:legacy
address public immutable RECIPIENT;
/// @notice Network which the recipient will receive fees on.
/// Use the `withdrawalNetwork()` getter as this is deprecated
/// and is subject to be removed in the future.
/// @custom:legacy
Types.WithdrawalNetwork public immutable WITHDRAWAL_NETWORK;
/// @notice The minimum gas limit for the FeeVault withdrawal transaction. /// @notice The minimum gas limit for the FeeVault withdrawal transaction.
uint32 internal constant WITHDRAWAL_MIN_GAS = 400_000; uint32 internal constant WITHDRAWAL_MIN_GAS = 400_000;
/// @notice Internal getter function for the L1Block contract.
/// @return Contract of the L1Block on this domain.
function L1_BLOCK() internal pure returns (IL1Block) {
return IL1Block(Predeploys.L1_BLOCK_ATTRIBUTES);
}
/// @notice Total amount of wei processed by the contract. /// @notice Total amount of wei processed by the contract.
uint256 public totalProcessed; uint256 public totalProcessed;
...@@ -45,76 +56,52 @@ abstract contract FeeVault { ...@@ -45,76 +56,52 @@ abstract contract FeeVault {
/// @param withdrawalNetwork Network which the to address will receive funds on. /// @param withdrawalNetwork Network which the to address will receive funds on.
event Withdrawal(uint256 value, address to, address from, Types.WithdrawalNetwork withdrawalNetwork); event Withdrawal(uint256 value, address to, address from, Types.WithdrawalNetwork withdrawalNetwork);
/// @param _recipient Wallet that will receive the fees.
/// @param _minWithdrawalAmount Minimum balance for withdrawals.
/// @param _withdrawalNetwork Network which the recipient will receive fees on.
constructor(address _recipient, uint256 _minWithdrawalAmount, Types.WithdrawalNetwork _withdrawalNetwork) {
RECIPIENT = _recipient;
MIN_WITHDRAWAL_AMOUNT = _minWithdrawalAmount;
WITHDRAWAL_NETWORK = _withdrawalNetwork;
}
/// @notice Allow the contract to receive ETH. /// @notice Allow the contract to receive ETH.
receive() external payable { } receive() external payable { }
/// @notice Returns the configuration of the FeeVault.
function config()
public
view
virtual
returns (address recipient_, uint256 amount_, Types.WithdrawalNetwork withdrawalNetwork_);
/// @notice Minimum balance before a withdrawal can be triggered. /// @notice Minimum balance before a withdrawal can be triggered.
function minWithdrawalAmount() public view virtual returns (uint256 amount_) { function minWithdrawalAmount() public view returns (uint256 amount_) {
(, amount_,) = config(); amount_ = MIN_WITHDRAWAL_AMOUNT;
}
/// @notice Minimum balance before a withdrawal can be triggered.
/// Use the `minWithdrawalAmount()` getter as this is deprecated
/// and is subject to be removed in the future.
/// @custom:legacy true
function MIN_WITHDRAWAL_AMOUNT() public view returns (uint256) {
return minWithdrawalAmount();
} }
/// @notice Account that will receive the fees. Can be located on L1 or L2. /// @notice Account that will receive the fees. Can be located on L1 or L2.
function recipient() public view virtual returns (address recipient_) { function recipient() public view returns (address recipient_) {
(recipient_,,) = config(); recipient_ = RECIPIENT;
}
/// @notice Account that will receive the fees. Can be located on L1 or L2.
/// Use the `recipient()` getter as this is deprecated
/// and is subject to be removed in the future.
/// @custom:legacy
function RECIPIENT() public view returns (address) {
return recipient();
} }
/// @notice Network which the recipient will receive fees on. /// @notice Network which the recipient will receive fees on.
function withdrawalNetwork() public view returns (Types.WithdrawalNetwork withdrawalNetwork_) { function withdrawalNetwork() public view returns (Types.WithdrawalNetwork network_) {
(,, withdrawalNetwork_) = config(); network_ = WITHDRAWAL_NETWORK;
}
/// @notice Network which the recipient will receive fees on.
/// Use the `withdrawalNetwork()` getter as this is deprecated
/// and is subject to be removed in the future.
/// @custom:legacy
function WITHDRAWAL_NETWORK() external view returns (Types.WithdrawalNetwork withdrawalNetwork_) {
withdrawalNetwork_ = withdrawalNetwork();
} }
/// @notice Triggers a withdrawal of funds to the fee wallet on L1 or L2. /// @notice Triggers a withdrawal of funds to the fee wallet on L1 or L2.
function withdraw() external { function withdraw() external {
(address withdrawalRecipient, uint256 withdrawalAmount, Types.WithdrawalNetwork network) = config();
require( require(
address(this).balance >= withdrawalAmount, address(this).balance >= MIN_WITHDRAWAL_AMOUNT,
"FeeVault: withdrawal amount must be greater than minimum withdrawal amount" "FeeVault: withdrawal amount must be greater than minimum withdrawal amount"
); );
uint256 value = address(this).balance; uint256 value = address(this).balance;
totalProcessed += value; totalProcessed += value;
emit Withdrawal(value, withdrawalRecipient, msg.sender); emit Withdrawal(value, RECIPIENT, msg.sender);
emit Withdrawal(value, withdrawalRecipient, msg.sender, network); emit Withdrawal(value, RECIPIENT, msg.sender, WITHDRAWAL_NETWORK);
if (network == Types.WithdrawalNetwork.L2) { if (WITHDRAWAL_NETWORK == Types.WithdrawalNetwork.L2) {
bool success = SafeCall.send(withdrawalRecipient, value); bool success = SafeCall.send(RECIPIENT, value);
require(success, "FeeVault: failed to send ETH to L2 fee recipient"); require(success, "FeeVault: failed to send ETH to L2 fee recipient");
} else { } else {
IL2ToL1MessagePasser(payable(Predeploys.L2_TO_L1_MESSAGE_PASSER)).initiateWithdrawal{ value: value }({ IL2ToL1MessagePasser(payable(Predeploys.L2_TO_L1_MESSAGE_PASSER)).initiateWithdrawal{ value: value }({
_target: withdrawalRecipient, _target: RECIPIENT,
_gasLimit: WITHDRAWAL_MIN_GAS, _gasLimit: WITHDRAWAL_MIN_GAS,
_data: hex"" _data: hex""
}); });
......
...@@ -29,8 +29,8 @@ contract GasPriceOracle is ISemver { ...@@ -29,8 +29,8 @@ contract GasPriceOracle is ISemver {
uint256 public constant DECIMALS = 6; uint256 public constant DECIMALS = 6;
/// @notice Semantic version. /// @notice Semantic version.
/// @custom:semver 1.3.1-beta.4 /// @custom:semver 1.3.1-beta.3
string public constant version = "1.3.1-beta.4"; string public constant version = "1.3.1-beta.3";
/// @notice This is the intercept value for the linear regression used to estimate the final size of the /// @notice This is the intercept value for the linear regression used to estimate the final size of the
/// compressed transaction. /// compressed transaction.
......
...@@ -3,17 +3,7 @@ pragma solidity 0.8.15; ...@@ -3,17 +3,7 @@ pragma solidity 0.8.15;
import { ISemver } from "src/universal/interfaces/ISemver.sol"; import { ISemver } from "src/universal/interfaces/ISemver.sol";
import { Constants } from "src/libraries/Constants.sol"; import { Constants } from "src/libraries/Constants.sol";
import { StaticConfig } from "src/libraries/StaticConfig.sol";
import { GasPayingToken, IGasToken } from "src/libraries/GasPayingToken.sol"; import { GasPayingToken, IGasToken } from "src/libraries/GasPayingToken.sol";
import { IFeeVault, Types as ITypes } from "src/L2/interfaces/IFeeVault.sol";
import { ICrossDomainMessenger } from "src/universal/interfaces/ICrossDomainMessenger.sol";
import { IStandardBridge } from "src/universal/interfaces/IStandardBridge.sol";
import { IERC721Bridge } from "src/universal/interfaces/IERC721Bridge.sol";
import { IOptimismMintableERC721Factory } from "src/L2/interfaces/IOptimismMintableERC721Factory.sol";
import { Predeploys } from "src/libraries/Predeploys.sol";
import { Encoding } from "src/libraries/Encoding.sol";
import { Storage } from "src/libraries/Storage.sol";
import { Types } from "src/libraries/Types.sol";
import { NotDepositor } from "src/libraries/L1BlockErrors.sol"; import { NotDepositor } from "src/libraries/L1BlockErrors.sol";
/// @custom:proxied true /// @custom:proxied true
...@@ -27,31 +17,6 @@ contract L1Block is ISemver, IGasToken { ...@@ -27,31 +17,6 @@ contract L1Block is ISemver, IGasToken {
/// @notice Event emitted when the gas paying token is set. /// @notice Event emitted when the gas paying token is set.
event GasPayingTokenSet(address indexed token, uint8 indexed decimals, bytes32 name, bytes32 symbol); event GasPayingTokenSet(address indexed token, uint8 indexed decimals, bytes32 name, bytes32 symbol);
/// @notice Storage slot for the base fee vault configuration
bytes32 internal constant BASE_FEE_VAULT_CONFIG_SLOT = bytes32(uint256(keccak256("opstack.basefeevaultconfig")) - 1);
/// @notice Storage slot for the L1 fee vault configuration
bytes32 internal constant L1_FEE_VAULT_CONFIG_SLOT = bytes32(uint256(keccak256("opstack.l1feevaultconfig")) - 1);
/// @notice Storage slot for the sequencer fee vault configuration
bytes32 internal constant SEQUENCER_FEE_VAULT_CONFIG_SLOT =
bytes32(uint256(keccak256("opstack.sequencerfeevaultconfig")) - 1);
/// @notice Storage slot for the L1 cross domain messenger address
bytes32 internal constant L1_CROSS_DOMAIN_MESSENGER_ADDRESS_SLOT =
bytes32(uint256(keccak256("opstack.l1crossdomainmessengeraddress")) - 1);
/// @notice Storage slot for the L1 ERC721 bridge address
bytes32 internal constant L1_ERC_721_BRIDGE_ADDRESS_SLOT =
bytes32(uint256(keccak256("opstack.l1erc721bridgeaddress")) - 1);
/// @notice Storage slot for the L1 standard bridge address
bytes32 internal constant L1_STANDARD_BRIDGE_ADDRESS_SLOT =
bytes32(uint256(keccak256("opstack.l1standardbridgeaddress")) - 1);
/// @notice Storage slot for the remote chain ID
bytes32 internal constant REMOTE_CHAIN_ID_SLOT = bytes32(uint256(keccak256("opstack.remotechainid")) - 1);
/// @notice Address of the special depositor account. /// @notice Address of the special depositor account.
function DEPOSITOR_ACCOUNT() public pure returns (address addr_) { function DEPOSITOR_ACCOUNT() public pure returns (address addr_) {
addr_ = Constants.DEPOSITOR_ACCOUNT; addr_ = Constants.DEPOSITOR_ACCOUNT;
...@@ -92,12 +57,9 @@ contract L1Block is ISemver, IGasToken { ...@@ -92,12 +57,9 @@ contract L1Block is ISemver, IGasToken {
/// @notice The latest L1 blob base fee. /// @notice The latest L1 blob base fee.
uint256 public blobBaseFee; uint256 public blobBaseFee;
/// @notice Indicates whether the network has gone through the Isthmus upgrade. /// @custom:semver 1.5.1-beta.3
bool public isIsthmus;
/// @custom:semver 1.5.1-beta.4
function version() public pure virtual returns (string memory) { function version() public pure virtual returns (string memory) {
return "1.5.1-beta.4"; return "1.5.1-beta.3";
} }
/// @notice Returns the gas paying token, its decimals, name and symbol. /// @notice Returns the gas paying token, its decimals, name and symbol.
...@@ -206,117 +168,14 @@ contract L1Block is ISemver, IGasToken { ...@@ -206,117 +168,14 @@ contract L1Block is ISemver, IGasToken {
} }
} }
/// @notice Sets static configuration options for the L2 system. Can only be called by the special
/// depositor account.
/// @param _type The type of configuration to set.
/// @param _value The encoded value with which to set the configuration.
function setConfig(Types.ConfigType _type, bytes calldata _value) public virtual {
if (msg.sender != DEPOSITOR_ACCOUNT()) revert NotDepositor();
if (_type == Types.ConfigType.GAS_PAYING_TOKEN) {
(address token, uint8 decimals, bytes32 name, bytes32 symbol) = StaticConfig.decodeSetGasPayingToken(_value);
GasPayingToken.set({ _token: token, _decimals: decimals, _name: name, _symbol: symbol });
emit GasPayingTokenSet({ token: token, decimals: decimals, name: name, symbol: symbol });
} else if (_type == Types.ConfigType.BASE_FEE_VAULT_CONFIG) {
Storage.setBytes32(BASE_FEE_VAULT_CONFIG_SLOT, abi.decode(_value, (bytes32)));
} else if (_type == Types.ConfigType.L1_FEE_VAULT_CONFIG) {
Storage.setBytes32(L1_FEE_VAULT_CONFIG_SLOT, abi.decode(_value, (bytes32)));
} else if (_type == Types.ConfigType.L1_ERC_721_BRIDGE_ADDRESS) {
Storage.setAddress(L1_ERC_721_BRIDGE_ADDRESS_SLOT, abi.decode(_value, (address)));
} else if (_type == Types.ConfigType.REMOTE_CHAIN_ID) {
Storage.setUint(REMOTE_CHAIN_ID_SLOT, abi.decode(_value, (uint256)));
} else if (_type == Types.ConfigType.L1_CROSS_DOMAIN_MESSENGER_ADDRESS) {
Storage.setAddress(L1_CROSS_DOMAIN_MESSENGER_ADDRESS_SLOT, abi.decode(_value, (address)));
} else if (_type == Types.ConfigType.L1_STANDARD_BRIDGE_ADDRESS) {
Storage.setAddress(L1_STANDARD_BRIDGE_ADDRESS_SLOT, abi.decode(_value, (address)));
} else if (_type == Types.ConfigType.SEQUENCER_FEE_VAULT_CONFIG) {
Storage.setBytes32(SEQUENCER_FEE_VAULT_CONFIG_SLOT, abi.decode(_value, (bytes32)));
}
}
/// @notice Returns the configuration value for the given type. All configuration related storage values in
/// the L2 contracts, should be stored in this contract.
/// @param _type The type of configuration to get.
/// @return data_ The encoded configuration value.
function getConfig(Types.ConfigType _type) public view virtual returns (bytes memory data_) {
if (_type == Types.ConfigType.GAS_PAYING_TOKEN) {
(address addr, uint8 decimals) = gasPayingToken();
data_ = abi.encode(
addr,
decimals,
GasPayingToken.sanitize(gasPayingTokenName()),
GasPayingToken.sanitize(gasPayingTokenSymbol())
);
} else if (_type == Types.ConfigType.BASE_FEE_VAULT_CONFIG) {
data_ = abi.encode(Storage.getBytes32(BASE_FEE_VAULT_CONFIG_SLOT));
} else if (_type == Types.ConfigType.L1_ERC_721_BRIDGE_ADDRESS) {
data_ = abi.encode(Storage.getAddress(L1_ERC_721_BRIDGE_ADDRESS_SLOT));
} else if (_type == Types.ConfigType.REMOTE_CHAIN_ID) {
data_ = abi.encode(Storage.getUint(REMOTE_CHAIN_ID_SLOT));
} else if (_type == Types.ConfigType.L1_CROSS_DOMAIN_MESSENGER_ADDRESS) {
data_ = abi.encode(Storage.getAddress(L1_CROSS_DOMAIN_MESSENGER_ADDRESS_SLOT));
} else if (_type == Types.ConfigType.L1_STANDARD_BRIDGE_ADDRESS) {
data_ = abi.encode(Storage.getAddress(L1_STANDARD_BRIDGE_ADDRESS_SLOT));
} else if (_type == Types.ConfigType.SEQUENCER_FEE_VAULT_CONFIG) {
data_ = abi.encode(Storage.getBytes32(SEQUENCER_FEE_VAULT_CONFIG_SLOT));
} else if (_type == Types.ConfigType.L1_FEE_VAULT_CONFIG) {
data_ = abi.encode(Storage.getBytes32(L1_FEE_VAULT_CONFIG_SLOT));
}
}
/// @notice Sets the gas paying token for the L2 system. Can only be called by the special /// @notice Sets the gas paying token for the L2 system. Can only be called by the special
/// depositor account, initiated by a deposit transaction from L1. /// depositor account. This function is not called on every L2 block but instead
/// This is a legacy setter that exists to give compabilitity with the legacy SystemConfig. /// only called by specially crafted L1 deposit transactions.
/// Custom gas token can now be set using `setConfig`. This can be removed in the future.
function setGasPayingToken(address _token, uint8 _decimals, bytes32 _name, bytes32 _symbol) external { function setGasPayingToken(address _token, uint8 _decimals, bytes32 _name, bytes32 _symbol) external {
if (msg.sender != DEPOSITOR_ACCOUNT()) revert NotDepositor(); if (msg.sender != DEPOSITOR_ACCOUNT()) revert NotDepositor();
GasPayingToken.set({ _token: _token, _decimals: _decimals, _name: _name, _symbol: _symbol }); GasPayingToken.set({ _token: _token, _decimals: _decimals, _name: _name, _symbol: _symbol });
emit GasPayingTokenSet({ token: _token, decimals: _decimals, name: _name, symbol: _symbol });
}
/// @notice Sets the L1 block values for an Isthmus upgraded chain. emit GasPayingTokenSet({ token: _token, decimals: _decimals, name: _name, symbol: _symbol });
/// This function is intended to be called only once, and only on existing chains which are undergoing
/// the Isthmus upgrade. Chains deployed with the Isthmus upgrade activated will have the values set here
/// already populated by the L2 Genesis generation process.
/// In the case of an existing chain underoing the Isthmus upgrade, the expectation is that
/// The upgrade flow will use the following series of Network upgrade automation transactions:
/// 1. Deploy a new `L1BlockImpl` contract.
/// 2. Upgrade only the `L1Block` contract to the new implementation by
/// calling `L2ProxyAdmin.upgrade(address(L1BlockProxy), address(L1BlockImpl))`.
/// 3. Call `L1Block.setIsthmus()` to pull the values from L2 contracts.
/// 4. Upgrades the remainder of the L2 contracts via `L2ProxyAdmin.upgrade()`.
function setIsthmus() external {
if (msg.sender != DEPOSITOR_ACCOUNT()) revert NotDepositor();
require(isIsthmus == false, "L1Block: Isthmus already active");
isIsthmus = true;
Storage.setBytes32(BASE_FEE_VAULT_CONFIG_SLOT, _migrateFeeVaultConfig(Predeploys.BASE_FEE_VAULT));
Storage.setBytes32(L1_FEE_VAULT_CONFIG_SLOT, _migrateFeeVaultConfig(Predeploys.L1_FEE_VAULT));
Storage.setBytes32(SEQUENCER_FEE_VAULT_CONFIG_SLOT, _migrateFeeVaultConfig(Predeploys.SEQUENCER_FEE_WALLET));
Storage.setAddress(
L1_CROSS_DOMAIN_MESSENGER_ADDRESS_SLOT,
address(ICrossDomainMessenger(Predeploys.L2_CROSS_DOMAIN_MESSENGER).otherMessenger())
);
Storage.setAddress(
L1_STANDARD_BRIDGE_ADDRESS_SLOT,
address(IStandardBridge(payable(Predeploys.L2_STANDARD_BRIDGE)).otherBridge())
);
Storage.setAddress(
L1_ERC_721_BRIDGE_ADDRESS_SLOT, address(IERC721Bridge(Predeploys.L2_ERC721_BRIDGE).otherBridge())
);
Storage.setUint(
REMOTE_CHAIN_ID_SLOT,
IOptimismMintableERC721Factory(Predeploys.OPTIMISM_MINTABLE_ERC721_FACTORY).remoteChainId()
);
}
/// @notice Helper function for migrating deploy config.
function _migrateFeeVaultConfig(address _addr) internal view returns (bytes32) {
address recipient = IFeeVault(payable(_addr)).recipient();
uint256 amount = IFeeVault(payable(_addr)).minWithdrawalAmount();
ITypes.WithdrawalNetwork network = IFeeVault(payable(_addr)).withdrawalNetwork();
return Encoding.encodeFeeVaultConfig(recipient, amount, Types.WithdrawalNetwork(uint8(network)));
} }
} }
...@@ -6,9 +6,9 @@ import { L1Block } from "src/L2/L1Block.sol"; ...@@ -6,9 +6,9 @@ import { L1Block } from "src/L2/L1Block.sol";
// Libraries // Libraries
import { EnumerableSet } from "@openzeppelin/contracts/utils/structs/EnumerableSet.sol"; import { EnumerableSet } from "@openzeppelin/contracts/utils/structs/EnumerableSet.sol";
import { GasPayingToken } from "src/libraries/GasPayingToken.sol";
import { StaticConfig } from "src/libraries/StaticConfig.sol"; import { StaticConfig } from "src/libraries/StaticConfig.sol";
import { Predeploys } from "src/libraries/Predeploys.sol"; import { Predeploys } from "src/libraries/Predeploys.sol";
import { Types } from "src/libraries/Types.sol";
import { import {
NotDepositor, NotDepositor,
NotCrossL2Inbox, NotCrossL2Inbox,
...@@ -18,6 +18,16 @@ import { ...@@ -18,6 +18,16 @@ import {
CantRemovedDependency CantRemovedDependency
} from "src/libraries/L1BlockErrors.sol"; } from "src/libraries/L1BlockErrors.sol";
/// @notice Enum representing different types of configurations that can be set on L1BlockInterop.
/// @custom:value SET_GAS_PAYING_TOKEN Represents the config type for setting the gas paying token.
/// @custom:value ADD_DEPENDENCY Represents the config type for adding a chain to the interop dependency set.
/// @custom:value REMOVE_DEPENDENCY Represents the config type for removing a chain from the interop dependency set.
enum ConfigType {
SET_GAS_PAYING_TOKEN,
ADD_DEPENDENCY,
REMOVE_DEPENDENCY
}
/// @custom:proxied true /// @custom:proxied true
/// @custom:predeploy 0x4200000000000000000000000000000000000015 /// @custom:predeploy 0x4200000000000000000000000000000000000015
/// @title L1BlockInterop /// @title L1BlockInterop
...@@ -39,9 +49,9 @@ contract L1BlockInterop is L1Block { ...@@ -39,9 +49,9 @@ contract L1BlockInterop is L1Block {
/// keccak256(abi.encode(uint256(keccak256("l1Block.identifier.isDeposit")) - 1)) & ~bytes32(uint256(0xff)) /// keccak256(abi.encode(uint256(keccak256("l1Block.identifier.isDeposit")) - 1)) & ~bytes32(uint256(0xff))
uint256 internal constant IS_DEPOSIT_SLOT = 0x921bd3a089295c6e5540e8fba8195448d253efd6f2e3e495b499b627dc36a300; uint256 internal constant IS_DEPOSIT_SLOT = 0x921bd3a089295c6e5540e8fba8195448d253efd6f2e3e495b499b627dc36a300;
/// @custom:semver +interop-beta.2 /// @custom:semver +interop-beta.1
function version() public pure override returns (string memory) { function version() public pure override returns (string memory) {
return string.concat(super.version(), "+interop-beta.2"); return string.concat(super.version(), "+interop-beta.1");
} }
/// @notice Returns whether the call was triggered from a a deposit or not. /// @notice Returns whether the call was triggered from a a deposit or not.
...@@ -94,16 +104,28 @@ contract L1BlockInterop is L1Block { ...@@ -94,16 +104,28 @@ contract L1BlockInterop is L1Block {
/// depositor account. /// depositor account.
/// @param _type The type of configuration to set. /// @param _type The type of configuration to set.
/// @param _value The encoded value with which to set the configuration. /// @param _value The encoded value with which to set the configuration.
function setConfig(Types.ConfigType _type, bytes calldata _value) public override { function setConfig(ConfigType _type, bytes calldata _value) external {
super.setConfig(_type, _value); if (msg.sender != DEPOSITOR_ACCOUNT()) revert NotDepositor();
if (_type == Types.ConfigType.ADD_DEPENDENCY) { if (_type == ConfigType.SET_GAS_PAYING_TOKEN) {
_setGasPayingToken(_value);
} else if (_type == ConfigType.ADD_DEPENDENCY) {
_addDependency(_value); _addDependency(_value);
} else if (_type == Types.ConfigType.REMOVE_DEPENDENCY) { } else if (_type == ConfigType.REMOVE_DEPENDENCY) {
_removeDependency(_value); _removeDependency(_value);
} }
} }
/// @notice Internal method to set the gas paying token.
/// @param _value The encoded value with which to set the gas paying token.
function _setGasPayingToken(bytes calldata _value) internal {
(address token, uint8 decimals, bytes32 name, bytes32 symbol) = StaticConfig.decodeSetGasPayingToken(_value);
GasPayingToken.set({ _token: token, _decimals: decimals, _name: name, _symbol: symbol });
emit GasPayingTokenSet({ token: token, decimals: decimals, name: name, symbol: symbol });
}
/// @notice Internal method to add a dependency to the interop dependency set. /// @notice Internal method to add a dependency to the interop dependency set.
/// @param _value The encoded value with which to add the dependency. /// @param _value The encoded value with which to add the dependency.
function _addDependency(bytes calldata _value) internal { function _addDependency(bytes calldata _value) internal {
......
...@@ -3,8 +3,8 @@ pragma solidity 0.8.15; ...@@ -3,8 +3,8 @@ pragma solidity 0.8.15;
import { ISemver } from "src/universal/interfaces/ISemver.sol"; import { ISemver } from "src/universal/interfaces/ISemver.sol";
import { FeeVault } from "src/L2/FeeVault.sol"; import { FeeVault } from "src/L2/FeeVault.sol";
import { Types } from "src/libraries/Types.sol"; import { Types } from "src/libraries/Types.sol";
import { Encoding } from "src/libraries/Encoding.sol";
/// @custom:proxied true /// @custom:proxied true
/// @custom:predeploy 0x420000000000000000000000000000000000001A /// @custom:predeploy 0x420000000000000000000000000000000000001A
...@@ -12,20 +12,18 @@ import { Encoding } from "src/libraries/Encoding.sol"; ...@@ -12,20 +12,18 @@ import { Encoding } from "src/libraries/Encoding.sol";
/// @notice The L1FeeVault accumulates the L1 portion of the transaction fees. /// @notice The L1FeeVault accumulates the L1 portion of the transaction fees.
contract L1FeeVault is FeeVault, ISemver { contract L1FeeVault is FeeVault, ISemver {
/// @notice Semantic version. /// @notice Semantic version.
/// @custom:semver 1.5.0-beta.4 /// @custom:semver 1.5.0-beta.3
string public constant version = "1.5.0-beta.4"; string public constant version = "1.5.0-beta.3";
/// @notice Returns the FeeVault config /// @notice Constructs the L1FeeVault contract.
/// @return recipient_ Wallet that will receive the fees. /// @param _recipient Wallet that will receive the fees.
/// @return amount_ Minimum balance for withdrawals. /// @param _minWithdrawalAmount Minimum balance for withdrawals.
/// @return withdrawalNetwork_ Network which the recipient will receive fees on. /// @param _withdrawalNetwork Network which the recipient will receive fees on.
function config() constructor(
public address _recipient,
view uint256 _minWithdrawalAmount,
override Types.WithdrawalNetwork _withdrawalNetwork
returns (address recipient_, uint256 amount_, Types.WithdrawalNetwork withdrawalNetwork_) )
{ FeeVault(_recipient, _minWithdrawalAmount, _withdrawalNetwork)
bytes memory data = L1_BLOCK().getConfig(Types.ConfigType.L1_FEE_VAULT_CONFIG); { }
(recipient_, amount_, withdrawalNetwork_) = Encoding.decodeFeeVaultConfig(abi.decode(data, (bytes32)));
}
} }
...@@ -7,7 +7,6 @@ import { CrossDomainMessenger } from "src/universal/CrossDomainMessenger.sol"; ...@@ -7,7 +7,6 @@ import { CrossDomainMessenger } from "src/universal/CrossDomainMessenger.sol";
// Libraries // Libraries
import { AddressAliasHelper } from "src/vendor/AddressAliasHelper.sol"; import { AddressAliasHelper } from "src/vendor/AddressAliasHelper.sol";
import { Predeploys } from "src/libraries/Predeploys.sol"; import { Predeploys } from "src/libraries/Predeploys.sol";
import { Types } from "src/libraries/Types.sol";
// Interfaces // Interfaces
import { ISemver } from "src/universal/interfaces/ISemver.sol"; import { ISemver } from "src/universal/interfaces/ISemver.sol";
...@@ -21,22 +20,26 @@ import { IL1Block } from "src/L2/interfaces/IL1Block.sol"; ...@@ -21,22 +20,26 @@ import { IL1Block } from "src/L2/interfaces/IL1Block.sol";
/// L2 on the L2 side. Users are generally encouraged to use this contract instead of lower /// L2 on the L2 side. Users are generally encouraged to use this contract instead of lower
/// level message passing contracts. /// level message passing contracts.
contract L2CrossDomainMessenger is CrossDomainMessenger, ISemver { contract L2CrossDomainMessenger is CrossDomainMessenger, ISemver {
/// @custom:semver 2.1.1-beta.5 /// @custom:semver 2.1.1-beta.4
string public constant version = "2.1.1-beta.5"; string public constant version = "2.1.1-beta.4";
/// @notice Getter for the remote chain's messenger. /// @notice Constructs the L2CrossDomainMessenger contract.
function otherMessenger() public view override returns (CrossDomainMessenger) { constructor() CrossDomainMessenger() {
bytes memory data = initialize({ _l1CrossDomainMessenger: CrossDomainMessenger(address(0)) });
IL1Block(Predeploys.L1_BLOCK_ATTRIBUTES).getConfig(Types.ConfigType.L1_CROSS_DOMAIN_MESSENGER_ADDRESS); }
return CrossDomainMessenger(abi.decode(data, (address)));
/// @notice Initializer.
/// @param _l1CrossDomainMessenger L1CrossDomainMessenger contract on the other network.
function initialize(CrossDomainMessenger _l1CrossDomainMessenger) public initializer {
__CrossDomainMessenger_init({ _otherMessenger: _l1CrossDomainMessenger });
} }
/// @notice Legay getter for the remote chain's messenger. /// @notice Getter for the remote messenger.
/// Public getter is legacy and will be removed in the future. Use `otherMessenger()` instead. /// Public getter is legacy and will be removed in the future. Use `otherMessenger()` instead.
/// @return L1CrossDomainMessenger contract. /// @return L1CrossDomainMessenger contract.
/// @custom:legacy /// @custom:legacy
function l1CrossDomainMessenger() public view returns (CrossDomainMessenger) { function l1CrossDomainMessenger() public view returns (CrossDomainMessenger) {
return otherMessenger(); return otherMessenger;
} }
/// @inheritdoc CrossDomainMessenger /// @inheritdoc CrossDomainMessenger
...@@ -53,7 +56,7 @@ contract L2CrossDomainMessenger is CrossDomainMessenger, ISemver { ...@@ -53,7 +56,7 @@ contract L2CrossDomainMessenger is CrossDomainMessenger, ISemver {
/// @inheritdoc CrossDomainMessenger /// @inheritdoc CrossDomainMessenger
function _isOtherMessenger() internal view override returns (bool) { function _isOtherMessenger() internal view override returns (bool) {
return AddressAliasHelper.undoL1ToL2Alias(msg.sender) == address(otherMessenger()); return AddressAliasHelper.undoL1ToL2Alias(msg.sender) == address(otherMessenger);
} }
/// @inheritdoc CrossDomainMessenger /// @inheritdoc CrossDomainMessenger
......
// SPDX-License-Identifier: MIT // SPDX-License-Identifier: MIT
pragma solidity 0.8.25; pragma solidity 0.8.15;
// Contracts // Contracts
import { ERC721Bridge } from "src/universal/ERC721Bridge.sol"; import { ERC721Bridge } from "src/universal/ERC721Bridge.sol";
...@@ -7,13 +7,11 @@ import { ERC721Bridge } from "src/universal/ERC721Bridge.sol"; ...@@ -7,13 +7,11 @@ import { ERC721Bridge } from "src/universal/ERC721Bridge.sol";
// Libraries // Libraries
import { ERC165Checker } from "@openzeppelin/contracts/utils/introspection/ERC165Checker.sol"; import { ERC165Checker } from "@openzeppelin/contracts/utils/introspection/ERC165Checker.sol";
import { Predeploys } from "src/libraries/Predeploys.sol"; import { Predeploys } from "src/libraries/Predeploys.sol";
import { Types } from "src/libraries/Types.sol";
// Interfaces // Interfaces
import { IL1ERC721Bridge } from "src/L1/interfaces/IL1ERC721Bridge.sol"; import { IL1ERC721Bridge } from "src/L1/interfaces/IL1ERC721Bridge.sol";
import { IOptimismMintableERC721 } from "src/universal/interfaces/IOptimismMintableERC721.sol"; import { IOptimismMintableERC721 } from "src/universal/interfaces/IOptimismMintableERC721.sol";
import { ICrossDomainMessenger } from "src/universal/interfaces/ICrossDomainMessenger.sol"; import { ICrossDomainMessenger } from "src/universal/interfaces/ICrossDomainMessenger.sol";
import { IL1Block } from "src/L2/interfaces/IL1Block.sol";
import { ISemver } from "src/universal/interfaces/ISemver.sol"; import { ISemver } from "src/universal/interfaces/ISemver.sol";
/// @custom:proxied true /// @custom:proxied true
...@@ -28,21 +26,21 @@ import { ISemver } from "src/universal/interfaces/ISemver.sol"; ...@@ -28,21 +26,21 @@ import { ISemver } from "src/universal/interfaces/ISemver.sol";
/// wait for the one-week challenge period to elapse before their Optimism-native NFT /// wait for the one-week challenge period to elapse before their Optimism-native NFT
/// can be refunded on L2. /// can be refunded on L2.
contract L2ERC721Bridge is ERC721Bridge, ISemver { contract L2ERC721Bridge is ERC721Bridge, ISemver {
/// @custom:semver 1.8.0-beta.3 /// @custom:semver 1.8.0-beta.2
string public constant version = "1.8.0-beta.3"; string public constant version = "1.8.0-beta.2";
/// @notice Getter function for the messenger contract. /// @notice Constructs the L2ERC721Bridge contract.
/// @return Address of the messenger on this domain. constructor() ERC721Bridge() {
function messenger() public pure override returns (ICrossDomainMessenger) { initialize({ _l1ERC721Bridge: payable(address(0)) });
return ICrossDomainMessenger(Predeploys.L2_CROSS_DOMAIN_MESSENGER);
} }
/// @notice Getter function for the other bridge. /// @notice Initializes the contract.
/// @return Address of the bridge on the other network. /// @param _l1ERC721Bridge Address of the ERC721 bridge contract on the other network.
function otherBridge() public view override returns (ERC721Bridge) { function initialize(address payable _l1ERC721Bridge) public initializer {
bytes memory data = __ERC721Bridge_init({
IL1Block(Predeploys.L1_BLOCK_ATTRIBUTES).getConfig(Types.ConfigType.L1_ERC_721_BRIDGE_ADDRESS); _messenger: ICrossDomainMessenger(Predeploys.L2_CROSS_DOMAIN_MESSENGER),
return ERC721Bridge(abi.decode(data, (address))); _otherBridge: ERC721Bridge(_l1ERC721Bridge)
});
} }
/// @notice Completes an ERC721 bridge from the other domain and sends the ERC721 token to the /// @notice Completes an ERC721 bridge from the other domain and sends the ERC721 token to the
...@@ -125,7 +123,7 @@ contract L2ERC721Bridge is ERC721Bridge, ISemver { ...@@ -125,7 +123,7 @@ contract L2ERC721Bridge is ERC721Bridge, ISemver {
// Send message to L1 bridge // Send message to L1 bridge
// slither-disable-next-line reentrancy-events // slither-disable-next-line reentrancy-events
messenger().sendMessage({ _target: address(otherBridge()), _message: message, _minGasLimit: _minGasLimit }); messenger.sendMessage({ _target: address(otherBridge), _message: message, _minGasLimit: _minGasLimit });
// slither-disable-next-line reentrancy-events // slither-disable-next-line reentrancy-events
emit ERC721BridgeInitiated(_localToken, remoteToken, _from, _to, _tokenId, _extraData); emit ERC721BridgeInitiated(_localToken, remoteToken, _from, _to, _tokenId, _extraData);
......
// SPDX-License-Identifier: MIT
pragma solidity 0.8.15;
import { OptimismMintableERC20Factory } from "src/universal/OptimismMintableERC20Factory.sol";
import { Predeploys } from "src/libraries/Predeploys.sol";
/// @custom:proxied true
/// @custom:predeployed 0x4200000000000000000000000000000000000012
/// @title L2OptimismMintableERC20Factory
/// @notice L2OptimismMintableERC20Factory is a factory contract that generates OptimismMintableERC20
/// contracts on the network it's deployed to. Simplifies the deployment process for users
/// who may be less familiar with deploying smart contracts. Designed to be backwards
/// compatible with the older StandardL2ERC20Factory contract.
contract L2OptimismMintableERC20Factory is OptimismMintableERC20Factory {
/// @custom:semver 1.3.1-beta.5
/// @notice Semantic version.
/// The semver MUST be bumped any time that there is a change in
/// the OptimismMintableERC20 token contract since this contract
/// is responsible for deploying OptimismMintableERC20 contracts.
string public constant version = "1.3.1-beta.5";
function bridge() public view virtual override returns (address) {
return Predeploys.L2_STANDARD_BRIDGE;
}
}
// SPDX-License-Identifier: MIT
pragma solidity 0.8.15;
import { ProxyAdmin } from "src/universal/ProxyAdmin.sol";
import { Constants } from "src/libraries/Constants.sol";
/// @custom:proxied true
/// @custom:predeploy
/// @title L2ProxyAdmin
contract L2ProxyAdmin is ProxyAdmin {
constructor() ProxyAdmin(Constants.DEPOSITOR_ACCOUNT) { }
/// @notice The owner of the L2ProxyAdmin is the `DEPOSITOR_ACCOUNT`.
function owner() public pure override returns (address) {
return Constants.DEPOSITOR_ACCOUNT;
}
}
...@@ -3,12 +3,10 @@ pragma solidity 0.8.15; ...@@ -3,12 +3,10 @@ pragma solidity 0.8.15;
// Contracts // Contracts
import { StandardBridge } from "src/universal/StandardBridge.sol"; import { StandardBridge } from "src/universal/StandardBridge.sol";
import { IStandardBridge } from "src/universal/interfaces/IStandardBridge.sol";
import { OptimismMintableERC20 } from "src/universal/OptimismMintableERC20.sol"; import { OptimismMintableERC20 } from "src/universal/OptimismMintableERC20.sol";
// Libraries // Libraries
import { Predeploys } from "src/libraries/Predeploys.sol"; import { Predeploys } from "src/libraries/Predeploys.sol";
import { Types } from "src/libraries/Types.sol";
// Interfaces // Interfaces
import { ISemver } from "src/universal/interfaces/ISemver.sol"; import { ISemver } from "src/universal/interfaces/ISemver.sol";
...@@ -60,21 +58,23 @@ contract L2StandardBridge is StandardBridge, ISemver { ...@@ -60,21 +58,23 @@ contract L2StandardBridge is StandardBridge, ISemver {
); );
/// @notice Semantic version. /// @notice Semantic version.
/// @custom:semver 1.11.1-beta.4 /// @custom:semver 1.11.1-beta.3
function version() public pure virtual returns (string memory) { function version() public pure virtual returns (string memory) {
return "1.11.1-beta.4"; return "1.11.1-beta.3";
} }
/// @notice Returns the corresponding L1 StandardBridge contract. /// @notice Constructs the L2StandardBridge contract.
function otherBridge() public view override returns (IStandardBridge) { constructor() StandardBridge() {
bytes memory data = initialize({ _otherBridge: StandardBridge(payable(address(0))) });
IL1Block(Predeploys.L1_BLOCK_ATTRIBUTES).getConfig(Types.ConfigType.L1_STANDARD_BRIDGE_ADDRESS);
return IStandardBridge(abi.decode(data, (address)));
} }
/// @notice Returns the cross domain messenger. /// @notice Initializer.
function messenger() public pure override returns (ICrossDomainMessenger) { /// @param _otherBridge Contract for the corresponding bridge on the other chain.
return ICrossDomainMessenger(Predeploys.L2_CROSS_DOMAIN_MESSENGER); function initialize(StandardBridge _otherBridge) public initializer {
__StandardBridge_init({
_messenger: ICrossDomainMessenger(Predeploys.L2_CROSS_DOMAIN_MESSENGER),
_otherBridge: _otherBridge
});
} }
/// @notice Allows EOAs to bridge ETH by sending directly to the bridge. /// @notice Allows EOAs to bridge ETH by sending directly to the bridge.
...@@ -146,7 +146,7 @@ contract L2StandardBridge is StandardBridge, ISemver { ...@@ -146,7 +146,7 @@ contract L2StandardBridge is StandardBridge, ISemver {
/// @notice Retrieves the access of the corresponding L1 bridge contract. /// @notice Retrieves the access of the corresponding L1 bridge contract.
/// @return Address of the corresponding L1 bridge contract. /// @return Address of the corresponding L1 bridge contract.
function l1TokenBridge() external view returns (address) { function l1TokenBridge() external view returns (address) {
return address(otherBridge()); return address(otherBridge);
} }
/// @custom:legacy /// @custom:legacy
......
...@@ -40,9 +40,9 @@ contract L2StandardBridgeInterop is L2StandardBridge { ...@@ -40,9 +40,9 @@ contract L2StandardBridgeInterop is L2StandardBridge {
event Converted(address indexed from, address indexed to, address indexed caller, uint256 amount); event Converted(address indexed from, address indexed to, address indexed caller, uint256 amount);
/// @notice Semantic version. /// @notice Semantic version.
/// @custom:semver +interop-beta.3 /// @custom:semver +interop-beta.2
function version() public pure override returns (string memory) { function version() public pure override returns (string memory) {
return string.concat(super.version(), "+interop-beta.3"); return string.concat(super.version(), "+interop-beta.2");
} }
/// @notice Converts `amount` of `from` token to `to` token. /// @notice Converts `amount` of `from` token to `to` token.
......
...@@ -65,8 +65,8 @@ contract L2ToL2CrossDomainMessenger is ISemver, TransientReentrancyAware { ...@@ -65,8 +65,8 @@ contract L2ToL2CrossDomainMessenger is ISemver, TransientReentrancyAware {
uint16 public constant messageVersion = uint16(0); uint16 public constant messageVersion = uint16(0);
/// @notice Semantic version. /// @notice Semantic version.
/// @custom:semver 1.0.0-beta.11 /// @custom:semver 1.0.0-beta.10
string public constant version = "1.0.0-beta.11"; string public constant version = "1.0.0-beta.10";
/// @notice Mapping of message hashes to boolean receipt values. Note that a message will only be present in this /// @notice Mapping of message hashes to boolean receipt values. Note that a message will only be present in this
/// mapping if it has successfully been relayed on this chain, and can therefore not be relayed again. /// mapping if it has successfully been relayed on this chain, and can therefore not be relayed again.
......
...@@ -58,8 +58,8 @@ contract OptimismSuperchainERC20 is SuperchainERC20, Initializable { ...@@ -58,8 +58,8 @@ contract OptimismSuperchainERC20 is SuperchainERC20, Initializable {
} }
/// @notice Semantic version. /// @notice Semantic version.
/// @custom:semver 1.0.0-beta.10 /// @custom:semver 1.0.0-beta.9
string public constant override version = "1.0.0-beta.10"; string public constant override version = "1.0.0-beta.9";
/// @notice Constructs the OptimismSuperchainERC20 contract. /// @notice Constructs the OptimismSuperchainERC20 contract.
constructor() { constructor() {
......
...@@ -11,8 +11,8 @@ import { Predeploys } from "src/libraries/Predeploys.sol"; ...@@ -11,8 +11,8 @@ import { Predeploys } from "src/libraries/Predeploys.sol";
/// @notice OptimismSuperchainERC20Beacon is the beacon proxy for the OptimismSuperchainERC20 implementation. /// @notice OptimismSuperchainERC20Beacon is the beacon proxy for the OptimismSuperchainERC20 implementation.
contract OptimismSuperchainERC20Beacon is IBeacon, ISemver { contract OptimismSuperchainERC20Beacon is IBeacon, ISemver {
/// @notice Semantic version. /// @notice Semantic version.
/// @custom:semver 1.0.0-beta.3 /// @custom:semver 1.0.0-beta.2
string public constant version = "1.0.0-beta.3"; string public constant version = "1.0.0-beta.2";
/// @inheritdoc IBeacon /// @inheritdoc IBeacon
function implementation() external pure override returns (address) { function implementation() external pure override returns (address) {
......
...@@ -22,8 +22,8 @@ contract OptimismSuperchainERC20Factory is ISemver { ...@@ -22,8 +22,8 @@ contract OptimismSuperchainERC20Factory is ISemver {
); );
/// @notice Semantic version. /// @notice Semantic version.
/// @custom:semver 1.0.0-beta.5 /// @custom:semver 1.0.0-beta.4
string public constant version = "1.0.0-beta.5"; string public constant version = "1.0.0-beta.4";
/// @notice Mapping of the deployed OptimismSuperchainERC20 to the remote token address. /// @notice Mapping of the deployed OptimismSuperchainERC20 to the remote token address.
/// This is used to keep track of the token deployments. /// This is used to keep track of the token deployments.
......
...@@ -3,8 +3,8 @@ pragma solidity 0.8.15; ...@@ -3,8 +3,8 @@ pragma solidity 0.8.15;
import { ISemver } from "src/universal/interfaces/ISemver.sol"; import { ISemver } from "src/universal/interfaces/ISemver.sol";
import { FeeVault } from "src/L2/FeeVault.sol"; import { FeeVault } from "src/L2/FeeVault.sol";
import { Types } from "src/libraries/Types.sol"; import { Types } from "src/libraries/Types.sol";
import { Encoding } from "src/libraries/Encoding.sol";
/// @custom:proxied true /// @custom:proxied true
/// @custom:predeploy 0x4200000000000000000000000000000000000011 /// @custom:predeploy 0x4200000000000000000000000000000000000011
...@@ -12,27 +12,25 @@ import { Encoding } from "src/libraries/Encoding.sol"; ...@@ -12,27 +12,25 @@ import { Encoding } from "src/libraries/Encoding.sol";
/// @notice The SequencerFeeVault is the contract that holds any fees paid to the Sequencer during /// @notice The SequencerFeeVault is the contract that holds any fees paid to the Sequencer during
/// transaction processing and block production. /// transaction processing and block production.
contract SequencerFeeVault is FeeVault, ISemver { contract SequencerFeeVault is FeeVault, ISemver {
/// @custom:semver 1.5.0-beta.4 /// @custom:semver 1.5.0-beta.3
string public constant version = "1.5.0-beta.4"; string public constant version = "1.5.0-beta.3";
/// @notice Returns the FeeVault config /// @notice Constructs the SequencerFeeVault contract.
/// @return recipient_ Wallet that will receive the fees. /// @param _recipient Wallet that will receive the fees.
/// @return amount_ Minimum balance for withdrawals. /// @param _minWithdrawalAmount Minimum balance for withdrawals.
/// @return withdrawalNetwork_ Network which the recipient will receive fees on. /// @param _withdrawalNetwork Network which the recipient will receive fees on.
function config() constructor(
public address _recipient,
view uint256 _minWithdrawalAmount,
override Types.WithdrawalNetwork _withdrawalNetwork
returns (address recipient_, uint256 amount_, Types.WithdrawalNetwork withdrawalNetwork_) )
{ FeeVault(_recipient, _minWithdrawalAmount, _withdrawalNetwork)
bytes memory data = L1_BLOCK().getConfig(Types.ConfigType.SEQUENCER_FEE_VAULT_CONFIG); { }
(recipient_, amount_, withdrawalNetwork_) = Encoding.decodeFeeVaultConfig(abi.decode(data, (bytes32)));
}
/// @custom:legacy /// @custom:legacy
/// @notice Legacy getter for the recipient address. /// @notice Legacy getter for the recipient address.
/// @return recipient_ The recipient address. /// @return The recipient address.
function l1FeeWallet() public view returns (address recipient_) { function l1FeeWallet() public view returns (address) {
recipient_ = recipient(); return RECIPIENT;
} }
} }
...@@ -24,8 +24,8 @@ import { Unauthorized, NotCustomGasToken } from "src/libraries/errors/CommonErro ...@@ -24,8 +24,8 @@ import { Unauthorized, NotCustomGasToken } from "src/libraries/errors/CommonErro
/// do not use a custom gas token. /// do not use a custom gas token.
contract SuperchainWETH is WETH98, IERC7802, ISemver { contract SuperchainWETH is WETH98, IERC7802, ISemver {
/// @notice Semantic version. /// @notice Semantic version.
/// @custom:semver 1.0.0-beta.11 /// @custom:semver 1.0.0-beta.10
string public constant version = "1.0.0-beta.11"; string public constant version = "1.0.0-beta.10";
/// @inheritdoc WETH98 /// @inheritdoc WETH98
function deposit() public payable override { function deposit() public payable override {
......
...@@ -14,8 +14,8 @@ import { IL1Block } from "src/L2/interfaces/IL1Block.sol"; ...@@ -14,8 +14,8 @@ import { IL1Block } from "src/L2/interfaces/IL1Block.sol";
/// @title WETH contract that reads the name and symbol from the L1Block contract. /// @title WETH contract that reads the name and symbol from the L1Block contract.
/// Allows for nice rendering of token names for chains using custom gas token. /// Allows for nice rendering of token names for chains using custom gas token.
contract WETH is WETH98, ISemver { contract WETH is WETH98, ISemver {
/// @custom:semver 1.1.0-beta.4 /// @custom:semver 1.1.0-beta.3
string public constant version = "1.1.0-beta.4"; string public constant version = "1.1.0-beta.3";
/// @notice Returns the name of the wrapped native asset. Will be "Wrapped Ether" /// @notice Returns the name of the wrapped native asset. Will be "Wrapped Ether"
/// if the native asset is Ether. /// if the native asset is Ether.
......
...@@ -11,17 +11,19 @@ interface IBaseFeeVault { ...@@ -11,17 +11,19 @@ interface IBaseFeeVault {
function MIN_WITHDRAWAL_AMOUNT() external view returns (uint256); function MIN_WITHDRAWAL_AMOUNT() external view returns (uint256);
function RECIPIENT() external view returns (address); function RECIPIENT() external view returns (address);
function WITHDRAWAL_NETWORK() external view returns (Types.WithdrawalNetwork withdrawalNetwork_); function WITHDRAWAL_NETWORK() external view returns (Types.WithdrawalNetwork);
function minWithdrawalAmount() external view returns (uint256 amount_); function minWithdrawalAmount() external view returns (uint256 amount_);
function recipient() external view returns (address recipient_); function recipient() external view returns (address recipient_);
function totalProcessed() external view returns (uint256); function totalProcessed() external view returns (uint256);
function withdraw() external; function withdraw() external;
function withdrawalNetwork() external view returns (Types.WithdrawalNetwork withdrawalNetwork_); function withdrawalNetwork() external view returns (Types.WithdrawalNetwork network_);
function config()
external
view
returns (address recipient_, uint256 amount_, Types.WithdrawalNetwork withdrawalNetwork_);
function version() external view returns (string memory); function version() external view returns (string memory);
function __constructor__() external; function __constructor__(
address _recipient,
uint256 _minWithdrawalAmount,
Types.WithdrawalNetwork _withdrawalNetwork
)
external;
} }
...@@ -16,16 +16,12 @@ interface IFeeVault { ...@@ -16,16 +16,12 @@ interface IFeeVault {
function MIN_WITHDRAWAL_AMOUNT() external view returns (uint256); function MIN_WITHDRAWAL_AMOUNT() external view returns (uint256);
function RECIPIENT() external view returns (address); function RECIPIENT() external view returns (address);
function WITHDRAWAL_NETWORK() external view returns (Types.WithdrawalNetwork withdrawalNetwork_); function WITHDRAWAL_NETWORK() external view returns (Types.WithdrawalNetwork);
function minWithdrawalAmount() external view returns (uint256 amount_); function minWithdrawalAmount() external view returns (uint256 amount_);
function recipient() external view returns (address recipient_); function recipient() external view returns (address recipient_);
function totalProcessed() external view returns (uint256); function totalProcessed() external view returns (uint256);
function withdraw() external; function withdraw() external;
function withdrawalNetwork() external view returns (Types.WithdrawalNetwork withdrawalNetwork_); function withdrawalNetwork() external view returns (Types.WithdrawalNetwork network_);
function config()
external
view
returns (address recipient_, uint256 amount_, Types.WithdrawalNetwork withdrawalNetwork_);
function __constructor__() external; function __constructor__() external;
} }
// SPDX-License-Identifier: MIT // SPDX-License-Identifier: MIT
pragma solidity ^0.8.0; pragma solidity ^0.8.0;
import { Types } from "src/libraries/Types.sol";
interface IL1Block { interface IL1Block {
error NotDepositor(); error NotDepositor();
error UnsafeCast();
event GasPayingTokenSet(address indexed token, uint8 indexed decimals, bytes32 name, bytes32 symbol); event GasPayingTokenSet(address indexed token, uint8 indexed decimals, bytes32 name, bytes32 symbol);
...@@ -20,15 +17,11 @@ interface IL1Block { ...@@ -20,15 +17,11 @@ interface IL1Block {
function gasPayingTokenSymbol() external view returns (string memory symbol_); function gasPayingTokenSymbol() external view returns (string memory symbol_);
function hash() external view returns (bytes32); function hash() external view returns (bytes32);
function isCustomGasToken() external view returns (bool); function isCustomGasToken() external view returns (bool);
function isIsthmus() external view returns (bool);
function l1FeeOverhead() external view returns (uint256); function l1FeeOverhead() external view returns (uint256);
function l1FeeScalar() external view returns (uint256); function l1FeeScalar() external view returns (uint256);
function number() external view returns (uint64); function number() external view returns (uint64);
function sequenceNumber() external view returns (uint64); function sequenceNumber() external view returns (uint64);
function setConfig(Types.ConfigType _type, bytes memory _value) external;
function getConfig(Types.ConfigType _type) external view returns (bytes memory data_);
function setGasPayingToken(address _token, uint8 _decimals, bytes32 _name, bytes32 _symbol) external; function setGasPayingToken(address _token, uint8 _decimals, bytes32 _name, bytes32 _symbol) external;
function setIsthmus() external;
function setL1BlockValues( function setL1BlockValues(
uint64 _number, uint64 _number,
uint64 _timestamp, uint64 _timestamp,
......
// SPDX-License-Identifier: MIT // SPDX-License-Identifier: MIT
pragma solidity ^0.8.0; pragma solidity ^0.8.0;
import { Types } from "src/libraries/Types.sol"; enum ConfigType {
SET_GAS_PAYING_TOKEN,
ADD_DEPENDENCY,
REMOVE_DEPENDENCY
}
interface IL1BlockInterop { interface IL1BlockInterop {
error AlreadyDependency(); error AlreadyDependency();
...@@ -10,7 +14,6 @@ interface IL1BlockInterop { ...@@ -10,7 +14,6 @@ interface IL1BlockInterop {
error NotCrossL2Inbox(); error NotCrossL2Inbox();
error NotDependency(); error NotDependency();
error NotDepositor(); error NotDepositor();
error UnsafeCast();
event DependencyAdded(uint256 indexed chainId); event DependencyAdded(uint256 indexed chainId);
event DependencyRemoved(uint256 indexed chainId); event DependencyRemoved(uint256 indexed chainId);
...@@ -27,19 +30,16 @@ interface IL1BlockInterop { ...@@ -27,19 +30,16 @@ interface IL1BlockInterop {
function gasPayingToken() external view returns (address addr_, uint8 decimals_); function gasPayingToken() external view returns (address addr_, uint8 decimals_);
function gasPayingTokenName() external view returns (string memory name_); function gasPayingTokenName() external view returns (string memory name_);
function gasPayingTokenSymbol() external view returns (string memory symbol_); function gasPayingTokenSymbol() external view returns (string memory symbol_);
function getConfig(Types.ConfigType _type) external view returns (bytes memory data_);
function hash() external view returns (bytes32); function hash() external view returns (bytes32);
function isCustomGasToken() external view returns (bool); function isCustomGasToken() external view returns (bool);
function isDeposit() external view returns (bool isDeposit_); function isDeposit() external view returns (bool isDeposit_);
function isIsthmus() external view returns (bool);
function isInDependencySet(uint256 _chainId) external view returns (bool); function isInDependencySet(uint256 _chainId) external view returns (bool);
function l1FeeOverhead() external view returns (uint256); function l1FeeOverhead() external view returns (uint256);
function l1FeeScalar() external view returns (uint256); function l1FeeScalar() external view returns (uint256);
function number() external view returns (uint64); function number() external view returns (uint64);
function sequenceNumber() external view returns (uint64); function sequenceNumber() external view returns (uint64);
function setConfig(Types.ConfigType _type, bytes memory _value) external; function setConfig(ConfigType _type, bytes memory _value) external;
function setGasPayingToken(address _token, uint8 _decimals, bytes32 _name, bytes32 _symbol) external; function setGasPayingToken(address _token, uint8 _decimals, bytes32 _name, bytes32 _symbol) external;
function setIsthmus() external;
function setL1BlockValues( function setL1BlockValues(
uint64 _number, uint64 _number,
uint64 _timestamp, uint64 _timestamp,
......
...@@ -9,20 +9,21 @@ interface IL1FeeVault { ...@@ -9,20 +9,21 @@ interface IL1FeeVault {
receive() external payable; receive() external payable;
function config()
external
view
returns (address recipient_, uint256 amount_, Types.WithdrawalNetwork withdrawalNetwork_);
function MIN_WITHDRAWAL_AMOUNT() external view returns (uint256); function MIN_WITHDRAWAL_AMOUNT() external view returns (uint256);
function RECIPIENT() external view returns (address); function RECIPIENT() external view returns (address);
function WITHDRAWAL_NETWORK() external view returns (Types.WithdrawalNetwork withdrawalNetwork_); function WITHDRAWAL_NETWORK() external view returns (Types.WithdrawalNetwork);
function minWithdrawalAmount() external view returns (uint256 amount_); function minWithdrawalAmount() external view returns (uint256 amount_);
function recipient() external view returns (address recipient_); function recipient() external view returns (address recipient_);
function totalProcessed() external view returns (uint256); function totalProcessed() external view returns (uint256);
function withdraw() external; function withdraw() external;
function withdrawalNetwork() external view returns (Types.WithdrawalNetwork withdrawalNetwork_); function withdrawalNetwork() external view returns (Types.WithdrawalNetwork network_);
function version() external view returns (string memory); function version() external view returns (string memory);
function __constructor__() external; function __constructor__(
address _recipient,
uint256 _minWithdrawalAmount,
Types.WithdrawalNetwork _withdrawalNetwork
)
external;
} }
...@@ -5,9 +5,8 @@ import { ICrossDomainMessenger } from "src/universal/interfaces/ICrossDomainMess ...@@ -5,9 +5,8 @@ import { ICrossDomainMessenger } from "src/universal/interfaces/ICrossDomainMess
interface IL2CrossDomainMessenger is ICrossDomainMessenger { interface IL2CrossDomainMessenger is ICrossDomainMessenger {
function MESSAGE_VERSION() external view returns (uint16); function MESSAGE_VERSION() external view returns (uint16);
function initialize(ICrossDomainMessenger _l1CrossDomainMessenger) external;
function l1CrossDomainMessenger() external view returns (ICrossDomainMessenger); function l1CrossDomainMessenger() external view returns (ICrossDomainMessenger);
function OTHER_MESSENGER() external view returns (ICrossDomainMessenger);
function otherMessenger() external view returns (ICrossDomainMessenger);
function version() external view returns (string memory); function version() external view returns (string memory);
function __constructor__() external; function __constructor__() external;
......
...@@ -2,7 +2,6 @@ ...@@ -2,7 +2,6 @@
pragma solidity ^0.8.0; pragma solidity ^0.8.0;
import { IERC721Bridge } from "src/universal/interfaces/IERC721Bridge.sol"; import { IERC721Bridge } from "src/universal/interfaces/IERC721Bridge.sol";
import { ICrossDomainMessenger } from "src/universal/interfaces/ICrossDomainMessenger.sol";
interface IL2ERC721Bridge is IERC721Bridge { interface IL2ERC721Bridge is IERC721Bridge {
function finalizeBridgeERC721( function finalizeBridgeERC721(
...@@ -14,7 +13,7 @@ interface IL2ERC721Bridge is IERC721Bridge { ...@@ -14,7 +13,7 @@ interface IL2ERC721Bridge is IERC721Bridge {
bytes memory _extraData bytes memory _extraData
) )
external; external;
function messenger() external pure returns (ICrossDomainMessenger); function initialize(address payable _l1ERC721Bridge) external;
function version() external view returns (string memory); function version() external view returns (string memory);
function __constructor__() external; function __constructor__() external;
......
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;
interface IL2OptimismMintableERC20Factory {
event OptimismMintableERC20Created(address indexed localToken, address indexed remoteToken, address deployer);
event StandardL2TokenCreated(address indexed remoteToken, address indexed localToken);
function BRIDGE() external view returns (address);
function bridge() external view returns (address);
function createOptimismMintableERC20(
address _remoteToken,
string memory _name,
string memory _symbol
)
external
returns (address);
function createOptimismMintableERC20WithDecimals(
address _remoteToken,
string memory _name,
string memory _symbol,
uint8 _decimals
)
external
returns (address);
function createStandardL2Token(
address _remoteToken,
string memory _name,
string memory _symbol
)
external
returns (address);
function deployments(address) external view returns (address);
function version() external view returns (string memory);
function __constructor__() external;
}
...@@ -2,7 +2,6 @@ ...@@ -2,7 +2,6 @@
pragma solidity ^0.8.0; pragma solidity ^0.8.0;
import { IStandardBridge } from "src/universal/interfaces/IStandardBridge.sol"; import { IStandardBridge } from "src/universal/interfaces/IStandardBridge.sol";
import { ICrossDomainMessenger } from "src/universal/interfaces/ICrossDomainMessenger.sol";
interface IL2StandardBridge is IStandardBridge { interface IL2StandardBridge is IStandardBridge {
event DepositFinalized( event DepositFinalized(
...@@ -24,13 +23,8 @@ interface IL2StandardBridge is IStandardBridge { ...@@ -24,13 +23,8 @@ interface IL2StandardBridge is IStandardBridge {
receive() external payable; receive() external payable;
function initialize(IStandardBridge _otherBridge) external;
function l1TokenBridge() external view returns (address); function l1TokenBridge() external view returns (address);
function MESSENGER() external view returns (ICrossDomainMessenger);
function messenger() external pure returns (ICrossDomainMessenger);
function OTHER_BRIDGE() external view returns (IStandardBridge);
function otherBridge() external view returns (IStandardBridge);
function version() external pure returns (string memory); function version() external pure returns (string memory);
function withdraw( function withdraw(
address _l2Token, address _l2Token,
......
...@@ -31,6 +31,8 @@ interface IL2StandardBridgeInterop is IStandardBridge { ...@@ -31,6 +31,8 @@ interface IL2StandardBridgeInterop is IStandardBridge {
bytes extraData bytes extraData
); );
function MESSENGER() external view returns (ICrossDomainMessenger);
function OTHER_BRIDGE() external view returns (IStandardBridge);
function bridgeERC20( function bridgeERC20(
address _localToken, address _localToken,
address _remoteToken, address _remoteToken,
...@@ -61,15 +63,11 @@ interface IL2StandardBridgeInterop is IStandardBridge { ...@@ -61,15 +63,11 @@ interface IL2StandardBridgeInterop is IStandardBridge {
) )
external; external;
function finalizeBridgeETH(address _from, address _to, uint256 _amount, bytes memory _extraData) external payable; function finalizeBridgeETH(address _from, address _to, uint256 _amount, bytes memory _extraData) external payable;
function messenger() external view returns (ICrossDomainMessenger);
function MESSENGER() external view returns (ICrossDomainMessenger);
function messenger() external pure returns (ICrossDomainMessenger);
function OTHER_BRIDGE() external view returns (IStandardBridge);
function otherBridge() external view returns (IStandardBridge); function otherBridge() external view returns (IStandardBridge);
function paused() external view returns (bool); function paused() external view returns (bool);
function initialize(IStandardBridge _otherBridge) external;
function l1TokenBridge() external view returns (address); function l1TokenBridge() external view returns (address);
function withdraw( function withdraw(
address _l2Token, address _l2Token,
......
...@@ -11,18 +11,20 @@ interface ISequencerFeeVault { ...@@ -11,18 +11,20 @@ interface ISequencerFeeVault {
function MIN_WITHDRAWAL_AMOUNT() external view returns (uint256); function MIN_WITHDRAWAL_AMOUNT() external view returns (uint256);
function RECIPIENT() external view returns (address); function RECIPIENT() external view returns (address);
function WITHDRAWAL_NETWORK() external view returns (Types.WithdrawalNetwork withdrawalNetwork_); function WITHDRAWAL_NETWORK() external view returns (Types.WithdrawalNetwork);
function minWithdrawalAmount() external view returns (uint256 amount_); function minWithdrawalAmount() external view returns (uint256 amount_);
function recipient() external view returns (address recipient_); function recipient() external view returns (address recipient_);
function totalProcessed() external view returns (uint256); function totalProcessed() external view returns (uint256);
function withdraw() external; function withdraw() external;
function withdrawalNetwork() external view returns (Types.WithdrawalNetwork withdrawalNetwork_); function withdrawalNetwork() external view returns (Types.WithdrawalNetwork network_);
function version() external view returns (string memory); function version() external view returns (string memory);
function l1FeeWallet() external view returns (address recipient_); function l1FeeWallet() external view returns (address);
function config()
external function __constructor__(
view address _recipient,
returns (address recipient_, uint256 amount_, Types.WithdrawalNetwork withdrawalNetwork_); uint256 _minWithdrawalAmount,
function __constructor__() external; Types.WithdrawalNetwork _withdrawalNetwork
)
external;
} }
...@@ -8,9 +8,6 @@ import { RLPWriter } from "src/libraries/rlp/RLPWriter.sol"; ...@@ -8,9 +8,6 @@ import { RLPWriter } from "src/libraries/rlp/RLPWriter.sol";
/// @title Encoding /// @title Encoding
/// @notice Encoding handles Optimism's various different encoding schemes. /// @notice Encoding handles Optimism's various different encoding schemes.
library Encoding { library Encoding {
/// @notice Error to be used when an unsafe cast is attempted.
error UnsafeCast();
/// @notice RLP encodes the L2 transaction that would be generated when a given deposit is sent /// @notice RLP encodes the L2 transaction that would be generated when a given deposit is sent
/// to the L2 system. Useful for searching for a deposit in the L2 system. The /// to the L2 system. Useful for searching for a deposit in the L2 system. The
/// transaction is prefixed with 0x7e to identify its EIP-2718 type. /// transaction is prefixed with 0x7e to identify its EIP-2718 type.
...@@ -139,39 +136,6 @@ library Encoding { ...@@ -139,39 +136,6 @@ library Encoding {
return (nonce, version); return (nonce, version);
} }
/// @notice Encodes a fee vault configuration.
/// @param _recipient Address of the recipient of the fee vault.
/// @param _amount Amount of the fee vault.
/// @param _network Network of the fee vault.
/// @return Encoded fee vault configuration.
function encodeFeeVaultConfig(
address _recipient,
uint256 _amount,
Types.WithdrawalNetwork _network
)
internal
pure
returns (bytes32)
{
if (_amount > type(uint88).max) revert UnsafeCast();
return bytes32(uint256(_network) << 248 | _amount << 160 | uint256(uint160(_recipient)));
}
/// @notice Decodes a fee vault configuration.
/// @param _data Encoded fee vault configuration.
/// @return recipient_ Recipient of the fee vault.
/// @return amount_ Amount of the fee vault.
/// @return network_ Network of the fee vault.
function decodeFeeVaultConfig(bytes32 _data)
internal
pure
returns (address recipient_, uint256 amount_, Types.WithdrawalNetwork network_)
{
recipient_ = address(uint160(uint256(_data) & uint256(type(uint160).max)));
amount_ = (uint256(_data) & uint256(type(uint88).max) << 160) >> 160;
network_ = Types.WithdrawalNetwork(uint8(uint256(_data >> 248)));
}
/// @notice Returns an appropriately encoded call to L1Block.setL1BlockValuesEcotone /// @notice Returns an appropriately encoded call to L1Block.setL1BlockValuesEcotone
/// @param _baseFeeScalar L1 base fee Scalar /// @param _baseFeeScalar L1 base fee Scalar
/// @param _blobBaseFeeScalar L1 blob base fee Scalar /// @param _blobBaseFeeScalar L1 blob base fee Scalar
......
...@@ -119,13 +119,13 @@ library Predeploys { ...@@ -119,13 +119,13 @@ library Predeploys {
if (_addr == GAS_PRICE_ORACLE) return "GasPriceOracle"; if (_addr == GAS_PRICE_ORACLE) return "GasPriceOracle";
if (_addr == L2_STANDARD_BRIDGE) return "L2StandardBridge"; if (_addr == L2_STANDARD_BRIDGE) return "L2StandardBridge";
if (_addr == SEQUENCER_FEE_WALLET) return "SequencerFeeVault"; if (_addr == SEQUENCER_FEE_WALLET) return "SequencerFeeVault";
if (_addr == OPTIMISM_MINTABLE_ERC20_FACTORY) return "L2OptimismMintableERC20Factory"; if (_addr == OPTIMISM_MINTABLE_ERC20_FACTORY) return "OptimismMintableERC20Factory";
if (_addr == L1_BLOCK_NUMBER) return "L1BlockNumber"; if (_addr == L1_BLOCK_NUMBER) return "L1BlockNumber";
if (_addr == L2_ERC721_BRIDGE) return "L2ERC721Bridge"; if (_addr == L2_ERC721_BRIDGE) return "L2ERC721Bridge";
if (_addr == L1_BLOCK_ATTRIBUTES) return "L1Block"; if (_addr == L1_BLOCK_ATTRIBUTES) return "L1Block";
if (_addr == L2_TO_L1_MESSAGE_PASSER) return "L2ToL1MessagePasser"; if (_addr == L2_TO_L1_MESSAGE_PASSER) return "L2ToL1MessagePasser";
if (_addr == OPTIMISM_MINTABLE_ERC721_FACTORY) return "OptimismMintableERC721Factory"; if (_addr == OPTIMISM_MINTABLE_ERC721_FACTORY) return "OptimismMintableERC721Factory";
if (_addr == PROXY_ADMIN) return "L2ProxyAdmin"; if (_addr == PROXY_ADMIN) return "ProxyAdmin";
if (_addr == BASE_FEE_VAULT) return "BaseFeeVault"; if (_addr == BASE_FEE_VAULT) return "BaseFeeVault";
if (_addr == L1_FEE_VAULT) return "L1FeeVault"; if (_addr == L1_FEE_VAULT) return "L1FeeVault";
if (_addr == SCHEMA_REGISTRY) return "SchemaRegistry"; if (_addr == SCHEMA_REGISTRY) return "SchemaRegistry";
......
// SPDX-License-Identifier: MIT // SPDX-License-Identifier: MIT
pragma solidity ^0.8.0; pragma solidity ^0.8.0;
import { Types } from "src/libraries/Types.sol";
/// @title StaticConfig /// @title StaticConfig
/// @notice Library for encoding and decoding static configuration data. /// @notice Library for encoding and decoding static configuration data.
library StaticConfig { library StaticConfig {
...@@ -59,60 +57,4 @@ library StaticConfig { ...@@ -59,60 +57,4 @@ library StaticConfig {
function decodeRemoveDependency(bytes memory _data) internal pure returns (uint256) { function decodeRemoveDependency(bytes memory _data) internal pure returns (uint256) {
return abi.decode(_data, (uint256)); return abi.decode(_data, (uint256));
} }
/// @notice Encodes the static configuration data for setting a fee vault config.
/// @param _recipient Address of the recipient of the fee vault.
/// @param _min Minimum withdrawal amount allowed to be processed.
/// @param _network The network in which the fees should be withdrawn to.
/// @return Encoded static configuration data.
function encodeSetFeeVaultConfig(
address _recipient,
uint256 _min,
Types.WithdrawalNetwork _network
)
internal
pure
returns (bytes memory)
{
return abi.encode(_recipient, _min, _network);
}
/// @notice Decodes the static configuration data for setting a fee vault config.
/// @param _data Encoded static configuration data.
/// @return Decoded fee vault config data (recipient, min, network).
function decodeSetFeeVaultConfig(bytes memory _data)
internal
pure
returns (address, uint256, Types.WithdrawalNetwork)
{
return abi.decode(_data, (address, uint256, Types.WithdrawalNetwork));
}
/// @notice Encodes the static configuration data for setting an address.
/// @param _address Address to set.
/// @return Encoded static configuration data.
function encodeSetAddress(address _address) internal pure returns (bytes memory) {
return abi.encode(_address);
}
/// @notice Decodes the static configuration data for setting an address.
/// @param _data Encoded static configuration data.
/// @return Decoded address.
function decodeSetAddress(bytes memory _data) internal pure returns (address) {
return abi.decode(_data, (address));
}
/// @notice Encodes the static configuration data for setting a remote chain ID.
/// @param _chainId Chain ID of the remote chain.
/// @return Encoded static configuration data.
function encodeSetRemoteChainId(uint256 _chainId) internal pure returns (bytes memory) {
return abi.encode(_chainId);
}
/// @notice Decodes the static configuration data for setting a remote chain ID.
/// @param _data Encoded static configuration data.
/// @return Decoded chain ID of the remote chain.
function decodeSetRemoteChainId(bytes memory _data) internal pure returns (uint256) {
return abi.decode(_data, (uint256));
}
} }
...@@ -75,29 +75,4 @@ library Types { ...@@ -75,29 +75,4 @@ library Types {
L1, L1,
L2 L2
} }
/// @notice Enum representing different types of configurations that can be set on L1BlockIsthmus.
/// @custom:value GAS_PAYING_TOKEN Config type for the gas paying token.
/// @custom:value BASE_FEE_VAULT_CONFIG Config type for the base fee vault config.
/// @custom:value L1_FEE_VAULT_CONFIG Config type for the L1 fee vault config.
/// @custom:value SEQUENCER_FEE_VAULT_CONFIG Config type for the sequencer fee vault config.
/// @custom:value L1_CROSS_DOMAIN_MESSENGER_ADDRESS Config type for the L1 Cross Domain Messenger address.
/// @custom:value L1_ERC_721_BRIDGE_ADDRESS Config type for the L1 ERC721 Bridge address.
/// @custom:value L1_STANDARD_BRIDGE_ADDRESS Config type for the L1 Standard Bridge address.
/// @custom:value REMOTE_CHAIN_ID Config type for the remote chain ID.
/// @custom:value ADD_DEPENDENCY Config type for adding a chain to the interop dependency set.
/// @custom:value REMOVE_DEPENDENCY Config type for removing a chain from the interop dependency
/// set.
enum ConfigType {
GAS_PAYING_TOKEN,
BASE_FEE_VAULT_CONFIG,
L1_FEE_VAULT_CONFIG,
SEQUENCER_FEE_VAULT_CONFIG,
L1_CROSS_DOMAIN_MESSENGER_ADDRESS,
L1_ERC_721_BRIDGE_ADDRESS,
L1_STANDARD_BRIDGE_ADDRESS,
REMOTE_CHAIN_ID,
ADD_DEPENDENCY,
REMOVE_DEPENDENCY
}
} }
// SPDX-License-Identifier: MIT // SPDX-License-Identifier: MIT
pragma solidity 0.8.15; pragma solidity 0.8.15;
import { Initializable } from "@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol";
import { SafeCall } from "src/libraries/SafeCall.sol"; import { SafeCall } from "src/libraries/SafeCall.sol";
import { Hashing } from "src/libraries/Hashing.sol"; import { Hashing } from "src/libraries/Hashing.sol";
import { Encoding } from "src/libraries/Encoding.sol"; import { Encoding } from "src/libraries/Encoding.sol";
import { Constants } from "src/libraries/Constants.sol"; import { Constants } from "src/libraries/Constants.sol";
/// @custom:legacy /// @custom:legacy
/// @title CrossDomainMessengerLegacySpacer /// @title CrossDomainMessengerLegacySpacer0
/// @notice Contract only exists to add a spacer to the CrossDomainMessenger where the /// @notice Contract only exists to add a spacer to the CrossDomainMessenger where the
/// libAddressManager variable, PausableUpgradable and OwnableUpgradeable /// libAddressManager variable used to exist. Must be the first contract in the inheritance
/// variables used to exist. /// tree of the CrossDomainMessenger.
abstract contract CrossDomainMessengerLegacySpacer { contract CrossDomainMessengerLegacySpacer0 {
/// @custom:legacy /// @custom:legacy
/// @custom:spacer libAddressManager /// @custom:spacer libAddressManager
/// @notice Spacer for backwards compatibility. /// @notice Spacer for backwards compatibility.
address private spacer_0_0_20; address private spacer_0_0_20;
}
/// @custom:legacy /// @custom:legacy
/// @custom:spacer initializer /// @title CrossDomainMessengerLegacySpacer1
/// @notice Spacer for backwards compatibility. /// @notice Contract only exists to add a spacer to the CrossDomainMessenger where the
bytes12 private spacer_0_20_12; /// PausableUpgradable and OwnableUpgradeable variables used to exist. Must be
/// the third contract in the inheritance tree of the CrossDomainMessenger.
contract CrossDomainMessengerLegacySpacer1 {
/// @custom:legacy /// @custom:legacy
/// @custom:spacer ContextUpgradable's __gap /// @custom:spacer ContextUpgradable's __gap
/// @notice Spacer for backwards compatibility. Comes from OpenZeppelin /// @notice Spacer for backwards compatibility. Comes from OpenZeppelin
...@@ -31,7 +34,7 @@ abstract contract CrossDomainMessengerLegacySpacer { ...@@ -31,7 +34,7 @@ abstract contract CrossDomainMessengerLegacySpacer {
/// @custom:legacy /// @custom:legacy
/// @custom:spacer OwnableUpgradeable's _owner /// @custom:spacer OwnableUpgradeable's _owner
/// @notice Spacer for backwards compatibility. /// @notice Spacer for backwards compatibility.
/// Comes from OpenZeppelin OwnableUpgradeable. /// Come from OpenZeppelin OwnableUpgradeable.
address private spacer_51_0_20; address private spacer_51_0_20;
/// @custom:legacy /// @custom:legacy
...@@ -81,7 +84,11 @@ abstract contract CrossDomainMessengerLegacySpacer { ...@@ -81,7 +84,11 @@ abstract contract CrossDomainMessengerLegacySpacer {
/// chain it's deployed on. Currently only designed for message passing between two paired /// chain it's deployed on. Currently only designed for message passing between two paired
/// chains and does not support one-to-many interactions. /// chains and does not support one-to-many interactions.
/// Any changes to this contract MUST result in a semver bump for contracts that inherit it. /// Any changes to this contract MUST result in a semver bump for contracts that inherit it.
abstract contract CrossDomainMessenger is CrossDomainMessengerLegacySpacer { abstract contract CrossDomainMessenger is
CrossDomainMessengerLegacySpacer0,
Initializable,
CrossDomainMessengerLegacySpacer1
{
/// @notice Current message version identifier. /// @notice Current message version identifier.
uint16 public constant MESSAGE_VERSION = 1; uint16 public constant MESSAGE_VERSION = 1;
...@@ -112,12 +119,11 @@ abstract contract CrossDomainMessenger is CrossDomainMessengerLegacySpacer { ...@@ -112,12 +119,11 @@ abstract contract CrossDomainMessenger is CrossDomainMessengerLegacySpacer {
/// can therefore not be relayed again. /// can therefore not be relayed again.
mapping(bytes32 => bool) public successfulMessages; mapping(bytes32 => bool) public successfulMessages;
/// @custom:legacy /// @notice Address of the sender of the currently executing message on the other chain. If the
/// @custom:spacer xDomainMsgSender /// value of this variable is the default value (0x00000000...dead) then no message is
/// @notice Spacer for backwards compatibility. The storage slot was migrated when the /// currently being executed. Use the xDomainMessageSender getter which will throw an
/// initializer pattern was moved away from in the base contract to remove the /// error if this is the case.
/// need to set `Constants.DEFAULT_L2_SENDER` into storage during a call to `initialize`. address internal xDomainMsgSender;
bytes20 internal spacer_204_0_20;
/// @notice Nonce for the next message to be sent, without the message version applied. Use the /// @notice Nonce for the next message to be sent, without the message version applied. Use the
/// messageNonce getter which will insert the message version into the nonce to give you /// messageNonce getter which will insert the message version into the nonce to give you
...@@ -129,23 +135,14 @@ abstract contract CrossDomainMessenger is CrossDomainMessengerLegacySpacer { ...@@ -129,23 +135,14 @@ abstract contract CrossDomainMessenger is CrossDomainMessengerLegacySpacer {
/// successfully executed on the first attempt. /// successfully executed on the first attempt.
mapping(bytes32 => bool) public failedMessages; mapping(bytes32 => bool) public failedMessages;
/// @custom:legacy /// @notice CrossDomainMessenger contract on the other chain.
/// @custom:spacer CrossDomainMessenger /// @custom:network-specific
/// @notice Spacer for backwards compatibility. CrossDomainMessenger public otherMessenger;
address private spacer_207_0_20;
/// @notice Address of the sender of the currently executing message on the other chain. If the
/// value of this variable is address(0) then no message is currently being executed.
/// Use the xDomainMessageSender getter which will throw an error if this is the case.
address private xDomainMsgSender;
/// @notice Spacer to ensure that there is no collision with the xDomainMsgSender slot.
bytes12 private spacer_208_20_12;
/// @notice Reserve extra slots in the storage layout for future upgrades. /// @notice Reserve extra slots in the storage layout for future upgrades.
/// A gap size of 40 was chosen here, so that the first slot used in a child contract /// A gap size of 43 was chosen here, so that the first slot used in a child contract
/// would be 1 plus a multiple of 50. /// would be 1 plus a multiple of 50.
uint256[41] private __gap; uint256[43] private __gap;
/// @notice Emitted whenever a message is sent to the other chain. /// @notice Emitted whenever a message is sent to the other chain.
/// @param target Address of the recipient of the message. /// @param target Address of the recipient of the message.
...@@ -186,7 +183,7 @@ abstract contract CrossDomainMessenger is CrossDomainMessengerLegacySpacer { ...@@ -186,7 +183,7 @@ abstract contract CrossDomainMessenger is CrossDomainMessengerLegacySpacer {
// guarantee the property that the call to the target contract will always have at least // guarantee the property that the call to the target contract will always have at least
// the minimum gas limit specified by the user. // the minimum gas limit specified by the user.
_sendMessage({ _sendMessage({
_to: address(otherMessenger()), _to: address(otherMessenger),
_gasLimit: baseGas(_message, _minGasLimit), _gasLimit: baseGas(_message, _minGasLimit),
_value: msg.value, _value: msg.value,
_data: abi.encodeWithSelector( _data: abi.encodeWithSelector(
...@@ -269,7 +266,7 @@ abstract contract CrossDomainMessenger is CrossDomainMessengerLegacySpacer { ...@@ -269,7 +266,7 @@ abstract contract CrossDomainMessenger is CrossDomainMessengerLegacySpacer {
// is being re-entered. This marks the message as failed to allow it to be replayed. // is being re-entered. This marks the message as failed to allow it to be replayed.
if ( if (
!SafeCall.hasMinGas(_minGasLimit, RELAY_RESERVED_GAS + RELAY_GAS_CHECK_BUFFER) !SafeCall.hasMinGas(_minGasLimit, RELAY_RESERVED_GAS + RELAY_GAS_CHECK_BUFFER)
|| getCrossDomainMessageSender() != Constants.DEFAULT_L2_SENDER || xDomainMsgSender != Constants.DEFAULT_L2_SENDER
) { ) {
failedMessages[versionedHash] = true; failedMessages[versionedHash] = true;
emit FailedRelayedMessage(versionedHash); emit FailedRelayedMessage(versionedHash);
...@@ -286,9 +283,9 @@ abstract contract CrossDomainMessenger is CrossDomainMessengerLegacySpacer { ...@@ -286,9 +283,9 @@ abstract contract CrossDomainMessenger is CrossDomainMessengerLegacySpacer {
return; return;
} }
setCrossDomainMessageSender(_sender); xDomainMsgSender = _sender;
bool success = SafeCall.call(_target, gasleft() - RELAY_RESERVED_GAS, _value, _message); bool success = SafeCall.call(_target, gasleft() - RELAY_RESERVED_GAS, _value, _message);
setCrossDomainMessageSender(address(0)); xDomainMsgSender = Constants.DEFAULT_L2_SENDER;
if (success) { if (success) {
// This check is identical to one above, but it ensures that the same message cannot be relayed // This check is identical to one above, but it ensures that the same message cannot be relayed
...@@ -311,40 +308,24 @@ abstract contract CrossDomainMessenger is CrossDomainMessengerLegacySpacer { ...@@ -311,40 +308,24 @@ abstract contract CrossDomainMessenger is CrossDomainMessengerLegacySpacer {
} }
} }
/// @notice Retrieves the address of the contract or wallet that initiated the currently
/// executing message on the other chain.
/// @return Address of the sender of the currently executing message on the other chain.
function getCrossDomainMessageSender() internal view returns (address) {
if (xDomainMsgSender == address(0)) return Constants.DEFAULT_L2_SENDER;
return xDomainMsgSender;
}
/// @notice Setter function for the cross-domain message sender.
/// @param _address Address of the sender of the currently executing message on the other chain.
function setCrossDomainMessageSender(address _address) internal {
xDomainMsgSender = _address;
}
/// @notice Retrieves the address of the contract or wallet that initiated the currently /// @notice Retrieves the address of the contract or wallet that initiated the currently
/// executing message on the other chain. Will throw an error if there is no message /// executing message on the other chain. Will throw an error if there is no message
/// currently being executed. Allows the recipient of a call to see who triggered it. /// currently being executed. Allows the recipient of a call to see who triggered it.
/// @return Address of the sender of the currently executing message on the other chain. /// @return Address of the sender of the currently executing message on the other chain.
function xDomainMessageSender() external view returns (address) { function xDomainMessageSender() external view returns (address) {
address sender = getCrossDomainMessageSender(); require(
require(sender != Constants.DEFAULT_L2_SENDER, "CrossDomainMessenger: xDomainMessageSender is not set"); xDomainMsgSender != Constants.DEFAULT_L2_SENDER, "CrossDomainMessenger: xDomainMessageSender is not set"
return sender; );
}
/// @notice Returns the contract of the other messenger on this chain. return xDomainMsgSender;
/// @return Contract of the other messenger on this chain. }
function otherMessenger() public view virtual returns (CrossDomainMessenger);
/// @notice Retrieves the address of the paired CrossDomainMessenger contract on the other chain /// @notice Retrieves the address of the paired CrossDomainMessenger contract on the other chain
/// Public getter is legacy and will be removed in the future. Use `otherMessenger()` instead. /// Public getter is legacy and will be removed in the future. Use `otherMessenger()` instead.
/// @return CrossDomainMessenger contract on the other chain. /// @return CrossDomainMessenger contract on the other chain.
/// @custom:legacy /// @custom:legacy
function OTHER_MESSENGER() public view returns (CrossDomainMessenger) { function OTHER_MESSENGER() public view returns (CrossDomainMessenger) {
return otherMessenger(); return otherMessenger;
} }
/// @notice Retrieves the next message nonce. Message version will be added to the upper two /// @notice Retrieves the next message nonce. Message version will be added to the upper two
...@@ -390,6 +371,19 @@ abstract contract CrossDomainMessenger is CrossDomainMessengerLegacySpacer { ...@@ -390,6 +371,19 @@ abstract contract CrossDomainMessenger is CrossDomainMessengerLegacySpacer {
return token != Constants.ETHER; return token != Constants.ETHER;
} }
/// @notice Initializer.
/// @param _otherMessenger CrossDomainMessenger contract on the other chain.
function __CrossDomainMessenger_init(CrossDomainMessenger _otherMessenger) internal onlyInitializing {
// We only want to set the xDomainMsgSender to the default value if it hasn't been initialized yet,
// meaning that this is a fresh contract deployment.
// This prevents resetting the xDomainMsgSender to the default value during an upgrade, which would enable
// a reentrant withdrawal to sandwhich the upgrade replay a withdrawal twice.
if (xDomainMsgSender == address(0)) {
xDomainMsgSender = Constants.DEFAULT_L2_SENDER;
}
otherMessenger = _otherMessenger;
}
/// @notice Sends a low-level message to the other messenger. Needs to be implemented by child /// @notice Sends a low-level message to the other messenger. Needs to be implemented by child
/// contracts because the logic for this depends on the network where the messenger is /// contracts because the logic for this depends on the network where the messenger is
/// being deployed. /// being deployed.
......
// SPDX-License-Identifier: MIT // SPDX-License-Identifier: MIT
pragma solidity 0.8.25; pragma solidity 0.8.15;
import { ICrossDomainMessenger } from "src/universal/interfaces/ICrossDomainMessenger.sol"; import { ICrossDomainMessenger } from "src/universal/interfaces/ICrossDomainMessenger.sol";
import { Address } from "@openzeppelin/contracts/utils/Address.sol"; import { Address } from "@openzeppelin/contracts/utils/Address.sol";
import { Initializable } from "@openzeppelin/contracts/proxy/utils/Initializable.sol";
/// @title ERC721Bridge /// @title ERC721Bridge
/// @notice ERC721Bridge is a base contract for the L1 and L2 ERC721 bridges. /// @notice ERC721Bridge is a base contract for the L1 and L2 ERC721 bridges.
abstract contract ERC721Bridge { abstract contract ERC721Bridge is Initializable {
/// @custom:spacer ERC721Bridge's initializer slot spacing /// @custom:spacer ERC721Bridge's initializer slot spacing
/// @notice Spacer for legacy initializable slot /// @notice Spacer to avoid packing into the initializer slot
bytes32 private spacer_0_0_32; bytes30 private spacer_0_2_30;
/// @custom:legacy /// @notice Messenger contract on this domain.
/// @custom:spacer messenger /// @custom:network-specific
/// @notice Spacer for backwards compatibility. ICrossDomainMessenger public messenger;
address private spacer_1_0_20;
/// @custom:legacy /// @notice Contract of the bridge on the other network.
/// @custom:spacer otherBridge /// @custom:network-specific
/// @notice Spacer for backwards compatibility. ERC721Bridge public otherBridge;
address private spacer_2_0_20;
/// @notice Reserve extra slots (to a total of 50) in the storage layout for future upgrades. /// @notice Reserve extra slots (to a total of 50) in the storage layout for future upgrades.
uint256[46] private __gap; uint256[46] private __gap;
...@@ -58,37 +57,41 @@ abstract contract ERC721Bridge { ...@@ -58,37 +57,41 @@ abstract contract ERC721Bridge {
/// @notice Ensures that the caller is a cross-chain message from the other bridge. /// @notice Ensures that the caller is a cross-chain message from the other bridge.
modifier onlyOtherBridge() { modifier onlyOtherBridge() {
ICrossDomainMessenger crossDomainMessenger = messenger();
require( require(
msg.sender == address(crossDomainMessenger) msg.sender == address(messenger) && messenger.xDomainMessageSender() == address(otherBridge),
&& crossDomainMessenger.xDomainMessageSender() == address(otherBridge()),
"ERC721Bridge: function can only be called from the other bridge" "ERC721Bridge: function can only be called from the other bridge"
); );
_; _;
} }
/// @notice Getter function for the messenger contract. /// @notice Initializer.
/// @return Messenger contract on this domain. /// @param _messenger Contract of the CrossDomainMessenger on this network.
function messenger() public view virtual returns (ICrossDomainMessenger); /// @param _otherBridge Contract of the ERC721 bridge on the other network.
function __ERC721Bridge_init(
ICrossDomainMessenger _messenger,
ERC721Bridge _otherBridge
)
internal
onlyInitializing
{
messenger = _messenger;
otherBridge = _otherBridge;
}
/// @notice Legacy getter for messenger contract. /// @notice Legacy getter for messenger contract.
/// Public getter is legacy and will be removed in the future. Use `messenger` instead. /// Public getter is legacy and will be removed in the future. Use `messenger` instead.
/// @return Messenger contract on this domain. /// @return Messenger contract on this domain.
/// @custom:legacy /// @custom:legacy
function MESSENGER() external view returns (ICrossDomainMessenger) { function MESSENGER() external view returns (ICrossDomainMessenger) {
return messenger(); return messenger;
} }
/// @notice Getter function for the other bridge.
/// @return Contract of the bridge on the other network.
function otherBridge() public view virtual returns (ERC721Bridge);
/// @notice Legacy getter for other bridge address. /// @notice Legacy getter for other bridge address.
/// Public getter is legacy and will be removed in the future. Use `otherBridge` instead. /// Public getter is legacy and will be removed in the future. Use `otherBridge` instead.
/// @return Contract of the bridge on the other network. /// @return Contract of the bridge on the other network.
/// @custom:legacy /// @custom:legacy
function OTHER_BRIDGE() external view returns (ERC721Bridge) { function OTHER_BRIDGE() external view returns (ERC721Bridge) {
return otherBridge(); return otherBridge;
} }
/// @notice This function should return true if the contract is paused. /// @notice This function should return true if the contract is paused.
......
...@@ -3,21 +3,24 @@ pragma solidity 0.8.15; ...@@ -3,21 +3,24 @@ pragma solidity 0.8.15;
import { OptimismMintableERC20 } from "src/universal/OptimismMintableERC20.sol"; import { OptimismMintableERC20 } from "src/universal/OptimismMintableERC20.sol";
import { ISemver } from "src/universal/interfaces/ISemver.sol"; import { ISemver } from "src/universal/interfaces/ISemver.sol";
import { Initializable } from "@openzeppelin/contracts/proxy/utils/Initializable.sol";
import { IOptimismERC20Factory } from "src/L2/interfaces/IOptimismERC20Factory.sol"; import { IOptimismERC20Factory } from "src/L2/interfaces/IOptimismERC20Factory.sol";
/// @custom:proxied true
/// @custom:predeployed 0x4200000000000000000000000000000000000012
/// @title OptimismMintableERC20Factory /// @title OptimismMintableERC20Factory
/// @notice OptimismMintableERC20Factory is an abstract factory contract that generates OptimismMintableERC20 /// @notice OptimismMintableERC20Factory is a factory contract that generates OptimismMintableERC20
/// contracts on the network it's deployed to. It should be inherited by a child contract that /// contracts on the network it's deployed to. Simplifies the deployment process for users
/// implements the `bridge` getter function. /// who may be less familiar with deploying smart contracts. Designed to be backwards
/// Any changes to this contract MUST result in a semver bump for contracts that inherit it. /// compatible with the older StandardL2ERC20Factory contract.
abstract contract OptimismMintableERC20Factory is ISemver, IOptimismERC20Factory { contract OptimismMintableERC20Factory is ISemver, Initializable, IOptimismERC20Factory {
/// @custom:spacer OptimismMintableERC20Factory's initializer slot spacing /// @custom:spacer OptimismMintableERC20Factory's initializer slot spacing
/// @notice Spacer to avoid packing into the initializer slot /// @notice Spacer to avoid packing into the initializer slot
bytes32 private spacer_0_0_32; bytes30 private spacer_0_2_30;
/// @custom:spacer bridge /// @notice Address of the StandardBridge on this chain.
/// @notice Spacer to avoid packing into the initializer slot /// @custom:network-specific
bytes32 private spacer_1_0_32; address public bridge;
/// @notice Mapping of local token address to remote token address. /// @notice Mapping of local token address to remote token address.
/// This is used to keep track of the token deployments. /// This is used to keep track of the token deployments.
...@@ -41,14 +44,30 @@ abstract contract OptimismMintableERC20Factory is ISemver, IOptimismERC20Factory ...@@ -41,14 +44,30 @@ abstract contract OptimismMintableERC20Factory is ISemver, IOptimismERC20Factory
/// @param deployer Address of the account that deployed the token. /// @param deployer Address of the account that deployed the token.
event OptimismMintableERC20Created(address indexed localToken, address indexed remoteToken, address deployer); event OptimismMintableERC20Created(address indexed localToken, address indexed remoteToken, address deployer);
function bridge() public view virtual returns (address); /// @notice The semver MUST be bumped any time that there is a change in
/// the OptimismMintableERC20 token contract since this contract
/// is responsible for deploying OptimismMintableERC20 contracts.
/// @notice Semantic version.
/// @custom:semver 1.10.1-beta.4
string public constant version = "1.10.1-beta.4";
/// @notice Constructs the OptimismMintableERC20Factory contract.
constructor() {
initialize({ _bridge: address(0) });
}
/// @notice Initializes the contract.
/// @param _bridge Address of the StandardBridge on this chain.
function initialize(address _bridge) public initializer {
bridge = _bridge;
}
/// @notice Getter function for the address of the StandardBridge on this chain. /// @notice Getter function for the address of the StandardBridge on this chain.
/// Public getter is legacy and will be removed in the future. Use `bridge` instead. /// Public getter is legacy and will be removed in the future. Use `bridge` instead.
/// @return Address of the StandardBridge on this chain. /// @return Address of the StandardBridge on this chain.
/// @custom:legacy /// @custom:legacy
function BRIDGE() external view returns (address) { function BRIDGE() external view returns (address) {
return bridge(); return bridge;
} }
/// @custom:legacy /// @custom:legacy
...@@ -105,7 +124,7 @@ abstract contract OptimismMintableERC20Factory is ISemver, IOptimismERC20Factory ...@@ -105,7 +124,7 @@ abstract contract OptimismMintableERC20Factory is ISemver, IOptimismERC20Factory
bytes32 salt = keccak256(abi.encode(_remoteToken, _name, _symbol, _decimals)); bytes32 salt = keccak256(abi.encode(_remoteToken, _name, _symbol, _decimals));
address localToken = address localToken =
address(new OptimismMintableERC20{ salt: salt }(bridge(), _remoteToken, _name, _symbol, _decimals)); address(new OptimismMintableERC20{ salt: salt }(bridge, _remoteToken, _name, _symbol, _decimals));
deployments[localToken] = _remoteToken; deployments[localToken] = _remoteToken;
......
...@@ -5,7 +5,6 @@ import { ERC721Enumerable } from "@openzeppelin/contracts/token/ERC721/extension ...@@ -5,7 +5,6 @@ import { ERC721Enumerable } from "@openzeppelin/contracts/token/ERC721/extension
import { ERC721 } from "@openzeppelin/contracts/token/ERC721/ERC721.sol"; import { ERC721 } from "@openzeppelin/contracts/token/ERC721/ERC721.sol";
import { Strings } from "@openzeppelin/contracts/utils/Strings.sol"; import { Strings } from "@openzeppelin/contracts/utils/Strings.sol";
import { IOptimismMintableERC721 } from "src/universal/interfaces/IOptimismMintableERC721.sol"; import { IOptimismMintableERC721 } from "src/universal/interfaces/IOptimismMintableERC721.sol";
import { IL2ERC721Bridge } from "src/L2/interfaces/IL2ERC721Bridge.sol";
import { ISemver } from "src/universal/interfaces/ISemver.sol"; import { ISemver } from "src/universal/interfaces/ISemver.sol";
/// @title OptimismMintableERC721 /// @title OptimismMintableERC721
...@@ -30,20 +29,20 @@ contract OptimismMintableERC721 is ERC721Enumerable, ISemver { ...@@ -30,20 +29,20 @@ contract OptimismMintableERC721 is ERC721Enumerable, ISemver {
address public immutable REMOTE_TOKEN; address public immutable REMOTE_TOKEN;
/// @notice Address of the ERC721 bridge on this network. /// @notice Address of the ERC721 bridge on this network.
IL2ERC721Bridge public immutable BRIDGE; address public immutable BRIDGE;
/// @notice Base token URI for this token. /// @notice Base token URI for this token.
string public baseTokenURI; string public baseTokenURI;
/// @notice Modifier that prevents callers other than the bridge from calling the function. /// @notice Modifier that prevents callers other than the bridge from calling the function.
modifier onlyBridge() { modifier onlyBridge() {
require(msg.sender == address(BRIDGE), "OptimismMintableERC721: only bridge can call this function"); require(msg.sender == BRIDGE, "OptimismMintableERC721: only bridge can call this function");
_; _;
} }
/// @notice Semantic version. /// @notice Semantic version.
/// @custom:semver 1.3.1-beta.4 /// @custom:semver 1.3.1-beta.3
string public constant version = "1.3.1-beta.4"; string public constant version = "1.3.1-beta.3";
/// @param _bridge Address of the bridge on this network. /// @param _bridge Address of the bridge on this network.
/// @param _remoteChainId Chain ID where the remote token is deployed. /// @param _remoteChainId Chain ID where the remote token is deployed.
...@@ -51,7 +50,7 @@ contract OptimismMintableERC721 is ERC721Enumerable, ISemver { ...@@ -51,7 +50,7 @@ contract OptimismMintableERC721 is ERC721Enumerable, ISemver {
/// @param _name ERC721 name. /// @param _name ERC721 name.
/// @param _symbol ERC721 symbol. /// @param _symbol ERC721 symbol.
constructor( constructor(
IL2ERC721Bridge _bridge, address _bridge,
uint256 _remoteChainId, uint256 _remoteChainId,
address _remoteToken, address _remoteToken,
string memory _name, string memory _name,
...@@ -59,7 +58,7 @@ contract OptimismMintableERC721 is ERC721Enumerable, ISemver { ...@@ -59,7 +58,7 @@ contract OptimismMintableERC721 is ERC721Enumerable, ISemver {
) )
ERC721(_name, _symbol) ERC721(_name, _symbol)
{ {
require(address(_bridge) != address(0), "OptimismMintableERC721: bridge cannot be address(0)"); require(_bridge != address(0), "OptimismMintableERC721: bridge cannot be address(0)");
require(_remoteChainId != 0, "OptimismMintableERC721: remote chain id cannot be zero"); require(_remoteChainId != 0, "OptimismMintableERC721: remote chain id cannot be zero");
require(_remoteToken != address(0), "OptimismMintableERC721: remote token cannot be address(0)"); require(_remoteToken != address(0), "OptimismMintableERC721: remote token cannot be address(0)");
...@@ -91,8 +90,8 @@ contract OptimismMintableERC721 is ERC721Enumerable, ISemver { ...@@ -91,8 +90,8 @@ contract OptimismMintableERC721 is ERC721Enumerable, ISemver {
} }
/// @notice Address of the ERC721 bridge on this network. /// @notice Address of the ERC721 bridge on this network.
function bridge() external view returns (IL2ERC721Bridge) { function bridge() external view returns (address) {
return IL2ERC721Bridge(BRIDGE); return BRIDGE;
} }
/// @notice Mints some token ID for a user, checking first that contract recipients /// @notice Mints some token ID for a user, checking first that contract recipients
......
...@@ -2,18 +2,19 @@ ...@@ -2,18 +2,19 @@
pragma solidity 0.8.15; pragma solidity 0.8.15;
import { OptimismMintableERC721 } from "src/universal/OptimismMintableERC721.sol"; import { OptimismMintableERC721 } from "src/universal/OptimismMintableERC721.sol";
import { IL2ERC721Bridge } from "src/L2/interfaces/IL2ERC721Bridge.sol";
import { ISemver } from "src/universal/interfaces/ISemver.sol"; import { ISemver } from "src/universal/interfaces/ISemver.sol";
import { IL1Block } from "src/L2/interfaces/IL1Block.sol";
import { Predeploys } from "src/libraries/Predeploys.sol";
import { Types } from "src/libraries/Types.sol";
/// @title OptimismMintableERC721Factory /// @title OptimismMintableERC721Factory
/// @notice Factory contract for creating OptimismMintableERC721 contracts. /// @notice Factory contract for creating OptimismMintableERC721 contracts.
/// This contract could in theory live on both L1 and L2 but it is not widely
/// used and is therefore set up to work on L2. This could be abstracted in the
/// future to be deployable on L1 as well.
contract OptimismMintableERC721Factory is ISemver { contract OptimismMintableERC721Factory is ISemver {
/// @custom:legacy true
/// @notice Address of the ERC721 bridge on this network.
address public immutable BRIDGE;
/// @custom:legacy true
/// @notice Chain ID for the remote network.
uint256 public immutable REMOTE_CHAIN_ID;
/// @notice Tracks addresses created by this factory. /// @notice Tracks addresses created by this factory.
mapping(address => bool) public isOptimismMintableERC721; mapping(address => bool) public isOptimismMintableERC721;
...@@ -24,34 +25,27 @@ contract OptimismMintableERC721Factory is ISemver { ...@@ -24,34 +25,27 @@ contract OptimismMintableERC721Factory is ISemver {
event OptimismMintableERC721Created(address indexed localToken, address indexed remoteToken, address deployer); event OptimismMintableERC721Created(address indexed localToken, address indexed remoteToken, address deployer);
/// @notice Semantic version. /// @notice Semantic version.
/// The semver MUST be bumped any time that there is a change in
/// the OptimismMintableERC721 token contract since this contract
/// is responsible for deploying OptimismMintableERC721 contracts.
/// @custom:semver 1.4.1-beta.4 /// @custom:semver 1.4.1-beta.4
string public constant version = "1.4.1-beta.4"; string public constant version = "1.4.1-beta.4";
/// @notice Returns the remote chain id /// @notice The semver MUST be bumped any time that there is a change in
function REMOTE_CHAIN_ID() external view returns (uint256) { /// the OptimismMintableERC721 token contract since this contract
return remoteChainId(); /// is responsible for deploying OptimismMintableERC721 contracts.
} /// @param _bridge Address of the ERC721 bridge on this network.
/// @param _remoteChainId Chain ID for the remote network.
/// @notice Getter function for the remote chain id. constructor(address _bridge, uint256 _remoteChainId) {
function remoteChainId() public view returns (uint256) { BRIDGE = _bridge;
bytes memory data = IL1Block(Predeploys.L1_BLOCK_ATTRIBUTES).getConfig(Types.ConfigType.REMOTE_CHAIN_ID); REMOTE_CHAIN_ID = _remoteChainId;
return abi.decode(data, (uint256));
} }
/// @notice Getter function for the bridge contract. /// @notice Address of the ERC721 bridge on this network.
/// Public getter is legacy and will be removed in the future. Use `bridge()` instead. function bridge() external view returns (address) {
/// @return Bridge contract on this domain. return BRIDGE;
/// @custom:legacy
function BRIDGE() external pure returns (IL2ERC721Bridge) {
return bridge();
} }
/// @notice Returns the ERC721 bridge contract. /// @notice Chain ID for the remote network.
function bridge() public pure returns (IL2ERC721Bridge) { function remoteChainID() external view returns (uint256) {
return IL2ERC721Bridge(Predeploys.L2_ERC721_BRIDGE); return REMOTE_CHAIN_ID;
} }
/// @notice Creates an instance of the standard ERC721. /// @notice Creates an instance of the standard ERC721.
...@@ -70,7 +64,7 @@ contract OptimismMintableERC721Factory is ISemver { ...@@ -70,7 +64,7 @@ contract OptimismMintableERC721Factory is ISemver {
bytes32 salt = keccak256(abi.encode(_remoteToken, _name, _symbol)); bytes32 salt = keccak256(abi.encode(_remoteToken, _name, _symbol));
address localToken = address localToken =
address(new OptimismMintableERC721{ salt: salt }(bridge(), remoteChainId(), _remoteToken, _name, _symbol)); address(new OptimismMintableERC721{ salt: salt }(BRIDGE, REMOTE_CHAIN_ID, _remoteToken, _name, _symbol));
isOptimismMintableERC721[localToken] = true; isOptimismMintableERC721[localToken] = true;
emit OptimismMintableERC721Created(localToken, _remoteToken, msg.sender); emit OptimismMintableERC721Created(localToken, _remoteToken, msg.sender);
......
...@@ -9,8 +9,8 @@ import { SafeCall } from "src/libraries/SafeCall.sol"; ...@@ -9,8 +9,8 @@ import { SafeCall } from "src/libraries/SafeCall.sol";
import { IOptimismMintableERC20 } from "src/universal/interfaces/IOptimismMintableERC20.sol"; import { IOptimismMintableERC20 } from "src/universal/interfaces/IOptimismMintableERC20.sol";
import { ILegacyMintableERC20 } from "src/universal/interfaces/ILegacyMintableERC20.sol"; import { ILegacyMintableERC20 } from "src/universal/interfaces/ILegacyMintableERC20.sol";
import { ICrossDomainMessenger } from "src/universal/interfaces/ICrossDomainMessenger.sol"; import { ICrossDomainMessenger } from "src/universal/interfaces/ICrossDomainMessenger.sol";
import { IStandardBridge } from "src/universal/interfaces/IStandardBridge.sol";
import { OptimismMintableERC20 } from "src/universal/OptimismMintableERC20.sol"; import { OptimismMintableERC20 } from "src/universal/OptimismMintableERC20.sol";
import { Initializable } from "@openzeppelin/contracts/proxy/utils/Initializable.sol";
import { Constants } from "src/libraries/Constants.sol"; import { Constants } from "src/libraries/Constants.sol";
/// @custom:upgradeable /// @custom:upgradeable
...@@ -18,16 +18,16 @@ import { Constants } from "src/libraries/Constants.sol"; ...@@ -18,16 +18,16 @@ import { Constants } from "src/libraries/Constants.sol";
/// @notice StandardBridge is a base contract for the L1 and L2 standard ERC20 bridges. It handles /// @notice StandardBridge is a base contract for the L1 and L2 standard ERC20 bridges. It handles
/// the core bridging logic, including escrowing tokens that are native to the local chain /// the core bridging logic, including escrowing tokens that are native to the local chain
/// and minting/burning tokens that are native to the remote chain. /// and minting/burning tokens that are native to the remote chain.
abstract contract StandardBridge { abstract contract StandardBridge is Initializable {
using SafeERC20 for IERC20; using SafeERC20 for IERC20;
/// @notice The L2 gas limit set when eth is depoisited using the receive() function. /// @notice The L2 gas limit set when eth is depoisited using the receive() function.
uint32 internal constant RECEIVE_DEFAULT_GAS_LIMIT = 200_000; uint32 internal constant RECEIVE_DEFAULT_GAS_LIMIT = 200_000;
/// @custom:legacy /// @custom:legacy
/// @custom:spacer messenger + initializable /// @custom:spacer messenger
/// @notice Spacer for backwards compatibility. /// @notice Spacer for backwards compatibility.
bytes32 private spacer_0_0_32; bytes30 private spacer_0_2_30;
/// @custom:legacy /// @custom:legacy
/// @custom:spacer l2TokenBridge /// @custom:spacer l2TokenBridge
...@@ -37,20 +37,18 @@ abstract contract StandardBridge { ...@@ -37,20 +37,18 @@ abstract contract StandardBridge {
/// @notice Mapping that stores deposits for a given pair of local and remote tokens. /// @notice Mapping that stores deposits for a given pair of local and remote tokens.
mapping(address => mapping(address => uint256)) public deposits; mapping(address => mapping(address => uint256)) public deposits;
/// @custom:legacy /// @notice Messenger contract on this domain.
/// @custom:spacer messenger /// @custom:network-specific
/// @notice Spacer for backwards compatibility. ICrossDomainMessenger public messenger;
address private spacer_3_0_20;
/// @custom:legacy /// @notice Corresponding bridge on the other domain.
/// @custom:spacer otherBridge /// @custom:network-specific
/// @notice Spacer for backwards compatibility. StandardBridge public otherBridge;
address private spacer_4_0_20;
/// @notice Reserve extra slots (to a total of 50) in the storage layout for future upgrades. /// @notice Reserve extra slots (to a total of 50) in the storage layout for future upgrades.
/// The gap size was previously 45, but is now 44, allowing for the initializer slot to be /// A gap size of 45 was chosen here, so that the first slot used in a child contract
/// included in the L1StandardBridge contract without breaking its storage layout. /// would be a multiple of 50.
uint256[44] private __gap; uint256[45] private __gap;
/// @notice Emitted when an ETH bridge is initiated to the other chain. /// @notice Emitted when an ETH bridge is initiated to the other chain.
/// @param from Address of the sender. /// @param from Address of the sender.
...@@ -108,15 +106,27 @@ abstract contract StandardBridge { ...@@ -108,15 +106,27 @@ abstract contract StandardBridge {
/// @notice Ensures that the caller is a cross-chain message from the other bridge. /// @notice Ensures that the caller is a cross-chain message from the other bridge.
modifier onlyOtherBridge() { modifier onlyOtherBridge() {
ICrossDomainMessenger crossDomainMessenger = messenger();
require( require(
msg.sender == address(crossDomainMessenger) msg.sender == address(messenger) && messenger.xDomainMessageSender() == address(otherBridge),
&& crossDomainMessenger.xDomainMessageSender() == address(otherBridge()),
"StandardBridge: function can only be called from the other bridge" "StandardBridge: function can only be called from the other bridge"
); );
_; _;
} }
/// @notice Initializer.
/// @param _messenger Contract for CrossDomainMessenger on this network.
/// @param _otherBridge Contract for the other StandardBridge contract.
function __StandardBridge_init(
ICrossDomainMessenger _messenger,
StandardBridge _otherBridge
)
internal
onlyInitializing
{
messenger = _messenger;
otherBridge = _otherBridge;
}
/// @notice Allows EOAs to bridge ETH by sending directly to the bridge. /// @notice Allows EOAs to bridge ETH by sending directly to the bridge.
/// Must be implemented by contracts that inherit. /// Must be implemented by contracts that inherit.
receive() external payable virtual; receive() external payable virtual;
...@@ -130,28 +140,20 @@ abstract contract StandardBridge { ...@@ -130,28 +140,20 @@ abstract contract StandardBridge {
return token != Constants.ETHER; return token != Constants.ETHER;
} }
/// @notice Returns the contract of the CrossDomainMessenger on this chain.
/// @return Contract of the CrossDomainMessenger on this chain.
function messenger() public view virtual returns (ICrossDomainMessenger);
/// @notice Getter for messenger contract. /// @notice Getter for messenger contract.
/// Public getter is legacy and will be removed in the future. Use `messenger` instead. /// Public getter is legacy and will be removed in the future. Use `messenger` instead.
/// @return Contract of the messenger on this domain. /// @return Contract of the messenger on this domain.
/// @custom:legacy /// @custom:legacy
function MESSENGER() external view returns (ICrossDomainMessenger) { function MESSENGER() external view returns (ICrossDomainMessenger) {
return messenger(); return messenger;
} }
/// @notice Returns the contract of the bridge on the other chain.
/// @return Contract of the bridge on the other chain.
function otherBridge() public view virtual returns (IStandardBridge);
/// @notice Getter for the other bridge contract. /// @notice Getter for the other bridge contract.
/// Public getter is legacy and will be removed in the future. Use `otherBridge` instead. /// Public getter is legacy and will be removed in the future. Use `otherBridge` instead.
/// @return Contract of the bridge on the other network. /// @return Contract of the bridge on the other network.
/// @custom:legacy /// @custom:legacy
function OTHER_BRIDGE() external view returns (IStandardBridge) { function OTHER_BRIDGE() external view returns (StandardBridge) {
return otherBridge(); return otherBridge;
} }
/// @notice This function should return true if the contract is paused. /// @notice This function should return true if the contract is paused.
...@@ -254,7 +256,7 @@ abstract contract StandardBridge { ...@@ -254,7 +256,7 @@ abstract contract StandardBridge {
require(isCustomGasToken() == false, "StandardBridge: cannot bridge ETH with custom gas token"); require(isCustomGasToken() == false, "StandardBridge: cannot bridge ETH with custom gas token");
require(msg.value == _amount, "StandardBridge: amount sent does not match amount required"); require(msg.value == _amount, "StandardBridge: amount sent does not match amount required");
require(_to != address(this), "StandardBridge: cannot send to self"); require(_to != address(this), "StandardBridge: cannot send to self");
require(_to != address(messenger()), "StandardBridge: cannot send to messenger"); require(_to != address(messenger), "StandardBridge: cannot send to messenger");
// Emit the correct events. By default this will be _amount, but child // Emit the correct events. By default this will be _amount, but child
// contracts may override this function in order to emit legacy events as well. // contracts may override this function in order to emit legacy events as well.
...@@ -327,8 +329,8 @@ abstract contract StandardBridge { ...@@ -327,8 +329,8 @@ abstract contract StandardBridge {
// contracts may override this function in order to emit legacy events as well. // contracts may override this function in order to emit legacy events as well.
_emitETHBridgeInitiated(_from, _to, _amount, _extraData); _emitETHBridgeInitiated(_from, _to, _amount, _extraData);
messenger().sendMessage{ value: _amount }({ messenger.sendMessage{ value: _amount }({
_target: address(otherBridge()), _target: address(otherBridge),
_message: abi.encodeWithSelector(this.finalizeBridgeETH.selector, _from, _to, _amount, _extraData), _message: abi.encodeWithSelector(this.finalizeBridgeETH.selector, _from, _to, _amount, _extraData),
_minGasLimit: _minGasLimit _minGasLimit: _minGasLimit
}); });
...@@ -372,8 +374,8 @@ abstract contract StandardBridge { ...@@ -372,8 +374,8 @@ abstract contract StandardBridge {
// contracts may override this function in order to emit legacy events as well. // contracts may override this function in order to emit legacy events as well.
_emitERC20BridgeInitiated(_localToken, _remoteToken, _from, _to, _amount, _extraData); _emitERC20BridgeInitiated(_localToken, _remoteToken, _from, _to, _amount, _extraData);
messenger().sendMessage({ messenger.sendMessage({
_target: address(otherBridge()), _target: address(otherBridge),
_message: abi.encodeWithSelector( _message: abi.encodeWithSelector(
this.finalizeBridgeERC20.selector, this.finalizeBridgeERC20.selector,
// Because this call will be executed on the remote chain, we reverse the order of // Because this call will be executed on the remote chain, we reverse the order of
......
...@@ -3,6 +3,7 @@ pragma solidity ^0.8.0; ...@@ -3,6 +3,7 @@ pragma solidity ^0.8.0;
interface ICrossDomainMessenger { interface ICrossDomainMessenger {
event FailedRelayedMessage(bytes32 indexed msgHash); event FailedRelayedMessage(bytes32 indexed msgHash);
event Initialized(uint8 version);
event RelayedMessage(bytes32 indexed msgHash); event RelayedMessage(bytes32 indexed msgHash);
event SentMessage(address indexed target, address sender, bytes message, uint256 messageNonce, uint256 gasLimit); event SentMessage(address indexed target, address sender, bytes message, uint256 messageNonce, uint256 gasLimit);
event SentMessageExtension1(address indexed sender, uint256 value); event SentMessageExtension1(address indexed sender, uint256 value);
...@@ -12,7 +13,6 @@ interface ICrossDomainMessenger { ...@@ -12,7 +13,6 @@ interface ICrossDomainMessenger {
function MIN_GAS_DYNAMIC_OVERHEAD_DENOMINATOR() external view returns (uint64); function MIN_GAS_DYNAMIC_OVERHEAD_DENOMINATOR() external view returns (uint64);
function MIN_GAS_DYNAMIC_OVERHEAD_NUMERATOR() external view returns (uint64); function MIN_GAS_DYNAMIC_OVERHEAD_NUMERATOR() external view returns (uint64);
function OTHER_MESSENGER() external view returns (ICrossDomainMessenger); function OTHER_MESSENGER() external view returns (ICrossDomainMessenger);
function otherMessenger() external view returns (ICrossDomainMessenger);
function RELAY_CALL_OVERHEAD() external view returns (uint64); function RELAY_CALL_OVERHEAD() external view returns (uint64);
function RELAY_CONSTANT_OVERHEAD() external view returns (uint64); function RELAY_CONSTANT_OVERHEAD() external view returns (uint64);
function RELAY_GAS_CHECK_BUFFER() external view returns (uint64); function RELAY_GAS_CHECK_BUFFER() external view returns (uint64);
...@@ -20,6 +20,7 @@ interface ICrossDomainMessenger { ...@@ -20,6 +20,7 @@ interface ICrossDomainMessenger {
function baseGas(bytes memory _message, uint32 _minGasLimit) external pure returns (uint64); function baseGas(bytes memory _message, uint32 _minGasLimit) external pure returns (uint64);
function failedMessages(bytes32) external view returns (bool); function failedMessages(bytes32) external view returns (bool);
function messageNonce() external view returns (uint256); function messageNonce() external view returns (uint256);
function otherMessenger() external view returns (ICrossDomainMessenger);
function paused() external view returns (bool); function paused() external view returns (bool);
function relayMessage( function relayMessage(
uint256 _nonce, uint256 _nonce,
......
...@@ -20,6 +20,7 @@ interface IERC721Bridge { ...@@ -20,6 +20,7 @@ interface IERC721Bridge {
uint256 tokenId, uint256 tokenId,
bytes extraData bytes extraData
); );
event Initialized(uint8 version);
function MESSENGER() external view returns (ICrossDomainMessenger); function MESSENGER() external view returns (ICrossDomainMessenger);
function OTHER_BRIDGE() external view returns (IERC721Bridge); function OTHER_BRIDGE() external view returns (IERC721Bridge);
......
...@@ -2,6 +2,7 @@ ...@@ -2,6 +2,7 @@
pragma solidity ^0.8.0; pragma solidity ^0.8.0;
interface IOptimismMintableERC20Factory { interface IOptimismMintableERC20Factory {
event Initialized(uint8 version);
event OptimismMintableERC20Created(address indexed localToken, address indexed remoteToken, address deployer); event OptimismMintableERC20Created(address indexed localToken, address indexed remoteToken, address deployer);
event StandardL2TokenCreated(address indexed remoteToken, address indexed localToken); event StandardL2TokenCreated(address indexed remoteToken, address indexed localToken);
...@@ -30,6 +31,7 @@ interface IOptimismMintableERC20Factory { ...@@ -30,6 +31,7 @@ interface IOptimismMintableERC20Factory {
external external
returns (address); returns (address);
function deployments(address) external view returns (address); function deployments(address) external view returns (address);
function initialize(address _bridge) external;
function version() external view returns (string memory); function version() external view returns (string memory);
function __constructor__() external; function __constructor__() external;
......
// SPDX-License-Identifier: MIT // SPDX-License-Identifier: MIT
pragma solidity ^0.8.0; pragma solidity ^0.8.0;
import { IL2ERC721Bridge } from "src/L2/interfaces/IL2ERC721Bridge.sol";
/// @title IOptimismMintableERC721 /// @title IOptimismMintableERC721
/// @notice Interface for contracts that are compatible with the OptimismMintableERC721 standard. /// @notice Interface for contracts that are compatible with the OptimismMintableERC721 standard.
/// Tokens that follow this standard can be easily transferred across the ERC721 bridge. /// Tokens that follow this standard can be easily transferred across the ERC721 bridge.
interface IOptimismMintableERC721 { interface IOptimismMintableERC721 {
function __constructor__( function __constructor__(
IL2ERC721Bridge _bridge, address _bridge,
uint256 _remoteChainId, uint256 _remoteChainId,
address _remoteToken, address _remoteToken,
string memory _name, string memory _name,
...@@ -66,13 +64,11 @@ interface IOptimismMintableERC721 { ...@@ -66,13 +64,11 @@ interface IOptimismMintableERC721 {
function REMOTE_TOKEN() external view returns (address); function REMOTE_TOKEN() external view returns (address);
/// @notice Address of the ERC721 bridge on this network. function BRIDGE() external view returns (address);
function BRIDGE() external view returns (IL2ERC721Bridge);
function remoteChainId() external view returns (uint256); function remoteChainId() external view returns (uint256);
function remoteToken() external view returns (address); function remoteToken() external view returns (address);
/// @notice Address of the ERC721 bridge on this network. function bridge() external view returns (address);
function bridge() external view returns (IL2ERC721Bridge);
} }
// SPDX-License-Identifier: MIT // SPDX-License-Identifier: MIT
pragma solidity ^0.8.0; pragma solidity ^0.8.0;
import { IL2ERC721Bridge } from "src/L2/interfaces/IL2ERC721Bridge.sol";
interface IOptimismMintableERC721Factory { interface IOptimismMintableERC721Factory {
event OptimismMintableERC721Created(address indexed localToken, address indexed remoteToken, address deployer); event OptimismMintableERC721Created(address indexed localToken, address indexed remoteToken, address deployer);
function BRIDGE() external pure returns (IL2ERC721Bridge); function BRIDGE() external view returns (address);
function bridge() external pure returns (IL2ERC721Bridge); function REMOTE_CHAIN_ID() external view returns (uint256);
function bridge() external view returns (address);
function createOptimismMintableERC721( function createOptimismMintableERC721(
address _remoteToken, address _remoteToken,
string memory _name, string memory _name,
...@@ -16,9 +15,8 @@ interface IOptimismMintableERC721Factory { ...@@ -16,9 +15,8 @@ interface IOptimismMintableERC721Factory {
external external
returns (address); returns (address);
function isOptimismMintableERC721(address) external view returns (bool); function isOptimismMintableERC721(address) external view returns (bool);
function REMOTE_CHAIN_ID() external view returns (uint256); function remoteChainID() external view returns (uint256);
function remoteChainId() external view returns (uint256);
function version() external view returns (string memory); function version() external view returns (string memory);
function __constructor__() external; function __constructor__(address _bridge, uint256 _remoteChainId) external;
} }
...@@ -22,10 +22,12 @@ interface IStandardBridge { ...@@ -22,10 +22,12 @@ interface IStandardBridge {
); );
event ETHBridgeFinalized(address indexed from, address indexed to, uint256 amount, bytes extraData); event ETHBridgeFinalized(address indexed from, address indexed to, uint256 amount, bytes extraData);
event ETHBridgeInitiated(address indexed from, address indexed to, uint256 amount, bytes extraData); event ETHBridgeInitiated(address indexed from, address indexed to, uint256 amount, bytes extraData);
event Initialized(uint8 version);
receive() external payable; receive() external payable;
function MESSENGER() external view returns (ICrossDomainMessenger); function MESSENGER() external view returns (ICrossDomainMessenger);
function OTHER_BRIDGE() external view returns (IStandardBridge);
function bridgeERC20( function bridgeERC20(
address _localToken, address _localToken,
address _remoteToken, address _remoteToken,
...@@ -58,7 +60,6 @@ interface IStandardBridge { ...@@ -58,7 +60,6 @@ interface IStandardBridge {
function finalizeBridgeETH(address _from, address _to, uint256 _amount, bytes memory _extraData) external payable; function finalizeBridgeETH(address _from, address _to, uint256 _amount, bytes memory _extraData) external payable;
function messenger() external view returns (ICrossDomainMessenger); function messenger() external view returns (ICrossDomainMessenger);
function otherBridge() external view returns (IStandardBridge); function otherBridge() external view returns (IStandardBridge);
function OTHER_BRIDGE() external view returns (IStandardBridge);
function paused() external view returns (bool); function paused() external view returns (bool);
function __constructor__() external; function __constructor__() external;
......
...@@ -70,8 +70,7 @@ contract OPContractsManager_Deploy_Test is DeployOPChain_TestBase { ...@@ -70,8 +70,7 @@ contract OPContractsManager_Deploy_Test is DeployOPChain_TestBase {
batcher: _doi.batcher(), batcher: _doi.batcher(),
unsafeBlockSigner: _doi.unsafeBlockSigner(), unsafeBlockSigner: _doi.unsafeBlockSigner(),
proposer: _doi.proposer(), proposer: _doi.proposer(),
challenger: _doi.challenger(), challenger: _doi.challenger()
systemConfigFeeAdmin: msg.sender
}), }),
basefeeScalar: _doi.basefeeScalar(), basefeeScalar: _doi.basefeeScalar(),
blobBasefeeScalar: _doi.blobBaseFeeScalar(), blobBasefeeScalar: _doi.blobBaseFeeScalar(),
......
...@@ -19,7 +19,6 @@ import { Constants } from "src/libraries/Constants.sol"; ...@@ -19,7 +19,6 @@ import { Constants } from "src/libraries/Constants.sol";
import { Predeploys } from "src/libraries/Predeploys.sol"; import { Predeploys } from "src/libraries/Predeploys.sol";
import { GasPayingToken } from "src/libraries/GasPayingToken.sol"; import { GasPayingToken } from "src/libraries/GasPayingToken.sol";
import { AddressAliasHelper } from "src/vendor/AddressAliasHelper.sol"; import { AddressAliasHelper } from "src/vendor/AddressAliasHelper.sol";
import { StaticConfig } from "src/libraries/StaticConfig.sol";
import "src/libraries/PortalErrors.sol"; import "src/libraries/PortalErrors.sol";
// Interfaces // Interfaces
...@@ -68,7 +67,6 @@ contract OptimismPortal_Test is CommonTest { ...@@ -68,7 +67,6 @@ contract OptimismPortal_Test is CommonTest {
assertEq(optimismPortal.paused(), false); assertEq(optimismPortal.paused(), false);
(uint128 prevBaseFee, uint64 prevBoughtGas, uint64 prevBlockNum) = optimismPortal.params(); (uint128 prevBaseFee, uint64 prevBoughtGas, uint64 prevBlockNum) = optimismPortal.params();
assertEq(prevBaseFee, 1 gwei); assertEq(prevBaseFee, 1 gwei);
// someplace upstream there is a deposit tx
assertEq(prevBoughtGas, 0); assertEq(prevBoughtGas, 0);
assertEq(prevBlockNum, uint64(block.number)); assertEq(prevBlockNum, uint64(block.number));
} }
...@@ -459,7 +457,6 @@ contract OptimismPortal_Test is CommonTest { ...@@ -459,7 +457,6 @@ contract OptimismPortal_Test is CommonTest {
) )
external external
{ {
bytes memory data = StaticConfig.encodeSetGasPayingToken(_token, _decimals, _name, _symbol);
vm.expectEmit(address(optimismPortal)); vm.expectEmit(address(optimismPortal));
emit TransactionDeposited( emit TransactionDeposited(
0xDeaDDEaDDeAdDeAdDEAdDEaddeAddEAdDEAd0001, 0xDeaDDEaDDeAdDeAdDEAdDEaddeAddEAdDEAd0001,
...@@ -470,12 +467,12 @@ contract OptimismPortal_Test is CommonTest { ...@@ -470,12 +467,12 @@ contract OptimismPortal_Test is CommonTest {
uint256(0), // value uint256(0), // value
uint64(200_000), // gasLimit uint64(200_000), // gasLimit
false, // isCreation, false, // isCreation,
abi.encodeCall(IL1Block.setConfig, (Types.ConfigType.GAS_PAYING_TOKEN, data)) abi.encodeCall(IL1Block.setGasPayingToken, (_token, _decimals, _name, _symbol))
) )
); );
vm.prank(address(systemConfig)); vm.prank(address(systemConfig));
optimismPortal.setConfig(Types.ConfigType.GAS_PAYING_TOKEN, data); optimismPortal.setGasPayingToken({ _token: _token, _decimals: _decimals, _name: _name, _symbol: _symbol });
} }
/// @notice Ensures that the deposit event is correct for the `setGasPayingToken` /// @notice Ensures that the deposit event is correct for the `setGasPayingToken`
...@@ -494,13 +491,10 @@ contract OptimismPortal_Test is CommonTest { ...@@ -494,13 +491,10 @@ contract OptimismPortal_Test is CommonTest {
bytes32 name = GasPayingToken.sanitize(_name); bytes32 name = GasPayingToken.sanitize(_name);
bytes32 symbol = GasPayingToken.sanitize(_symbol); bytes32 symbol = GasPayingToken.sanitize(_symbol);
bytes memory data =
StaticConfig.encodeSetGasPayingToken({ _token: _token, _decimals: 18, _name: name, _symbol: symbol });
vm.recordLogs(); vm.recordLogs();
vm.prank(address(systemConfig)); vm.prank(address(systemConfig));
optimismPortal.setConfig(Types.ConfigType.GAS_PAYING_TOKEN, data); optimismPortal.setGasPayingToken({ _token: _token, _decimals: 18, _name: name, _symbol: symbol });
vm.prank(Constants.DEPOSITOR_ACCOUNT, Constants.DEPOSITOR_ACCOUNT); vm.prank(Constants.DEPOSITOR_ACCOUNT, Constants.DEPOSITOR_ACCOUNT);
optimismPortal.depositTransaction({ optimismPortal.depositTransaction({
...@@ -508,7 +502,7 @@ contract OptimismPortal_Test is CommonTest { ...@@ -508,7 +502,7 @@ contract OptimismPortal_Test is CommonTest {
_value: 0, _value: 0,
_gasLimit: 200_000, _gasLimit: 200_000,
_isCreation: false, _isCreation: false,
_data: abi.encodeCall(IL1Block.setConfig, (Types.ConfigType.GAS_PAYING_TOKEN, data)) _data: abi.encodeCall(IL1Block.setGasPayingToken, (_token, 18, name, symbol))
}); });
VmSafe.Log[] memory logs = vm.getRecordedLogs(); VmSafe.Log[] memory logs = vm.getRecordedLogs();
...@@ -531,7 +525,7 @@ contract OptimismPortal_Test is CommonTest { ...@@ -531,7 +525,7 @@ contract OptimismPortal_Test is CommonTest {
vm.assume(_caller != address(systemConfig)); vm.assume(_caller != address(systemConfig));
vm.prank(_caller); vm.prank(_caller);
vm.expectRevert(Unauthorized.selector); vm.expectRevert(Unauthorized.selector);
optimismPortal.setConfig(Types.ConfigType.GAS_PAYING_TOKEN, hex""); optimismPortal.setGasPayingToken({ _token: address(0), _decimals: 0, _name: "", _symbol: "" });
} }
/// @dev Tests that `depositERC20Transaction` reverts when the gas paying token is ether. /// @dev Tests that `depositERC20Transaction` reverts when the gas paying token is ether.
......
...@@ -19,7 +19,6 @@ import { Constants } from "src/libraries/Constants.sol"; ...@@ -19,7 +19,6 @@ import { Constants } from "src/libraries/Constants.sol";
import { Predeploys } from "src/libraries/Predeploys.sol"; import { Predeploys } from "src/libraries/Predeploys.sol";
import { GasPayingToken } from "src/libraries/GasPayingToken.sol"; import { GasPayingToken } from "src/libraries/GasPayingToken.sol";
import { AddressAliasHelper } from "src/vendor/AddressAliasHelper.sol"; import { AddressAliasHelper } from "src/vendor/AddressAliasHelper.sol";
import { StaticConfig } from "src/libraries/StaticConfig.sol";
import "src/dispute/lib/Types.sol"; import "src/dispute/lib/Types.sol";
import "src/libraries/PortalErrors.sol"; import "src/libraries/PortalErrors.sol";
...@@ -309,13 +308,6 @@ contract OptimismPortal2_Test is CommonTest { ...@@ -309,13 +308,6 @@ contract OptimismPortal2_Test is CommonTest {
) )
external external
{ {
bytes memory data = StaticConfig.encodeSetGasPayingToken({
_token: _token,
_decimals: _decimals,
_name: _name,
_symbol: _symbol
});
vm.expectEmit(address(optimismPortal2)); vm.expectEmit(address(optimismPortal2));
emit TransactionDeposited( emit TransactionDeposited(
0xDeaDDEaDDeAdDeAdDEAdDEaddeAddEAdDEAd0001, 0xDeaDDEaDDeAdDeAdDEAdDEaddeAddEAdDEAd0001,
...@@ -326,12 +318,12 @@ contract OptimismPortal2_Test is CommonTest { ...@@ -326,12 +318,12 @@ contract OptimismPortal2_Test is CommonTest {
uint256(0), // value uint256(0), // value
uint64(200_000), // gasLimit uint64(200_000), // gasLimit
false, // isCreation, false, // isCreation,
abi.encodeCall(IL1Block.setConfig, (Types.ConfigType.GAS_PAYING_TOKEN, data)) abi.encodeCall(IL1Block.setGasPayingToken, (_token, _decimals, _name, _symbol))
) )
); );
vm.prank(address(systemConfig)); vm.prank(address(systemConfig));
optimismPortal2.setConfig(Types.ConfigType.GAS_PAYING_TOKEN, data); optimismPortal2.setGasPayingToken({ _token: _token, _decimals: _decimals, _name: _name, _symbol: _symbol });
} }
/// @notice Ensures that the deposit event is correct for the `setGasPayingToken` /// @notice Ensures that the deposit event is correct for the `setGasPayingToken`
...@@ -350,12 +342,10 @@ contract OptimismPortal2_Test is CommonTest { ...@@ -350,12 +342,10 @@ contract OptimismPortal2_Test is CommonTest {
bytes32 name = GasPayingToken.sanitize(_name); bytes32 name = GasPayingToken.sanitize(_name);
bytes32 symbol = GasPayingToken.sanitize(_symbol); bytes32 symbol = GasPayingToken.sanitize(_symbol);
bytes memory data = StaticConfig.encodeSetGasPayingToken(_token, 18, name, symbol);
vm.recordLogs(); vm.recordLogs();
vm.prank(address(systemConfig)); vm.prank(address(systemConfig));
optimismPortal2.setConfig(Types.ConfigType.GAS_PAYING_TOKEN, data); optimismPortal2.setGasPayingToken({ _token: _token, _decimals: 18, _name: name, _symbol: symbol });
vm.prank(Constants.DEPOSITOR_ACCOUNT, Constants.DEPOSITOR_ACCOUNT); vm.prank(Constants.DEPOSITOR_ACCOUNT, Constants.DEPOSITOR_ACCOUNT);
optimismPortal2.depositTransaction({ optimismPortal2.depositTransaction({
...@@ -363,70 +353,7 @@ contract OptimismPortal2_Test is CommonTest { ...@@ -363,70 +353,7 @@ contract OptimismPortal2_Test is CommonTest {
_value: 0, _value: 0,
_gasLimit: 200_000, _gasLimit: 200_000,
_isCreation: false, _isCreation: false,
_data: abi.encodeCall(IL1Block.setConfig, (Types.ConfigType.GAS_PAYING_TOKEN, data)) _data: abi.encodeCall(IL1Block.setGasPayingToken, (_token, 18, name, symbol))
});
VmSafe.Log[] memory logs = vm.getRecordedLogs();
assertEq(logs.length, 2);
VmSafe.Log memory systemPath = logs[0];
VmSafe.Log memory userPath = logs[1];
assertEq(systemPath.topics.length, 4);
assertEq(systemPath.topics.length, userPath.topics.length);
assertEq(systemPath.topics[0], userPath.topics[0]);
assertEq(systemPath.topics[1], userPath.topics[1]);
assertEq(systemPath.topics[2], userPath.topics[2]);
assertEq(systemPath.topics[3], userPath.topics[3]);
assertEq(systemPath.data, userPath.data);
}
/// @dev Tests that the upgrade function succeeds.
function testFuzz_upgrade_succeeds(uint32 _gasLimit, bytes memory _calldata) external {
address upgrader = superchainConfig.upgrader();
vm.expectEmit(address(optimismPortal2));
emit TransactionDeposited(
0xDeaDDEaDDeAdDeAdDEAdDEaddeAddEAdDEAd0001,
Predeploys.PROXY_ADMIN,
0,
abi.encodePacked(
uint256(0), // mint
uint256(0), // value
uint64(_gasLimit), // gasLimit
false, // isCreation,
_calldata
)
);
vm.prank(upgrader);
optimismPortal2.upgrade(_gasLimit, _calldata);
}
/// @notice Ensures that the deposit event is correct for the `setGasPayingToken`
/// code path that manually emits a deposit transaction outside of the
/// `depositTransaction` function. This is a simple differential test.
function test_upgrade_correctEvent_succeeds(uint32 _gasLimit, bytes memory _calldata) external {
vm.assume(_calldata.length <= 120_000);
IResourceMetering.ResourceConfig memory rcfg = systemConfig.resourceConfig();
_gasLimit =
uint32(bound(_gasLimit, optimismPortal2.minimumGasLimit(uint32(_calldata.length)), rcfg.maxResourceLimit));
vm.recordLogs();
vm.prank(superchainConfig.upgrader());
optimismPortal2.upgrade(_gasLimit, _calldata);
// Advance the block to ensure that the deposit transaction is processed in the next block, so that we
// aren't limited by the resource limit consumed by the previous call.
vm.roll(block.number + 1);
vm.prank(Constants.DEPOSITOR_ACCOUNT, Constants.DEPOSITOR_ACCOUNT);
optimismPortal2.depositTransaction({
_to: Predeploys.PROXY_ADMIN,
_value: 0,
_gasLimit: uint64(_gasLimit),
_isCreation: false,
_data: _calldata
}); });
VmSafe.Log[] memory logs = vm.getRecordedLogs(); VmSafe.Log[] memory logs = vm.getRecordedLogs();
...@@ -444,41 +371,12 @@ contract OptimismPortal2_Test is CommonTest { ...@@ -444,41 +371,12 @@ contract OptimismPortal2_Test is CommonTest {
assertEq(systemPath.data, userPath.data); assertEq(systemPath.data, userPath.data);
} }
/// @dev Tests that any config type can be set by the system config. /// @dev Tests that the gas paying token cannot be set by a non-system config.
function testFuzz_setConfig_succeeds(uint8 _configType, bytes calldata _value) public { function test_setGasPayingToken_notSystemConfig_fails(address _caller) external {
// Ensure that _configType is within the range of the ConfigType enum
_configType = uint8(bound(uint256(_configType), 0, uint256(type(Types.ConfigType).max)));
vm.expectEmit(address(optimismPortal2));
emitTransactionDeposited({
_from: Constants.DEPOSITOR_ACCOUNT,
_to: Predeploys.L1_BLOCK_ATTRIBUTES,
_value: 0,
_mint: 0,
_gasLimit: 200_000,
_isCreation: false,
_data: abi.encodeCall(IL1Block.setConfig, (Types.ConfigType(_configType), _value))
});
vm.prank(address(optimismPortal2.systemConfig()));
optimismPortal2.setConfig(Types.ConfigType(_configType), _value);
}
/// @dev Tests that the gas paying token cannot be set by a non-system config for any config type.
function testFuzz_setConfig_notSystemConfig_fails(
address _caller,
uint8 _configType,
bytes calldata _value
)
external
{
// Ensure that _configType is within the range of the ConfigType enum
_configType = uint8(bound(uint256(_configType), 0, uint256(type(Types.ConfigType).max)));
vm.assume(_caller != address(systemConfig)); vm.assume(_caller != address(systemConfig));
vm.prank(_caller); vm.prank(_caller);
vm.expectRevert(Unauthorized.selector); vm.expectRevert(Unauthorized.selector);
optimismPortal2.setConfig(Types.ConfigType(_configType), _value); optimismPortal2.setGasPayingToken({ _token: address(0), _decimals: 0, _name: "", _symbol: "" });
} }
/// @dev Tests that `depositERC20Transaction` reverts when the gas paying token is ether. /// @dev Tests that `depositERC20Transaction` reverts when the gas paying token is ether.
......
...@@ -7,13 +7,12 @@ import { CommonTest } from "test/setup/CommonTest.sol"; ...@@ -7,13 +7,12 @@ import { CommonTest } from "test/setup/CommonTest.sol";
// Libraries // Libraries
import { Constants } from "src/libraries/Constants.sol"; import { Constants } from "src/libraries/Constants.sol";
import { Predeploys } from "src/libraries/Predeploys.sol"; import { Predeploys } from "src/libraries/Predeploys.sol";
import { Types } from "src/libraries/Types.sol";
import "src/libraries/PortalErrors.sol"; import "src/libraries/PortalErrors.sol";
// Target contract dependencies // Target contract dependencies
import "src/libraries/PortalErrors.sol"; import "src/libraries/PortalErrors.sol";
import { OptimismPortalInterop } from "src/L1/OptimismPortalInterop.sol"; import { OptimismPortalInterop } from "src/L1/OptimismPortalInterop.sol";
import { L1BlockInterop } from "src/L2/L1BlockInterop.sol"; import { L1BlockInterop, ConfigType } from "src/L2/L1BlockInterop.sol";
// Interfaces // Interfaces
import { IOptimismPortalInterop } from "src/L1/interfaces/IOptimismPortalInterop.sol"; import { IOptimismPortalInterop } from "src/L1/interfaces/IOptimismPortalInterop.sol";
...@@ -26,11 +25,31 @@ contract OptimismPortalInterop_Test is CommonTest { ...@@ -26,11 +25,31 @@ contract OptimismPortalInterop_Test is CommonTest {
super.setUp(); super.setUp();
} }
/// @dev Tests that any config type can be set by the system config. /// @dev Tests that the config for the gas paying token can be set.
function testFuzz_setConfig_succeeds(uint8 _configType, bytes calldata _value) public { function testFuzz_setConfig_gasPayingToken_succeeds(bytes calldata _value) public {
// Ensure that _configType is within the range of the ConfigType enum vm.expectEmit(address(optimismPortal));
_configType = uint8(bound(uint256(_configType), 0, uint256(type(Types.ConfigType).max))); emitTransactionDeposited({
_from: Constants.DEPOSITOR_ACCOUNT,
_to: Predeploys.L1_BLOCK_ATTRIBUTES,
_value: 0,
_mint: 0,
_gasLimit: 200_000,
_isCreation: false,
_data: abi.encodeCall(L1BlockInterop.setConfig, (ConfigType.SET_GAS_PAYING_TOKEN, _value))
});
vm.prank(address(_optimismPortalInterop().systemConfig()));
_optimismPortalInterop().setConfig(ConfigType.SET_GAS_PAYING_TOKEN, _value);
}
/// @dev Tests that setting the gas paying token config as not the system config reverts.
function testFuzz_setConfig_gasPayingToken_notSystemConfig_reverts(bytes calldata _value) public {
vm.expectRevert(Unauthorized.selector);
_optimismPortalInterop().setConfig(ConfigType.SET_GAS_PAYING_TOKEN, _value);
}
/// @dev Tests that the config for adding a dependency can be set.
function testFuzz_setConfig_addDependency_succeeds(bytes calldata _value) public {
vm.expectEmit(address(optimismPortal)); vm.expectEmit(address(optimismPortal));
emitTransactionDeposited({ emitTransactionDeposited({
_from: Constants.DEPOSITOR_ACCOUNT, _from: Constants.DEPOSITOR_ACCOUNT,
...@@ -39,28 +58,40 @@ contract OptimismPortalInterop_Test is CommonTest { ...@@ -39,28 +58,40 @@ contract OptimismPortalInterop_Test is CommonTest {
_mint: 0, _mint: 0,
_gasLimit: 200_000, _gasLimit: 200_000,
_isCreation: false, _isCreation: false,
_data: abi.encodeCall(L1BlockInterop.setConfig, (Types.ConfigType(_configType), _value)) _data: abi.encodeCall(L1BlockInterop.setConfig, (ConfigType.ADD_DEPENDENCY, _value))
}); });
vm.prank(address(_optimismPortalInterop().systemConfig())); vm.prank(address(_optimismPortalInterop().systemConfig()));
_optimismPortalInterop().setConfig(Types.ConfigType(_configType), _value); _optimismPortalInterop().setConfig(ConfigType.ADD_DEPENDENCY, _value);
} }
/// @dev Tests that setting any config type as not the system config reverts. /// @dev Tests that setting the add dependency config as not the system config reverts.
function testFuzz_setConfig_notSystemConfig_reverts( function testFuzz_setConfig_addDependency_notSystemConfig_reverts(bytes calldata _value) public {
address _caller, vm.expectRevert(Unauthorized.selector);
uint8 _configType, _optimismPortalInterop().setConfig(ConfigType.ADD_DEPENDENCY, _value);
bytes calldata _value }
)
external /// @dev Tests that the config for removing a dependency can be set.
{ function testFuzz_setConfig_removeDependency_succeeds(bytes calldata _value) public {
// Ensure that _configType is within the range of the ConfigType enum vm.expectEmit(address(optimismPortal));
_configType = uint8(bound(uint256(_configType), 0, uint256(type(Types.ConfigType).max))); emitTransactionDeposited({
_from: Constants.DEPOSITOR_ACCOUNT,
_to: Predeploys.L1_BLOCK_ATTRIBUTES,
_value: 0,
_mint: 0,
_gasLimit: 200_000,
_isCreation: false,
_data: abi.encodeCall(L1BlockInterop.setConfig, (ConfigType.REMOVE_DEPENDENCY, _value))
});
vm.prank(address(_optimismPortalInterop().systemConfig()));
_optimismPortalInterop().setConfig(ConfigType.REMOVE_DEPENDENCY, _value);
}
vm.assume(_caller != address(_optimismPortalInterop().systemConfig())); /// @dev Tests that setting the remove dependency config as not the system config reverts.
vm.prank(_caller); function testFuzz_setConfig_removeDependency_notSystemConfig_reverts(bytes calldata _value) public {
vm.expectRevert(Unauthorized.selector); vm.expectRevert(Unauthorized.selector);
_optimismPortalInterop().setConfig(Types.ConfigType(_configType), _value); _optimismPortalInterop().setConfig(ConfigType.REMOVE_DEPENDENCY, _value);
} }
/// @dev Returns the OptimismPortalInterop instance. /// @dev Returns the OptimismPortalInterop instance.
......
...@@ -13,10 +13,9 @@ import { DeployUtils } from "scripts/libraries/DeployUtils.sol"; ...@@ -13,10 +13,9 @@ import { DeployUtils } from "scripts/libraries/DeployUtils.sol";
contract SuperchainConfig_Init_Test is CommonTest { contract SuperchainConfig_Init_Test is CommonTest {
/// @dev Tests that initialization sets the correct values. These are defined in CommonTest.sol. /// @dev Tests that initialization sets the correct values. These are defined in CommonTest.sol.
function test_initialize_succeeds() external view { function test_initialize_unpaused_succeeds() external view {
assertFalse(superchainConfig.paused()); assertFalse(superchainConfig.paused());
assertEq(superchainConfig.guardian(), deploy.cfg().superchainConfigGuardian()); assertEq(superchainConfig.guardian(), deploy.cfg().superchainConfigGuardian());
assertEq(superchainConfig.upgrader(), deploy.cfg().finalSystemOwner());
} }
/// @dev Tests that it can be intialized as paused. /// @dev Tests that it can be intialized as paused.
...@@ -37,15 +36,11 @@ contract SuperchainConfig_Init_Test is CommonTest { ...@@ -37,15 +36,11 @@ contract SuperchainConfig_Init_Test is CommonTest {
vm.startPrank(alice); vm.startPrank(alice);
newProxy.upgradeToAndCall( newProxy.upgradeToAndCall(
address(newImpl), address(newImpl),
abi.encodeCall( abi.encodeCall(ISuperchainConfig.initialize, (deploy.cfg().superchainConfigGuardian(), true))
ISuperchainConfig.initialize,
(deploy.cfg().superchainConfigGuardian(), deploy.cfg().finalSystemOwner(), true)
)
); );
assertTrue(ISuperchainConfig(address(newProxy)).paused()); assertTrue(ISuperchainConfig(address(newProxy)).paused());
assertEq(ISuperchainConfig(address(newProxy)).guardian(), deploy.cfg().superchainConfigGuardian()); assertEq(ISuperchainConfig(address(newProxy)).guardian(), deploy.cfg().superchainConfigGuardian());
assertEq(ISuperchainConfig(address(newProxy)).upgrader(), deploy.cfg().finalSystemOwner());
} }
} }
......
...@@ -3,7 +3,6 @@ pragma solidity 0.8.15; ...@@ -3,7 +3,6 @@ pragma solidity 0.8.15;
// Testing // Testing
import { CommonTest } from "test/setup/CommonTest.sol"; import { CommonTest } from "test/setup/CommonTest.sol";
import { VmSafe } from "forge-std/Vm.sol";
// Contracts // Contracts
import { ERC20 } from "@openzeppelin/contracts/token/ERC20/ERC20.sol"; import { ERC20 } from "@openzeppelin/contracts/token/ERC20/ERC20.sol";
...@@ -12,10 +11,6 @@ import { ERC20 } from "@openzeppelin/contracts/token/ERC20/ERC20.sol"; ...@@ -12,10 +11,6 @@ import { ERC20 } from "@openzeppelin/contracts/token/ERC20/ERC20.sol";
import { Constants } from "src/libraries/Constants.sol"; import { Constants } from "src/libraries/Constants.sol";
import { Predeploys } from "src/libraries/Predeploys.sol"; import { Predeploys } from "src/libraries/Predeploys.sol";
import { GasPayingToken } from "src/libraries/GasPayingToken.sol"; import { GasPayingToken } from "src/libraries/GasPayingToken.sol";
import { StaticConfig } from "src/libraries/StaticConfig.sol";
import { Types } from "src/libraries/Types.sol";
import { Encoding } from "src/libraries/Encoding.sol";
import { Bytes } from "src/libraries/Bytes.sol";
// Interfaces // Interfaces
import { IResourceMetering } from "src/L1/interfaces/IResourceMetering.sol"; import { IResourceMetering } from "src/L1/interfaces/IResourceMetering.sol";
...@@ -53,18 +48,18 @@ contract SystemConfig_Initialize_Test is SystemConfig_Init { ...@@ -53,18 +48,18 @@ contract SystemConfig_Initialize_Test is SystemConfig_Init {
/// @dev Tests that constructor sets the correct values. /// @dev Tests that constructor sets the correct values.
function test_constructor_succeeds() external view { function test_constructor_succeeds() external view {
ISystemConfig impl = ISystemConfig(systemConfigImpl); ISystemConfig impl = ISystemConfig(systemConfigImpl);
assertEq(impl.owner(), address(0)); assertEq(impl.owner(), address(0xdEaD));
assertEq(impl.overhead(), 0); assertEq(impl.overhead(), 0);
assertEq(impl.scalar(), 0); assertEq(impl.scalar(), uint256(0x01) << 248);
assertEq(impl.batcherHash(), bytes32(0)); assertEq(impl.batcherHash(), bytes32(0));
assertEq(impl.gasLimit(), 0); assertEq(impl.gasLimit(), 1);
assertEq(impl.unsafeBlockSigner(), address(0)); assertEq(impl.unsafeBlockSigner(), address(0));
assertEq(impl.basefeeScalar(), 0); assertEq(impl.basefeeScalar(), 0);
assertEq(impl.blobbasefeeScalar(), 0); assertEq(impl.blobbasefeeScalar(), 0);
IResourceMetering.ResourceConfig memory actual = impl.resourceConfig(); IResourceMetering.ResourceConfig memory actual = impl.resourceConfig();
assertEq(actual.maxResourceLimit, 0); assertEq(actual.maxResourceLimit, 1);
assertEq(actual.elasticityMultiplier, 0); assertEq(actual.elasticityMultiplier, 1);
assertEq(actual.baseFeeMaxChangeDenominator, 0); assertEq(actual.baseFeeMaxChangeDenominator, 2);
assertEq(actual.minimumBaseFee, 0); assertEq(actual.minimumBaseFee, 0);
assertEq(actual.systemTxMaxGas, 0); assertEq(actual.systemTxMaxGas, 0);
assertEq(actual.maximumBaseFee, 0); assertEq(actual.maximumBaseFee, 0);
...@@ -83,7 +78,6 @@ contract SystemConfig_Initialize_Test is SystemConfig_Init { ...@@ -83,7 +78,6 @@ contract SystemConfig_Initialize_Test is SystemConfig_Init {
assertEq(decimals, 18); assertEq(decimals, 18);
} }
// TODO: add a reinit test to ensure calls are made to the Portal.
/// @dev Tests that initialization sets the correct values. /// @dev Tests that initialization sets the correct values.
function test_initialize_succeeds() external view { function test_initialize_succeeds() external view {
assertEq(systemConfig.owner(), owner); assertEq(systemConfig.owner(), owner);
...@@ -119,54 +113,6 @@ contract SystemConfig_Initialize_Test is SystemConfig_Init { ...@@ -119,54 +113,6 @@ contract SystemConfig_Initialize_Test is SystemConfig_Init {
assertEq(token, Constants.ETHER); assertEq(token, Constants.ETHER);
assertEq(decimals, 18); assertEq(decimals, 18);
} }
/// @dev Tests that the gas usage of `initialize` does not exceed the max resource limit.
function test_initialize_gasUsage() external {
// Wipe out the initialized slot so the proxy can be initialized again
vm.store(address(systemConfig), bytes32(0), bytes32(0));
vm.recordLogs();
systemConfig.initialize({
_roles: ISystemConfig.Roles({
owner: alice,
feeAdmin: bob,
unsafeBlockSigner: address(1),
batcherHash: bytes32(hex"abcd")
}),
_basefeeScalar: basefeeScalar,
_blobbasefeeScalar: blobbasefeeScalar,
_gasLimit: gasLimit,
_config: Constants.DEFAULT_RESOURCE_CONFIG(),
_batchInbox: address(0),
_addresses: ISystemConfig.Addresses({
l1CrossDomainMessenger: address(0),
l1ERC721Bridge: address(0),
l1StandardBridge: address(0),
disputeGameFactory: address(0),
optimismPortal: address(optimismPortal),
optimismMintableERC20Factory: address(0),
gasPayingToken: Constants.ETHER
})
});
VmSafe.Log[] memory logs = vm.getRecordedLogs();
uint64 totalGasUsed = 0;
for (uint256 i = 0; i < logs.length; i++) {
if (logs[i].topics[0] == keccak256("TransactionDeposited(address,address,uint256,bytes)")) {
// The first 32 bytes of the Data will give us the offset of the opaqueData,
// The next 32 bytes indicate the length of the opaqueData content.
// The remaining data is the opaqueData which is tightly packed. There are two
// uint256 values before the gasLimit, so we'll start at 4x32 = 128.
uint256 start = 128;
uint64 gasUsed = uint64(bytes8(Bytes.slice(logs[i].data, start, 8)));
// Assert that the expected SYSTEM_DEPOSIT_GAS_LIMIT gas limit is used for the
// detected events.
assertEq(gasUsed, 200_000);
totalGasUsed += gasUsed;
}
}
assertLe(totalGasUsed, Constants.DEFAULT_RESOURCE_CONFIG().maxResourceLimit);
}
} }
contract SystemConfig_Initialize_TestFail is SystemConfig_Initialize_Test { contract SystemConfig_Initialize_TestFail is SystemConfig_Initialize_Test {
...@@ -182,15 +128,12 @@ contract SystemConfig_Initialize_TestFail is SystemConfig_Initialize_Test { ...@@ -182,15 +128,12 @@ contract SystemConfig_Initialize_TestFail is SystemConfig_Initialize_Test {
vm.expectRevert("SystemConfig: gas limit too low"); vm.expectRevert("SystemConfig: gas limit too low");
systemConfig.initialize({ systemConfig.initialize({
_roles: ISystemConfig.Roles({ _owner: alice,
owner: alice,
feeAdmin: bob,
unsafeBlockSigner: address(1),
batcherHash: bytes32(hex"abcd")
}),
_basefeeScalar: basefeeScalar, _basefeeScalar: basefeeScalar,
_blobbasefeeScalar: blobbasefeeScalar, _blobbasefeeScalar: blobbasefeeScalar,
_batcherHash: bytes32(hex"abcd"),
_gasLimit: minimumGasLimit - 1, _gasLimit: minimumGasLimit - 1,
_unsafeBlockSigner: address(1),
_config: Constants.DEFAULT_RESOURCE_CONFIG(), _config: Constants.DEFAULT_RESOURCE_CONFIG(),
_batchInbox: address(0), _batchInbox: address(0),
_addresses: ISystemConfig.Addresses({ _addresses: ISystemConfig.Addresses({
...@@ -198,7 +141,7 @@ contract SystemConfig_Initialize_TestFail is SystemConfig_Initialize_Test { ...@@ -198,7 +141,7 @@ contract SystemConfig_Initialize_TestFail is SystemConfig_Initialize_Test {
l1ERC721Bridge: address(0), l1ERC721Bridge: address(0),
l1StandardBridge: address(0), l1StandardBridge: address(0),
disputeGameFactory: address(0), disputeGameFactory: address(0),
optimismPortal: address(optimismPortal), optimismPortal: address(0),
optimismMintableERC20Factory: address(0), optimismMintableERC20Factory: address(0),
gasPayingToken: Constants.ETHER gasPayingToken: Constants.ETHER
}) })
...@@ -215,15 +158,12 @@ contract SystemConfig_Initialize_TestFail is SystemConfig_Initialize_Test { ...@@ -215,15 +158,12 @@ contract SystemConfig_Initialize_TestFail is SystemConfig_Initialize_Test {
// Initialize and check that StartBlock updates to current block number // Initialize and check that StartBlock updates to current block number
vm.prank(systemConfig.owner()); vm.prank(systemConfig.owner());
systemConfig.initialize({ systemConfig.initialize({
_roles: ISystemConfig.Roles({ _owner: alice,
owner: alice,
feeAdmin: bob,
unsafeBlockSigner: address(1),
batcherHash: bytes32(hex"abcd")
}),
_basefeeScalar: basefeeScalar, _basefeeScalar: basefeeScalar,
_blobbasefeeScalar: blobbasefeeScalar, _blobbasefeeScalar: blobbasefeeScalar,
_batcherHash: bytes32(hex"abcd"),
_gasLimit: gasLimit, _gasLimit: gasLimit,
_unsafeBlockSigner: address(1),
_config: Constants.DEFAULT_RESOURCE_CONFIG(), _config: Constants.DEFAULT_RESOURCE_CONFIG(),
_batchInbox: address(0), _batchInbox: address(0),
_addresses: ISystemConfig.Addresses({ _addresses: ISystemConfig.Addresses({
...@@ -231,7 +171,7 @@ contract SystemConfig_Initialize_TestFail is SystemConfig_Initialize_Test { ...@@ -231,7 +171,7 @@ contract SystemConfig_Initialize_TestFail is SystemConfig_Initialize_Test {
l1ERC721Bridge: address(0), l1ERC721Bridge: address(0),
l1StandardBridge: address(0), l1StandardBridge: address(0),
disputeGameFactory: address(0), disputeGameFactory: address(0),
optimismPortal: address(optimismPortal), optimismPortal: address(0),
optimismMintableERC20Factory: address(0), optimismMintableERC20Factory: address(0),
gasPayingToken: Constants.ETHER gasPayingToken: Constants.ETHER
}) })
...@@ -249,15 +189,12 @@ contract SystemConfig_Initialize_TestFail is SystemConfig_Initialize_Test { ...@@ -249,15 +189,12 @@ contract SystemConfig_Initialize_TestFail is SystemConfig_Initialize_Test {
// Initialize and check that StartBlock doesn't update // Initialize and check that StartBlock doesn't update
vm.prank(systemConfig.owner()); vm.prank(systemConfig.owner());
systemConfig.initialize({ systemConfig.initialize({
_roles: ISystemConfig.Roles({ _owner: alice,
owner: alice,
feeAdmin: bob,
unsafeBlockSigner: address(1),
batcherHash: bytes32(hex"abcd")
}),
_basefeeScalar: basefeeScalar, _basefeeScalar: basefeeScalar,
_blobbasefeeScalar: blobbasefeeScalar, _blobbasefeeScalar: blobbasefeeScalar,
_batcherHash: bytes32(hex"abcd"),
_gasLimit: gasLimit, _gasLimit: gasLimit,
_unsafeBlockSigner: address(1),
_config: Constants.DEFAULT_RESOURCE_CONFIG(), _config: Constants.DEFAULT_RESOURCE_CONFIG(),
_batchInbox: address(0), _batchInbox: address(0),
_addresses: ISystemConfig.Addresses({ _addresses: ISystemConfig.Addresses({
...@@ -265,7 +202,7 @@ contract SystemConfig_Initialize_TestFail is SystemConfig_Initialize_Test { ...@@ -265,7 +202,7 @@ contract SystemConfig_Initialize_TestFail is SystemConfig_Initialize_Test {
l1ERC721Bridge: address(0), l1ERC721Bridge: address(0),
l1StandardBridge: address(0), l1StandardBridge: address(0),
disputeGameFactory: address(0), disputeGameFactory: address(0),
optimismPortal: address(optimismPortal), optimismPortal: address(0),
optimismMintableERC20Factory: address(0), optimismMintableERC20Factory: address(0),
gasPayingToken: Constants.ETHER gasPayingToken: Constants.ETHER
}) })
...@@ -347,15 +284,12 @@ contract SystemConfig_Init_ResourceConfig is SystemConfig_Init { ...@@ -347,15 +284,12 @@ contract SystemConfig_Init_ResourceConfig is SystemConfig_Init {
vm.expectRevert(bytes(revertMessage)); vm.expectRevert(bytes(revertMessage));
systemConfig.initialize({ systemConfig.initialize({
_roles: ISystemConfig.Roles({ _owner: address(0xdEaD),
owner: address(0xdEaD),
feeAdmin: address(0xdEaD),
unsafeBlockSigner: address(1),
batcherHash: bytes32(0)
}),
_basefeeScalar: 0, _basefeeScalar: 0,
_blobbasefeeScalar: 0, _blobbasefeeScalar: 0,
_batcherHash: bytes32(0),
_gasLimit: gasLimit, _gasLimit: gasLimit,
_unsafeBlockSigner: address(0),
_config: config, _config: config,
_batchInbox: address(0), _batchInbox: address(0),
_addresses: ISystemConfig.Addresses({ _addresses: ISystemConfig.Addresses({
...@@ -363,7 +297,7 @@ contract SystemConfig_Init_ResourceConfig is SystemConfig_Init { ...@@ -363,7 +297,7 @@ contract SystemConfig_Init_ResourceConfig is SystemConfig_Init {
l1ERC721Bridge: address(0), l1ERC721Bridge: address(0),
l1StandardBridge: address(0), l1StandardBridge: address(0),
disputeGameFactory: address(0), disputeGameFactory: address(0),
optimismPortal: address(optimismPortal), optimismPortal: address(0),
optimismMintableERC20Factory: address(0), optimismMintableERC20Factory: address(0),
gasPayingToken: address(0) gasPayingToken: address(0)
}) })
...@@ -389,15 +323,12 @@ contract SystemConfig_Init_CustomGasToken is SystemConfig_Init { ...@@ -389,15 +323,12 @@ contract SystemConfig_Init_CustomGasToken is SystemConfig_Init {
vm.store(address(systemConfig), GasPayingToken.GAS_PAYING_TOKEN_SYMBOL_SLOT, bytes32(0)); vm.store(address(systemConfig), GasPayingToken.GAS_PAYING_TOKEN_SYMBOL_SLOT, bytes32(0));
systemConfig.initialize({ systemConfig.initialize({
_roles: ISystemConfig.Roles({ _owner: alice,
owner: alice,
feeAdmin: bob,
unsafeBlockSigner: address(1),
batcherHash: bytes32(hex"abcd")
}),
_basefeeScalar: 2100, _basefeeScalar: 2100,
_blobbasefeeScalar: 1000000, _blobbasefeeScalar: 1000000,
_batcherHash: bytes32(hex"abcd"),
_gasLimit: 30_000_000, _gasLimit: 30_000_000,
_unsafeBlockSigner: address(1),
_config: Constants.DEFAULT_RESOURCE_CONFIG(), _config: Constants.DEFAULT_RESOURCE_CONFIG(),
_batchInbox: address(0), _batchInbox: address(0),
_addresses: ISystemConfig.Addresses({ _addresses: ISystemConfig.Addresses({
...@@ -410,13 +341,6 @@ contract SystemConfig_Init_CustomGasToken is SystemConfig_Init { ...@@ -410,13 +341,6 @@ contract SystemConfig_Init_CustomGasToken is SystemConfig_Init {
gasPayingToken: _gasPayingToken gasPayingToken: _gasPayingToken
}) })
}); });
vm.roll(block.number + 1);
// Reset the OptimismPortal resource config gas used
bytes32 slot = vm.load(address(optimismPortal), bytes32(uint256(1)));
vm.store(
address(optimismPortal), bytes32(uint256(1)), bytes32(uint256(slot) & ~(uint256(type(uint64).max) << 64))
);
} }
/// @dev Tests that initialization sets the correct values and getters work. /// @dev Tests that initialization sets the correct values and getters work.
...@@ -527,15 +451,9 @@ contract SystemConfig_Init_CustomGasToken is SystemConfig_Init { ...@@ -527,15 +451,9 @@ contract SystemConfig_Init_CustomGasToken is SystemConfig_Init {
/// @dev Tests that initialization works with OptimismPortal. /// @dev Tests that initialization works with OptimismPortal.
function test_initialize_customGasTokenCall_succeeds() external { function test_initialize_customGasTokenCall_succeeds() external {
bytes memory data = StaticConfig.encodeSetGasPayingToken({
_token: address(token),
_decimals: 18,
_name: bytes32("Silly"),
_symbol: bytes32("SIL")
});
vm.expectCall( vm.expectCall(
address(optimismPortal), abi.encodeCall(optimismPortal.setConfig, (Types.ConfigType.GAS_PAYING_TOKEN, data)) address(optimismPortal),
abi.encodeCall(optimismPortal.setGasPayingToken, (address(token), 18, bytes32("Silly"), bytes32("SIL")))
); );
vm.expectEmit(address(optimismPortal)); vm.expectEmit(address(optimismPortal));
...@@ -548,7 +466,7 @@ contract SystemConfig_Init_CustomGasToken is SystemConfig_Init { ...@@ -548,7 +466,7 @@ contract SystemConfig_Init_CustomGasToken is SystemConfig_Init {
uint256(0), // value uint256(0), // value
uint64(200_000), // gasLimit uint64(200_000), // gasLimit
false, // isCreation, false, // isCreation,
abi.encodeCall(IL1Block.setConfig, (Types.ConfigType.GAS_PAYING_TOKEN, data)) abi.encodeCall(IL1Block.setGasPayingToken, (address(token), 18, bytes32("Silly"), bytes32("SIL")))
) )
); );
...@@ -609,26 +527,6 @@ contract SystemConfig_Setters_TestFail is SystemConfig_Init { ...@@ -609,26 +527,6 @@ contract SystemConfig_Setters_TestFail is SystemConfig_Init {
systemConfig.setGasLimit(maximumGasLimit + 1); systemConfig.setGasLimit(maximumGasLimit + 1);
} }
/// @dev Tests that `setFeeVaultConfig` reverts if the config type is not a fee vault config.
function testFuzz_setFeeVaultConfig_badType_reverts(uint8 _type) external {
// Ensure that _type is a valid ConfigType, but not a fee vault type.
_type = uint8(bound(uint256(_type), 0, uint256(uint8(type(Types.ConfigType).max))));
vm.assume(_type == 0 || _type > 3);
vm.prank(systemConfig.feeAdmin());
vm.expectRevert("SystemConfig: ConfigType is is not a Fee Vault Config type");
systemConfig.setFeeVaultConfig(Types.ConfigType(_type), address(0), 0, Types.WithdrawalNetwork.L1);
}
/// @dev Tests that `setFeeVaultConfig` reverts if the caller is not authorized.
function testFuzz_setFeeVaultConfig_badAuth_reverts(address _caller) external {
vm.assume(_caller != systemConfig.feeAdmin());
vm.expectRevert("SystemConfig: caller is not the fee admin");
vm.prank(_caller);
systemConfig.setFeeVaultConfig(Types.ConfigType.L1_FEE_VAULT_CONFIG, _caller, 0, Types.WithdrawalNetwork.L1);
}
/// @dev Tests that `setEIP1559Params` reverts if the caller is not the owner. /// @dev Tests that `setEIP1559Params` reverts if the caller is not the owner.
function test_setEIP1559Params_notOwner_reverts(uint32 _denominator, uint32 _elasticity) external { function test_setEIP1559Params_notOwner_reverts(uint32 _denominator, uint32 _elasticity) external {
vm.expectRevert("Ownable: caller is not the owner"); vm.expectRevert("Ownable: caller is not the owner");
...@@ -717,42 +615,6 @@ contract SystemConfig_Setters_Test is SystemConfig_Init { ...@@ -717,42 +615,6 @@ contract SystemConfig_Setters_Test is SystemConfig_Init {
assertEq(systemConfig.unsafeBlockSigner(), newUnsafeSigner); assertEq(systemConfig.unsafeBlockSigner(), newUnsafeSigner);
} }
/// @dev Tests that `setFeeVaultConfig` emits the expected event in the OptimismPortal
function testFuzz_setFeeVaultConfig_succeeds(
uint8 _vaultConfig,
address _recipient,
uint256 _min,
uint8 _network
)
external
{
vm.assume(_min <= type(uint88).max);
// Bound the _vaultConfig to one of the 3 enum entries associated with Fee Vault Config.
Types.ConfigType feeType = Types.ConfigType(uint8(bound(_vaultConfig, 1, 3)));
// Bound the _network to one of the 2 enum entries associated with Withdrawal Network.
Types.WithdrawalNetwork withdrawalNetwork = Types.WithdrawalNetwork(uint8(bound(_network, 0, 1)));
bytes memory value = abi.encode(Encoding.encodeFeeVaultConfig(_recipient, _min, withdrawalNetwork));
address feeAdmin = systemConfig.feeAdmin();
vm.expectEmit(address(optimismPortal2));
emit TransactionDeposited(
0xDeaDDEaDDeAdDeAdDEAdDEaddeAddEAdDEAd0001,
Predeploys.L1_BLOCK_ATTRIBUTES,
0,
abi.encodePacked(
uint256(0), // mint
uint256(0), // value
uint64(200_000), // gasLimit
false, // isCreation,
abi.encodeCall(IL1Block.setConfig, (feeType, value))
)
);
vm.prank(feeAdmin);
systemConfig.setFeeVaultConfig(feeType, _recipient, _min, withdrawalNetwork);
}
/// @dev Tests that `setEIP1559Params` updates the EIP1559 parameters successfully. /// @dev Tests that `setEIP1559Params` updates the EIP1559 parameters successfully.
function testFuzz_setEIP1559Params_succeeds(uint32 _denominator, uint32 _elasticity) external { function testFuzz_setEIP1559Params_succeeds(uint32 _denominator, uint32 _elasticity) external {
vm.assume(_denominator > 1); vm.assume(_denominator > 1);
...@@ -769,5 +631,3 @@ contract SystemConfig_Setters_Test is SystemConfig_Init { ...@@ -769,5 +631,3 @@ contract SystemConfig_Setters_Test is SystemConfig_Init {
assertEq(systemConfig.eip1559Elasticity(), _elasticity); assertEq(systemConfig.eip1559Elasticity(), _elasticity);
} }
} }
// TODO: GasBenchmarks for initialize
...@@ -6,12 +6,12 @@ import { CommonTest } from "test/setup/CommonTest.sol"; ...@@ -6,12 +6,12 @@ import { CommonTest } from "test/setup/CommonTest.sol";
// Contracts // Contracts
import { ERC20 } from "@openzeppelin/contracts/token/ERC20/ERC20.sol"; import { ERC20 } from "@openzeppelin/contracts/token/ERC20/ERC20.sol";
import { ConfigType } from "src/L2/L1BlockInterop.sol";
// Libraries // Libraries
import { Constants } from "src/libraries/Constants.sol"; import { Constants } from "src/libraries/Constants.sol";
import { StaticConfig } from "src/libraries/StaticConfig.sol"; import { StaticConfig } from "src/libraries/StaticConfig.sol";
import { GasPayingToken } from "src/libraries/GasPayingToken.sol"; import { GasPayingToken } from "src/libraries/GasPayingToken.sol";
import { Types } from "src/libraries/Types.sol";
// Interfaces // Interfaces
import { ISystemConfig } from "src/L1/interfaces/ISystemConfig.sol"; import { ISystemConfig } from "src/L1/interfaces/ISystemConfig.sol";
...@@ -50,7 +50,7 @@ contract SystemConfigInterop_Test is CommonTest { ...@@ -50,7 +50,7 @@ contract SystemConfigInterop_Test is CommonTest {
abi.encodeCall( abi.encodeCall(
IOptimismPortalInterop.setConfig, IOptimismPortalInterop.setConfig,
( (
Types.ConfigType.GAS_PAYING_TOKEN, ConfigType.SET_GAS_PAYING_TOKEN,
StaticConfig.encodeSetGasPayingToken({ StaticConfig.encodeSetGasPayingToken({
_token: _token, _token: _token,
_decimals: 18, _decimals: 18,
...@@ -70,7 +70,7 @@ contract SystemConfigInterop_Test is CommonTest { ...@@ -70,7 +70,7 @@ contract SystemConfigInterop_Test is CommonTest {
address(optimismPortal), address(optimismPortal),
abi.encodeCall( abi.encodeCall(
IOptimismPortalInterop.setConfig, IOptimismPortalInterop.setConfig,
(Types.ConfigType.ADD_DEPENDENCY, StaticConfig.encodeAddDependency(_chainId)) (ConfigType.ADD_DEPENDENCY, StaticConfig.encodeAddDependency(_chainId))
) )
); );
...@@ -92,7 +92,7 @@ contract SystemConfigInterop_Test is CommonTest { ...@@ -92,7 +92,7 @@ contract SystemConfigInterop_Test is CommonTest {
address(optimismPortal), address(optimismPortal),
abi.encodeCall( abi.encodeCall(
IOptimismPortalInterop.setConfig, IOptimismPortalInterop.setConfig,
(Types.ConfigType.REMOVE_DEPENDENCY, StaticConfig.encodeRemoveDependency(_chainId)) (ConfigType.REMOVE_DEPENDENCY, StaticConfig.encodeRemoveDependency(_chainId))
) )
); );
...@@ -117,15 +117,12 @@ contract SystemConfigInterop_Test is CommonTest { ...@@ -117,15 +117,12 @@ contract SystemConfigInterop_Test is CommonTest {
vm.store(address(systemConfig), GasPayingToken.GAS_PAYING_TOKEN_SYMBOL_SLOT, bytes32(0)); vm.store(address(systemConfig), GasPayingToken.GAS_PAYING_TOKEN_SYMBOL_SLOT, bytes32(0));
systemConfig.initialize({ systemConfig.initialize({
_roles: ISystemConfig.Roles({ _owner: alice,
owner: alice,
feeAdmin: bob,
unsafeBlockSigner: address(1),
batcherHash: bytes32(hex"abcd")
}),
_basefeeScalar: 2100, _basefeeScalar: 2100,
_blobbasefeeScalar: 1000000, _blobbasefeeScalar: 1000000,
_batcherHash: bytes32(hex"abcd"),
_gasLimit: 30_000_000, _gasLimit: 30_000_000,
_unsafeBlockSigner: address(1),
_config: Constants.DEFAULT_RESOURCE_CONFIG(), _config: Constants.DEFAULT_RESOURCE_CONFIG(),
_batchInbox: address(0), _batchInbox: address(0),
_addresses: ISystemConfig.Addresses({ _addresses: ISystemConfig.Addresses({
......
...@@ -8,7 +8,7 @@ import { Bridge_Initializer } from "test/setup/Bridge_Initializer.sol"; ...@@ -8,7 +8,7 @@ import { Bridge_Initializer } from "test/setup/Bridge_Initializer.sol";
import { Types } from "src/libraries/Types.sol"; import { Types } from "src/libraries/Types.sol";
// Test the implementations of the FeeVault // Test the implementations of the FeeVault
contract BaseFeeVault_Test is Bridge_Initializer { contract FeeVault_Test is Bridge_Initializer {
/// @dev Tests that the constructor sets the correct values. /// @dev Tests that the constructor sets the correct values.
function test_constructor_baseFeeVault_succeeds() external view { function test_constructor_baseFeeVault_succeeds() external view {
assertEq(baseFeeVault.RECIPIENT(), deploy.cfg().baseFeeVaultRecipient()); assertEq(baseFeeVault.RECIPIENT(), deploy.cfg().baseFeeVaultRecipient());
......
...@@ -7,6 +7,7 @@ import { Bridge_Initializer } from "test/setup/Bridge_Initializer.sol"; ...@@ -7,6 +7,7 @@ import { Bridge_Initializer } from "test/setup/Bridge_Initializer.sol";
// Libraries // Libraries
import { Hashing } from "src/libraries/Hashing.sol"; import { Hashing } from "src/libraries/Hashing.sol";
import { Encoding } from "src/libraries/Encoding.sol"; import { Encoding } from "src/libraries/Encoding.sol";
import { Bytes32AddressLib } from "@rari-capital/solmate/src/utils/Bytes32AddressLib.sol";
// Target contract dependencies // Target contract dependencies
import { AddressAliasHelper } from "src/vendor/AddressAliasHelper.sol"; import { AddressAliasHelper } from "src/vendor/AddressAliasHelper.sol";
...@@ -38,6 +39,18 @@ contract CrossDomainOwnable2_Test is Bridge_Initializer { ...@@ -38,6 +39,18 @@ contract CrossDomainOwnable2_Test is Bridge_Initializer {
setter.set(1); setter.set(1);
} }
/// @dev Tests that the `onlyOwner` modifier reverts when not called by the owner.
function test_onlyOwner_notOwner_reverts() external {
// set the xDomainMsgSender storage slot
bytes32 key = bytes32(uint256(204));
bytes32 value = Bytes32AddressLib.fillLast12Bytes(address(alice));
vm.store(address(l2CrossDomainMessenger), key, value);
vm.prank(address(l2CrossDomainMessenger));
vm.expectRevert("CrossDomainOwnable2: caller is not the owner");
setter.set(1);
}
/// @dev Tests that the `onlyOwner` modifier causes the relayed message to fail. /// @dev Tests that the `onlyOwner` modifier causes the relayed message to fail.
function test_onlyOwner_notOwner2_reverts() external { function test_onlyOwner_notOwner2_reverts() external {
uint240 nonce = 0; uint240 nonce = 0;
......
...@@ -71,7 +71,7 @@ contract CrossDomainOwnable3_Test is Bridge_Initializer { ...@@ -71,7 +71,7 @@ contract CrossDomainOwnable3_Test is Bridge_Initializer {
setter.transferOwnership({ _owner: alice, _isLocal: false }); setter.transferOwnership({ _owner: alice, _isLocal: false });
// set the xDomainMsgSender storage slot // set the xDomainMsgSender storage slot
bytes32 key = bytes32(uint256(208)); bytes32 key = bytes32(uint256(204));
bytes32 value = Bytes32AddressLib.fillLast12Bytes(bob); bytes32 value = Bytes32AddressLib.fillLast12Bytes(bob);
vm.store(address(l2CrossDomainMessenger), key, value); vm.store(address(l2CrossDomainMessenger), key, value);
......
// SPDX-License-Identifier: MIT
pragma solidity 0.8.15;
// Testing utilities
import { Bridge_Initializer } from "test/setup/Bridge_Initializer.sol";
// Libraries
import { Types } from "src/libraries/Types.sol";
// Test the implementations of the FeeVault
contract FeeVault_Test is Bridge_Initializer {
/// @dev Tests that the constructor sets the correct values.
function test_constructor_baseFeeVault_succeeds() external view {
assertEq(baseFeeVault.RECIPIENT(), deploy.cfg().baseFeeVaultRecipient());
assertEq(baseFeeVault.recipient(), deploy.cfg().baseFeeVaultRecipient());
assertEq(baseFeeVault.MIN_WITHDRAWAL_AMOUNT(), deploy.cfg().baseFeeVaultMinimumWithdrawalAmount());
assertEq(baseFeeVault.minWithdrawalAmount(), deploy.cfg().baseFeeVaultMinimumWithdrawalAmount());
assertEq(uint8(baseFeeVault.WITHDRAWAL_NETWORK()), uint8(Types.WithdrawalNetwork.L1));
assertEq(uint8(baseFeeVault.withdrawalNetwork()), uint8(Types.WithdrawalNetwork.L1));
}
}
...@@ -6,11 +6,8 @@ import { CommonTest } from "test/setup/CommonTest.sol"; ...@@ -6,11 +6,8 @@ import { CommonTest } from "test/setup/CommonTest.sol";
// Libraries // Libraries
import { Encoding } from "src/libraries/Encoding.sol"; import { Encoding } from "src/libraries/Encoding.sol";
import { Types } from "src/libraries/Types.sol";
import { GasPayingToken } from "src/libraries/GasPayingToken.sol";
import { Constants } from "src/libraries/Constants.sol"; import { Constants } from "src/libraries/Constants.sol";
import "src/libraries/L1BlockErrors.sol"; import "src/libraries/L1BlockErrors.sol";
import { LibString } from "lib/solady/src/utils/LibString.sol";
contract L1BlockTest is CommonTest { contract L1BlockTest is CommonTest {
address depositor; address depositor;
...@@ -168,148 +165,6 @@ contract L1BlockEcotone_Test is L1BlockTest { ...@@ -168,148 +165,6 @@ contract L1BlockEcotone_Test is L1BlockTest {
} }
} }
contract L1BlockIsthmus_Test is L1BlockTest {
/// @dev Tests that `setIsthmus` succeeds if sender address is the depositor
function test_setIsthmus_isDepositor_succeeds() external {
vm.prank(depositor);
l1Block.setIsthmus();
assertTrue(l1Block.isIsthmus());
bytes memory baseFeeVaultConfig = l1Block.getConfig(Types.ConfigType.BASE_FEE_VAULT_CONFIG);
(address recipient, uint256 min, Types.WithdrawalNetwork network) =
Encoding.decodeFeeVaultConfig(bytes32(baseFeeVaultConfig));
assertEq(recipient, deploy.cfg().baseFeeVaultRecipient());
assertEq(min, deploy.cfg().baseFeeVaultMinimumWithdrawalAmount());
assertEq(uint8(network), uint8(deploy.cfg().baseFeeVaultWithdrawalNetwork()));
bytes memory sequencerFeeVaultConfig = l1Block.getConfig(Types.ConfigType.SEQUENCER_FEE_VAULT_CONFIG);
(recipient, min, network) = Encoding.decodeFeeVaultConfig(bytes32(sequencerFeeVaultConfig));
assertEq(recipient, deploy.cfg().sequencerFeeVaultRecipient());
assertEq(min, deploy.cfg().sequencerFeeVaultMinimumWithdrawalAmount());
assertEq(uint8(network), uint8(deploy.cfg().sequencerFeeVaultWithdrawalNetwork()));
bytes memory l1FeeVaultConfig = l1Block.getConfig(Types.ConfigType.L1_FEE_VAULT_CONFIG);
(recipient, min, network) = Encoding.decodeFeeVaultConfig(bytes32(l1FeeVaultConfig));
assertEq(recipient, deploy.cfg().l1FeeVaultRecipient());
assertEq(min, deploy.cfg().l1FeeVaultMinimumWithdrawalAmount());
assertEq(uint8(network), uint8(deploy.cfg().l1FeeVaultWithdrawalNetwork()));
assertEq(
abi.decode(l1Block.getConfig(Types.ConfigType.L1_ERC_721_BRIDGE_ADDRESS), (address)),
address(l1ERC721Bridge)
);
assertEq(
abi.decode(l1Block.getConfig(Types.ConfigType.L1_CROSS_DOMAIN_MESSENGER_ADDRESS), (address)),
address(l1CrossDomainMessenger)
);
assertEq(
abi.decode(l1Block.getConfig(Types.ConfigType.L1_STANDARD_BRIDGE_ADDRESS), (address)),
address(l1StandardBridge)
);
assertEq(abi.decode(l1Block.getConfig(Types.ConfigType.REMOTE_CHAIN_ID), (uint256)), deploy.cfg().l1ChainID());
}
/// @dev Tests that `setIsthmus` reverts if sender address is not the depositor
function test_setIsthmus_notDepositor_reverts() external {
vm.expectRevert(NotDepositor.selector);
l1Block.setIsthmus();
}
}
contract L1BlockConfig_Test is L1BlockTest {
/// @notice Ensures that `setConfig` always reverts when called, across all possible config types.
/// Use a magic number of 10 since solidity doesn't offer a good way to know the nubmer
/// of enum elements.
function test_setConfig_onlyDepositor_reverts(address _caller, uint8 _type) external {
vm.assume(_caller != Constants.DEPOSITOR_ACCOUNT);
vm.assume(_type < 10); // the number of defined config types
vm.expectRevert(NotDepositor.selector);
vm.prank(_caller);
l1Block.setConfig(Types.ConfigType(_type), hex"");
}
function test_getConfigRoundtripGasPayingToken_succeeds(
address _token,
uint8 _decimals,
bytes32 _name,
bytes32 _symbol
)
external
{
_name = LibString.normalizeSmallString(_name);
_symbol = LibString.normalizeSmallString(_symbol);
// Both the 0 address and the ether address are prevented from being set by
// `_setGasPayingToken` in `SystemConfig.sol`
vm.assume(_token != address(0) && _token != Constants.ETHER);
vm.prank(Constants.DEPOSITOR_ACCOUNT);
l1Block.setConfig(Types.ConfigType.GAS_PAYING_TOKEN, abi.encode(_token, _decimals, _name, _symbol));
bytes memory data = l1Block.getConfig(Types.ConfigType.GAS_PAYING_TOKEN);
(address token, uint8 decimals, bytes32 name, bytes32 symbol) =
abi.decode(data, (address, uint8, bytes32, bytes32));
assertEq(token, _token);
assertEq(decimals, _decimals);
assertEq(name, _name);
assertEq(symbol, _symbol);
}
/// @notice Tests roundtrip setConfig/getConfig for base fee vault config
function test_getConfigRoundtripBaseFeeVault_succeeds(bytes32 _config) external {
_getConfigRoundTrip(_config, Types.ConfigType.BASE_FEE_VAULT_CONFIG);
}
/// @notice Tests roundtrip setConfig/getConfig for L1 fee vault config
function test_getConfigRoundtripL1FeeVault_succeeds(bytes32 _config) external {
_getConfigRoundTrip(_config, Types.ConfigType.L1_FEE_VAULT_CONFIG);
}
/// @notice Tests roundtrip setConfig/getConfig for sequencer fee vault config
function test_getConfigRoundtripSequencerFeeVault_succeeds(bytes32 _config) external {
_getConfigRoundTrip(_config, Types.ConfigType.SEQUENCER_FEE_VAULT_CONFIG);
}
/// @notice Internal function for logic on round trip testing fee vault config
function _getConfigRoundTrip(bytes32 _config, Types.ConfigType _type) internal {
vm.prank(Constants.DEPOSITOR_ACCOUNT);
l1Block.setConfig(_type, abi.encode(_config));
bytes memory data = l1Block.getConfig(_type);
bytes32 config = abi.decode(data, (bytes32));
assertEq(config, _config);
}
function test_getConfigRoundtripL1CrossDomainMessenger_succeeds(address _addr) external {
_getConfigRoundTrip(_addr, Types.ConfigType.L1_CROSS_DOMAIN_MESSENGER_ADDRESS);
}
function test_getConfigRoundtripL1ERC721Bridge_succeeds(address _addr) external {
_getConfigRoundTrip(_addr, Types.ConfigType.L1_ERC_721_BRIDGE_ADDRESS);
}
function test_getConfigRoundtripL1StandardBridge_succeeds(address _addr) external {
_getConfigRoundTrip(_addr, Types.ConfigType.L1_STANDARD_BRIDGE_ADDRESS);
}
function _getConfigRoundTrip(address _addr, Types.ConfigType _type) internal {
vm.prank(Constants.DEPOSITOR_ACCOUNT);
l1Block.setConfig(_type, abi.encode(_addr));
bytes memory data = l1Block.getConfig(_type);
address addr = abi.decode(data, (address));
assertEq(addr, _addr);
}
function test_getConfigRoundtripRemoteChainId_succeeds(uint256 _value) external {
_getConfigRoundTrip(_value, Types.ConfigType.REMOTE_CHAIN_ID);
}
function _getConfigRoundTrip(uint256 _value, Types.ConfigType _type) internal {
vm.prank(Constants.DEPOSITOR_ACCOUNT);
l1Block.setConfig(_type, abi.encode(_value));
bytes memory data = l1Block.getConfig(_type);
uint256 value = abi.decode(data, (uint256));
assertEq(value, _value);
}
}
contract L1BlockCustomGasToken_Test is L1BlockTest { contract L1BlockCustomGasToken_Test is L1BlockTest {
function testFuzz_setGasPayingToken_succeeds( function testFuzz_setGasPayingToken_succeeds(
address _token, address _token,
......
...@@ -6,10 +6,9 @@ import { CommonTest } from "test/setup/CommonTest.sol"; ...@@ -6,10 +6,9 @@ import { CommonTest } from "test/setup/CommonTest.sol";
// Libraries // Libraries
import { StaticConfig } from "src/libraries/StaticConfig.sol"; import { StaticConfig } from "src/libraries/StaticConfig.sol";
import { Types } from "src/libraries/Types.sol";
// Target contract dependencies // Target contract dependencies
import { L1BlockInterop } from "src/L2/L1BlockInterop.sol"; import { L1BlockInterop, ConfigType } from "src/L2/L1BlockInterop.sol";
import { Predeploys } from "src/libraries/Predeploys.sol"; import { Predeploys } from "src/libraries/Predeploys.sol";
import "src/libraries/L1BlockErrors.sol"; import "src/libraries/L1BlockErrors.sol";
...@@ -35,7 +34,7 @@ contract L1BlockInteropTest is CommonTest { ...@@ -35,7 +34,7 @@ contract L1BlockInteropTest is CommonTest {
function testFuzz_isInDependencySet_succeeds(uint256 _chainId) public prankDepositor { function testFuzz_isInDependencySet_succeeds(uint256 _chainId) public prankDepositor {
vm.assume(_chainId != block.chainid); vm.assume(_chainId != block.chainid);
_l1BlockInterop().setConfig(Types.ConfigType.ADD_DEPENDENCY, StaticConfig.encodeAddDependency(_chainId)); _l1BlockInterop().setConfig(ConfigType.ADD_DEPENDENCY, StaticConfig.encodeAddDependency(_chainId));
assertTrue(_l1BlockInterop().isInDependencySet(_chainId)); assertTrue(_l1BlockInterop().isInDependencySet(_chainId));
} }
...@@ -71,7 +70,7 @@ contract L1BlockInteropTest is CommonTest { ...@@ -71,7 +70,7 @@ contract L1BlockInteropTest is CommonTest {
for (uint256 i = 0; i < _dependencySetSize; i++) { for (uint256 i = 0; i < _dependencySetSize; i++) {
if (i == block.chainid) continue; if (i == block.chainid) continue;
_l1BlockInterop().setConfig(Types.ConfigType.ADD_DEPENDENCY, StaticConfig.encodeAddDependency(i)); _l1BlockInterop().setConfig(ConfigType.ADD_DEPENDENCY, StaticConfig.encodeAddDependency(i));
uniqueCount++; uniqueCount++;
} }
...@@ -99,7 +98,7 @@ contract L1BlockInteropTest is CommonTest { ...@@ -99,7 +98,7 @@ contract L1BlockInteropTest is CommonTest {
emit GasPayingTokenSet({ token: _token, decimals: _decimals, name: _name, symbol: _symbol }); emit GasPayingTokenSet({ token: _token, decimals: _decimals, name: _name, symbol: _symbol });
_l1BlockInterop().setConfig( _l1BlockInterop().setConfig(
Types.ConfigType.GAS_PAYING_TOKEN, ConfigType.SET_GAS_PAYING_TOKEN,
StaticConfig.encodeSetGasPayingToken({ _token: _token, _decimals: _decimals, _name: _name, _symbol: _symbol }) StaticConfig.encodeSetGasPayingToken({ _token: _token, _decimals: _decimals, _name: _name, _symbol: _symbol })
); );
} }
...@@ -117,7 +116,7 @@ contract L1BlockInteropTest is CommonTest { ...@@ -117,7 +116,7 @@ contract L1BlockInteropTest is CommonTest {
vm.expectRevert(NotDepositor.selector); vm.expectRevert(NotDepositor.selector);
_l1BlockInterop().setConfig( _l1BlockInterop().setConfig(
Types.ConfigType.GAS_PAYING_TOKEN, ConfigType.SET_GAS_PAYING_TOKEN,
StaticConfig.encodeSetGasPayingToken({ _token: _token, _decimals: _decimals, _name: _name, _symbol: _symbol }) StaticConfig.encodeSetGasPayingToken({ _token: _token, _decimals: _decimals, _name: _name, _symbol: _symbol })
); );
} }
...@@ -129,41 +128,41 @@ contract L1BlockInteropTest is CommonTest { ...@@ -129,41 +128,41 @@ contract L1BlockInteropTest is CommonTest {
vm.expectEmit(address(l1Block)); vm.expectEmit(address(l1Block));
emit DependencyAdded(_chainId); emit DependencyAdded(_chainId);
_l1BlockInterop().setConfig(Types.ConfigType.ADD_DEPENDENCY, StaticConfig.encodeAddDependency(_chainId)); _l1BlockInterop().setConfig(ConfigType.ADD_DEPENDENCY, StaticConfig.encodeAddDependency(_chainId));
} }
/// @dev Tests that adding a dependency reverts if it's the chain's chain id /// @dev Tests that adding a dependency reverts if it's the chain's chain id
function test_setConfig_addDependency_chainChainId_reverts() public prankDepositor { function test_setConfig_addDependency_chainChainId_reverts() public prankDepositor {
vm.expectRevert(AlreadyDependency.selector); vm.expectRevert(AlreadyDependency.selector);
_l1BlockInterop().setConfig(Types.ConfigType.ADD_DEPENDENCY, StaticConfig.encodeAddDependency(block.chainid)); _l1BlockInterop().setConfig(ConfigType.ADD_DEPENDENCY, StaticConfig.encodeAddDependency(block.chainid));
} }
/// @dev Tests that adding a dependency already in the set reverts /// @dev Tests that adding a dependency already in the set reverts
function test_setConfig_addDependency_alreadyDependency_reverts(uint256 _chainId) public prankDepositor { function test_setConfig_addDependency_alreadyDependency_reverts(uint256 _chainId) public prankDepositor {
vm.assume(_chainId != block.chainid); vm.assume(_chainId != block.chainid);
_l1BlockInterop().setConfig(Types.ConfigType.ADD_DEPENDENCY, StaticConfig.encodeAddDependency(_chainId)); _l1BlockInterop().setConfig(ConfigType.ADD_DEPENDENCY, StaticConfig.encodeAddDependency(_chainId));
vm.expectRevert(AlreadyDependency.selector); vm.expectRevert(AlreadyDependency.selector);
_l1BlockInterop().setConfig(Types.ConfigType.ADD_DEPENDENCY, StaticConfig.encodeAddDependency(_chainId)); _l1BlockInterop().setConfig(ConfigType.ADD_DEPENDENCY, StaticConfig.encodeAddDependency(_chainId));
} }
/// @dev Tests that setting the add dependency config as not the depositor reverts. /// @dev Tests that setting the add dependency config as not the depositor reverts.
function testFuzz_setConfig_addDependency_notDepositor_reverts(uint256 _chainId) public { function testFuzz_setConfig_addDependency_notDepositor_reverts(uint256 _chainId) public {
vm.expectRevert(NotDepositor.selector); vm.expectRevert(NotDepositor.selector);
_l1BlockInterop().setConfig(Types.ConfigType.ADD_DEPENDENCY, StaticConfig.encodeAddDependency(_chainId)); _l1BlockInterop().setConfig(ConfigType.ADD_DEPENDENCY, StaticConfig.encodeAddDependency(_chainId));
} }
/// @dev Tests that setting the add dependency config when the dependency set size is too large reverts. /// @dev Tests that setting the add dependency config when the dependency set size is too large reverts.
function test_setConfig_addDependency_dependencySetSizeTooLarge_reverts() public prankDepositor { function test_setConfig_addDependency_dependencySetSizeTooLarge_reverts() public prankDepositor {
for (uint256 i = 0; i < type(uint8).max; i++) { for (uint256 i = 0; i < type(uint8).max; i++) {
_l1BlockInterop().setConfig(Types.ConfigType.ADD_DEPENDENCY, StaticConfig.encodeAddDependency(i)); _l1BlockInterop().setConfig(ConfigType.ADD_DEPENDENCY, StaticConfig.encodeAddDependency(i));
} }
assertEq(_l1BlockInterop().dependencySetSize(), type(uint8).max); assertEq(_l1BlockInterop().dependencySetSize(), type(uint8).max);
vm.expectRevert(DependencySetSizeTooLarge.selector); vm.expectRevert(DependencySetSizeTooLarge.selector);
_l1BlockInterop().setConfig(Types.ConfigType.ADD_DEPENDENCY, StaticConfig.encodeAddDependency(1)); _l1BlockInterop().setConfig(ConfigType.ADD_DEPENDENCY, StaticConfig.encodeAddDependency(1));
} }
/// @dev Tests that the config for removing a dependency can be set. /// @dev Tests that the config for removing a dependency can be set.
...@@ -171,26 +170,24 @@ contract L1BlockInteropTest is CommonTest { ...@@ -171,26 +170,24 @@ contract L1BlockInteropTest is CommonTest {
vm.assume(_chainId != block.chainid); vm.assume(_chainId != block.chainid);
// Add the chain ID to the dependency set before removing it // Add the chain ID to the dependency set before removing it
_l1BlockInterop().setConfig(Types.ConfigType.ADD_DEPENDENCY, StaticConfig.encodeAddDependency(_chainId)); _l1BlockInterop().setConfig(ConfigType.ADD_DEPENDENCY, StaticConfig.encodeAddDependency(_chainId));
vm.expectEmit(address(l1Block)); vm.expectEmit(address(l1Block));
emit DependencyRemoved(_chainId); emit DependencyRemoved(_chainId);
_l1BlockInterop().setConfig(Types.ConfigType.REMOVE_DEPENDENCY, StaticConfig.encodeRemoveDependency(_chainId)); _l1BlockInterop().setConfig(ConfigType.REMOVE_DEPENDENCY, StaticConfig.encodeRemoveDependency(_chainId));
} }
/// @dev Tests that setting the remove dependency config as not the depositor reverts. /// @dev Tests that setting the remove dependency config as not the depositor reverts.
function testFuzz_setConfig_removeDependency_notDepositor_reverts(uint256 _chainId) public { function testFuzz_setConfig_removeDependency_notDepositor_reverts(uint256 _chainId) public {
vm.expectRevert(NotDepositor.selector); vm.expectRevert(NotDepositor.selector);
_l1BlockInterop().setConfig(Types.ConfigType.REMOVE_DEPENDENCY, StaticConfig.encodeRemoveDependency(_chainId)); _l1BlockInterop().setConfig(ConfigType.REMOVE_DEPENDENCY, StaticConfig.encodeRemoveDependency(_chainId));
} }
/// @dev Tests that setting the remove dependency config for the chain's chain ID reverts. /// @dev Tests that setting the remove dependency config for the chain's chain ID reverts.
function test_setConfig_removeDependency_chainChainId_reverts() public prankDepositor { function test_setConfig_removeDependency_chainChainId_reverts() public prankDepositor {
vm.expectRevert(CantRemovedDependency.selector); vm.expectRevert(CantRemovedDependency.selector);
_l1BlockInterop().setConfig( _l1BlockInterop().setConfig(ConfigType.REMOVE_DEPENDENCY, StaticConfig.encodeRemoveDependency(block.chainid));
Types.ConfigType.REMOVE_DEPENDENCY, StaticConfig.encodeRemoveDependency(block.chainid)
);
} }
/// @dev Tests that setting the remove dependency config for a chain ID that is not in the dependency set reverts. /// @dev Tests that setting the remove dependency config for a chain ID that is not in the dependency set reverts.
...@@ -198,7 +195,7 @@ contract L1BlockInteropTest is CommonTest { ...@@ -198,7 +195,7 @@ contract L1BlockInteropTest is CommonTest {
vm.assume(_chainId != block.chainid); vm.assume(_chainId != block.chainid);
vm.expectRevert(NotDependency.selector); vm.expectRevert(NotDependency.selector);
_l1BlockInterop().setConfig(Types.ConfigType.REMOVE_DEPENDENCY, StaticConfig.encodeRemoveDependency(_chainId)); _l1BlockInterop().setConfig(ConfigType.REMOVE_DEPENDENCY, StaticConfig.encodeRemoveDependency(_chainId));
} }
/// @dev Returns the L1BlockInterop instance. /// @dev Returns the L1BlockInterop instance.
......
...@@ -8,7 +8,7 @@ import { Bridge_Initializer } from "test/setup/Bridge_Initializer.sol"; ...@@ -8,7 +8,7 @@ import { Bridge_Initializer } from "test/setup/Bridge_Initializer.sol";
import { Types } from "src/libraries/Types.sol"; import { Types } from "src/libraries/Types.sol";
// Test the implementations of the FeeVault // Test the implementations of the FeeVault
contract L1FeeVault_Test is Bridge_Initializer { contract FeeVault_Test is Bridge_Initializer {
/// @dev Tests that the constructor sets the correct values. /// @dev Tests that the constructor sets the correct values.
function test_constructor_l1FeeVault_succeeds() external view { function test_constructor_l1FeeVault_succeeds() external view {
assertEq(l1FeeVault.RECIPIENT(), deploy.cfg().l1FeeVaultRecipient()); assertEq(l1FeeVault.RECIPIENT(), deploy.cfg().l1FeeVaultRecipient());
......
...@@ -21,14 +21,12 @@ contract L2CrossDomainMessenger_Test is Bridge_Initializer { ...@@ -21,14 +21,12 @@ contract L2CrossDomainMessenger_Test is Bridge_Initializer {
address recipient = address(0xabbaacdc); address recipient = address(0xabbaacdc);
/// @dev Tests that the implementation is initialized correctly. /// @dev Tests that the implementation is initialized correctly.
/// The implementation returns the actual address rather than `address(0)`
/// because the contract calls L1Block for the result.
function test_constructor_succeeds() external view { function test_constructor_succeeds() external view {
IL2CrossDomainMessenger impl = IL2CrossDomainMessenger impl =
IL2CrossDomainMessenger(EIP1967Helper.getImplementation(deploy.mustGetAddress("L2CrossDomainMessenger"))); IL2CrossDomainMessenger(EIP1967Helper.getImplementation(deploy.mustGetAddress("L2CrossDomainMessenger")));
assertEq(address(impl.OTHER_MESSENGER()), address(l1CrossDomainMessenger)); assertEq(address(impl.OTHER_MESSENGER()), address(0));
assertEq(address(impl.otherMessenger()), address(l1CrossDomainMessenger)); assertEq(address(impl.otherMessenger()), address(0));
assertEq(address(impl.l1CrossDomainMessenger()), address(l1CrossDomainMessenger)); assertEq(address(impl.l1CrossDomainMessenger()), address(0));
} }
/// @dev Tests that the proxy is initialized correctly. /// @dev Tests that the proxy is initialized correctly.
......
...@@ -22,7 +22,7 @@ contract TestERC721 is ERC721 { ...@@ -22,7 +22,7 @@ contract TestERC721 is ERC721 {
contract TestMintableERC721 is OptimismMintableERC721 { contract TestMintableERC721 is OptimismMintableERC721 {
constructor( constructor(
IL2ERC721Bridge _bridge, address _bridge,
address _remoteToken address _remoteToken
) )
OptimismMintableERC721(_bridge, 1, _remoteToken, "Test", "TST") OptimismMintableERC721(_bridge, 1, _remoteToken, "Test", "TST")
...@@ -61,7 +61,7 @@ contract L2ERC721Bridge_Test is Bridge_Initializer { ...@@ -61,7 +61,7 @@ contract L2ERC721Bridge_Test is Bridge_Initializer {
super.setUp(); super.setUp();
remoteToken = new TestERC721(); remoteToken = new TestERC721();
localToken = new TestMintableERC721(l2ERC721Bridge, address(remoteToken)); localToken = new TestMintableERC721(address(l2ERC721Bridge), address(remoteToken));
// Mint alice a token. // Mint alice a token.
localToken.mint(alice, tokenId); localToken.mint(alice, tokenId);
......
...@@ -191,7 +191,7 @@ contract L2GenesisTest is Test { ...@@ -191,7 +191,7 @@ contract L2GenesisTest is Test {
// 16 prefunded dev accounts are excluded // 16 prefunded dev accounts are excluded
assertEq(expected, getJSONKeyCount(_path), "key count check"); assertEq(expected, getJSONKeyCount(_path), "key count check");
// 2 slots: implementation, admin // 3 slots: implementation, owner, admin
assertEq(2, getStorageKeysCount(_path, Predeploys.PROXY_ADMIN), "proxy admin storage check"); assertEq(3, getStorageKeysCount(_path, Predeploys.PROXY_ADMIN), "proxy admin storage check");
} }
} }
...@@ -28,12 +28,12 @@ contract L2StandardBridge_Test is Bridge_Initializer { ...@@ -28,12 +28,12 @@ contract L2StandardBridge_Test is Bridge_Initializer {
function test_constructor_succeeds() external view { function test_constructor_succeeds() external view {
IL2StandardBridge impl = IL2StandardBridge impl =
IL2StandardBridge(payable(EIP1967Helper.getImplementation(deploy.mustGetAddress("L2StandardBridge")))); IL2StandardBridge(payable(EIP1967Helper.getImplementation(deploy.mustGetAddress("L2StandardBridge"))));
// The implementation contract calls out to L1Block to get the otherBridge // The implementation contract is initialized with a 0 L1 bridge address,
// but the L2 cross-domain-messenger is always set to the predeploy address for both proxy and implementation. // but the L2 cross-domain-messenger is always set to the predeploy address for both proxy and implementation.
assertEq(address(impl.MESSENGER()), Predeploys.L2_CROSS_DOMAIN_MESSENGER, "constructor check MESSENGER"); assertEq(address(impl.MESSENGER()), Predeploys.L2_CROSS_DOMAIN_MESSENGER, "constructor zero check MESSENGER");
assertEq(address(impl.messenger()), Predeploys.L2_CROSS_DOMAIN_MESSENGER, "constructor check messenger"); assertEq(address(impl.messenger()), Predeploys.L2_CROSS_DOMAIN_MESSENGER, "constructor zero check messenger");
assertEq(address(impl.OTHER_BRIDGE()), address(l1StandardBridge), "constructor check OTHER_BRIDGE"); assertEq(address(impl.OTHER_BRIDGE()), address(0), "constructor zero check OTHER_BRIDGE");
assertEq(address(impl.otherBridge()), address(l1StandardBridge), "constructor check otherBridge"); assertEq(address(impl.otherBridge()), address(0), "constructor zero check otherBridge");
} }
/// @dev Tests that the bridge is initialized correctly. /// @dev Tests that the bridge is initialized correctly.
......
...@@ -21,9 +21,10 @@ contract PredeploysBaseTest is CommonTest { ...@@ -21,9 +21,10 @@ contract PredeploysBaseTest is CommonTest {
return _addr == Predeploys.L1_MESSAGE_SENDER; return _addr == Predeploys.L1_MESSAGE_SENDER;
} }
/// @dev No predeploys should ever be initializable. /// @dev Returns true if the predeploy is initializable.
function _isInitializable(address) internal pure returns (bool) { function _isInitializable(address _addr) internal pure returns (bool) {
return false; return _addr == Predeploys.L2_CROSS_DOMAIN_MESSENGER || _addr == Predeploys.L2_STANDARD_BRIDGE
|| _addr == Predeploys.L2_ERC721_BRIDGE || _addr == Predeploys.OPTIMISM_MINTABLE_ERC20_FACTORY;
} }
/// @dev Returns true if the predeploy uses immutables. /// @dev Returns true if the predeploy uses immutables.
...@@ -48,7 +49,7 @@ contract PredeploysBaseTest is CommonTest { ...@@ -48,7 +49,7 @@ contract PredeploysBaseTest is CommonTest {
); );
} }
function _test_predeploys(bool _useInterop) internal view { function _test_predeploys(bool _useInterop) internal {
uint256 count = 2048; uint256 count = 2048;
uint160 prefix = uint160(0x420) << 148; uint160 prefix = uint160(0x420) << 148;
...@@ -103,6 +104,10 @@ contract PredeploysBaseTest is CommonTest { ...@@ -103,6 +104,10 @@ contract PredeploysBaseTest is CommonTest {
// can't check bytecode if it's modified with immutables in genesis. // can't check bytecode if it's modified with immutables in genesis.
assertEq(implAddr.code, supposedCode, "proxy implementation contract should match contract source"); assertEq(implAddr.code, supposedCode, "proxy implementation contract should match contract source");
} }
if (_isInitializable(addr)) {
assertEq(l2Genesis.loadInitializedSlot(cname), uint8(1));
}
} }
} }
} }
...@@ -110,7 +115,7 @@ contract PredeploysBaseTest is CommonTest { ...@@ -110,7 +115,7 @@ contract PredeploysBaseTest is CommonTest {
contract PredeploysTest is PredeploysBaseTest { contract PredeploysTest is PredeploysBaseTest {
/// @dev Tests that the predeploy addresses are set correctly. They have code /// @dev Tests that the predeploy addresses are set correctly. They have code
/// and the proxied accounts have the correct admin. /// and the proxied accounts have the correct admin.
function test_predeploys_succeeds() external view { function test_predeploys_succeeds() external {
_test_predeploys(false); _test_predeploys(false);
} }
} }
...@@ -124,7 +129,7 @@ contract PredeploysInteropTest is PredeploysBaseTest { ...@@ -124,7 +129,7 @@ contract PredeploysInteropTest is PredeploysBaseTest {
/// @dev Tests that the predeploy addresses are set correctly. They have code /// @dev Tests that the predeploy addresses are set correctly. They have code
/// and the proxied accounts have the correct admin. Using interop. /// and the proxied accounts have the correct admin. Using interop.
function test_predeploys_succeeds() external view { function test_predeploys_succeeds() external {
_test_predeploys(true); _test_predeploys(true);
} }
} }
...@@ -4,29 +4,33 @@ pragma solidity 0.8.15; ...@@ -4,29 +4,33 @@ pragma solidity 0.8.15;
// Testing // Testing
import { CommonTest } from "test/setup/CommonTest.sol"; import { CommonTest } from "test/setup/CommonTest.sol";
import { Reverter } from "test/mocks/Callers.sol"; import { Reverter } from "test/mocks/Callers.sol";
import { EIP1967Helper } from "test/mocks/EIP1967Helper.sol";
// Contracts
import { ISequencerFeeVault } from "src/L2/interfaces/ISequencerFeeVault.sol";
// Libraries // Libraries
import { Hashing } from "src/libraries/Hashing.sol"; import { Hashing } from "src/libraries/Hashing.sol";
import { Types } from "src/libraries/Types.sol"; import { Types } from "src/libraries/Types.sol";
import { Predeploys } from "src/libraries/Predeploys.sol"; import { Predeploys } from "src/libraries/Predeploys.sol";
import { Encoding } from "src/libraries/Encoding.sol"; import { DeployUtils } from "scripts/libraries/DeployUtils.sol";
import { Constants } from "src/libraries/Constants.sol";
contract SequencerFeeVault_Test is CommonTest { contract SequencerFeeVault_Test is CommonTest {
address recipient;
/// @dev Sets up the test suite.
function setUp() public override { function setUp() public override {
super.setUp(); super.setUp();
assertEq(uint8(deploy.cfg().sequencerFeeVaultWithdrawalNetwork()), uint8(Types.WithdrawalNetwork.L1)); recipient = deploy.cfg().sequencerFeeVaultRecipient();
} }
/// @dev Tests that the sequencer fee wallet is correct. /// @dev Tests that the l1 fee wallet is correct.
function test_constructor_succeeds() external view { function test_constructor_succeeds() external view {
address recipient = deploy.cfg().sequencerFeeVaultRecipient();
uint256 amount = deploy.cfg().sequencerFeeVaultMinimumWithdrawalAmount();
assertEq(sequencerFeeVault.l1FeeWallet(), recipient); assertEq(sequencerFeeVault.l1FeeWallet(), recipient);
assertEq(sequencerFeeVault.RECIPIENT(), recipient); assertEq(sequencerFeeVault.RECIPIENT(), recipient);
assertEq(sequencerFeeVault.recipient(), recipient); assertEq(sequencerFeeVault.recipient(), recipient);
assertEq(sequencerFeeVault.MIN_WITHDRAWAL_AMOUNT(), amount); assertEq(sequencerFeeVault.MIN_WITHDRAWAL_AMOUNT(), deploy.cfg().sequencerFeeVaultMinimumWithdrawalAmount());
assertEq(sequencerFeeVault.minWithdrawalAmount(), amount); assertEq(sequencerFeeVault.minWithdrawalAmount(), deploy.cfg().sequencerFeeVaultMinimumWithdrawalAmount());
assertEq(uint8(sequencerFeeVault.WITHDRAWAL_NETWORK()), uint8(Types.WithdrawalNetwork.L1)); assertEq(uint8(sequencerFeeVault.WITHDRAWAL_NETWORK()), uint8(Types.WithdrawalNetwork.L1));
assertEq(uint8(sequencerFeeVault.withdrawalNetwork()), uint8(Types.WithdrawalNetwork.L1)); assertEq(uint8(sequencerFeeVault.withdrawalNetwork()), uint8(Types.WithdrawalNetwork.L1));
} }
...@@ -59,8 +63,6 @@ contract SequencerFeeVault_Test is CommonTest { ...@@ -59,8 +63,6 @@ contract SequencerFeeVault_Test is CommonTest {
// No ether has been withdrawn yet // No ether has been withdrawn yet
assertEq(sequencerFeeVault.totalProcessed(), 0); assertEq(sequencerFeeVault.totalProcessed(), 0);
address recipient = deploy.cfg().sequencerFeeVaultRecipient();
vm.expectEmit(address(Predeploys.SEQUENCER_FEE_WALLET)); vm.expectEmit(address(Predeploys.SEQUENCER_FEE_WALLET));
emit Withdrawal(address(sequencerFeeVault).balance, recipient, address(this)); emit Withdrawal(address(sequencerFeeVault).balance, recipient, address(this));
vm.expectEmit(address(Predeploys.SEQUENCER_FEE_WALLET)); vm.expectEmit(address(Predeploys.SEQUENCER_FEE_WALLET));
...@@ -100,31 +102,34 @@ contract SequencerFeeVault_Test is CommonTest { ...@@ -100,31 +102,34 @@ contract SequencerFeeVault_Test is CommonTest {
} }
contract SequencerFeeVault_L2Withdrawal_Test is CommonTest { contract SequencerFeeVault_L2Withdrawal_Test is CommonTest {
/// @dev a cache for the config fee recipient
address recipient;
/// @dev Sets up the test suite. /// @dev Sets up the test suite.
function setUp() public override { function setUp() public override {
super.setUp(); super.setUp();
// Explicitly use L2 withdrawal network // Alter the deployment to use WithdrawalNetwork.L2
bytes32 sequencerFeeVaultConfig = Encoding.encodeFeeVaultConfig({ vm.etch(
_recipient: deploy.cfg().sequencerFeeVaultRecipient(), EIP1967Helper.getImplementation(Predeploys.SEQUENCER_FEE_WALLET),
_amount: deploy.cfg().sequencerFeeVaultMinimumWithdrawalAmount(), address(
_network: Types.WithdrawalNetwork.L2 DeployUtils.create1({
}); _name: "SequencerFeeVault",
vm.prank(Constants.DEPOSITOR_ACCOUNT); _args: DeployUtils.encodeConstructor(
l1Block.setConfig(Types.ConfigType.SEQUENCER_FEE_VAULT_CONFIG, abi.encode(sequencerFeeVaultConfig)); abi.encodeCall(
} ISequencerFeeVault.__constructor__,
(
deploy.cfg().sequencerFeeVaultRecipient(),
deploy.cfg().sequencerFeeVaultMinimumWithdrawalAmount(),
Types.WithdrawalNetwork.L2
)
)
)
})
).code
);
/// @dev Tests that the sequencer fee wallet is correct. recipient = deploy.cfg().sequencerFeeVaultRecipient();
function test_constructor_succeeds() external view {
address recipient = deploy.cfg().sequencerFeeVaultRecipient();
uint256 amount = deploy.cfg().sequencerFeeVaultMinimumWithdrawalAmount();
assertEq(sequencerFeeVault.l1FeeWallet(), recipient);
assertEq(sequencerFeeVault.RECIPIENT(), recipient);
assertEq(sequencerFeeVault.recipient(), recipient);
assertEq(sequencerFeeVault.MIN_WITHDRAWAL_AMOUNT(), amount);
assertEq(sequencerFeeVault.minWithdrawalAmount(), amount);
assertEq(uint8(sequencerFeeVault.WITHDRAWAL_NETWORK()), uint8(Types.WithdrawalNetwork.L2));
assertEq(uint8(sequencerFeeVault.withdrawalNetwork()), uint8(Types.WithdrawalNetwork.L2));
} }
/// @dev Tests that `withdraw` successfully initiates a withdrawal to L2. /// @dev Tests that `withdraw` successfully initiates a withdrawal to L2.
...@@ -143,14 +148,14 @@ contract SequencerFeeVault_L2Withdrawal_Test is CommonTest { ...@@ -143,14 +148,14 @@ contract SequencerFeeVault_L2Withdrawal_Test is CommonTest {
); );
// The entire vault's balance is withdrawn // The entire vault's balance is withdrawn
vm.expectCall(sequencerFeeVault.RECIPIENT(), address(sequencerFeeVault).balance, bytes("")); vm.expectCall(recipient, address(sequencerFeeVault).balance, bytes(""));
sequencerFeeVault.withdraw(); sequencerFeeVault.withdraw();
// The withdrawal was successful // The withdrawal was successful
assertEq(sequencerFeeVault.totalProcessed(), amount); assertEq(sequencerFeeVault.totalProcessed(), amount);
assertEq(address(sequencerFeeVault).balance, 0); assertEq(address(sequencerFeeVault).balance, 0);
assertEq(sequencerFeeVault.recipient().balance, amount); assertEq(recipient.balance, amount);
} }
/// @dev Tests that `withdraw` fails if the Recipient reverts. This also serves to simulate /// @dev Tests that `withdraw` fails if the Recipient reverts. This also serves to simulate
...@@ -166,7 +171,7 @@ contract SequencerFeeVault_L2Withdrawal_Test is CommonTest { ...@@ -166,7 +171,7 @@ contract SequencerFeeVault_L2Withdrawal_Test is CommonTest {
vm.etch(sequencerFeeVault.RECIPIENT(), type(Reverter).runtimeCode); vm.etch(sequencerFeeVault.RECIPIENT(), type(Reverter).runtimeCode);
// The entire vault's balance is withdrawn // The entire vault's balance is withdrawn
vm.expectCall(sequencerFeeVault.recipient(), address(sequencerFeeVault).balance, bytes("")); vm.expectCall(recipient, address(sequencerFeeVault).balance, bytes(""));
vm.expectRevert("FeeVault: failed to send ETH to L2 fee recipient"); vm.expectRevert("FeeVault: failed to send ETH to L2 fee recipient");
sequencerFeeVault.withdraw(); sequencerFeeVault.withdraw();
assertEq(sequencerFeeVault.totalProcessed(), 0); assertEq(sequencerFeeVault.totalProcessed(), 0);
......
...@@ -7,12 +7,6 @@ import { IProxy } from "src/universal/interfaces/IProxy.sol"; ...@@ -7,12 +7,6 @@ import { IProxy } from "src/universal/interfaces/IProxy.sol";
import { Constants } from "src/libraries/Constants.sol"; import { Constants } from "src/libraries/Constants.sol";
import { DeployUtils } from "scripts/libraries/DeployUtils.sol"; import { DeployUtils } from "scripts/libraries/DeployUtils.sol";
contract ConfigSetter {
function setConfig(uint8, bytes calldata) external {
// noop
}
}
contract SystemConfig_GasLimitBoundaries_Invariant is Test { contract SystemConfig_GasLimitBoundaries_Invariant is Test {
ISystemConfig public config; ISystemConfig public config;
...@@ -29,7 +23,6 @@ contract SystemConfig_GasLimitBoundaries_Invariant is Test { ...@@ -29,7 +23,6 @@ contract SystemConfig_GasLimitBoundaries_Invariant is Test {
_args: DeployUtils.encodeConstructor(abi.encodeCall(ISystemConfig.__constructor__, ())) _args: DeployUtils.encodeConstructor(abi.encodeCall(ISystemConfig.__constructor__, ()))
}) })
); );
ConfigSetter setter = new ConfigSetter();
vm.prank(msg.sender); vm.prank(msg.sender);
proxy.upgradeToAndCall( proxy.upgradeToAndCall(
...@@ -37,15 +30,12 @@ contract SystemConfig_GasLimitBoundaries_Invariant is Test { ...@@ -37,15 +30,12 @@ contract SystemConfig_GasLimitBoundaries_Invariant is Test {
abi.encodeCall( abi.encodeCall(
configImpl.initialize, configImpl.initialize,
( (
ISystemConfig.Roles({ address(0xbeef), // owner
owner: address(0xbeef),
feeAdmin: address(0xbeef),
unsafeBlockSigner: address(1),
batcherHash: bytes32(hex"abcd")
}),
2100, // overhead 2100, // overhead
1000000, // scalar 1000000, // scalar
bytes32(hex"abcd"), // batcher hash
30_000_000, // gas limit 30_000_000, // gas limit
address(1), // unsafe block signer
Constants.DEFAULT_RESOURCE_CONFIG(), Constants.DEFAULT_RESOURCE_CONFIG(),
address(0), // _batchInbox address(0), // _batchInbox
ISystemConfig.Addresses({ // _addrs ISystemConfig.Addresses({ // _addrs
...@@ -53,7 +43,7 @@ contract SystemConfig_GasLimitBoundaries_Invariant is Test { ...@@ -53,7 +43,7 @@ contract SystemConfig_GasLimitBoundaries_Invariant is Test {
l1ERC721Bridge: address(0), l1ERC721Bridge: address(0),
l1StandardBridge: address(0), l1StandardBridge: address(0),
disputeGameFactory: address(0), disputeGameFactory: address(0),
optimismPortal: address(setter), optimismPortal: address(0),
optimismMintableERC20Factory: address(0), optimismMintableERC20Factory: address(0),
gasPayingToken: Constants.ETHER gasPayingToken: Constants.ETHER
}) })
......
...@@ -93,15 +93,4 @@ contract Encoding_Test is CommonTest { ...@@ -93,15 +93,4 @@ contract Encoding_Test is CommonTest {
assertEq(txn, _txn); assertEq(txn, _txn);
} }
// using a bool simulates the 2 enum values that exist
function testFuzz_encodeFeeVaultConfig_succeeds(address _recipient, uint88 _amount, bool _network) public pure {
Types.WithdrawalNetwork _withdrawalNetwork = _network ? Types.WithdrawalNetwork.L1 : Types.WithdrawalNetwork.L2;
bytes32 encoded = Encoding.encodeFeeVaultConfig(_recipient, uint256(_amount), _withdrawalNetwork);
(address recipient, uint256 amount, Types.WithdrawalNetwork withdrawalNetwork) =
Encoding.decodeFeeVaultConfig(encoded);
assertEq(_recipient, recipient, "bad recipient");
assertEq(uint256(_amount), amount, "bad amount");
assertEq(uint256(withdrawalNetwork), uint256(withdrawalNetwork), "bad network");
}
} }
...@@ -35,7 +35,6 @@ contract DeployOPChainInput_Test is Test { ...@@ -35,7 +35,6 @@ contract DeployOPChainInput_Test is Test {
// Define defaults. // Define defaults.
address opChainProxyAdminOwner = makeAddr("opChainProxyAdminOwner"); address opChainProxyAdminOwner = makeAddr("opChainProxyAdminOwner");
address systemConfigOwner = makeAddr("systemConfigOwner"); address systemConfigOwner = makeAddr("systemConfigOwner");
address systemConfigFeeAdmin = makeAddr("systemConfigFeeAdmin");
address batcher = makeAddr("batcher"); address batcher = makeAddr("batcher");
address unsafeBlockSigner = makeAddr("unsafeBlockSigner"); address unsafeBlockSigner = makeAddr("unsafeBlockSigner");
address proposer = makeAddr("proposer"); address proposer = makeAddr("proposer");
...@@ -53,7 +52,6 @@ contract DeployOPChainInput_Test is Test { ...@@ -53,7 +52,6 @@ contract DeployOPChainInput_Test is Test {
function test_set_succeeds() public { function test_set_succeeds() public {
doi.set(doi.opChainProxyAdminOwner.selector, opChainProxyAdminOwner); doi.set(doi.opChainProxyAdminOwner.selector, opChainProxyAdminOwner);
doi.set(doi.systemConfigOwner.selector, systemConfigOwner); doi.set(doi.systemConfigOwner.selector, systemConfigOwner);
doi.set(doi.systemConfigFeeAdmin.selector, systemConfigFeeAdmin);
doi.set(doi.batcher.selector, batcher); doi.set(doi.batcher.selector, batcher);
doi.set(doi.unsafeBlockSigner.selector, unsafeBlockSigner); doi.set(doi.unsafeBlockSigner.selector, unsafeBlockSigner);
doi.set(doi.proposer.selector, proposer); doi.set(doi.proposer.selector, proposer);
...@@ -69,7 +67,6 @@ contract DeployOPChainInput_Test is Test { ...@@ -69,7 +67,6 @@ contract DeployOPChainInput_Test is Test {
// Compare the default inputs to the getter methods. // Compare the default inputs to the getter methods.
assertEq(opChainProxyAdminOwner, doi.opChainProxyAdminOwner(), "200"); assertEq(opChainProxyAdminOwner, doi.opChainProxyAdminOwner(), "200");
assertEq(systemConfigOwner, doi.systemConfigOwner(), "300"); assertEq(systemConfigOwner, doi.systemConfigOwner(), "300");
assertEq(systemConfigFeeAdmin, doi.systemConfigFeeAdmin(), "310");
assertEq(batcher, doi.batcher(), "400"); assertEq(batcher, doi.batcher(), "400");
assertEq(unsafeBlockSigner, doi.unsafeBlockSigner(), "500"); assertEq(unsafeBlockSigner, doi.unsafeBlockSigner(), "500");
assertEq(proposer, doi.proposer(), "600"); assertEq(proposer, doi.proposer(), "600");
...@@ -90,9 +87,6 @@ contract DeployOPChainInput_Test is Test { ...@@ -90,9 +87,6 @@ contract DeployOPChainInput_Test is Test {
vm.expectRevert(expectedErr); vm.expectRevert(expectedErr);
doi.systemConfigOwner(); doi.systemConfigOwner();
vm.expectRevert(expectedErr);
doi.systemConfigFeeAdmin();
vm.expectRevert(expectedErr); vm.expectRevert(expectedErr);
doi.batcher(); doi.batcher();
...@@ -336,7 +330,6 @@ contract DeployOPChain_TestBase is Test { ...@@ -336,7 +330,6 @@ contract DeployOPChain_TestBase is Test {
// `opcm` is set during `setUp` since it is an output of the previous step. // `opcm` is set during `setUp` since it is an output of the previous step.
address opChainProxyAdminOwner = makeAddr("defaultOPChainProxyAdminOwner"); address opChainProxyAdminOwner = makeAddr("defaultOPChainProxyAdminOwner");
address systemConfigOwner = makeAddr("defaultSystemConfigOwner"); address systemConfigOwner = makeAddr("defaultSystemConfigOwner");
address systemConfigFeeAdmin = makeAddr("defaultSystemConfigFeeAdmin");
address batcher = makeAddr("defaultBatcher"); address batcher = makeAddr("defaultBatcher");
address unsafeBlockSigner = makeAddr("defaultUnsafeBlockSigner"); address unsafeBlockSigner = makeAddr("defaultUnsafeBlockSigner");
address proposer = makeAddr("defaultProposer"); address proposer = makeAddr("defaultProposer");
...@@ -437,14 +430,13 @@ contract DeployOPChain_Test is DeployOPChain_TestBase { ...@@ -437,14 +430,13 @@ contract DeployOPChain_Test is DeployOPChain_TestBase {
function testFuzz_run_memory_succeed(bytes32 _seed) public { function testFuzz_run_memory_succeed(bytes32 _seed) public {
opChainProxyAdminOwner = address(uint160(uint256(hash(_seed, 0)))); opChainProxyAdminOwner = address(uint160(uint256(hash(_seed, 0))));
systemConfigOwner = address(uint160(uint256(hash(_seed, 1)))); systemConfigOwner = address(uint160(uint256(hash(_seed, 1))));
systemConfigFeeAdmin = address(uint160(uint256(hash(_seed, 2)))); batcher = address(uint160(uint256(hash(_seed, 2))));
batcher = address(uint160(uint256(hash(_seed, 3)))); unsafeBlockSigner = address(uint160(uint256(hash(_seed, 3))));
unsafeBlockSigner = address(uint160(uint256(hash(_seed, 4)))); proposer = address(uint160(uint256(hash(_seed, 4))));
proposer = address(uint160(uint256(hash(_seed, 5)))); challenger = address(uint160(uint256(hash(_seed, 5))));
challenger = address(uint160(uint256(hash(_seed, 6)))); basefeeScalar = uint32(uint256(hash(_seed, 6)));
basefeeScalar = uint32(uint256(hash(_seed, 7))); blobBaseFeeScalar = uint32(uint256(hash(_seed, 7)));
blobBaseFeeScalar = uint32(uint256(hash(_seed, 8))); l2ChainId = uint256(hash(_seed, 8));
l2ChainId = uint256(hash(_seed, 9));
// Set the initial anchor states. The typical usage we expect is to pass in one root per game type. // Set the initial anchor states. The typical usage we expect is to pass in one root per game type.
uint256 cannonBlock = uint256(hash(_seed, 9)); uint256 cannonBlock = uint256(hash(_seed, 9));
...@@ -467,7 +459,6 @@ contract DeployOPChain_Test is DeployOPChain_TestBase { ...@@ -467,7 +459,6 @@ contract DeployOPChain_Test is DeployOPChain_TestBase {
doi.set(doi.opChainProxyAdminOwner.selector, opChainProxyAdminOwner); doi.set(doi.opChainProxyAdminOwner.selector, opChainProxyAdminOwner);
doi.set(doi.systemConfigOwner.selector, systemConfigOwner); doi.set(doi.systemConfigOwner.selector, systemConfigOwner);
doi.set(doi.systemConfigFeeAdmin.selector, systemConfigFeeAdmin);
doi.set(doi.batcher.selector, batcher); doi.set(doi.batcher.selector, batcher);
doi.set(doi.unsafeBlockSigner.selector, unsafeBlockSigner); doi.set(doi.unsafeBlockSigner.selector, unsafeBlockSigner);
doi.set(doi.proposer.selector, proposer); doi.set(doi.proposer.selector, proposer);
...@@ -492,7 +483,6 @@ contract DeployOPChain_Test is DeployOPChain_TestBase { ...@@ -492,7 +483,6 @@ contract DeployOPChain_Test is DeployOPChain_TestBase {
// Assert that individual input fields were properly set based on the inputs. // Assert that individual input fields were properly set based on the inputs.
assertEq(opChainProxyAdminOwner, doi.opChainProxyAdminOwner(), "100"); assertEq(opChainProxyAdminOwner, doi.opChainProxyAdminOwner(), "100");
assertEq(systemConfigOwner, doi.systemConfigOwner(), "200"); assertEq(systemConfigOwner, doi.systemConfigOwner(), "200");
assertEq(systemConfigFeeAdmin, doi.systemConfigFeeAdmin(), "210");
assertEq(batcher, doi.batcher(), "300"); assertEq(batcher, doi.batcher(), "300");
assertEq(unsafeBlockSigner, doi.unsafeBlockSigner(), "400"); assertEq(unsafeBlockSigner, doi.unsafeBlockSigner(), "400");
assertEq(proposer, doi.proposer(), "500"); assertEq(proposer, doi.proposer(), "500");
...@@ -512,7 +502,6 @@ contract DeployOPChain_Test is DeployOPChain_TestBase { ...@@ -512,7 +502,6 @@ contract DeployOPChain_Test is DeployOPChain_TestBase {
// Assert inputs were properly passed through to the contract initializers. // Assert inputs were properly passed through to the contract initializers.
assertEq(address(doo.opChainProxyAdmin().owner()), opChainProxyAdminOwner, "2100"); assertEq(address(doo.opChainProxyAdmin().owner()), opChainProxyAdminOwner, "2100");
assertEq(address(doo.systemConfigProxy().owner()), systemConfigOwner, "2200"); assertEq(address(doo.systemConfigProxy().owner()), systemConfigOwner, "2200");
assertEq(address(doo.systemConfigProxy().feeAdmin()), systemConfigFeeAdmin, "2210");
address batcherActual = address(uint160(uint256(doo.systemConfigProxy().batcherHash()))); address batcherActual = address(uint160(uint256(doo.systemConfigProxy().batcherHash())));
assertEq(batcherActual, batcher, "2300"); assertEq(batcherActual, batcher, "2300");
assertEq(address(doo.systemConfigProxy().unsafeBlockSigner()), unsafeBlockSigner, "2400"); assertEq(address(doo.systemConfigProxy().unsafeBlockSigner()), unsafeBlockSigner, "2400");
...@@ -563,7 +552,6 @@ contract DeployOPChain_Test is DeployOPChain_TestBase { ...@@ -563,7 +552,6 @@ contract DeployOPChain_Test is DeployOPChain_TestBase {
function setDOI() internal { function setDOI() internal {
doi.set(doi.opChainProxyAdminOwner.selector, opChainProxyAdminOwner); doi.set(doi.opChainProxyAdminOwner.selector, opChainProxyAdminOwner);
doi.set(doi.systemConfigOwner.selector, systemConfigOwner); doi.set(doi.systemConfigOwner.selector, systemConfigOwner);
doi.set(doi.systemConfigFeeAdmin.selector, systemConfigFeeAdmin);
doi.set(doi.batcher.selector, batcher); doi.set(doi.batcher.selector, batcher);
doi.set(doi.unsafeBlockSigner.selector, unsafeBlockSigner); doi.set(doi.unsafeBlockSigner.selector, unsafeBlockSigner);
doi.set(doi.proposer.selector, proposer); doi.set(doi.proposer.selector, proposer);
......
...@@ -15,9 +15,6 @@ import { OutputMode, Fork, ForkUtils } from "scripts/libraries/Config.sol"; ...@@ -15,9 +15,6 @@ import { OutputMode, Fork, ForkUtils } from "scripts/libraries/Config.sol";
import { Predeploys } from "src/libraries/Predeploys.sol"; import { Predeploys } from "src/libraries/Predeploys.sol";
import { Preinstalls } from "src/libraries/Preinstalls.sol"; import { Preinstalls } from "src/libraries/Preinstalls.sol";
import { AddressAliasHelper } from "src/vendor/AddressAliasHelper.sol"; import { AddressAliasHelper } from "src/vendor/AddressAliasHelper.sol";
import { Constants } from "src/libraries/Constants.sol";
import { Encoding } from "src/libraries/Encoding.sol";
import { Types } from "src/libraries/Types.sol";
// Interfaces // Interfaces
import { IOptimismPortal } from "src/L1/interfaces/IOptimismPortal.sol"; import { IOptimismPortal } from "src/L1/interfaces/IOptimismPortal.sol";
...@@ -30,7 +27,7 @@ import { IDataAvailabilityChallenge } from "src/L1/interfaces/IDataAvailabilityC ...@@ -30,7 +27,7 @@ import { IDataAvailabilityChallenge } from "src/L1/interfaces/IDataAvailabilityC
import { IL1StandardBridge } from "src/L1/interfaces/IL1StandardBridge.sol"; import { IL1StandardBridge } from "src/L1/interfaces/IL1StandardBridge.sol";
import { IProtocolVersions } from "src/L1/interfaces/IProtocolVersions.sol"; import { IProtocolVersions } from "src/L1/interfaces/IProtocolVersions.sol";
import { IL1ERC721Bridge } from "src/L1/interfaces/IL1ERC721Bridge.sol"; import { IL1ERC721Bridge } from "src/L1/interfaces/IL1ERC721Bridge.sol";
import { IOptimismMintableERC721Factory } from "src/L2/interfaces/IOptimismMintableERC721Factory.sol"; import { IOptimismMintableERC721Factory } from "src/universal/interfaces/IOptimismMintableERC721Factory.sol";
import { IDisputeGameFactory } from "src/dispute/interfaces/IDisputeGameFactory.sol"; import { IDisputeGameFactory } from "src/dispute/interfaces/IDisputeGameFactory.sol";
import { IDelayedWETH } from "src/dispute/interfaces/IDelayedWETH.sol"; import { IDelayedWETH } from "src/dispute/interfaces/IDelayedWETH.sol";
import { IAnchorStateRegistry } from "src/dispute/interfaces/IAnchorStateRegistry.sol"; import { IAnchorStateRegistry } from "src/dispute/interfaces/IAnchorStateRegistry.sol";
...@@ -38,8 +35,7 @@ import { IL2CrossDomainMessenger } from "src/L2/interfaces/IL2CrossDomainMesseng ...@@ -38,8 +35,7 @@ import { IL2CrossDomainMessenger } from "src/L2/interfaces/IL2CrossDomainMesseng
import { IL2StandardBridgeInterop } from "src/L2/interfaces/IL2StandardBridgeInterop.sol"; import { IL2StandardBridgeInterop } from "src/L2/interfaces/IL2StandardBridgeInterop.sol";
import { IL2ToL1MessagePasser } from "src/L2/interfaces/IL2ToL1MessagePasser.sol"; import { IL2ToL1MessagePasser } from "src/L2/interfaces/IL2ToL1MessagePasser.sol";
import { IL2ERC721Bridge } from "src/L2/interfaces/IL2ERC721Bridge.sol"; import { IL2ERC721Bridge } from "src/L2/interfaces/IL2ERC721Bridge.sol";
import { IL1OptimismMintableERC20Factory } from "src/L1/interfaces/IL1OptimismMintableERC20Factory.sol"; import { IOptimismMintableERC20Factory } from "src/universal/interfaces/IOptimismMintableERC20Factory.sol";
import { IL2OptimismMintableERC20Factory } from "src/L2/interfaces/IL2OptimismMintableERC20Factory.sol";
import { IAddressManager } from "src/legacy/interfaces/IAddressManager.sol"; import { IAddressManager } from "src/legacy/interfaces/IAddressManager.sol";
import { IOptimismSuperchainERC20Factory } from "src/L2/interfaces/IOptimismSuperchainERC20Factory.sol"; import { IOptimismSuperchainERC20Factory } from "src/L2/interfaces/IOptimismSuperchainERC20Factory.sol";
import { IBaseFeeVault } from "src/L2/interfaces/IBaseFeeVault.sol"; import { IBaseFeeVault } from "src/L2/interfaces/IBaseFeeVault.sol";
...@@ -87,7 +83,7 @@ contract Setup { ...@@ -87,7 +83,7 @@ contract Setup {
IL1CrossDomainMessenger l1CrossDomainMessenger; IL1CrossDomainMessenger l1CrossDomainMessenger;
IAddressManager addressManager; IAddressManager addressManager;
IL1ERC721Bridge l1ERC721Bridge; IL1ERC721Bridge l1ERC721Bridge;
IL1OptimismMintableERC20Factory l1OptimismMintableERC20Factory; IOptimismMintableERC20Factory l1OptimismMintableERC20Factory;
IProtocolVersions protocolVersions; IProtocolVersions protocolVersions;
ISuperchainConfig superchainConfig; ISuperchainConfig superchainConfig;
IDataAvailabilityChallenge dataAvailabilityChallenge; IDataAvailabilityChallenge dataAvailabilityChallenge;
...@@ -97,8 +93,8 @@ contract Setup { ...@@ -97,8 +93,8 @@ contract Setup {
IL2CrossDomainMessenger(payable(Predeploys.L2_CROSS_DOMAIN_MESSENGER)); IL2CrossDomainMessenger(payable(Predeploys.L2_CROSS_DOMAIN_MESSENGER));
IL2StandardBridgeInterop l2StandardBridge = IL2StandardBridgeInterop(payable(Predeploys.L2_STANDARD_BRIDGE)); IL2StandardBridgeInterop l2StandardBridge = IL2StandardBridgeInterop(payable(Predeploys.L2_STANDARD_BRIDGE));
IL2ToL1MessagePasser l2ToL1MessagePasser = IL2ToL1MessagePasser(payable(Predeploys.L2_TO_L1_MESSAGE_PASSER)); IL2ToL1MessagePasser l2ToL1MessagePasser = IL2ToL1MessagePasser(payable(Predeploys.L2_TO_L1_MESSAGE_PASSER));
IL2OptimismMintableERC20Factory l2OptimismMintableERC20Factory = IOptimismMintableERC20Factory l2OptimismMintableERC20Factory =
IL2OptimismMintableERC20Factory(Predeploys.OPTIMISM_MINTABLE_ERC20_FACTORY); IOptimismMintableERC20Factory(Predeploys.OPTIMISM_MINTABLE_ERC20_FACTORY);
IL2ERC721Bridge l2ERC721Bridge = IL2ERC721Bridge(Predeploys.L2_ERC721_BRIDGE); IL2ERC721Bridge l2ERC721Bridge = IL2ERC721Bridge(Predeploys.L2_ERC721_BRIDGE);
IOptimismMintableERC721Factory l2OptimismMintableERC721Factory = IOptimismMintableERC721Factory l2OptimismMintableERC721Factory =
IOptimismMintableERC721Factory(Predeploys.OPTIMISM_MINTABLE_ERC721_FACTORY); IOptimismMintableERC721Factory(Predeploys.OPTIMISM_MINTABLE_ERC721_FACTORY);
...@@ -158,7 +154,7 @@ contract Setup { ...@@ -158,7 +154,7 @@ contract Setup {
addressManager = IAddressManager(deploy.mustGetAddress("AddressManager")); addressManager = IAddressManager(deploy.mustGetAddress("AddressManager"));
l1ERC721Bridge = IL1ERC721Bridge(deploy.mustGetAddress("L1ERC721BridgeProxy")); l1ERC721Bridge = IL1ERC721Bridge(deploy.mustGetAddress("L1ERC721BridgeProxy"));
l1OptimismMintableERC20Factory = l1OptimismMintableERC20Factory =
IL1OptimismMintableERC20Factory(deploy.mustGetAddress("L1OptimismMintableERC20FactoryProxy")); IOptimismMintableERC20Factory(deploy.mustGetAddress("OptimismMintableERC20FactoryProxy"));
protocolVersions = IProtocolVersions(deploy.mustGetAddress("ProtocolVersionsProxy")); protocolVersions = IProtocolVersions(deploy.mustGetAddress("ProtocolVersionsProxy"));
superchainConfig = ISuperchainConfig(deploy.mustGetAddress("SuperchainConfigProxy")); superchainConfig = ISuperchainConfig(deploy.mustGetAddress("SuperchainConfigProxy"));
anchorStateRegistry = IAnchorStateRegistry(deploy.mustGetAddress("AnchorStateRegistryProxy")); anchorStateRegistry = IAnchorStateRegistry(deploy.mustGetAddress("AnchorStateRegistryProxy"));
...@@ -178,8 +174,8 @@ contract Setup { ...@@ -178,8 +174,8 @@ contract Setup {
vm.label(address(addressManager), "AddressManager"); vm.label(address(addressManager), "AddressManager");
vm.label(address(l1ERC721Bridge), "L1ERC721Bridge"); vm.label(address(l1ERC721Bridge), "L1ERC721Bridge");
vm.label(deploy.mustGetAddress("L1ERC721BridgeProxy"), "L1ERC721BridgeProxy"); vm.label(deploy.mustGetAddress("L1ERC721BridgeProxy"), "L1ERC721BridgeProxy");
vm.label(address(l1OptimismMintableERC20Factory), "L1OptimismMintableERC20Factory"); vm.label(address(l1OptimismMintableERC20Factory), "OptimismMintableERC20Factory");
vm.label(deploy.mustGetAddress("L1OptimismMintableERC20FactoryProxy"), "L1OptimismMintableERC20FactoryProxy"); vm.label(deploy.mustGetAddress("OptimismMintableERC20FactoryProxy"), "OptimismMintableERC20FactoryProxy");
vm.label(address(protocolVersions), "ProtocolVersions"); vm.label(address(protocolVersions), "ProtocolVersions");
vm.label(deploy.mustGetAddress("ProtocolVersionsProxy"), "ProtocolVersionsProxy"); vm.label(deploy.mustGetAddress("ProtocolVersionsProxy"), "ProtocolVersionsProxy");
vm.label(address(superchainConfig), "SuperchainConfig"); vm.label(address(superchainConfig), "SuperchainConfig");
...@@ -204,16 +200,15 @@ contract Setup { ...@@ -204,16 +200,15 @@ contract Setup {
/// @dev Sets up the L2 contracts. Depends on `L1()` being called first. /// @dev Sets up the L2 contracts. Depends on `L1()` being called first.
function L2() public { function L2() public {
console.log("Setup: creating L2 genesis with fork %s", l2Fork.toString()); console.log("Setup: creating L2 genesis with fork %s", l2Fork.toString());
l2Genesis.runWithOptions({ l2Genesis.runWithOptions(
_mode: OutputMode.NONE, OutputMode.NONE,
_fork: l2Fork, l2Fork,
_populateNetworkConfig: false, L1Dependencies({
_l1Dependencies: L1Dependencies({
l1CrossDomainMessengerProxy: payable(address(l1CrossDomainMessenger)), l1CrossDomainMessengerProxy: payable(address(l1CrossDomainMessenger)),
l1StandardBridgeProxy: payable(address(l1StandardBridge)), l1StandardBridgeProxy: payable(address(l1StandardBridge)),
l1ERC721BridgeProxy: payable(address(l1ERC721Bridge)) l1ERC721BridgeProxy: payable(address(l1ERC721Bridge))
}) })
}); );
// Set the governance token's owner to be the final system owner // Set the governance token's owner to be the final system owner
address finalSystemOwner = deploy.cfg().finalSystemOwner(); address finalSystemOwner = deploy.cfg().finalSystemOwner();
...@@ -221,46 +216,8 @@ contract Setup { ...@@ -221,46 +216,8 @@ contract Setup {
governanceToken.transferOwnership(finalSystemOwner); governanceToken.transferOwnership(finalSystemOwner);
vm.stopPrank(); vm.stopPrank();
// These calls by the depositor account simulate the SystemConfig setting the
// network specific configuration into L2. Ideally there is a library that automatically
// translates TransactionDeposited and ConfigUpdate events into the appropriate calls
vm.startPrank(Constants.DEPOSITOR_ACCOUNT);
l1Block.setConfig(Types.ConfigType.L1_ERC_721_BRIDGE_ADDRESS, abi.encode(l1ERC721Bridge));
l1Block.setConfig(Types.ConfigType.REMOTE_CHAIN_ID, abi.encode(deploy.cfg().l1ChainID()));
l1Block.setConfig(Types.ConfigType.L1_CROSS_DOMAIN_MESSENGER_ADDRESS, abi.encode(l1CrossDomainMessenger));
l1Block.setConfig(Types.ConfigType.L1_STANDARD_BRIDGE_ADDRESS, abi.encode(l1StandardBridge));
bytes32 sequencerFeeVaultConfig = Encoding.encodeFeeVaultConfig({
_recipient: deploy.cfg().sequencerFeeVaultRecipient(),
_amount: deploy.cfg().sequencerFeeVaultMinimumWithdrawalAmount(),
_network: Types.WithdrawalNetwork(deploy.cfg().sequencerFeeVaultWithdrawalNetwork())
});
l1Block.setConfig(Types.ConfigType.SEQUENCER_FEE_VAULT_CONFIG, abi.encode(sequencerFeeVaultConfig));
bytes32 baseFeeVaultConfig = Encoding.encodeFeeVaultConfig({
_recipient: deploy.cfg().baseFeeVaultRecipient(),
_amount: deploy.cfg().baseFeeVaultMinimumWithdrawalAmount(),
_network: Types.WithdrawalNetwork(deploy.cfg().baseFeeVaultWithdrawalNetwork())
});
l1Block.setConfig(Types.ConfigType.BASE_FEE_VAULT_CONFIG, abi.encode(baseFeeVaultConfig));
bytes32 l1FeeVaultConfig = Encoding.encodeFeeVaultConfig({
_recipient: deploy.cfg().l1FeeVaultRecipient(),
_amount: deploy.cfg().l1FeeVaultMinimumWithdrawalAmount(),
_network: Types.WithdrawalNetwork(deploy.cfg().l1FeeVaultWithdrawalNetwork())
});
l1Block.setConfig(Types.ConfigType.L1_FEE_VAULT_CONFIG, abi.encode(l1FeeVaultConfig));
vm.stopPrank();
// Reset the ResourceConfig gas used to 0
bytes32 slot = vm.load(address(optimismPortal), bytes32(uint256(1)));
slot = bytes32(uint256(slot) & ~(uint256(type(uint64).max) << 128));
vm.store(address(optimismPortal), bytes32(uint256(1)), slot);
vm.store(address(optimismPortal2), bytes32(uint256(1)), slot);
// L2 predeploys // L2 predeploys
labelPredeploy(Predeploys.L2_STANDARD_BRIDGE); labelPredeploy(Predeploys.L2_STANDARD_BRIDGE);
labelPredeploy(Predeploys.OPTIMISM_MINTABLE_ERC721_FACTORY);
labelPredeploy(Predeploys.L2_CROSS_DOMAIN_MESSENGER); labelPredeploy(Predeploys.L2_CROSS_DOMAIN_MESSENGER);
labelPredeploy(Predeploys.L2_TO_L1_MESSAGE_PASSER); labelPredeploy(Predeploys.L2_TO_L1_MESSAGE_PASSER);
labelPredeploy(Predeploys.SEQUENCER_FEE_WALLET); labelPredeploy(Predeploys.SEQUENCER_FEE_WALLET);
...@@ -275,7 +232,6 @@ contract Setup { ...@@ -275,7 +232,6 @@ contract Setup {
labelPredeploy(Predeploys.EAS); labelPredeploy(Predeploys.EAS);
labelPredeploy(Predeploys.SCHEMA_REGISTRY); labelPredeploy(Predeploys.SCHEMA_REGISTRY);
labelPredeploy(Predeploys.WETH); labelPredeploy(Predeploys.WETH);
labelPredeploy(Predeploys.L2_ERC721_BRIDGE);
labelPredeploy(Predeploys.SUPERCHAIN_WETH); labelPredeploy(Predeploys.SUPERCHAIN_WETH);
labelPredeploy(Predeploys.ETH_LIQUIDITY); labelPredeploy(Predeploys.ETH_LIQUIDITY);
labelPredeploy(Predeploys.OPTIMISM_SUPERCHAIN_ERC20_FACTORY); labelPredeploy(Predeploys.OPTIMISM_SUPERCHAIN_ERC20_FACTORY);
...@@ -303,11 +259,7 @@ contract Setup { ...@@ -303,11 +259,7 @@ contract Setup {
} }
function labelPredeploy(address _addr) internal { function labelPredeploy(address _addr) internal {
string memory name = Predeploys.getName(_addr); vm.label(_addr, Predeploys.getName(_addr));
vm.label(_addr, name);
if (!Predeploys.notProxied(_addr)) {
vm.label(Predeploys.predeployToCodeNamespace(_addr), string.concat(name, "Implementation"));
}
} }
function labelPreinstall(address _addr) internal { function labelPreinstall(address _addr) internal {
......
...@@ -12,11 +12,19 @@ import { OptimismMintableERC20Factory } from "src/universal/OptimismMintableERC2 ...@@ -12,11 +12,19 @@ import { OptimismMintableERC20Factory } from "src/universal/OptimismMintableERC2
// Interfaces // Interfaces
import { IProxy } from "src/universal/interfaces/IProxy.sol"; import { IProxy } from "src/universal/interfaces/IProxy.sol";
import { IOptimismMintableERC20Factory } from "src/universal/interfaces/IOptimismMintableERC20Factory.sol";
contract OptimismMintableTokenFactory_Test is Bridge_Initializer { contract OptimismMintableTokenFactory_Test is Bridge_Initializer {
event StandardL2TokenCreated(address indexed remoteToken, address indexed localToken); event StandardL2TokenCreated(address indexed remoteToken, address indexed localToken);
event OptimismMintableERC20Created(address indexed localToken, address indexed remoteToken, address deployer); event OptimismMintableERC20Created(address indexed localToken, address indexed remoteToken, address deployer);
/// @notice Tests that the constructor is initialized correctly.
function test_constructor_succeeds() external {
IOptimismMintableERC20Factory impl = IOptimismMintableERC20Factory(address(new OptimismMintableERC20Factory()));
assertEq(address(impl.BRIDGE()), address(0));
assertEq(address(impl.bridge()), address(0));
}
/// @notice Tests that the proxy is initialized correctly. /// @notice Tests that the proxy is initialized correctly.
function test_initialize_succeeds() external view { function test_initialize_succeeds() external view {
assertEq(address(l1OptimismMintableERC20Factory.BRIDGE()), address(l1StandardBridge)); assertEq(address(l1OptimismMintableERC20Factory.BRIDGE()), address(l1StandardBridge));
...@@ -25,7 +33,7 @@ contract OptimismMintableTokenFactory_Test is Bridge_Initializer { ...@@ -25,7 +33,7 @@ contract OptimismMintableTokenFactory_Test is Bridge_Initializer {
/// @notice Tests that the upgrade is successful. /// @notice Tests that the upgrade is successful.
function test_upgrading_succeeds() external { function test_upgrading_succeeds() external {
IProxy proxy = IProxy(deploy.mustGetAddress("L1OptimismMintableERC20FactoryProxy")); IProxy proxy = IProxy(deploy.mustGetAddress("OptimismMintableERC20FactoryProxy"));
// Check an unused slot before upgrading. // Check an unused slot before upgrading.
bytes32 slot21Before = vm.load(address(l1OptimismMintableERC20Factory), bytes32(uint256(21))); bytes32 slot21Before = vm.load(address(l1OptimismMintableERC20Factory), bytes32(uint256(21)));
assertEq(bytes32(0), slot21Before); assertEq(bytes32(0), slot21Before);
......
...@@ -23,7 +23,7 @@ contract OptimismMintableERC721_Test is Bridge_Initializer { ...@@ -23,7 +23,7 @@ contract OptimismMintableERC721_Test is Bridge_Initializer {
// Set up the token pair. // Set up the token pair.
L1NFT = new ERC721("L1NFT", "L1T"); L1NFT = new ERC721("L1NFT", "L1T");
L2NFT = new OptimismMintableERC721(l2ERC721Bridge, 1, address(L1NFT), "L2NFT", "L2T"); L2NFT = new OptimismMintableERC721(address(l2ERC721Bridge), 1, address(L1NFT), "L2NFT", "L2T");
// Label the addresses for nice traces. // Label the addresses for nice traces.
vm.label(address(L1NFT), "L1ERC721Token"); vm.label(address(L1NFT), "L1ERC721Token");
...@@ -34,10 +34,10 @@ contract OptimismMintableERC721_Test is Bridge_Initializer { ...@@ -34,10 +34,10 @@ contract OptimismMintableERC721_Test is Bridge_Initializer {
assertEq(L2NFT.name(), "L2NFT"); assertEq(L2NFT.name(), "L2NFT");
assertEq(L2NFT.symbol(), "L2T"); assertEq(L2NFT.symbol(), "L2T");
assertEq(L2NFT.remoteToken(), address(L1NFT)); assertEq(L2NFT.remoteToken(), address(L1NFT));
assertEq(address(L2NFT.bridge()), address(l2ERC721Bridge)); assertEq(L2NFT.bridge(), address(l2ERC721Bridge));
assertEq(L2NFT.remoteChainId(), 1); assertEq(L2NFT.remoteChainId(), 1);
assertEq(L2NFT.REMOTE_TOKEN(), address(L1NFT)); assertEq(L2NFT.REMOTE_TOKEN(), address(L1NFT));
assertEq(address(L2NFT.BRIDGE()), address(l2ERC721Bridge)); assertEq(L2NFT.BRIDGE(), address(l2ERC721Bridge));
assertEq(L2NFT.REMOTE_CHAIN_ID(), 1); assertEq(L2NFT.REMOTE_CHAIN_ID(), 1);
} }
......
...@@ -4,15 +4,16 @@ pragma solidity 0.8.15; ...@@ -4,15 +4,16 @@ pragma solidity 0.8.15;
import { ERC721 } from "@openzeppelin/contracts/token/ERC721/ERC721.sol"; import { ERC721 } from "@openzeppelin/contracts/token/ERC721/ERC721.sol";
import { Bridge_Initializer } from "test/setup/Bridge_Initializer.sol"; import { Bridge_Initializer } from "test/setup/Bridge_Initializer.sol";
import { OptimismMintableERC721 } from "src/universal/OptimismMintableERC721.sol"; import { OptimismMintableERC721 } from "src/universal/OptimismMintableERC721.sol";
import { OptimismMintableERC721Factory } from "src/universal/OptimismMintableERC721Factory.sol";
contract OptimismMintableERC721Factory_Test is Bridge_Initializer { contract OptimismMintableERC721Factory_Test is Bridge_Initializer {
event OptimismMintableERC721Created(address indexed localToken, address indexed remoteToken, address deployer); event OptimismMintableERC721Created(address indexed localToken, address indexed remoteToken, address deployer);
function test_constructor_succeeds() external view { function test_constructor_succeeds() external view {
assertEq(address(l2OptimismMintableERC721Factory.BRIDGE()), address(l2ERC721Bridge)); assertEq(l2OptimismMintableERC721Factory.BRIDGE(), address(l2ERC721Bridge));
assertEq(address(l2OptimismMintableERC721Factory.bridge()), address(l2ERC721Bridge)); assertEq(l2OptimismMintableERC721Factory.bridge(), address(l2ERC721Bridge));
assertEq(l2OptimismMintableERC721Factory.REMOTE_CHAIN_ID(), deploy.cfg().l1ChainID()); assertEq(l2OptimismMintableERC721Factory.REMOTE_CHAIN_ID(), deploy.cfg().l1ChainID());
assertEq(l2OptimismMintableERC721Factory.remoteChainId(), deploy.cfg().l1ChainID()); assertEq(l2OptimismMintableERC721Factory.remoteChainID(), deploy.cfg().l1ChainID());
} }
function test_createOptimismMintableERC721_succeeds() external { function test_createOptimismMintableERC721_succeeds() external {
...@@ -39,7 +40,7 @@ contract OptimismMintableERC721Factory_Test is Bridge_Initializer { ...@@ -39,7 +40,7 @@ contract OptimismMintableERC721Factory_Test is Bridge_Initializer {
assertEq(created.name(), "L2Token"); assertEq(created.name(), "L2Token");
assertEq(created.symbol(), "L2T"); assertEq(created.symbol(), "L2T");
assertEq(created.REMOTE_TOKEN(), remote); assertEq(created.REMOTE_TOKEN(), remote);
assertEq(address(created.BRIDGE()), address(l2ERC721Bridge)); assertEq(created.BRIDGE(), address(l2ERC721Bridge));
assertEq(created.REMOTE_CHAIN_ID(), deploy.cfg().l1ChainID()); assertEq(created.REMOTE_CHAIN_ID(), deploy.cfg().l1ChainID());
} }
......
...@@ -14,6 +14,7 @@ import { OPContractsManager } from "src/L1/OPContractsManager.sol"; ...@@ -14,6 +14,7 @@ import { OPContractsManager } from "src/L1/OPContractsManager.sol";
// Interfaces // Interfaces
import { IOptimismPortal } from "src/L1/interfaces/IOptimismPortal.sol"; import { IOptimismPortal } from "src/L1/interfaces/IOptimismPortal.sol";
import { IOptimismPortal2 } from "src/L1/interfaces/IOptimismPortal2.sol"; import { IOptimismPortal2 } from "src/L1/interfaces/IOptimismPortal2.sol";
import { IOptimismPortalInterop } from "src/L1/interfaces/IOptimismPortalInterop.sol";
import { ISystemConfig } from "src/L1/interfaces/ISystemConfig.sol"; import { ISystemConfig } from "src/L1/interfaces/ISystemConfig.sol";
import { IDataAvailabilityChallenge } from "src/L1/interfaces/IDataAvailabilityChallenge.sol"; import { IDataAvailabilityChallenge } from "src/L1/interfaces/IDataAvailabilityChallenge.sol";
import { IProtocolVersions } from "src/L1/interfaces/IProtocolVersions.sol"; import { IProtocolVersions } from "src/L1/interfaces/IProtocolVersions.sol";
...@@ -41,8 +42,7 @@ contract Specification_Test is CommonTest { ...@@ -41,8 +42,7 @@ contract Specification_Test is CommonTest {
DELAYEDWETHOWNER, DELAYEDWETHOWNER,
COUNCILSAFE, COUNCILSAFE,
COUNCILSAFEOWNER, COUNCILSAFEOWNER,
DEPENDENCYMANAGER, DEPENDENCYMANAGER
FEEADMIN
} }
/// @notice Represents the specification of a function. /// @notice Represents the specification of a function.
...@@ -276,7 +276,7 @@ contract Specification_Test is CommonTest { ...@@ -276,7 +276,7 @@ contract Specification_Test is CommonTest {
_name: "OptimismPortal", _name: "OptimismPortal",
_sel: _getSel("depositERC20Transaction(address,uint256,uint256,uint64,bool,bytes)") _sel: _getSel("depositERC20Transaction(address,uint256,uint256,uint64,bool,bytes)")
}); });
_addSpec({ _name: "OptimismPortal", _sel: _getSel("setConfig(uint8,bytes)") }); _addSpec({ _name: "OptimismPortal", _sel: _getSel("setGasPayingToken(address,uint8,bytes32,bytes32)") });
// OptimismPortalInterop // OptimismPortalInterop
_addSpec({ _addSpec({
...@@ -335,8 +335,12 @@ contract Specification_Test is CommonTest { ...@@ -335,8 +335,12 @@ contract Specification_Test is CommonTest {
_name: "OptimismPortalInterop", _name: "OptimismPortalInterop",
_sel: _getSel("depositERC20Transaction(address,uint256,uint256,uint64,bool,bytes)") _sel: _getSel("depositERC20Transaction(address,uint256,uint256,uint64,bool,bytes)")
}); });
_addSpec({ _name: "OptimismPortalInterop", _sel: _getSel("upgrade(uint32,bytes)"), _auth: Role.FEEADMIN }); _addSpec({ _name: "OptimismPortalInterop", _sel: _getSel("setGasPayingToken(address,uint8,bytes32,bytes32)") });
_addSpec({ _name: "OptimismPortalInterop", _sel: _getSel("setConfig(uint8,bytes)") }); _addSpec({
_name: "OptimismPortalInterop",
_sel: IOptimismPortalInterop.setConfig.selector,
_auth: Role.SYSTEMCONFIGOWNER
});
// OptimismPortal2 // OptimismPortal2
_addSpec({ _name: "OptimismPortal2", _sel: _getSel("depositTransaction(address,uint256,uint64,bool,bytes)") }); _addSpec({ _name: "OptimismPortal2", _sel: _getSel("depositTransaction(address,uint256,uint64,bool,bytes)") });
...@@ -383,27 +387,7 @@ contract Specification_Test is CommonTest { ...@@ -383,27 +387,7 @@ contract Specification_Test is CommonTest {
_name: "OptimismPortal2", _name: "OptimismPortal2",
_sel: _getSel("depositERC20Transaction(address,uint256,uint256,uint64,bool,bytes)") _sel: _getSel("depositERC20Transaction(address,uint256,uint256,uint64,bool,bytes)")
}); });
_addSpec({ _name: "OptimismPortal2", _sel: _getSel("upgrade(uint32,bytes)"), _auth: Role.FEEADMIN }); _addSpec({ _name: "OptimismPortal2", _sel: _getSel("setGasPayingToken(address,uint8,bytes32,bytes32)") });
_addSpec({ _name: "OptimismPortal2", _sel: _getSel("setConfig(uint8,bytes)") });
// L1OptimismMintableERC20Factory
_addSpec({ _name: "L1OptimismMintableERC20Factory", _sel: _getSel("BRIDGE()") });
_addSpec({ _name: "L1OptimismMintableERC20Factory", _sel: _getSel("bridge()") });
_addSpec({
_name: "L1OptimismMintableERC20Factory",
_sel: _getSel("createOptimismMintableERC20(address,string,string)")
});
_addSpec({
_name: "L1OptimismMintableERC20Factory",
_sel: _getSel("createOptimismMintableERC20WithDecimals(address,string,string,uint8)")
});
_addSpec({
_name: "L1OptimismMintableERC20Factory",
_sel: _getSel("createStandardL2Token(address,string,string)")
});
_addSpec({ _name: "L1OptimismMintableERC20Factory", _sel: _getSel("deployments(address)") });
_addSpec({ _name: "L1OptimismMintableERC20Factory", _sel: _getSel("version()") });
_addSpec({ _name: "L1OptimismMintableERC20Factory", _sel: _getSel("initialize(address)") });
// ProtocolVersions // ProtocolVersions
_addSpec({ _name: "ProtocolVersions", _sel: _getSel("RECOMMENDED_SLOT()") }); _addSpec({ _name: "ProtocolVersions", _sel: _getSel("RECOMMENDED_SLOT()") });
...@@ -434,13 +418,11 @@ contract Specification_Test is CommonTest { ...@@ -434,13 +418,11 @@ contract Specification_Test is CommonTest {
_addSpec({ _name: "SuperchainConfig", _sel: _getSel("GUARDIAN_SLOT()") }); _addSpec({ _name: "SuperchainConfig", _sel: _getSel("GUARDIAN_SLOT()") });
_addSpec({ _name: "SuperchainConfig", _sel: _getSel("PAUSED_SLOT()") }); _addSpec({ _name: "SuperchainConfig", _sel: _getSel("PAUSED_SLOT()") });
_addSpec({ _name: "SuperchainConfig", _sel: _getSel("guardian()") }); _addSpec({ _name: "SuperchainConfig", _sel: _getSel("guardian()") });
_addSpec({ _name: "SuperchainConfig", _sel: _getSel("initialize(address,address,bool)") }); _addSpec({ _name: "SuperchainConfig", _sel: _getSel("initialize(address,bool)") });
_addSpec({ _name: "SuperchainConfig", _sel: _getSel("pause(string)"), _auth: Role.GUARDIAN }); _addSpec({ _name: "SuperchainConfig", _sel: _getSel("pause(string)"), _auth: Role.GUARDIAN });
_addSpec({ _name: "SuperchainConfig", _sel: _getSel("paused()") }); _addSpec({ _name: "SuperchainConfig", _sel: _getSel("paused()") });
_addSpec({ _name: "SuperchainConfig", _sel: _getSel("unpause()"), _auth: Role.GUARDIAN }); _addSpec({ _name: "SuperchainConfig", _sel: _getSel("unpause()"), _auth: Role.GUARDIAN });
_addSpec({ _name: "SuperchainConfig", _sel: _getSel("version()") }); _addSpec({ _name: "SuperchainConfig", _sel: _getSel("version()") });
_addSpec({ _name: "SuperchainConfig", _sel: _getSel("UPGRADER_SLOT()") });
_addSpec({ _name: "SuperchainConfig", _sel: _getSel("upgrader()") });
// SystemConfig // SystemConfig
_addSpec({ _name: "SystemConfig", _sel: _getSel("UNSAFE_BLOCK_SIGNER_SLOT()") }); _addSpec({ _name: "SystemConfig", _sel: _getSel("UNSAFE_BLOCK_SIGNER_SLOT()") });
...@@ -454,7 +436,6 @@ contract Specification_Test is CommonTest { ...@@ -454,7 +436,6 @@ contract Specification_Test is CommonTest {
_addSpec({ _name: "SystemConfig", _sel: ISystemConfig.minimumGasLimit.selector }); _addSpec({ _name: "SystemConfig", _sel: ISystemConfig.minimumGasLimit.selector });
_addSpec({ _name: "SystemConfig", _sel: _getSel("overhead()") }); _addSpec({ _name: "SystemConfig", _sel: _getSel("overhead()") });
_addSpec({ _name: "SystemConfig", _sel: _getSel("owner()") }); _addSpec({ _name: "SystemConfig", _sel: _getSel("owner()") });
_addSpec({ _name: "SystemConfig", _sel: _getSel("feeAdmin()") });
_addSpec({ _name: "SystemConfig", _sel: _getSel("renounceOwnership()"), _auth: Role.SYSTEMCONFIGOWNER }); _addSpec({ _name: "SystemConfig", _sel: _getSel("renounceOwnership()"), _auth: Role.SYSTEMCONFIGOWNER });
_addSpec({ _name: "SystemConfig", _sel: ISystemConfig.resourceConfig.selector }); _addSpec({ _name: "SystemConfig", _sel: ISystemConfig.resourceConfig.selector });
_addSpec({ _name: "SystemConfig", _sel: _getSel("scalar()") }); _addSpec({ _name: "SystemConfig", _sel: _getSel("scalar()") });
...@@ -497,7 +478,6 @@ contract Specification_Test is CommonTest { ...@@ -497,7 +478,6 @@ contract Specification_Test is CommonTest {
_addSpec({ _name: "SystemConfig", _sel: _getSel("basefeeScalar()") }); _addSpec({ _name: "SystemConfig", _sel: _getSel("basefeeScalar()") });
_addSpec({ _name: "SystemConfig", _sel: _getSel("blobbasefeeScalar()") }); _addSpec({ _name: "SystemConfig", _sel: _getSel("blobbasefeeScalar()") });
_addSpec({ _name: "SystemConfig", _sel: _getSel("maximumGasLimit()") }); _addSpec({ _name: "SystemConfig", _sel: _getSel("maximumGasLimit()") });
_addSpec({ _name: "SystemConfig", _sel: _getSel("setFeeVaultConfig(uint8,address,uint256,uint8)") });
// SystemConfigInterop // SystemConfigInterop
_addSpec({ _name: "SystemConfigInterop", _sel: _getSel("UNSAFE_BLOCK_SIGNER_SLOT()") }); _addSpec({ _name: "SystemConfigInterop", _sel: _getSel("UNSAFE_BLOCK_SIGNER_SLOT()") });
...@@ -509,15 +489,8 @@ contract Specification_Test is CommonTest { ...@@ -509,15 +489,8 @@ contract Specification_Test is CommonTest {
_addSpec({ _name: "SystemConfigInterop", _sel: _getSel("eip1559Elasticity()") }); _addSpec({ _name: "SystemConfigInterop", _sel: _getSel("eip1559Elasticity()") });
_addSpec({ _name: "SystemConfigInterop", _sel: ISystemConfig.initialize.selector }); _addSpec({ _name: "SystemConfigInterop", _sel: ISystemConfig.initialize.selector });
_addSpec({ _name: "SystemConfigInterop", _sel: ISystemConfig.minimumGasLimit.selector }); _addSpec({ _name: "SystemConfigInterop", _sel: ISystemConfig.minimumGasLimit.selector });
_addSpec({
_name: "SystemConfigInterop",
_sel: _getSel(
"initialize((address,address,address,bytes32),uint32,uint32,uint64,(uint32,uint8,uint8,uint32,uint32,uint128),address,(address,address,address,address,address,address,address),address)"
)
});
_addSpec({ _name: "SystemConfigInterop", _sel: _getSel("overhead()") }); _addSpec({ _name: "SystemConfigInterop", _sel: _getSel("overhead()") });
_addSpec({ _name: "SystemConfigInterop", _sel: _getSel("owner()") }); _addSpec({ _name: "SystemConfigInterop", _sel: _getSel("owner()") });
_addSpec({ _name: "SystemConfigInterop", _sel: _getSel("feeAdmin()") });
_addSpec({ _name: "SystemConfigInterop", _sel: _getSel("renounceOwnership()"), _auth: Role.SYSTEMCONFIGOWNER }); _addSpec({ _name: "SystemConfigInterop", _sel: _getSel("renounceOwnership()"), _auth: Role.SYSTEMCONFIGOWNER });
_addSpec({ _name: "SystemConfigInterop", _sel: ISystemConfig.resourceConfig.selector }); _addSpec({ _name: "SystemConfigInterop", _sel: ISystemConfig.resourceConfig.selector });
_addSpec({ _name: "SystemConfigInterop", _sel: _getSel("scalar()") }); _addSpec({ _name: "SystemConfigInterop", _sel: _getSel("scalar()") });
...@@ -587,7 +560,12 @@ contract Specification_Test is CommonTest { ...@@ -587,7 +560,12 @@ contract Specification_Test is CommonTest {
_auth: Role.DEPENDENCYMANAGER _auth: Role.DEPENDENCYMANAGER
}); });
_addSpec({ _name: "SystemConfigInterop", _sel: _getSel("dependencyManager()") }); _addSpec({ _name: "SystemConfigInterop", _sel: _getSel("dependencyManager()") });
_addSpec({ _name: "SystemConfigInterop", _sel: _getSel("setFeeVaultConfig(uint8,address,uint256,uint8)") }); _addSpec({
_name: "SystemConfigInterop",
_sel: _getSel(
"initialize(address,uint32,uint32,bytes32,uint64,address,(uint32,uint8,uint8,uint32,uint32,uint128),address,(address,address,address,address,address,address,address),address)"
)
});
// ProxyAdmin // ProxyAdmin
_addSpec({ _name: "ProxyAdmin", _sel: _getSel("addressManager()") }); _addSpec({ _name: "ProxyAdmin", _sel: _getSel("addressManager()") });
......
...@@ -2,12 +2,10 @@ ...@@ -2,12 +2,10 @@
pragma solidity 0.8.15; pragma solidity 0.8.15;
import { StandardBridge } from "src/universal/StandardBridge.sol"; import { StandardBridge } from "src/universal/StandardBridge.sol";
import { IStandardBridge } from "src/universal/interfaces/IStandardBridge.sol";
import { CommonTest } from "test/setup/CommonTest.sol"; import { CommonTest } from "test/setup/CommonTest.sol";
import { OptimismMintableERC20, ILegacyMintableERC20 } from "src/universal/OptimismMintableERC20.sol"; import { OptimismMintableERC20, ILegacyMintableERC20 } from "src/universal/OptimismMintableERC20.sol";
import { ERC20 } from "@openzeppelin/contracts/token/ERC20/ERC20.sol"; import { ERC20 } from "@openzeppelin/contracts/token/ERC20/ERC20.sol";
import { Constants } from "src/libraries/Constants.sol"; import { Constants } from "src/libraries/Constants.sol";
import { ICrossDomainMessenger } from "src/universal/interfaces/ICrossDomainMessenger.sol";
/// @title StandardBridgeTester /// @title StandardBridgeTester
/// @notice Simple wrapper around the StandardBridge contract that exposes /// @notice Simple wrapper around the StandardBridge contract that exposes
...@@ -23,14 +21,6 @@ contract StandardBridgeTester is StandardBridge { ...@@ -23,14 +21,6 @@ contract StandardBridgeTester is StandardBridge {
return _isCorrectTokenPair(_mintableToken, _otherToken); return _isCorrectTokenPair(_mintableToken, _otherToken);
} }
function otherBridge() public pure override returns (IStandardBridge) {
return IStandardBridge(payable(address(0)));
}
function messenger() public pure override returns (ICrossDomainMessenger) {
return ICrossDomainMessenger(address(0));
}
function gasPayingToken() internal pure override returns (address, uint8) { function gasPayingToken() internal pure override returns (address, uint8) {
return (Constants.ETHER, 18); return (Constants.ETHER, 18);
} }
......
...@@ -28,10 +28,6 @@ import { IAnchorStateRegistry } from "src/dispute/interfaces/IAnchorStateRegistr ...@@ -28,10 +28,6 @@ import { IAnchorStateRegistry } from "src/dispute/interfaces/IAnchorStateRegistr
/// deepest contract in the inheritance chain for setting up the system contracts. /// deepest contract in the inheritance chain for setting up the system contracts.
/// For each L1 contract both the implementation and the proxy are tested. /// For each L1 contract both the implementation and the proxy are tested.
contract Initializer_Test is Bridge_Initializer { contract Initializer_Test is Bridge_Initializer {
/// @notice Error used by openzeppelin v5 initializable.
/// The contract is already initialized.
error InvalidInitialization();
/// @notice Contains the address of an `Initializable` contract and the calldata /// @notice Contains the address of an `Initializable` contract and the calldata
/// used to initialize it. /// used to initialize it.
struct InitializeableContract { struct InitializeableContract {
...@@ -61,7 +57,7 @@ contract Initializer_Test is Bridge_Initializer { ...@@ -61,7 +57,7 @@ contract Initializer_Test is Bridge_Initializer {
InitializeableContract({ InitializeableContract({
name: "SuperchainConfig", name: "SuperchainConfig",
target: deploy.mustGetAddress("SuperchainConfig"), target: deploy.mustGetAddress("SuperchainConfig"),
initCalldata: abi.encodeCall(superchainConfig.initialize, (address(0), address(0), false)) initCalldata: abi.encodeCall(superchainConfig.initialize, (address(0), false))
}) })
); );
// SuperchainConfigProxy // SuperchainConfigProxy
...@@ -69,7 +65,7 @@ contract Initializer_Test is Bridge_Initializer { ...@@ -69,7 +65,7 @@ contract Initializer_Test is Bridge_Initializer {
InitializeableContract({ InitializeableContract({
name: "SuperchainConfigProxy", name: "SuperchainConfigProxy",
target: address(superchainConfig), target: address(superchainConfig),
initCalldata: abi.encodeCall(superchainConfig.initialize, (address(0), address(0), false)) initCalldata: abi.encodeCall(superchainConfig.initialize, (address(0), false))
}) })
); );
// L1CrossDomainMessengerImpl // L1CrossDomainMessengerImpl
...@@ -180,15 +176,12 @@ contract Initializer_Test is Bridge_Initializer { ...@@ -180,15 +176,12 @@ contract Initializer_Test is Bridge_Initializer {
initCalldata: abi.encodeCall( initCalldata: abi.encodeCall(
systemConfig.initialize, systemConfig.initialize,
( (
ISystemConfig.Roles({ address(0xdead),
owner: address(0xdead),
feeAdmin: address(0xdead),
unsafeBlockSigner: address(0),
batcherHash: bytes32(0)
}),
0, 0,
0, 0,
bytes32(0),
1, 1,
address(0),
IResourceMetering.ResourceConfig({ IResourceMetering.ResourceConfig({
maxResourceLimit: 1, maxResourceLimit: 1,
elasticityMultiplier: 1, elasticityMultiplier: 1,
...@@ -219,15 +212,12 @@ contract Initializer_Test is Bridge_Initializer { ...@@ -219,15 +212,12 @@ contract Initializer_Test is Bridge_Initializer {
initCalldata: abi.encodeCall( initCalldata: abi.encodeCall(
systemConfig.initialize, systemConfig.initialize,
( (
ISystemConfig.Roles({ address(0xdead),
owner: address(0xdead),
feeAdmin: address(0xdead),
unsafeBlockSigner: address(0),
batcherHash: bytes32(0)
}),
0, 0,
0, 0,
bytes32(0),
1, 1,
address(0),
IResourceMetering.ResourceConfig({ IResourceMetering.ResourceConfig({
maxResourceLimit: 1, maxResourceLimit: 1,
elasticityMultiplier: 1, elasticityMultiplier: 1,
...@@ -270,6 +260,14 @@ contract Initializer_Test is Bridge_Initializer { ...@@ -270,6 +260,14 @@ contract Initializer_Test is Bridge_Initializer {
) )
}) })
); );
// L2CrossDomainMessenger
contracts.push(
InitializeableContract({
name: "L2CrossDomainMessenger",
target: address(l2CrossDomainMessenger),
initCalldata: abi.encodeCall(l2CrossDomainMessenger.initialize, (l1CrossDomainMessenger))
})
);
// L1StandardBridgeImpl // L1StandardBridgeImpl
contracts.push( contracts.push(
InitializeableContract({ InitializeableContract({
...@@ -290,6 +288,22 @@ contract Initializer_Test is Bridge_Initializer { ...@@ -290,6 +288,22 @@ contract Initializer_Test is Bridge_Initializer {
) )
}) })
); );
// L2StandardBridge
contracts.push(
InitializeableContract({
name: "L2StandardBridge",
target: address(l2StandardBridge),
initCalldata: abi.encodeCall(l2StandardBridge.initialize, (l1StandardBridge))
})
);
// L2StandardBridgeInterop
contracts.push(
InitializeableContract({
name: "L2StandardBridgeInterop",
target: address(l2StandardBridge),
initCalldata: abi.encodeCall(l2StandardBridge.initialize, (l1StandardBridge))
})
);
// L1ERC721BridgeImpl // L1ERC721BridgeImpl
contracts.push( contracts.push(
InitializeableContract({ InitializeableContract({
...@@ -306,18 +320,26 @@ contract Initializer_Test is Bridge_Initializer { ...@@ -306,18 +320,26 @@ contract Initializer_Test is Bridge_Initializer {
initCalldata: abi.encodeCall(l1ERC721Bridge.initialize, (l1CrossDomainMessenger, superchainConfig)) initCalldata: abi.encodeCall(l1ERC721Bridge.initialize, (l1CrossDomainMessenger, superchainConfig))
}) })
); );
// L1OptimismMintableERC20FactoryImpl // L2ERC721Bridge
contracts.push(
InitializeableContract({
name: "L2ERC721Bridge",
target: address(l2ERC721Bridge),
initCalldata: abi.encodeCall(l2ERC721Bridge.initialize, (payable(address(l1ERC721Bridge))))
})
);
// OptimismMintableERC20FactoryImpl
contracts.push( contracts.push(
InitializeableContract({ InitializeableContract({
name: "L1OptimismMintableERC20Factory", name: "OptimismMintableERC20Factory",
target: deploy.mustGetAddress("OptimismMintableERC20Factory"), target: deploy.mustGetAddress("OptimismMintableERC20Factory"),
initCalldata: abi.encodeCall(l1OptimismMintableERC20Factory.initialize, (address(l1StandardBridge))) initCalldata: abi.encodeCall(l1OptimismMintableERC20Factory.initialize, (address(l1StandardBridge)))
}) })
); );
// L1OptimismMintableERC20FactoryProxy // OptimismMintableERC20FactoryProxy
contracts.push( contracts.push(
InitializeableContract({ InitializeableContract({
name: "L1OptimismMintableERC20FactoryProxy", name: "OptimismMintableERC20FactoryProxy",
target: address(l1OptimismMintableERC20Factory), target: address(l1OptimismMintableERC20Factory),
initCalldata: abi.encodeCall(l1OptimismMintableERC20Factory.initialize, (address(l1StandardBridge))) initCalldata: abi.encodeCall(l1OptimismMintableERC20Factory.initialize, (address(l1StandardBridge)))
}) })
...@@ -465,7 +487,7 @@ contract Initializer_Test is Bridge_Initializer { ...@@ -465,7 +487,7 @@ contract Initializer_Test is Bridge_Initializer {
// Then, attempt to re-initialize the contract. This should fail. // Then, attempt to re-initialize the contract. This should fail.
(bool success, bytes memory returnData) = _contract.target.call(_contract.initCalldata); (bool success, bytes memory returnData) = _contract.target.call(_contract.initCalldata);
assertFalse(success); assertFalse(success);
assertErrorString(returnData); assertEq(_extractErrorString(returnData), "Initializable: contract is already initialized");
} }
} }
...@@ -487,12 +509,10 @@ contract Initializer_Test is Bridge_Initializer { ...@@ -487,12 +509,10 @@ contract Initializer_Test is Bridge_Initializer {
real_ = bytes(nicknames[_name]).length > 0 ? nicknames[_name] : _name; real_ = bytes(nicknames[_name]).length > 0 ? nicknames[_name] : _name;
} }
/// @dev Asserts the expected revert from the returndata /// @dev Extracts the revert string from returndata encoded in the form of `Error(string)`.
function assertErrorString(bytes memory _returnData) internal pure returns (string memory error_) { function _extractErrorString(bytes memory _returnData) internal pure returns (string memory error_) {
if (bytes4(_returnData) == InvalidInitialization.selector) {
// do nothing as this is the correct 4byte returndata
} else if (bytes4(_returnData) == 0x08c379a0) {
// The first 4 bytes of the return data should be the selector for `Error(string)`. If not, revert. // The first 4 bytes of the return data should be the selector for `Error(string)`. If not, revert.
if (bytes4(_returnData) == 0x08c379a0) {
// Extract the error string from the returndata. The error string is located 68 bytes after // Extract the error string from the returndata. The error string is located 68 bytes after
// the pointer to `returnData`. // the pointer to `returnData`.
// //
...@@ -503,7 +523,6 @@ contract Initializer_Test is Bridge_Initializer { ...@@ -503,7 +523,6 @@ contract Initializer_Test is Bridge_Initializer {
assembly { assembly {
error_ := add(_returnData, 0x44) error_ := add(_returnData, 0x44)
} }
assertEq(error_, "Initializable: contract is already initialized");
} else { } else {
revert("Initializer_Test: Invalid returndata format. Expected `Error(string)`"); revert("Initializer_Test: Invalid returndata format. Expected `Error(string)`");
} }
......
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