diff --git a/op-chain-ops/genz/configs.go b/op-chain-ops/genz/configs.go index db78837d5607f..30da2226d9f88 100644 --- a/op-chain-ops/genz/configs.go +++ b/op-chain-ops/genz/configs.go @@ -14,6 +14,7 @@ import ( type L1Config struct { ChainID *big.Int genesis.DevL1DeployConfig + Prefund map[common.Address]*big.Int } func (c *L1Config) Check(log log.Logger) error { @@ -50,6 +51,7 @@ type L2Config struct { Deployer common.Address // account used to deploy contracts to L2 genesis.L2InitializationConfig genesis.FaultProofDeployConfig + Prefund map[common.Address]*big.Int } func (c *L2Config) Check(log log.Logger) error { diff --git a/op-chain-ops/genz/deploy.go b/op-chain-ops/genz/deploy.go index 74a55284bf0d2..5d24253d01f6d 100644 --- a/op-chain-ops/genz/deploy.go +++ b/op-chain-ops/genz/deploy.go @@ -392,6 +392,12 @@ func completeL1(l1Host *script.Host, cfg *L1Config) (*L1Output, error) { return nil, fmt.Errorf("unexpected deployed account content by L1 genesis deployer: %w", err) } + for addr, amount := range cfg.Prefund { + acc := allocs.Accounts[addr] + acc.Balance = amount + allocs.Accounts[addr] = acc + } + l1Genesis.Alloc = allocs.Accounts // Insert an empty beaconchain deposit contract with valid empty-tree prestate. @@ -433,6 +439,12 @@ func completeL2(l2Host *script.Host, cfg *L2Config, l1Block *types.Block, deploy return nil, fmt.Errorf("unexpected deployed account content by L2 genesis deployer: %w", err) } + for addr, amount := range cfg.Prefund { + acc := allocs.Accounts[addr] + acc.Balance = amount + allocs.Accounts[addr] = acc + } + l2Genesis.Alloc = allocs.Accounts l2GenesisBlock := l2Genesis.ToBlock() diff --git a/op-chain-ops/genz/recipe.go b/op-chain-ops/genz/recipe.go index a8fc8914ccae9..e584ffb95237b 100644 --- a/op-chain-ops/genz/recipe.go +++ b/op-chain-ops/genz/recipe.go @@ -27,7 +27,18 @@ func (r *InteropDevRecipe) Build(addrs devkeys.Addresses) (*WorldConfig, error) L1GenesisBlockTimestamp: hexutil.Uint64(r.GenesisTimestamp), L1GenesisBlockGasLimit: 30_000_000, }, + Prefund: make(map[common.Address]*big.Int), } + + l1Users := devkeys.ChainUserKeys(l1Cfg.ChainID) + for i := uint64(0); i < 20; i++ { + userAddr, err := addrs.Address(l1Users(i)) + if err != nil { + return nil, fmt.Errorf("failed to get L1 user addr %d: %w", i, err) + } + l1Cfg.Prefund[userAddr] = Ether(10_000_000) + } + superchainOps := devkeys.SuperchainOperatorKeys(l1Cfg.ChainID) superchainDeployer, err := addrs.Address(superchainOps(devkeys.SuperchainDeployerKey)) @@ -46,6 +57,10 @@ func (r *InteropDevRecipe) Build(addrs devkeys.Addresses) (*WorldConfig, error) if err != nil { return nil, err } + l1Cfg.Prefund[superchainDeployer] = Ether(10_000_000) + l1Cfg.Prefund[finalSystemOwner] = Ether(10_000_000) + l1Cfg.Prefund[superchainProxyAdmin] = Ether(10_000_000) + l1Cfg.Prefund[superchainConfigGuardian] = Ether(10_000_000) superchainCfg := &SuperchainConfig{ FinalSystemOwner: finalSystemOwner, ProxyAdminOwner: superchainProxyAdmin, @@ -66,11 +81,37 @@ func (r *InteropDevRecipe) Build(addrs devkeys.Addresses) (*WorldConfig, error) if err != nil { return nil, fmt.Errorf("failed to generate L2 config for chain %d: %w", l2ChainID, err) } + if err := prefundL2Accounts(l1Cfg, l2Cfg, addrs); err != nil { + return nil, fmt.Errorf("failed to prefund addresses on L1 for L2 chain %d: %w", l2ChainID, err) + } world.L2s[fmt.Sprintf("%d", l2ChainID)] = l2Cfg } return world, nil } +func prefundL2Accounts(l1Cfg *L1Config, l2Cfg *L2Config, addrs devkeys.Addresses) error { + l1Cfg.Prefund[l2Cfg.BatchSenderAddress] = Ether(10_000_000) + l1Cfg.Prefund[l2Cfg.Deployer] = Ether(10_000_000) + l1Cfg.Prefund[l2Cfg.FinalSystemOwner] = Ether(10_000_000) + proposer, err := addrs.Address(devkeys.ChainOperatorKey{ + ChainID: new(big.Int).SetUint64(l2Cfg.L2ChainID), + Role: devkeys.ProposerRole, + }) + if err != nil { + return err + } + l1Cfg.Prefund[proposer] = Ether(10_000_000) + challenger, err := addrs.Address(devkeys.ChainOperatorKey{ + ChainID: new(big.Int).SetUint64(l2Cfg.L2ChainID), + Role: devkeys.ChallengerRole, + }) + if err != nil { + return err + } + l1Cfg.Prefund[challenger] = Ether(10_000_000) + return nil +} + func InteropL2DevConfig(l1ChainID, l2ChainID uint64, addrs devkeys.Addresses) (*L2Config, error) { // Padded chain ID, hex encoded, prefixed with 0xff like inboxes, then 0x02 to signify devnet. batchInboxAddress := common.HexToAddress(fmt.Sprintf("0xff02%016x", l2ChainID)) @@ -109,7 +150,7 @@ func InteropL2DevConfig(l1ChainID, l2ChainID uint64, addrs devkeys.Addresses) (* return nil, err } - return &L2Config{ + l2Cfg := &L2Config{ Deployer: deployer, L2InitializationConfig: genesis.L2InitializationConfig{ DevDeployConfig: genesis.DevDeployConfig{ @@ -195,7 +236,21 @@ func InteropL2DevConfig(l1ChainID, l2ChainID uint64, addrs devkeys.Addresses) (* DisputeGameFinalityDelaySeconds: 6, RespectedGameType: 254, // "fast" game type }, - }, nil + Prefund: make(map[common.Address]*big.Int), + } + + l2Users := devkeys.ChainUserKeys(new(big.Int).SetUint64(l2ChainID)) + for i := uint64(0); i < 20; i++ { + userAddr, err := addrs.Address(l2Users(i)) + if err != nil { + return nil, fmt.Errorf("failed to get L2 user addr %d: %w", i, err) + } + l2Cfg.Prefund[userAddr] = Ether(10_000_000) + } + + l2Cfg.Prefund[l2ProxyAdminOwner] = Ether(10_000_000) + + return l2Cfg, nil } var etherScalar = new(big.Int).Exp(big.NewInt(10), big.NewInt(18), nil)