diff --git a/anvil/anvil.go b/anvil/anvil.go
index 536c50830..8bab11684 100644
--- a/anvil/anvil.go
+++ b/anvil/anvil.go
@@ -19,9 +19,10 @@ import (
 )
 
 type Config struct {
-	ChainId uint64
-	Port    uint64
-	Genesis []byte
+	ChainID       uint64
+	SourceChainID uint64
+	Port          uint64
+	Genesis       []byte
 }
 
 type Anvil struct {
@@ -63,7 +64,7 @@ func (a *Anvil) Start(ctx context.Context) error {
 
 	args := []string{
 		"--host", host,
-		"--chain-id", fmt.Sprintf("%d", a.cfg.ChainId),
+		"--chain-id", fmt.Sprintf("%d", a.cfg.ChainID),
 		"--port", fmt.Sprintf("%d", a.cfg.Port),
 	}
 
@@ -79,7 +80,7 @@ func (a *Anvil) Start(ctx context.Context) error {
 		args = append(args, "--init", tempFile.Name())
 	}
 
-	anvilLog := a.log.New("role", "anvil", "chain.id", a.cfg.ChainId)
+	anvilLog := a.log.New("role", "anvil", "chain.id", a.cfg.ChainID)
 	anvilLog.Info("starting anvil", "args", args)
 	a.cmd = exec.CommandContext(a.resourceCtx, "anvil", args...)
 	go func() {
@@ -92,7 +93,7 @@ func (a *Anvil) Start(ctx context.Context) error {
 	anvilPortCh := make(chan uint64)
 
 	// Handle stdout/stderr
-	logFile, err := os.CreateTemp("", fmt.Sprintf("anvil-chain-%d-", a.cfg.ChainId))
+	logFile, err := os.CreateTemp("", fmt.Sprintf("anvil-chain-%d-", a.cfg.ChainID))
 	if err != nil {
 		return fmt.Errorf("failed to create temp log file: %w", err)
 	}
@@ -187,8 +188,12 @@ func (a *Anvil) Endpoint() string {
 	return fmt.Sprintf("http://%s:%d", host, a.cfg.Port)
 }
 
-func (a *Anvil) ChainId() uint64 {
-	return a.cfg.ChainId
+func (a *Anvil) ChainID() uint64 {
+	return a.cfg.ChainID
+}
+
+func (a *Anvil) SourceChainID() uint64 {
+	return a.cfg.SourceChainID
 }
 
 func (a *Anvil) LogPath() string {
@@ -221,3 +226,9 @@ func (a *Anvil) WaitUntilReady(ctx context.Context) error {
 		}
 	}
 }
+
+func (a *Anvil) String() string {
+	var b strings.Builder
+	fmt.Fprintf(&b, "Chain ID: %d    RPC: %s    LogPath: %s", a.ChainID(), a.Endpoint(), a.LogPath())
+	return b.String()
+}
diff --git a/anvil/anvil_test.go b/anvil/anvil_test.go
index a19ef1ed3..a4bd8d124 100644
--- a/anvil/anvil_test.go
+++ b/anvil/anvil_test.go
@@ -13,7 +13,7 @@ import (
 )
 
 func TestAnvil(t *testing.T) {
-	cfg := Config{ChainId: 10, Port: 0}
+	cfg := Config{ChainID: 10, Port: 0}
 	testlog := testlog.Logger(t, log.LevelInfo)
 	anvil := New(testlog, &cfg)
 
@@ -28,5 +28,5 @@ func TestAnvil(t *testing.T) {
 	// query chainId
 	var chainId math.HexOrDecimal64
 	require.NoError(t, client.CallContext(context.Background(), &chainId, "eth_chainId"))
-	require.Equal(t, uint64(chainId), cfg.ChainId)
+	require.Equal(t, uint64(chainId), cfg.ChainID)
 }
diff --git a/cmd/main.go b/cmd/main.go
index 5dda1c92f..378432002 100644
--- a/cmd/main.go
+++ b/cmd/main.go
@@ -52,5 +52,10 @@ func SupersimMain(ctx *cli.Context, closeApp context.CancelCauseFunc) (cliapp.Li
 	}
 
 	// use config and setup supersim
-	return supersim.NewSupersim(log, &supersim.DefaultConfig), nil
+	s, err := supersim.NewSupersim(log, &supersim.DefaultConfig)
+	if err != nil {
+		return nil, fmt.Errorf("failed to create supersim")
+	}
+
+	return s, nil
 }
diff --git a/op-simulator/op_simulator.go b/op-simulator/op_simulator.go
index 54cf11a4e..4f4f2a077 100644
--- a/op-simulator/op_simulator.go
+++ b/op-simulator/op_simulator.go
@@ -22,7 +22,8 @@ const (
 )
 
 type Config struct {
-	Port uint64
+	Port          uint64
+	SourceChainID uint64
 }
 
 type OpSimulator struct {
@@ -57,7 +58,7 @@ func (opSim *OpSimulator) Start(ctx context.Context) error {
 		return fmt.Errorf("failed to start HTTP RPC server: %w", err)
 	}
 
-	opSim.log.Info("started op-simulator", "chain.id", opSim.ChainId(), "addr", hs.Addr())
+	opSim.log.Info("started op-simulator", "chain.id", opSim.ChainID(), "addr", hs.Addr())
 	opSim.httpServer = hs
 
 	if opSim.cfg.Port == 0 {
@@ -104,6 +105,16 @@ func (opSim *OpSimulator) Endpoint() string {
 	return fmt.Sprintf("http://%s:%d", host, opSim.cfg.Port)
 }
 
-func (opSim *OpSimulator) ChainId() uint64 {
-	return opSim.anvil.ChainId()
+func (opSim *OpSimulator) ChainID() uint64 {
+	return opSim.anvil.ChainID()
+}
+
+func (opSim *OpSimulator) SourceChainID() uint64 {
+	return opSim.cfg.SourceChainID
+}
+
+func (opSim *OpSimulator) String() string {
+	var b strings.Builder
+	fmt.Fprintf(&b, "Chain ID: %d    RPC: %s    LogPath: %s", opSim.ChainID(), opSim.Endpoint(), opSim.anvil.LogPath())
+	return b.String()
 }
diff --git a/genesis/genesis-l1.json b/orchestrator/genesisstates/genesis-l1.json
similarity index 100%
rename from genesis/genesis-l1.json
rename to orchestrator/genesisstates/genesis-l1.json
diff --git a/genesis/genesis-l2.json b/orchestrator/genesisstates/genesis-l2.json
similarity index 100%
rename from genesis/genesis-l2.json
rename to orchestrator/genesisstates/genesis-l2.json
diff --git a/orchestrator/orchestrator.go b/orchestrator/orchestrator.go
new file mode 100644
index 000000000..704fffd55
--- /dev/null
+++ b/orchestrator/orchestrator.go
@@ -0,0 +1,198 @@
+package orchestrator
+
+import (
+	"context"
+	_ "embed"
+	"fmt"
+	"strings"
+	"sync"
+
+	"github.com/ethereum-optimism/supersim/anvil"
+	op_simulator "github.com/ethereum-optimism/supersim/op-simulator"
+
+	"github.com/ethereum/go-ethereum/log"
+)
+
+type ChainConfig struct {
+	Port    uint64
+	ChainID uint64
+	// The base chain ID when the chain is a rollup.
+	// If set to 0, the chain is considered an L1 chain
+	SourceChainID uint64
+}
+
+type OrchestratorConfig struct {
+	ChainConfigs []ChainConfig
+}
+
+type Orchestrator struct {
+	log log.Logger
+
+	OpSimInstances []*op_simulator.OpSimulator
+	anvilInstances []*anvil.Anvil
+}
+
+//go:embed genesisstates/genesis-l1.json
+var genesisL1JSON []byte
+
+//go:embed genesisstates/genesis-l2.json
+var genesisL2JSON []byte
+
+func NewOrchestrator(log log.Logger, config *OrchestratorConfig) (*Orchestrator, error) {
+	var opSimInstances []*op_simulator.OpSimulator
+	var anvilInstances []*anvil.Anvil
+
+	l1Count := 0
+	for _, config := range config.ChainConfigs {
+		if config.SourceChainID == 0 {
+			l1Count++
+		}
+	}
+
+	if l1Count > 1 {
+		return nil, fmt.Errorf("supersim does not support more than one l1")
+	}
+
+	for _, chainConfig := range config.ChainConfigs {
+		genesis := genesisL2JSON
+		if chainConfig.SourceChainID == 0 {
+			genesis = genesisL1JSON
+		}
+		anvil := anvil.New(log, &anvil.Config{ChainID: chainConfig.ChainID, SourceChainID: chainConfig.SourceChainID, Genesis: genesis})
+		anvilInstances = append(anvilInstances, anvil)
+		// Only create Op Simulators for L2 chains.
+		if chainConfig.SourceChainID != 0 {
+			opSimInstances = append(opSimInstances, op_simulator.New(log, &op_simulator.Config{Port: chainConfig.Port, SourceChainID: chainConfig.SourceChainID}, anvil))
+		}
+	}
+
+	return &Orchestrator{log, opSimInstances, anvilInstances}, nil
+}
+
+func (o *Orchestrator) Start(ctx context.Context) error {
+	o.log.Info("starting orchestrator")
+
+	for _, anvilInstance := range o.anvilInstances {
+		if err := anvilInstance.Start(ctx); err != nil {
+			return fmt.Errorf("anvil instance chain.id=%v failed to start: %w", anvilInstance.ChainID(), err)
+		}
+	}
+	for _, opSimInstance := range o.OpSimInstances {
+		if err := opSimInstance.Start(ctx); err != nil {
+			return fmt.Errorf("op simulator instance chain.id=%v failed to start: %w", opSimInstance.ChainID(), err)
+		}
+	}
+
+	if err := o.WaitUntilReady(); err != nil {
+		return fmt.Errorf("orchestrator failed to get ready: %w", err)
+	}
+
+	o.log.Info("orchestrator is ready")
+
+	return nil
+}
+
+func (o *Orchestrator) Stop(ctx context.Context) error {
+	o.log.Info("stopping orchestrator")
+
+	for _, opSim := range o.OpSimInstances {
+		if err := opSim.Stop(ctx); err != nil {
+			return fmt.Errorf("op simulator chain.id=%v failed to stop: %w", opSim.ChainID(), err)
+		}
+		o.log.Info("stopped op simulator", "chain.id", opSim.ChainID())
+	}
+	for _, anvil := range o.anvilInstances {
+		if err := anvil.Stop(); err != nil {
+			return fmt.Errorf("anvil chain.id=%v failed to stop: %w", anvil.ChainID(), err)
+		}
+		o.log.Info("stopped anvil", "chain.id", anvil.ChainID())
+	}
+
+	o.log.Info("stopped orchestrator")
+
+	return nil
+}
+
+func (o *Orchestrator) Stopped() bool {
+	for _, anvil := range o.anvilInstances {
+		if stopped := anvil.Stopped(); !stopped {
+			return stopped
+		}
+	}
+	for _, opSim := range o.OpSimInstances {
+		if stopped := opSim.Stopped(); !stopped {
+			return stopped
+		}
+	}
+
+	return true
+}
+
+func (o *Orchestrator) WaitUntilReady() error {
+	var once sync.Once
+	var err error
+	ctx, cancel := context.WithCancel(context.Background())
+
+	handleErr := func(e error) {
+		if e == nil {
+			return
+		}
+
+		once.Do(func() {
+			err = e
+			cancel()
+		})
+	}
+
+	var wg sync.WaitGroup
+
+	waitForAnvil := func(anvil *anvil.Anvil) {
+		defer wg.Done()
+		handleErr(anvil.WaitUntilReady(ctx))
+	}
+
+	o.iterateAnvilInstances(func(chain *anvil.Anvil) {
+		wg.Add(1)
+		go waitForAnvil(chain)
+	})
+
+	wg.Wait()
+
+	return err
+}
+
+func (o *Orchestrator) iterateAnvilInstances(fn func(anvil *anvil.Anvil)) {
+	for _, anvilInstance := range o.anvilInstances {
+		fn(anvilInstance)
+	}
+}
+
+func (o *Orchestrator) L1Anvil() *anvil.Anvil {
+	var result *anvil.Anvil
+	for _, anvil := range o.anvilInstances {
+		if anvil.SourceChainID() == 0 {
+			result = anvil
+		}
+	}
+
+	return result
+}
+
+func (o *Orchestrator) ConfigAsString() string {
+	var b strings.Builder
+
+	fmt.Fprintf(&b, "\nSupersim Config:\n")
+	if o.L1Anvil() != nil {
+		fmt.Fprintf(&b, "L1:\n")
+		fmt.Fprintf(&b, "  %s\n", o.L1Anvil().String())
+	}
+
+	if len(o.OpSimInstances) > 0 {
+		fmt.Fprintf(&b, "L2:\n")
+		for _, opSim := range o.OpSimInstances {
+			fmt.Fprintf(&b, "  %s\n", opSim.String())
+		}
+	}
+
+	return b.String()
+}
diff --git a/orchestrator/orchestrator_test.go b/orchestrator/orchestrator_test.go
new file mode 100644
index 000000000..5d73b9c68
--- /dev/null
+++ b/orchestrator/orchestrator_test.go
@@ -0,0 +1,70 @@
+package orchestrator
+
+import (
+	"context"
+	"testing"
+
+	"github.com/ethereum-optimism/optimism/op-service/testlog"
+	"github.com/stretchr/testify/require"
+
+	"github.com/ethereum/go-ethereum/log"
+)
+
+type TestSuite struct {
+	t *testing.T
+
+	Cfg          *OrchestratorConfig
+	orchestrator *Orchestrator
+}
+
+func createTestSuite(t *testing.T) *TestSuite {
+	cfg := &OrchestratorConfig{
+		ChainConfigs: []ChainConfig{
+			{ChainID: 1, Port: 0},
+			{ChainID: 10, SourceChainID: 1, Port: 0},
+			{ChainID: 30, SourceChainID: 1, Port: 0},
+		},
+	}
+	testlog := testlog.Logger(t, log.LevelInfo)
+	orchestrator, _ := NewOrchestrator(testlog, cfg)
+	t.Cleanup(func() {
+		if err := orchestrator.Stop(context.Background()); err != nil {
+			t.Errorf("failed to stop orchestrator: %s", err)
+		}
+	})
+
+	if err := orchestrator.Start(context.Background()); err != nil {
+		t.Fatalf("unable to start orchestrator: %s", err)
+		return nil
+	}
+
+	return &TestSuite{
+		t:            t,
+		Cfg:          cfg,
+		orchestrator: orchestrator,
+	}
+}
+
+func TestStartup(t *testing.T) {
+	testSuite := createTestSuite(t)
+
+	require.Equal(t, testSuite.orchestrator.L1Anvil().ChainID(), uint64(1))
+	require.Equal(t, len(testSuite.orchestrator.OpSimInstances), 2)
+	require.Equal(t, testSuite.orchestrator.OpSimInstances[0].ChainID(), uint64(10))
+	require.Equal(t, testSuite.orchestrator.OpSimInstances[0].SourceChainID(), uint64(1))
+	require.Equal(t, testSuite.orchestrator.OpSimInstances[1].ChainID(), uint64(30))
+	require.Equal(t, testSuite.orchestrator.OpSimInstances[1].SourceChainID(), uint64(1))
+}
+
+func TestTooManyL1sError(t *testing.T) {
+	cfg := &OrchestratorConfig{
+		ChainConfigs: []ChainConfig{
+			{ChainID: 1, Port: 0},
+			{ChainID: 10, Port: 0},
+			{ChainID: 30, SourceChainID: 1, Port: 0},
+		},
+	}
+	testlog := testlog.Logger(t, log.LevelInfo)
+	_, err := NewOrchestrator(testlog, cfg)
+	require.Error(t, err)
+}
diff --git a/supersim.go b/supersim.go
index 55e2fa4eb..9491003b5 100644
--- a/supersim.go
+++ b/supersim.go
@@ -1,48 +1,26 @@
 package supersim
 
 import (
-	_ "embed"
 	"fmt"
 	"strings"
-	"sync"
 
 	"context"
 
-	"github.com/ethereum-optimism/supersim/anvil"
-	opsim "github.com/ethereum-optimism/supersim/op-simulator"
+	"github.com/ethereum-optimism/supersim/orchestrator"
 
 	"github.com/ethereum/go-ethereum/log"
 )
 
 type Config struct {
-	l1Chain  ChainConfig
-	l2Chains []ChainConfig
+	orchestratorConfig orchestrator.OrchestratorConfig
 }
 
-type ChainConfig struct {
-	anvilConfig anvil.Config
-	opSimConfig opsim.Config
-}
-
-//go:embed genesis/genesis-l1.json
-var genesisL1JSON []byte
-
-//go:embed genesis/genesis-l2.json
-var genesisL2JSON []byte
-
 var DefaultConfig = Config{
-	l1Chain: ChainConfig{
-		anvilConfig: anvil.Config{ChainId: 1, Port: 0, Genesis: genesisL1JSON},
-		opSimConfig: opsim.Config{Port: 0},
-	},
-	l2Chains: []ChainConfig{
-		{
-			anvilConfig: anvil.Config{ChainId: 10, Port: 0, Genesis: genesisL2JSON},
-			opSimConfig: opsim.Config{Port: 0},
-		},
-		{
-			anvilConfig: anvil.Config{ChainId: 30, Port: 0, Genesis: genesisL2JSON},
-			opSimConfig: opsim.Config{Port: 0},
+	orchestratorConfig: orchestrator.OrchestratorConfig{
+		ChainConfigs: []orchestrator.ChainConfig{
+			{ChainID: 1, Port: 0},
+			{ChainID: 10, SourceChainID: 1, Port: 0},
+			{ChainID: 30, SourceChainID: 1, Port: 0},
 		},
 	},
 }
@@ -50,52 +28,23 @@ var DefaultConfig = Config{
 type Supersim struct {
 	log log.Logger
 
-	l1Anvil *anvil.Anvil
-	l1OpSim *opsim.OpSimulator
-
-	l2Anvils map[uint64]*anvil.Anvil
-	l2OpSims map[uint64]*opsim.OpSimulator
+	Orchestrator *orchestrator.Orchestrator
 }
 
-func NewSupersim(log log.Logger, config *Config) *Supersim {
-	l1Anvil := anvil.New(log, &config.l1Chain.anvilConfig)
-	l1OpSim := opsim.New(log, &config.l1Chain.opSimConfig, l1Anvil)
-
-	l2Anvils := make(map[uint64]*anvil.Anvil)
-	l2OpSims := make(map[uint64]*opsim.OpSimulator)
-	for i := range config.l2Chains {
-		l2ChainConfig := config.l2Chains[i]
-		l2Anvil := anvil.New(log, &l2ChainConfig.anvilConfig)
-		l2Anvils[l2ChainConfig.anvilConfig.ChainId] = l2Anvil
-		l2OpSims[l2ChainConfig.anvilConfig.ChainId] = opsim.New(log, &l2ChainConfig.opSimConfig, l2Anvil)
+func NewSupersim(log log.Logger, config *Config) (*Supersim, error) {
+	o, err := orchestrator.NewOrchestrator(log, &DefaultConfig.orchestratorConfig)
+	if err != nil {
+		return nil, fmt.Errorf("failed to create orchestrator")
 	}
 
-	return &Supersim{log, l1Anvil, l1OpSim, l2Anvils, l2OpSims}
+	return &Supersim{log, o}, nil
 }
 
 func (s *Supersim) Start(ctx context.Context) error {
 	s.log.Info("starting supersim")
 
-	if err := s.l1Anvil.Start(ctx); err != nil {
-		return fmt.Errorf("l1 anvil failed to start: %w", err)
-	}
-	if err := s.l1OpSim.Start(ctx); err != nil {
-		return fmt.Errorf("l1 op simulator failed to start: %w", err)
-	}
-
-	for _, l2Anvil := range s.l2Anvils {
-		if err := l2Anvil.Start(ctx); err != nil {
-			return fmt.Errorf("l2 anvil failed to start: %w", err)
-		}
-	}
-	for _, l2OpSim := range s.l2OpSims {
-		if err := l2OpSim.Start(ctx); err != nil {
-			return fmt.Errorf("l2 op simulator failed to start: %w", err)
-		}
-	}
-
-	if err := s.WaitUntilReady(); err != nil {
-		return fmt.Errorf("supersim failed to get ready: %w", err)
+	if err := s.Orchestrator.Start(ctx); err != nil {
+		return fmt.Errorf("orchestrator failed to start: %w", err)
 	}
 
 	s.log.Info("supersim is ready")
@@ -107,101 +56,22 @@ func (s *Supersim) Start(ctx context.Context) error {
 func (s *Supersim) Stop(ctx context.Context) error {
 	s.log.Info("stopping supersim")
 
-	for _, l2OpSim := range s.l2OpSims {
-		if err := l2OpSim.Stop(ctx); err != nil {
-			return fmt.Errorf("l2 op simulator failed to stop: %w", err)
-		}
-		s.log.Info("stopped op simulator", "chain.id", l2OpSim.ChainId())
-	}
-	for _, l2Anvil := range s.l2Anvils {
-		if err := l2Anvil.Stop(); err != nil {
-			return fmt.Errorf("l2 anvil failed to stop: %w", err)
-		}
+	if err := s.Orchestrator.Stop(ctx); err != nil {
+		return fmt.Errorf("orchestrator failed to stop: %w", err)
 	}
 
-	if err := s.l1OpSim.Stop(ctx); err != nil {
-		return fmt.Errorf("l1 op simulator failed to stop: %w", err)
-	}
-	if err := s.l1Anvil.Stop(); err != nil {
-		return fmt.Errorf("l1 anvil failed to stop: %w", err)
-	}
-	s.log.Info("stopped op simulator", "chain.id", s.l1OpSim.ChainId())
-
 	return nil
 }
 
 func (s *Supersim) Stopped() bool {
-	for _, l2OpSim := range s.l2OpSims {
-		if stopped := l2OpSim.Stopped(); !stopped {
-			return stopped
-		}
-	}
-	for _, l2Anvil := range s.l2Anvils {
-		if stopped := l2Anvil.Stopped(); !stopped {
-			return stopped
-		}
-	}
-
-	if stopped := s.l1Anvil.Stopped(); !stopped {
-		return stopped
-	}
-	if stopped := s.l1OpSim.Stopped(); !stopped {
-		return stopped
-	}
-
-	return true
-}
-
-func (s *Supersim) WaitUntilReady() error {
-	var once sync.Once
-	var err error
-	ctx, cancel := context.WithCancel(context.Background())
-
-	handleErr := func(e error) {
-		if e != nil {
-			once.Do(func() {
-				err = e
-				cancel()
-			})
-		}
-	}
-
-	var wg sync.WaitGroup
-
-	waitForAnvil := func(anvil *anvil.Anvil) {
-		defer wg.Done()
-		handleErr(anvil.WaitUntilReady(ctx))
-	}
-
-	s.IterateChains(func(chain *anvil.Anvil) {
-		wg.Add(1)
-		go waitForAnvil(chain)
-	})
-
-	wg.Wait()
-
-	return err
-}
-
-func (s *Supersim) IterateChains(fn func(anvil *anvil.Anvil)) {
-	fn(s.l1Anvil)
-
-	for _, l2Anvil := range s.l2Anvils {
-		fn(l2Anvil)
-	}
+	return s.Orchestrator.Stopped()
 }
 
 func (s *Supersim) ConfigAsString() string {
 	var b strings.Builder
 
 	fmt.Fprintf(&b, "\nSupersim Config:\n")
-	fmt.Fprintf(&b, "L1:\n")
-	fmt.Fprintf(&b, "  Chain ID: %d     RPC: %s    LogPath: %s\n", s.l1OpSim.ChainId(), s.l1OpSim.Endpoint(), s.l1Anvil.LogPath())
-
-	fmt.Fprintf(&b, "L2:\n")
-	for id, l2OpSim := range s.l2OpSims {
-		fmt.Fprintf(&b, "  Chain ID: %d    RPC: %s    LogPath: %s\n", l2OpSim.ChainId(), l2OpSim.Endpoint(), s.l2Anvils[id].LogPath())
-	}
+	fmt.Fprint(&b, s.Orchestrator.ConfigAsString())
 
 	return b.String()
 }
diff --git a/supersim_test.go b/supersim_test.go
index c738548cc..8e1192d45 100644
--- a/supersim_test.go
+++ b/supersim_test.go
@@ -31,7 +31,7 @@ type TestSuite struct {
 func createTestSuite(t *testing.T) *TestSuite {
 	cfg := &DefaultConfig
 	testlog := testlog.Logger(t, log.LevelInfo)
-	supersim := NewSupersim(testlog, cfg)
+	supersim, _ := NewSupersim(testlog, cfg)
 	t.Cleanup(func() {
 		if err := supersim.Stop(context.Background()); err != nil {
 			t.Errorf("failed to stop supersim: %s", err)
@@ -53,20 +53,12 @@ func createTestSuite(t *testing.T) *TestSuite {
 func TestStartup(t *testing.T) {
 	testSuite := createTestSuite(t)
 
-	var chainId math.HexOrDecimal64
-
-	// test that all chains can be queried
-	l1Client, err := rpc.Dial(testSuite.Supersim.l1OpSim.Endpoint())
-	require.NoError(t, err)
-	require.NoError(t, l1Client.CallContext(context.Background(), &chainId, "eth_chainId"))
-	require.Equal(t, uint64(chainId), testSuite.Supersim.l1OpSim.ChainId())
-	l1Client.Close()
-
-	for id, l2Chain := range testSuite.Supersim.l2OpSims {
-		require.Equal(t, id, l2Chain.ChainId())
-
-		l2Client, err := rpc.Dial(l2Chain.Endpoint())
+	require.True(t, len(testSuite.Supersim.Orchestrator.OpSimInstances) > 0)
+	// test that all op simulators can be queried
+	for _, opSim := range testSuite.Supersim.Orchestrator.OpSimInstances {
+		l2Client, err := rpc.Dial(opSim.Endpoint())
 		require.NoError(t, err)
+		var chainId math.HexOrDecimal64
 		require.NoError(t, l2Client.CallContext(context.Background(), &chainId, "eth_chainId"))
 
 		// Commented out due to a bug in foundry that sets the chain id to 1 whenever genesis.json file is supplied
@@ -79,9 +71,10 @@ func TestStartup(t *testing.T) {
 func TestGenesisState(t *testing.T) {
 	testSuite := createTestSuite(t)
 
+	require.True(t, len(testSuite.Supersim.Orchestrator.OpSimInstances) > 0)
 	// assert that the predeploys exists on the l2 anvil instances
-	for _, l2Chain := range testSuite.Supersim.l2OpSims {
-		client, err := rpc.Dial(l2Chain.Endpoint())
+	for _, l2OpSim := range testSuite.Supersim.Orchestrator.OpSimInstances {
+		client, err := rpc.Dial(l2OpSim.Endpoint())
 		require.NoError(t, err)
 		defer client.Close()