Commit 5279572c authored by mergify[bot]'s avatar mergify[bot] Committed by GitHub

Merge branch 'develop' into 08-03-bridge_transaction/transfer_schema_models

parents d9ed92d7 86914a57
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
...@@ -9,7 +9,7 @@ import ( ...@@ -9,7 +9,7 @@ import (
"github.com/ethereum-optimism/optimism/op-bindings/solc" "github.com/ethereum-optimism/optimism/op-bindings/solc"
) )
const StandardBridgeStorageLayoutJSON = "{\"storage\":[{\"astId\":1000,\"contract\":\"src/universal/StandardBridge.sol:StandardBridge\",\"label\":\"spacer_0_0_20\",\"offset\":0,\"slot\":\"0\",\"type\":\"t_address\"},{\"astId\":1001,\"contract\":\"src/universal/StandardBridge.sol:StandardBridge\",\"label\":\"spacer_1_0_20\",\"offset\":0,\"slot\":\"1\",\"type\":\"t_address\"},{\"astId\":1002,\"contract\":\"src/universal/StandardBridge.sol:StandardBridge\",\"label\":\"deposits\",\"offset\":0,\"slot\":\"2\",\"type\":\"t_mapping(t_address,t_mapping(t_address,t_uint256))\"},{\"astId\":1003,\"contract\":\"src/universal/StandardBridge.sol:StandardBridge\",\"label\":\"__gap\",\"offset\":0,\"slot\":\"3\",\"type\":\"t_array(t_uint256)47_storage\"}],\"types\":{\"t_address\":{\"encoding\":\"inplace\",\"label\":\"address\",\"numberOfBytes\":\"20\"},\"t_array(t_uint256)47_storage\":{\"encoding\":\"inplace\",\"label\":\"uint256[47]\",\"numberOfBytes\":\"1504\",\"base\":\"t_uint256\"},\"t_mapping(t_address,t_mapping(t_address,t_uint256))\":{\"encoding\":\"mapping\",\"label\":\"mapping(address =\u003e mapping(address =\u003e uint256))\",\"numberOfBytes\":\"32\",\"key\":\"t_address\",\"value\":\"t_mapping(t_address,t_uint256)\"},\"t_mapping(t_address,t_uint256)\":{\"encoding\":\"mapping\",\"label\":\"mapping(address =\u003e uint256)\",\"numberOfBytes\":\"32\",\"key\":\"t_address\",\"value\":\"t_uint256\"},\"t_uint256\":{\"encoding\":\"inplace\",\"label\":\"uint256\",\"numberOfBytes\":\"32\"}}}" const StandardBridgeStorageLayoutJSON = "{\"storage\":[{\"astId\":1000,\"contract\":\"src/universal/StandardBridge.sol:StandardBridge\",\"label\":\"_initialized\",\"offset\":0,\"slot\":\"0\",\"type\":\"t_uint8\"},{\"astId\":1001,\"contract\":\"src/universal/StandardBridge.sol:StandardBridge\",\"label\":\"_initializing\",\"offset\":1,\"slot\":\"0\",\"type\":\"t_bool\"},{\"astId\":1002,\"contract\":\"src/universal/StandardBridge.sol:StandardBridge\",\"label\":\"spacer_0_2_20\",\"offset\":2,\"slot\":\"0\",\"type\":\"t_address\"},{\"astId\":1003,\"contract\":\"src/universal/StandardBridge.sol:StandardBridge\",\"label\":\"spacer_1_0_20\",\"offset\":0,\"slot\":\"1\",\"type\":\"t_address\"},{\"astId\":1004,\"contract\":\"src/universal/StandardBridge.sol:StandardBridge\",\"label\":\"deposits\",\"offset\":0,\"slot\":\"2\",\"type\":\"t_mapping(t_address,t_mapping(t_address,t_uint256))\"},{\"astId\":1005,\"contract\":\"src/universal/StandardBridge.sol:StandardBridge\",\"label\":\"messenger\",\"offset\":0,\"slot\":\"3\",\"type\":\"t_contract(CrossDomainMessenger)1007\"},{\"astId\":1006,\"contract\":\"src/universal/StandardBridge.sol:StandardBridge\",\"label\":\"__gap\",\"offset\":0,\"slot\":\"4\",\"type\":\"t_array(t_uint256)46_storage\"}],\"types\":{\"t_address\":{\"encoding\":\"inplace\",\"label\":\"address\",\"numberOfBytes\":\"20\"},\"t_array(t_uint256)46_storage\":{\"encoding\":\"inplace\",\"label\":\"uint256[46]\",\"numberOfBytes\":\"1472\",\"base\":\"t_uint256\"},\"t_bool\":{\"encoding\":\"inplace\",\"label\":\"bool\",\"numberOfBytes\":\"1\"},\"t_contract(CrossDomainMessenger)1007\":{\"encoding\":\"inplace\",\"label\":\"contract CrossDomainMessenger\",\"numberOfBytes\":\"20\"},\"t_mapping(t_address,t_mapping(t_address,t_uint256))\":{\"encoding\":\"mapping\",\"label\":\"mapping(address =\u003e mapping(address =\u003e uint256))\",\"numberOfBytes\":\"32\",\"key\":\"t_address\",\"value\":\"t_mapping(t_address,t_uint256)\"},\"t_mapping(t_address,t_uint256)\":{\"encoding\":\"mapping\",\"label\":\"mapping(address =\u003e uint256)\",\"numberOfBytes\":\"32\",\"key\":\"t_address\",\"value\":\"t_uint256\"},\"t_uint256\":{\"encoding\":\"inplace\",\"label\":\"uint256\",\"numberOfBytes\":\"32\"},\"t_uint8\":{\"encoding\":\"inplace\",\"label\":\"uint8\",\"numberOfBytes\":\"1\"}}}"
var StandardBridgeStorageLayout = new(solc.StorageLayout) var StandardBridgeStorageLayout = new(solc.StorageLayout)
......
...@@ -64,6 +64,15 @@ func (s *StorageLayout) GetStorageLayoutEntry(name string) (StorageLayoutEntry, ...@@ -64,6 +64,15 @@ func (s *StorageLayout) GetStorageLayoutEntry(name string) (StorageLayoutEntry,
return StorageLayoutEntry{}, fmt.Errorf("%s not found", name) return StorageLayoutEntry{}, fmt.Errorf("%s not found", name)
} }
// GetStorageLayoutType returns the StorageLayoutType where the label matches
// the provided name.
func (s *StorageLayout) GetStorageLayoutType(name string) (StorageLayoutType, error) {
if ty, ok := s.Types[name]; ok {
return ty, nil
}
return StorageLayoutType{}, fmt.Errorf("%s not found", name)
}
type StorageLayoutEntry struct { type StorageLayoutEntry struct {
AstId uint `json:"astId"` AstId uint `json:"astId"`
Contract string `json:"contract"` Contract string `json:"contract"`
......
...@@ -36,16 +36,16 @@ func main() { ...@@ -36,16 +36,16 @@ func main() {
Usage: "Check that an OP Stack L2 has been configured correctly", Usage: "Check that an OP Stack L2 has been configured correctly",
Flags: []cli.Flag{ Flags: []cli.Flag{
&cli.StringFlag{ &cli.StringFlag{
Name: "l1-rpc-url", Name: "l1-rpc-url",
Required: true, Value: "http://127.0.0.1:8545",
Usage: "L1 RPC URL", Usage: "L1 RPC URL",
EnvVars: []string{"L1_RPC_URL"}, EnvVars: []string{"L1_RPC_URL"},
}, },
&cli.StringFlag{ &cli.StringFlag{
Name: "l2-rpc-url", Name: "l2-rpc-url",
Required: true, Value: "http://127.0.0.1:9545",
Usage: "L2 RPC URL", Usage: "L2 RPC URL",
EnvVars: []string{"L2_RPC_URL"}, EnvVars: []string{"L2_RPC_URL"},
}, },
}, },
Action: entrypoint, Action: entrypoint,
...@@ -603,11 +603,17 @@ func checkL2StandardBridge(addr common.Address, client *ethclient.Client) error ...@@ -603,11 +603,17 @@ func checkL2StandardBridge(addr common.Address, client *ethclient.Client) error
if messenger != predeploys.L2CrossDomainMessengerAddr { if messenger != predeploys.L2CrossDomainMessengerAddr {
return fmt.Errorf("L2StandardBridge MESSENGER should be %s, got %s", predeploys.L2CrossDomainMessengerAddr, messenger) return fmt.Errorf("L2StandardBridge MESSENGER should be %s, got %s", predeploys.L2CrossDomainMessengerAddr, messenger)
} }
version, err := contract.Version(&bind.CallOpts{}) version, err := contract.Version(&bind.CallOpts{})
if err != nil { if err != nil {
return err return err
} }
initialized, err := getInitialized("L2StandardBridge", addr, client)
if err != nil {
return err
}
log.Info("L2StandardBridge", "_initialized", initialized)
log.Info("L2StandardBridge version", "version", version) log.Info("L2StandardBridge version", "version", version)
return nil return nil
} }
...@@ -714,6 +720,13 @@ func checkL2CrossDomainMessenger(addr common.Address, client *ethclient.Client) ...@@ -714,6 +720,13 @@ func checkL2CrossDomainMessenger(addr common.Address, client *ethclient.Client)
if err != nil { if err != nil {
return err return err
} }
initialized, err := getInitialized("L2CrossDomainMessenger", addr, client)
if err != nil {
return err
}
log.Info("L2CrossDomainMessenger", "_initialized", initialized)
log.Info("L2CrossDomainMessenger version", "version", version) log.Info("L2CrossDomainMessenger version", "version", version)
return nil return nil
} }
...@@ -805,3 +818,36 @@ func getEIP1967ImplementationAddress(client *ethclient.Client, addr common.Addre ...@@ -805,3 +818,36 @@ func getEIP1967ImplementationAddress(client *ethclient.Client, addr common.Addre
impl := common.BytesToAddress(slot) impl := common.BytesToAddress(slot)
return impl, nil return impl, nil
} }
// getInitialized will get the initialized value in storage of a contract.
// This is an incrementing number that starts at 1 and increments each time that
// the contract is upgraded.
func getInitialized(name string, addr common.Address, client *ethclient.Client) (*big.Int, error) {
layout, err := bindings.GetStorageLayout(name)
if err != nil {
return nil, err
}
entry, err := layout.GetStorageLayoutEntry("_initialized")
if err != nil {
return nil, err
}
typ, err := layout.GetStorageLayoutType(entry.Type)
if err != nil {
return nil, err
}
slot := common.BigToHash(big.NewInt(int64(entry.Slot)))
value, err := client.StorageAt(context.Background(), addr, slot, nil)
if err != nil {
return nil, err
}
if entry.Offset+typ.NumberOfBytes > uint(len(value)) {
return nil, fmt.Errorf("value length is too short")
}
// Swap the endianness
slice := common.CopyBytes(value)
for i, j := 0, len(slice)-1; i < j; i, j = i+1, j-1 {
slice[i], slice[j] = slice[j], slice[i]
}
initialized := new(big.Int).SetBytes(slice[entry.Offset : entry.Offset+typ.NumberOfBytes])
return initialized, nil
}
...@@ -656,6 +656,11 @@ func NewL2StorageConfig(config *DeployConfig, block *types.Block) (state.Storage ...@@ -656,6 +656,11 @@ func NewL2StorageConfig(config *DeployConfig, block *types.Block) (state.Storage
"xDomainMsgSender": "0x000000000000000000000000000000000000dEaD", "xDomainMsgSender": "0x000000000000000000000000000000000000dEaD",
"msgNonce": 0, "msgNonce": 0,
} }
storage["L2StandardBridge"] = state.StorageValues{
"_initialized": 2,
"_initializing": false,
"messenger": predeploys.L2CrossDomainMessengerAddr,
}
storage["L1Block"] = state.StorageValues{ storage["L1Block"] = state.StorageValues{
"number": block.Number(), "number": block.Number(),
"timestamp": block.Time(), "timestamp": block.Time(),
......
...@@ -3,6 +3,7 @@ package challenger ...@@ -3,6 +3,7 @@ package challenger
import ( import (
"context" "context"
"errors" "errors"
"os"
"testing" "testing"
"time" "time"
...@@ -40,6 +41,19 @@ func NewChallenger(t *testing.T, ctx context.Context, l1Endpoint string, name st ...@@ -40,6 +41,19 @@ func NewChallenger(t *testing.T, ctx context.Context, l1Endpoint string, name st
require.NotEmpty(t, cfg.TxMgrConfig.PrivateKey, "Missing private key for TxMgrConfig") require.NotEmpty(t, cfg.TxMgrConfig.PrivateKey, "Missing private key for TxMgrConfig")
require.NoError(t, cfg.Check(), "op-challenger config should be valid") require.NoError(t, cfg.Check(), "op-challenger config should be valid")
if cfg.CannonBin != "" {
_, err := os.Stat(cfg.CannonBin)
require.NoError(t, err, "cannon should be built. Make sure you've run make cannon-prestate")
}
if cfg.CannonServer != "" {
_, err := os.Stat(cfg.CannonServer)
require.NoError(t, err, "op-program should be built. Make sure you've run make cannon-prestate")
}
if cfg.CannonAbsolutePreState != "" {
_, err := os.Stat(cfg.CannonAbsolutePreState)
require.NoError(t, err, "cannon pre-state should be built. Make sure you've run make cannon-prestate")
}
errCh := make(chan error, 1) errCh := make(chan error, 1)
ctx, cancel := context.WithCancel(ctx) ctx, cancel := context.WithCancel(ctx)
go func() { go func() {
......
package disputegame
import (
"context"
"github.com/ethereum-optimism/optimism/op-challenger/config"
"github.com/ethereum-optimism/optimism/op-e2e/e2eutils/challenger"
)
type AlphabetGameHelper struct {
FaultGameHelper
claimedAlphabet string
}
func (g *AlphabetGameHelper) StartChallenger(ctx context.Context, l1Endpoint string, name string, options ...challenger.Option) *challenger.Helper {
opts := []challenger.Option{
func(c *config.Config) {
c.GameAddress = g.addr
c.GameDepth = alphabetGameDepth
c.TraceType = config.TraceTypeAlphabet
// By default the challenger agrees with the root claim (thus disagrees with the proposed output)
// This can be overridden by passing in options
c.AlphabetTrace = g.claimedAlphabet
c.AgreeWithProposedOutput = false
},
}
opts = append(opts, options...)
c := challenger.NewChallenger(g.t, ctx, l1Endpoint, name, opts...)
g.t.Cleanup(func() {
_ = c.Close()
})
return c
}
package disputegame
import (
"context"
"github.com/ethereum-optimism/optimism/op-challenger/config"
"github.com/ethereum-optimism/optimism/op-e2e/e2eutils/challenger"
)
type CannonGameHelper struct {
FaultGameHelper
}
func (g *CannonGameHelper) StartChallenger(ctx context.Context, l1Endpoint string, l2Endpoint string, name string, options ...challenger.Option) *challenger.Helper {
opts := []challenger.Option{
func(c *config.Config) {
c.GameAddress = g.addr
c.GameDepth = cannonGameDepth
c.TraceType = config.TraceTypeCannon
c.AgreeWithProposedOutput = false
c.CannonL2 = l2Endpoint
c.CannonBin = "../cannon/bin/cannon"
c.CannonDatadir = g.t.TempDir()
c.CannonServer = "../op-program/bin/op-program"
c.CannonAbsolutePreState = "../op-program/bin/prestate.json"
c.CannonSnapshotFreq = config.DefaultCannonSnapshotFreq
},
}
opts = append(opts, options...)
c := challenger.NewChallenger(g.t, ctx, l1Endpoint, name, opts...)
g.t.Cleanup(func() {
_ = c.Close()
})
return c
}
package disputegame
import (
"context"
"fmt"
"math/big"
"testing"
"time"
"github.com/ethereum-optimism/optimism/op-bindings/bindings"
"github.com/ethereum-optimism/optimism/op-challenger/fault/types"
"github.com/ethereum-optimism/optimism/op-service/client/utils"
"github.com/ethereum/go-ethereum/accounts/abi/bind"
"github.com/ethereum/go-ethereum/common"
"github.com/ethereum/go-ethereum/ethclient"
"github.com/stretchr/testify/require"
)
type FaultGameHelper struct {
t *testing.T
require *require.Assertions
client *ethclient.Client
opts *bind.TransactOpts
game *bindings.FaultDisputeGame
maxDepth int
addr common.Address
}
func (g *FaultGameHelper) GameDuration(ctx context.Context) time.Duration {
duration, err := g.game.GAMEDURATION(&bind.CallOpts{Context: ctx})
g.require.NoError(err, "failed to get game duration")
return time.Duration(duration) * time.Second
}
func (g *FaultGameHelper) WaitForClaimCount(ctx context.Context, count int64) {
ctx, cancel := context.WithTimeout(ctx, time.Minute)
defer cancel()
err := utils.WaitFor(ctx, time.Second, func() (bool, error) {
actual, err := g.game.ClaimDataLen(&bind.CallOpts{Context: ctx})
if err != nil {
return false, err
}
g.t.Log("Waiting for claim count", "current", actual, "expected", count, "game", g.addr)
return actual.Cmp(big.NewInt(count)) == 0, nil
})
g.require.NoError(err)
}
type ContractClaim struct {
ParentIndex uint32
Countered bool
Claim [32]byte
Position *big.Int
Clock *big.Int
}
func (g *FaultGameHelper) WaitForClaim(ctx context.Context, predicate func(claim ContractClaim) bool) {
ctx, cancel := context.WithTimeout(ctx, time.Minute)
defer cancel()
err := utils.WaitFor(ctx, time.Second, func() (bool, error) {
count, err := g.game.ClaimDataLen(&bind.CallOpts{Context: ctx})
if err != nil {
return false, fmt.Errorf("retrieve number of claims: %w", err)
}
// Search backwards because the new claims are at the end and more likely the ones we want.
for i := count.Int64() - 1; i >= 0; i-- {
claimData, err := g.game.ClaimData(&bind.CallOpts{Context: ctx}, big.NewInt(i))
if err != nil {
return false, fmt.Errorf("retrieve claim %v: %w", i, err)
}
if predicate(claimData) {
return true, nil
}
}
return false, nil
})
g.require.NoError(err)
}
func (g *FaultGameHelper) WaitForClaimAtMaxDepth(ctx context.Context, countered bool) {
g.WaitForClaim(ctx, func(claim ContractClaim) bool {
pos := types.NewPositionFromGIndex(claim.Position.Uint64())
return pos.Depth() == g.maxDepth && claim.Countered == countered
})
}
func (g *FaultGameHelper) Resolve(ctx context.Context) {
ctx, cancel := context.WithTimeout(ctx, time.Minute)
defer cancel()
tx, err := g.game.Resolve(g.opts)
g.require.NoError(err)
_, err = utils.WaitReceiptOK(ctx, g.client, tx.Hash())
g.require.NoError(err)
}
func (g *FaultGameHelper) WaitForGameStatus(ctx context.Context, expected Status) {
g.t.Logf("Waiting for game %v to have status %v", g.addr, expected)
ctx, cancel := context.WithTimeout(ctx, time.Minute)
defer cancel()
err := utils.WaitFor(ctx, time.Second, func() (bool, error) {
ctx, cancel := context.WithTimeout(ctx, 30*time.Second)
defer cancel()
status, err := g.game.Status(&bind.CallOpts{Context: ctx})
if err != nil {
return false, fmt.Errorf("game status unavailable: %w", err)
}
g.t.Logf("Game %v has state %v, waiting for state %v", g.addr, Status(status), expected)
return expected == Status(status), nil
})
g.require.NoError(err, "wait for game status")
}
This diff is collapsed.
...@@ -8,6 +8,7 @@ import ( ...@@ -8,6 +8,7 @@ import (
"github.com/ethereum-optimism/optimism/op-e2e/e2eutils" "github.com/ethereum-optimism/optimism/op-e2e/e2eutils"
"github.com/ethereum-optimism/optimism/op-e2e/e2eutils/disputegame" "github.com/ethereum-optimism/optimism/op-e2e/e2eutils/disputegame"
"github.com/ethereum-optimism/optimism/op-service/client/utils" "github.com/ethereum-optimism/optimism/op-service/client/utils"
"github.com/ethereum/go-ethereum/common"
"github.com/ethereum/go-ethereum/ethclient" "github.com/ethereum/go-ethereum/ethclient"
"github.com/stretchr/testify/require" "github.com/stretchr/testify/require"
) )
...@@ -143,6 +144,32 @@ func TestChallengerCompleteDisputeGame(t *testing.T) { ...@@ -143,6 +144,32 @@ func TestChallengerCompleteDisputeGame(t *testing.T) {
} }
} }
func TestCannonDisputeGame(t *testing.T) {
t.Skip("CLI-4290: op-challenger doesn't handle trace extension correctly for cannon")
InitParallel(t)
ctx := context.Background()
sys, l1Client := startFaultDisputeSystem(t)
t.Cleanup(sys.Close)
disputeGameFactory := disputegame.NewFactoryHelper(t, ctx, sys.cfg.L1Deployments, l1Client)
game := disputeGameFactory.StartCannonGame(ctx, common.Hash{0xaa})
require.NotNil(t, game)
game.StartChallenger(ctx, sys.NodeEndpoint("l1"), sys.NodeEndpoint("sequencer"), "Challenger", func(c *config.Config) {
c.AgreeWithProposedOutput = true // Agree with the proposed output, so disagree with the root claim
c.TxMgrConfig.PrivateKey = e2eutils.EncodePrivKeyToString(sys.cfg.Secrets.Alice)
})
// Challenger should counter the root claim
game.WaitForClaimCount(ctx, 2)
sys.TimeTravelClock.AdvanceTime(game.GameDuration(ctx))
require.NoError(t, utils.WaitNextBlock(ctx, l1Client))
game.WaitForGameStatus(ctx, disputegame.StatusChallengerWins)
}
func startFaultDisputeSystem(t *testing.T) (*System, *ethclient.Client) { func startFaultDisputeSystem(t *testing.T) (*System, *ethclient.Client) {
cfg := DefaultSystemConfig(t) cfg := DefaultSystemConfig(t)
delete(cfg.Nodes, "verifier") delete(cfg.Nodes, "verifier")
......
This diff is collapsed.
...@@ -8,7 +8,6 @@ import ( ...@@ -8,7 +8,6 @@ import (
"time" "time"
"github.com/ethereum-optimism/optimism/op-bindings/bindings" "github.com/ethereum-optimism/optimism/op-bindings/bindings"
"github.com/ethereum-optimism/optimism/op-e2e/config"
"github.com/ethereum-optimism/optimism/op-node/rollup/derive" "github.com/ethereum-optimism/optimism/op-node/rollup/derive"
"github.com/ethereum/go-ethereum/accounts/abi/bind" "github.com/ethereum/go-ethereum/accounts/abi/bind"
"github.com/ethereum/go-ethereum/common" "github.com/ethereum/go-ethereum/common"
...@@ -26,7 +25,7 @@ func SendDepositTx(t *testing.T, cfg SystemConfig, l1Client *ethclient.Client, l ...@@ -26,7 +25,7 @@ func SendDepositTx(t *testing.T, cfg SystemConfig, l1Client *ethclient.Client, l
applyL2Opts(l2Opts) applyL2Opts(l2Opts)
// Find deposit contract // Find deposit contract
depositContract, err := bindings.NewOptimismPortal(config.L1Deployments.OptimismPortalProxy, l1Client) depositContract, err := bindings.NewOptimismPortal(cfg.L1Deployments.OptimismPortalProxy, l1Client)
require.Nil(t, err) require.Nil(t, err)
// Finally send TX // Finally send TX
...@@ -54,7 +53,7 @@ func SendDepositTx(t *testing.T, cfg SystemConfig, l1Client *ethclient.Client, l ...@@ -54,7 +53,7 @@ func SendDepositTx(t *testing.T, cfg SystemConfig, l1Client *ethclient.Client, l
tx = types.NewTx(reconstructedDep) tx = types.NewTx(reconstructedDep)
receipt, err = waitForTransaction(tx.Hash(), l2Client, 10*time.Duration(cfg.DeployConfig.L2BlockTime)*time.Second) receipt, err = waitForTransaction(tx.Hash(), l2Client, 10*time.Duration(cfg.DeployConfig.L2BlockTime)*time.Second)
require.NoError(t, err) require.NoError(t, err)
require.Equal(t, l2Opts.ExpectedStatus, receipt.Status) require.Equal(t, l2Opts.ExpectedStatus, receipt.Status, "l2 transaction status")
} }
type DepositTxOptsFn func(l2Opts *DepositTxOpts) type DepositTxOptsFn func(l2Opts *DepositTxOpts)
......
...@@ -33,11 +33,8 @@ func setupL2OutputOracle() (common.Address, *bind.TransactOpts, *backends.Simula ...@@ -33,11 +33,8 @@ func setupL2OutputOracle() (common.Address, *bind.TransactOpts, *backends.Simula
backend, backend,
big.NewInt(10), big.NewInt(10),
big.NewInt(2), big.NewInt(2),
big.NewInt(0), big.NewInt(100),
big.NewInt(0), )
from,
common.Address{0xdd},
big.NewInt(100))
if err != nil { if err != nil {
return common.Address{}, nil, nil, nil, err return common.Address{}, nil, nil, nil, err
} }
......
This diff is collapsed.
This diff is collapsed.
...@@ -94,9 +94,9 @@ ...@@ -94,9 +94,9 @@
} }
}, },
"L1StandardBridge": { "L1StandardBridge": {
"spacer_0_0_20": { "spacer_0_2_20": {
"slot": 0, "slot": 0,
"offset": 0, "offset": 2,
"length": 20 "length": 20
}, },
"spacer_1_0_20": { "spacer_1_0_20": {
......
{ {
"src/L1/L1CrossDomainMessenger.sol": "0x76697013a600b9fe46f5606d445725a164a37cff7058d109dc2c1601a46a4d2a", "src/L1/L1CrossDomainMessenger.sol": "0x2b276f14475869cfd81868b03dc72b91dd726a787c9568caf4849fe34830b207",
"src/L1/L1ERC721Bridge.sol": "0xac9d8e236a1b35c358f9800834f65375cf4270155e817cf3d0f2bac1968f9107", "src/L1/L1ERC721Bridge.sol": "0xac9d8e236a1b35c358f9800834f65375cf4270155e817cf3d0f2bac1968f9107",
"src/L1/L1StandardBridge.sol": "0x26fd79e041c403f4bc68758c410fcc801975e7648c0b51a2c4a6e8c44fabcbfd", "src/L1/L1StandardBridge.sol": "0xa35dc0ab143043063c3bff73c8b065e401c23296a2017258ce8a87f4a4da9416",
"src/L1/L2OutputOracle.sol": "0xd6c5eb38732077c4705f46a61be68a7beccc069a99ed1d07b8e1fc6e1de8ffa6", "src/L1/L2OutputOracle.sol": "0x8f32ccb4c5cb63a459a0e79ee412177dc03fd279fdaaf1dac69e8c714902e857",
"src/L1/OptimismPortal.sol": "0xeaa47a63e8a3bcfdb7dfd3e6c8608369e34e362d9de82f3acf13cbc27c070bf7", "src/L1/OptimismPortal.sol": "0xeaa47a63e8a3bcfdb7dfd3e6c8608369e34e362d9de82f3acf13cbc27c070bf7",
"src/L1/SystemConfig.sol": "0x8e2b5103d2eb93b74af2e2f96a4505e637cdc3c44d80cf5ec2eca70060e1deff", "src/L1/SystemConfig.sol": "0x8e2b5103d2eb93b74af2e2f96a4505e637cdc3c44d80cf5ec2eca70060e1deff",
"src/L2/BaseFeeVault.sol": "0xa596e60762f16192cfa86459fcb9f4da9d8f756106eedac643a1ffeafbbfcc5f", "src/L2/BaseFeeVault.sol": "0xa596e60762f16192cfa86459fcb9f4da9d8f756106eedac643a1ffeafbbfcc5f",
"src/L2/GasPriceOracle.sol": "0xc735a8bf01ad8bca194345748537bfd9924909c0342bc133c4a31e2fb8cb9882", "src/L2/GasPriceOracle.sol": "0xc735a8bf01ad8bca194345748537bfd9924909c0342bc133c4a31e2fb8cb9882",
"src/L2/L1Block.sol": "0x7fbfc8b4da630386636c665570321fdec287b0867dbe0f91c2e7cd5b7697c220", "src/L2/L1Block.sol": "0x7fbfc8b4da630386636c665570321fdec287b0867dbe0f91c2e7cd5b7697c220",
"src/L2/L1FeeVault.sol": "0x62bfe739ff939fc68f90916399ac4160936d31eb37749cb014dd9d0c5dd4183a", "src/L2/L1FeeVault.sol": "0x62bfe739ff939fc68f90916399ac4160936d31eb37749cb014dd9d0c5dd4183a",
"src/L2/L2CrossDomainMessenger.sol": "0x1ffe8f6bad8eaa4c7ecff77456d382bdc5b371ffd672af6b539cb1a97f23e265", "src/L2/L2CrossDomainMessenger.sol": "0xc9641981f7aa79f44b5925100027098d8f76c6178c65aca99fafa859289182be",
"src/L2/L2ERC721Bridge.sol": "0x2b30a48241787580918a6ce4263823c036a21bde9cd80cc38d9beb6626c4f93b", "src/L2/L2ERC721Bridge.sol": "0x2b30a48241787580918a6ce4263823c036a21bde9cd80cc38d9beb6626c4f93b",
"src/L2/L2StandardBridge.sol": "0x73a4fea3dca8ac7d7ba32e38aadeb69bd344042666a40a75e8c28849f01999e5", "src/L2/L2StandardBridge.sol": "0x67e202bc6751807b20a98b88b0b65bdff30420bf1e71f2c1c7948de448cfcdc0",
"src/L2/L2ToL1MessagePasser.sol": "0xed800b600cb3f67e18a1ab10750e3934a8b3e42178f422bcacfde770a6e8e8bd", "src/L2/L2ToL1MessagePasser.sol": "0xed800b600cb3f67e18a1ab10750e3934a8b3e42178f422bcacfde770a6e8e8bd",
"src/L2/SequencerFeeVault.sol": "0xd57c143b1f042400430b991b806bf971628e6980406c751e82d19ae80eeb4e8d", "src/L2/SequencerFeeVault.sol": "0xd57c143b1f042400430b991b806bf971628e6980406c751e82d19ae80eeb4e8d",
"src/dispute/FaultDisputeGame.sol": "0x2a7f367443752f841d734f339a596c4ad93e16f7df0230f1cdd5e6f0b4b58368", "src/dispute/FaultDisputeGame.sol": "0x2a7f367443752f841d734f339a596c4ad93e16f7df0230f1cdd5e6f0b4b58368",
......
...@@ -14,18 +14,18 @@ import { L2ToL1MessagePasser } from "./L2ToL1MessagePasser.sol"; ...@@ -14,18 +14,18 @@ import { L2ToL1MessagePasser } from "./L2ToL1MessagePasser.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, Semver { contract L2CrossDomainMessenger is CrossDomainMessenger, Semver {
/// @custom:semver 1.4.1 /// @custom:semver 1.5.0
/// @notice Constructs the L2CrossDomainMessenger contract. /// @notice Constructs the L2CrossDomainMessenger contract.
/// @param _l1CrossDomainMessenger Address of the L1CrossDomainMessenger contract. /// @param _l1CrossDomainMessenger Address of the L1CrossDomainMessenger contract.
constructor(address _l1CrossDomainMessenger) constructor(address _l1CrossDomainMessenger)
Semver(1, 4, 1) Semver(1, 5, 0)
CrossDomainMessenger(_l1CrossDomainMessenger) CrossDomainMessenger(_l1CrossDomainMessenger)
{ {
initialize(); initialize();
} }
/// @notice Initializer. /// @notice Initializer.
function initialize() public initializer { function initialize() public reinitializer(2) {
__CrossDomainMessenger_init(); __CrossDomainMessenger_init();
} }
......
...@@ -35,6 +35,13 @@ contract L1StandardBridge_Initialize_Test is Bridge_Initializer { ...@@ -35,6 +35,13 @@ contract L1StandardBridge_Initialize_Test is Bridge_Initializer {
assertEq(address(L1Bridge.OTHER_BRIDGE()), Predeploys.L2_STANDARD_BRIDGE); assertEq(address(L1Bridge.OTHER_BRIDGE()), Predeploys.L2_STANDARD_BRIDGE);
assertEq(address(L2Bridge), Predeploys.L2_STANDARD_BRIDGE); assertEq(address(L2Bridge), Predeploys.L2_STANDARD_BRIDGE);
} }
function test_initialize_fix_succeeds() external {
bytes32 slot0 = vm.load(address(L1Bridge), bytes32(uint256(0)));
// The first storage slot should only have its first byte set to 0x02.
// This covers the `clearLegacySlot` fix.
assertEq(slot0, bytes32(uint256(2)));
}
} }
contract L1StandardBridge_Initialize_TestFail is Bridge_Initializer {} contract L1StandardBridge_Initialize_TestFail is Bridge_Initializer {}
......
...@@ -11,7 +11,7 @@ contract MIPS_Test is Test { ...@@ -11,7 +11,7 @@ contract MIPS_Test is Test {
function setUp() public { function setUp() public {
oracle = new PreimageOracle(); oracle = new PreimageOracle();
mips = new MIPS(); mips = new MIPS(oracle);
vm.store(address(mips), 0x0, bytes32(abi.encode(address(oracle)))); vm.store(address(mips), 0x0, bytes32(abi.encode(address(oracle))));
vm.label(address(oracle), "PreimageOracle"); vm.label(address(oracle), "PreimageOracle");
vm.label(address(mips), "MIPS"); vm.label(address(mips), "MIPS");
......
...@@ -14,7 +14,7 @@ import { ERC20 } from "@openzeppelin/contracts/token/ERC20/ERC20.sol"; ...@@ -14,7 +14,7 @@ import { ERC20 } from "@openzeppelin/contracts/token/ERC20/ERC20.sol";
/// internal functions so they can be more easily tested directly. /// internal functions so they can be more easily tested directly.
contract StandardBridgeTester is StandardBridge { contract StandardBridgeTester is StandardBridge {
constructor(address payable _messenger, address payable _otherBridge) constructor(address payable _messenger, address payable _otherBridge)
StandardBridge(_messenger, _otherBridge) StandardBridge(StandardBridge(_otherBridge))
{} {}
function isOptimismMintableERC20(address _token) external view returns (bool) { function isOptimismMintableERC20(address _token) external view returns (bool) {
......
...@@ -367,4 +367,4 @@ it possible for users to interact with contracts on L2 even when the Sequencer i ...@@ -367,4 +367,4 @@ it possible for users to interact with contracts on L2 even when the Sequencer i
A reference implementation of the deposit contract can be found in [OptimismPortal.sol]. A reference implementation of the deposit contract can be found in [OptimismPortal.sol].
[OptimismPortal.sol]: ../packages/contracts-bedrock/contracts/L1/OptimismPortal.sol [OptimismPortal.sol]: ../packages/contracts-bedrock/src/L1/OptimismPortal.sol
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