From ad7448d6dace64488d714255cbae6b22f0718248 Mon Sep 17 00:00:00 2001 From: niha <205694301+0xniha@users.noreply.github.com> Date: Tue, 16 Sep 2025 14:37:35 -0300 Subject: [PATCH 1/5] fix: import in OptimismPortal2CGT test and pre-pr --- .../contracts-bedrock/snapshots/semver-lock.json | 12 ++++++------ .../contracts-bedrock/src/L1/OPContractsManager.sol | 4 ++-- .../contracts-bedrock/src/L1/OptimismPortal2.sol | 4 ++-- packages/contracts-bedrock/src/L1/SystemConfig.sol | 4 ++-- .../test/L1/OptimismPortal2CGT.t.sol | 6 +++--- 5 files changed, 15 insertions(+), 15 deletions(-) diff --git a/packages/contracts-bedrock/snapshots/semver-lock.json b/packages/contracts-bedrock/snapshots/semver-lock.json index e77439f28b90c..42b0b52cd16ee 100644 --- a/packages/contracts-bedrock/snapshots/semver-lock.json +++ b/packages/contracts-bedrock/snapshots/semver-lock.json @@ -20,16 +20,16 @@ "sourceCodeHash": "0xfca613b5d055ffc4c3cbccb0773ddb9030abedc1aa6508c9e2e7727cc0cd617b" }, "src/L1/OPContractsManager.sol:OPContractsManager": { - "initCodeHash": "0x766ebe9b97e1689b51fd6d6f392265e2dad278d342258310366c460704d72726", - "sourceCodeHash": "0xd47c377f775ce677c995615cfc6bc66902640a8f12c1f4efe68ab1d824f89ccf" + "initCodeHash": "0x7df9acb5abebfb2c619531785e4aa7fcca48f3e4e83b08faada53991a579a789", + "sourceCodeHash": "0x69b4d3684719d3b7f5f1f5e235be92673ca2b3ff7e7edd9b17e50e12499df466" }, "src/L1/OPContractsManagerStandardValidator.sol:OPContractsManagerStandardValidator": { "initCodeHash": "0x17a40747da8a9978f7294f071ea371b8c021504b898919431e6acf62623e8adc", "sourceCodeHash": "0xa80dcd2ebafc5a6a437f712d8073f8a48998807aa317ad7762b3fc9dc2caa133" }, "src/L1/OptimismPortal2.sol:OptimismPortal2": { - "initCodeHash": "0x9d9692335395719b697cff1f2741237819491e1c74c539782dec0c43e76771b6", - "sourceCodeHash": "0xcc48f842635e58981162e9223579b688794bce145f5797a05c5c17393daf27fa" + "initCodeHash": "0x1cc12939347474e26a57c89f6fe70bc5c82e456e7583c81da4b327a045c32f38", + "sourceCodeHash": "0x48ff518993541028ba2c299509dcb506a58808900496b4878aae4ec841fa8256" }, "src/L1/OptimismPortalInterop.sol:OptimismPortalInterop": { "initCodeHash": "0x087281cd2a48e882648c09fa90bfcca7487d222e16300f9372deba6b2b8ccfad", @@ -44,8 +44,8 @@ "sourceCodeHash": "0xbf344c4369b8cb00ec7a3108f72795747f3bc59ab5b37ac18cf21e72e2979dbf" }, "src/L1/SystemConfig.sol:SystemConfig": { - "initCodeHash": "0x68ae57482325f122bd04b3dd28b15ff28e84ed592c11746a5c8dd50c49879183", - "sourceCodeHash": "0xc4b3c63a154027bdca2a4b7bdaaaef57ca77993638fa350679d74345c81a79f3" + "initCodeHash": "0xfb19d8929abb73b1678b280eab947847c3f5aed67d1a7773b713fb9911ed1839", + "sourceCodeHash": "0xf7bd98c11f7b35f5da4d73aa389e0d22c352b4246c3a2c199a5e8ce90da95520" }, "src/L2/BaseFeeVault.sol:BaseFeeVault": { "initCodeHash": "0x9b664e3d84ad510091337b4aacaa494b142512e2f6f7fbcdb6210ed62ca9b885", diff --git a/packages/contracts-bedrock/src/L1/OPContractsManager.sol b/packages/contracts-bedrock/src/L1/OPContractsManager.sol index fc8ef46451b5c..318cb5c1d9282 100644 --- a/packages/contracts-bedrock/src/L1/OPContractsManager.sol +++ b/packages/contracts-bedrock/src/L1/OPContractsManager.sol @@ -1808,9 +1808,9 @@ contract OPContractsManager is ISemver { // -------- Constants and Variables -------- - /// @custom:semver 3.3.0 + /// @custom:semver 3.3.1 function version() public pure virtual returns (string memory) { - return "3.3.0"; + return "3.3.1"; } OPContractsManagerGameTypeAdder public immutable opcmGameTypeAdder; diff --git a/packages/contracts-bedrock/src/L1/OptimismPortal2.sol b/packages/contracts-bedrock/src/L1/OptimismPortal2.sol index 026f754053b77..f5c158285c398 100644 --- a/packages/contracts-bedrock/src/L1/OptimismPortal2.sol +++ b/packages/contracts-bedrock/src/L1/OptimismPortal2.sol @@ -208,9 +208,9 @@ contract OptimismPortal2 is Initializable, ResourceMetering, ReinitializableBase error OptimismPortal_InvalidLockboxState(); /// @notice Semantic version. - /// @custom:semver 5.1.0 + /// @custom:semver 5.1.1 function version() public pure virtual returns (string memory) { - return "5.1.0"; + return "5.1.1"; } /// @param _proofMaturityDelaySeconds The proof maturity delay in seconds. diff --git a/packages/contracts-bedrock/src/L1/SystemConfig.sol b/packages/contracts-bedrock/src/L1/SystemConfig.sol index 58e69262a86c8..eb6b54754ab2a 100644 --- a/packages/contracts-bedrock/src/L1/SystemConfig.sol +++ b/packages/contracts-bedrock/src/L1/SystemConfig.sol @@ -154,9 +154,9 @@ contract SystemConfig is ProxyAdminOwnedBase, OwnableUpgradeable, Reinitializabl error SystemConfig_InvalidFeatureState(); /// @notice Semantic version. - /// @custom:semver 3.8.0 + /// @custom:semver 3.8.1 function version() public pure virtual returns (string memory) { - return "3.8.0"; + return "3.8.1"; } /// @notice Constructs the SystemConfig contract. diff --git a/packages/contracts-bedrock/test/L1/OptimismPortal2CGT.t.sol b/packages/contracts-bedrock/test/L1/OptimismPortal2CGT.t.sol index 6ed0bd9dd6e16..29833626a5864 100644 --- a/packages/contracts-bedrock/test/L1/OptimismPortal2CGT.t.sol +++ b/packages/contracts-bedrock/test/L1/OptimismPortal2CGT.t.sol @@ -7,7 +7,7 @@ import { OptimismPortal2_Version_Test, OptimismPortal2_Initialize_Test, OptimismPortal2_Constructor_Test, - OptimismPortal2_Upgrade_Test, + OptimismPortal2_UpgradeInterop_Test, OptimismPortal2_MinimumGasLimit_Test, OptimismPortal2_Paused_Test, OptimismPortal2_ProofMaturityDelaySeconds_Test, @@ -84,10 +84,10 @@ contract OptimismPortal2_CGT_Initialize_Test is OptimismPortal2_Initialize_Test } } -/// @title OptimismPortal2_CGT_Upgrade_Test +/// @title OptimismPortal2_CGT_UpgradeInterop_Test /// @notice Tests the upgrade functionality of the `OptimismPortal2` contract with custom gas token /// enabled. -contract OptimismPortal2_CGT_Upgrade_Test is OptimismPortal2_Upgrade_Test { +contract OptimismPortal2_CGT_UpgradeInterop_Test is OptimismPortal2_UpgradeInterop_Test { function setUp() public override { super.enableCustomGasToken(); super.setUp(); From fa190a3b503593eff03c2db32bd99a19e21734e4 Mon Sep 17 00:00:00 2001 From: niha <205694301+0xniha@users.noreply.github.com> Date: Tue, 16 Sep 2025 18:43:07 -0300 Subject: [PATCH 2/5] fix(cgt): add missing native asset amount (#543) * fix: upgrade contract name * feat: add nativeAssetLiquidityAmount to config json files * fix: add correct nativeAssetLiquidityAmount in op-deployer * fix: add correct nativeAssetLiquidityAmount in op-e2e and fix withCustomGasToken argument on op-devstack * fix: restore OptimismPortal2CGT * fix: all comments * fix: comments * fix: governace * fix: remove aux * fix: remove aux * fix: deploy cgt * fix: revert cgt deploy config * fix: deploy config * chore: run linter * fix: remove unnecessary GetNativeAssetLiquidityAmount --------- Co-authored-by: Ashitaka Co-authored-by: agusduha Co-authored-by: hexshire --- op-chain-ops/genesis/config.go | 2 ++ .../pkg/deployer/pipeline/l2genesis.go | 33 ++++++++++--------- .../pkg/deployer/pipeline/l2genesis_test.go | 16 +++++++-- .../pkg/deployer/state/chain_intent.go | 16 +++------ op-deployer/pkg/deployer/state/intent.go | 11 +++---- op-deployer/pkg/deployer/state/intent_test.go | 25 ++++++++++++-- op-devstack/sysgo/deployer.go | 4 +-- op-e2e/config/init.go | 7 ++-- op-e2e/e2eutils/intentbuilder/builder.go | 12 ++++--- op-e2e/e2eutils/intentbuilder/builder_test.go | 10 +++--- .../deploy-config/hardhat.json | 3 +- .../deploy-config/internal-devnet.json | 3 +- .../deploy-config/mainnet.json | 3 +- .../deploy-config/sepolia-devnet-0.json | 3 +- .../deploy-config/sepolia.json | 3 +- .../scripts/deploy/DeployOPChain.s.sol | 2 +- 16 files changed, 94 insertions(+), 59 deletions(-) diff --git a/op-chain-ops/genesis/config.go b/op-chain-ops/genesis/config.go index ad399f7da8873..872b2fad7017d 100644 --- a/op-chain-ops/genesis/config.go +++ b/op-chain-ops/genesis/config.go @@ -296,6 +296,8 @@ func (d *GasTokenDeployConfig) Check(log log.Logger) error { if d.NativeAssetLiquidityAmount == nil { return fmt.Errorf("%w: NativeAssetLiquidityAmount cannot be nil", ErrInvalidDeployConfig) } + + log.Info("Using custom gas token", "name", d.GasPayingTokenName, "symbol", d.GasPayingTokenSymbol, "nativeAssetLiquidityAmount", d.NativeAssetLiquidityAmount.ToInt()) } return nil } diff --git a/op-deployer/pkg/deployer/pipeline/l2genesis.go b/op-deployer/pkg/deployer/pipeline/l2genesis.go index 7088a8ec9e2be..f2f312dc0a691 100644 --- a/op-deployer/pkg/deployer/pipeline/l2genesis.go +++ b/op-deployer/pkg/deployer/pipeline/l2genesis.go @@ -22,9 +22,13 @@ import ( ) type l2GenesisOverrides struct { - UseCustomGasToken bool `json:"useCustomGasToken"` - GasPayingTokenName string `json:"gasPayingTokenName"` - GasPayingTokenSymbol string `json:"gasPayingTokenSymbol"` + // ===== CUSTOM GAS TOKEN (CGT) CONFIGURATION ===== + UseCustomGasToken bool `json:"useCustomGasToken"` // CGT: Enable custom gas token mode + GasPayingTokenName string `json:"gasPayingTokenName"` // CGT: Name of the custom gas token + GasPayingTokenSymbol string `json:"gasPayingTokenSymbol"` // CGT: Symbol of the custom gas token + NativeAssetLiquidityAmount *hexutil.Big `json:"nativeAssetLiquidityAmount"` // CGT: Liquidity amount for NativeAssetLiquidity contract + + // ===== GENERAL L2 CONFIGURATION (NON-CGT) ===== FundDevAccounts bool `json:"fundDevAccounts"` BaseFeeVaultMinimumWithdrawalAmount *hexutil.Big `json:"baseFeeVaultMinimumWithdrawalAmount"` L1FeeVaultMinimumWithdrawalAmount *hexutil.Big `json:"l1FeeVaultMinimumWithdrawalAmount"` @@ -34,7 +38,6 @@ type l2GenesisOverrides struct { SequencerFeeVaultWithdrawalNetwork genesis.WithdrawalNetwork `json:"sequencerFeeVaultWithdrawalNetwork"` EnableGovernance bool `json:"enableGovernance"` GovernanceTokenOwner common.Address `json:"governanceTokenOwner"` - NativeAssetLiquidityAmount *hexutil.Big `json:"nativeAssetLiquidityAmount"` } func GenerateL2Genesis(pEnv *Env, intent *state.Intent, bundle ArtifactsBundle, st *state.State, chainID common.Hash) error { @@ -98,10 +101,11 @@ func GenerateL2Genesis(pEnv *Env, intent *state.Intent, bundle ArtifactsBundle, DeployCrossL2Inbox: len(intent.Chains) > 1, EnableGovernance: overrides.EnableGovernance, FundDevAccounts: overrides.FundDevAccounts, - UseCustomGasToken: thisIntent.CustomGasToken.Enabled, - GasPayingTokenName: thisIntent.CustomGasToken.Name, - GasPayingTokenSymbol: thisIntent.CustomGasToken.Symbol, - NativeAssetLiquidityAmount: thisIntent.GetNativeAssetLiquidityAmount(), + // Custom Gas Token (CGT) configuration passed to L2Genesis script + UseCustomGasToken: thisIntent.CustomGasToken.Enabled, // CGT: Enable/disable custom gas token + GasPayingTokenName: thisIntent.CustomGasToken.Name, // CGT: Token name (e.g., "Custom Gas Token") + GasPayingTokenSymbol: thisIntent.CustomGasToken.Symbol, // CGT: Token symbol (e.g., "CGT") + NativeAssetLiquidityAmount: thisIntent.CustomGasToken.NativeAssetLiquidityAmount.ToInt(), // CGT: Liquidity amount for NativeAssetLiquidity contract }); err != nil { return fmt.Errorf("failed to call L2Genesis script: %w", err) } @@ -172,13 +176,8 @@ func wdNetworkToBig(wd genesis.WithdrawalNetwork) *big.Int { } func defaultOverrides() l2GenesisOverrides { - // Default to type(uint248).max = 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff - maxUint248, _ := new(big.Int).SetString("ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff", 16) - return l2GenesisOverrides{ - UseCustomGasToken: false, - GasPayingTokenName: "", - GasPayingTokenSymbol: "", + // ===== GENERAL L2 DEFAULTS ===== FundDevAccounts: false, BaseFeeVaultMinimumWithdrawalAmount: standard.VaultMinWithdrawalAmount, L1FeeVaultMinimumWithdrawalAmount: standard.VaultMinWithdrawalAmount, @@ -188,6 +187,10 @@ func defaultOverrides() l2GenesisOverrides { SequencerFeeVaultWithdrawalNetwork: "local", EnableGovernance: false, GovernanceTokenOwner: standard.GovernanceTokenOwner, - NativeAssetLiquidityAmount: (*hexutil.Big)(maxUint248), + // ===== CGT DEFAULTS ===== + UseCustomGasToken: false, // CGT disabled by default + GasPayingTokenName: "", // Empty when CGT disabled + GasPayingTokenSymbol: "", // Empty when CGT disabled + NativeAssetLiquidityAmount: (*hexutil.Big)(big.NewInt(0)), // Default to 0 when CGT disabled (consistent with "" and false) } } diff --git a/op-deployer/pkg/deployer/pipeline/l2genesis_test.go b/op-deployer/pkg/deployer/pipeline/l2genesis_test.go index 48e09f1523155..65bcf4860cb65 100644 --- a/op-deployer/pkg/deployer/pipeline/l2genesis_test.go +++ b/op-deployer/pkg/deployer/pipeline/l2genesis_test.go @@ -70,6 +70,7 @@ func TestCalculateL2GenesisOverrides(t *testing.T) { "useCustomGasToken": false, "gasPayingTokenName": "", "gasPayingTokenSymbol": "", + "nativeAssetLiquidityAmount": "0x0", }, }, chainIntent: &state.ChainIntent{}, @@ -85,6 +86,7 @@ func TestCalculateL2GenesisOverrides(t *testing.T) { defaults.SequencerFeeVaultWithdrawalNetwork = "remote" defaults.EnableGovernance = true defaults.GovernanceTokenOwner = common.HexToAddress("0x1111111111111111111111111111111111111111") + defaults.NativeAssetLiquidityAmount = (*hexutil.Big)(hexutil.MustDecodeBig("0x0")) return defaults }(), expectedSchedule: func() *genesis.UpgradeScheduleDeployConfig { @@ -116,6 +118,7 @@ func TestCalculateL2GenesisOverrides(t *testing.T) { "useCustomGasToken": false, "gasPayingTokenName": "", "gasPayingTokenSymbol": "", + "nativeAssetLiquidityAmount": "0x0", }, }, expectError: false, @@ -130,6 +133,7 @@ func TestCalculateL2GenesisOverrides(t *testing.T) { defaults.SequencerFeeVaultWithdrawalNetwork = "remote" defaults.EnableGovernance = true defaults.GovernanceTokenOwner = common.HexToAddress("0x1111111111111111111111111111111111111111") + defaults.NativeAssetLiquidityAmount = (*hexutil.Big)(hexutil.MustDecodeBig("0x0")) return defaults }(), expectedSchedule: func() *genesis.UpgradeScheduleDeployConfig { @@ -144,11 +148,17 @@ func TestCalculateL2GenesisOverrides(t *testing.T) { L1ContractsLocator: &artifacts.Locator{}, GlobalDeployOverrides: map[string]any{ "l2GenesisInteropTimeOffset": "0x0", + "nativeAssetLiquidityAmount": "0x0", }, }, - chainIntent: &state.ChainIntent{}, - expectError: false, - expectedOverrides: defaultOverrides(), + chainIntent: &state.ChainIntent{}, + expectError: false, + expectedOverrides: func() l2GenesisOverrides { + defaults := defaultOverrides() + // Override with the same value that comes from JSON merge to match internal representation + defaults.NativeAssetLiquidityAmount = (*hexutil.Big)(hexutil.MustDecodeBig("0x0")) + return defaults + }(), expectedSchedule: func() *genesis.UpgradeScheduleDeployConfig { schedule := standard.DefaultHardforkScheduleForTag("") schedule.L2GenesisInteropTimeOffset = op_service.U64UtilPtr(0) diff --git a/op-deployer/pkg/deployer/state/chain_intent.go b/op-deployer/pkg/deployer/state/chain_intent.go index 60f953ebb0a3b..71497dfed3888 100644 --- a/op-deployer/pkg/deployer/state/chain_intent.go +++ b/op-deployer/pkg/deployer/state/chain_intent.go @@ -2,7 +2,6 @@ package state import ( "fmt" - "math/big" "github.com/ethereum/go-ethereum/common" "github.com/ethereum/go-ethereum/common/hexutil" @@ -134,6 +133,10 @@ func (c *ChainIntent) Check() error { if c.CustomGasToken.Symbol == "" { return fmt.Errorf("%w: CustomGasToken.Symbol cannot be empty when enabled, chainId=%s", ErrIncompatibleValue, c.ID) } + + if c.CustomGasToken.NativeAssetLiquidityAmount == nil { + return fmt.Errorf("%w: CustomGasToken.NativeAssetLiquidityAmount must be set when custom gas token is enabled, chainId=%s", ErrIncompatibleValue, c.ID) + } } if c.DangerousAltDAConfig.UseAltDA { @@ -142,14 +145,3 @@ func (c *ChainIntent) Check() error { return nil } - -// GetNativeAssetLiquidityAmount returns the native asset liquidity amount for the chain. -// If not set, returns the default value of type(uint248).max. -func (c *ChainIntent) GetNativeAssetLiquidityAmount() *big.Int { - if c.CustomGasToken != nil && c.CustomGasToken.NativeAssetLiquidityAmount != nil { - return c.CustomGasToken.NativeAssetLiquidityAmount.ToInt() - } - // Default to type(uint248).max = 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff - maxUint248, _ := new(big.Int).SetString("ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff", 16) - return maxUint248 -} diff --git a/op-deployer/pkg/deployer/state/intent.go b/op-deployer/pkg/deployer/state/intent.go index ebeaf0d395a7a..8879e5df2375f 100644 --- a/op-deployer/pkg/deployer/state/intent.go +++ b/op-deployer/pkg/deployer/state/intent.go @@ -158,6 +158,10 @@ func (c *Intent) validateStandardValues() error { if len(chain.AdditionalDisputeGames) > 0 { return fmt.Errorf("%w: chainId=%s additionalDisputeGames must be nil", ErrNonStandardValue, chain.ID) } + + if chain.CustomGasToken != nil { + return fmt.Errorf("%w: chainId=%s custom gas token must be nil for standard chains", ErrNonStandardValue, chain.ID) + } } challenger, _ := standard.ChallengerAddressFor(c.L1ChainID) @@ -349,12 +353,7 @@ func NewIntentStandard(l1ChainId uint64, l2ChainIds []common.Hash) (Intent, erro L1ProxyAdminOwner: l1ProxyAdminOwner, L2ProxyAdminOwner: l2ProxyAdminOwner, }, - CustomGasToken: &CustomGasToken{ - Enabled: false, - Name: "", - Symbol: "", - NativeAssetLiquidityAmount: nil, - }, + CustomGasToken: nil, // Standard chains must have nil CustomGasToken }) } return intent, nil diff --git a/op-deployer/pkg/deployer/state/intent_test.go b/op-deployer/pkg/deployer/state/intent_test.go index fc220552914b9..9507054f575c6 100644 --- a/op-deployer/pkg/deployer/state/intent_test.go +++ b/op-deployer/pkg/deployer/state/intent_test.go @@ -1,10 +1,12 @@ package state import ( + "math/big" "testing" "github.com/ethereum-optimism/optimism/op-chain-ops/addresses" "github.com/ethereum/go-ethereum/common" + "github.com/ethereum/go-ethereum/common/hexutil" "github.com/stretchr/testify/require" ) @@ -62,6 +64,18 @@ func TestValidateStandardValues(t *testing.T) { }, ErrNonStandardValue, }, + { + "CustomGasToken", + func(intent *Intent) { + intent.Chains[0].CustomGasToken = &CustomGasToken{ + Enabled: false, + Name: "", + Symbol: "", + NativeAssetLiquidityAmount: (*hexutil.Big)(big.NewInt(0)), + } + }, + ErrNonStandardValue, + }, { "SuperchainConfigProxy", func(intent *Intent) { @@ -239,9 +253,14 @@ func setFeeAddresses(intent *Intent) { } func setCustomGasToken(intent *Intent) { + // 1000 ETH in wei (1000 * 10^18) + amount := new(big.Int) + amount.SetString("1000000000000000000000", 10) + intent.Chains[0].CustomGasToken = &CustomGasToken{ - Enabled: true, - Name: "Custom Gas Token", - Symbol: "CGT", + Enabled: true, + Name: "Custom Gas Token", + Symbol: "CGT", + NativeAssetLiquidityAmount: (*hexutil.Big)(amount), } } diff --git a/op-devstack/sysgo/deployer.go b/op-devstack/sysgo/deployer.go index 98679e2650854..c017ac4be92c2 100644 --- a/op-devstack/sysgo/deployer.go +++ b/op-devstack/sysgo/deployer.go @@ -339,10 +339,10 @@ func WithDisputeGameFinalityDelaySeconds(seconds uint64) DeployerOption { } } -func WithCustomGasToken(enabled bool, name, symbol string) DeployerOption { +func WithCustomGasToken(enabled bool, name, symbol string, nativeAssetLiquidityAmount *big.Int) DeployerOption { return func(p devtest.P, keys devkeys.Keys, builder intentbuilder.Builder) { for _, l2Cfg := range builder.L2s() { - l2Cfg.WithCustomGasToken(enabled, name, symbol) + l2Cfg.WithCustomGasToken(enabled, name, symbol, nativeAssetLiquidityAmount) } } } diff --git a/op-e2e/config/init.go b/op-e2e/config/init.go index 495831488cb53..37dcc27da3bf0 100644 --- a/op-e2e/config/init.go +++ b/op-e2e/config/init.go @@ -401,9 +401,10 @@ func defaultIntent(root string, loc *artifacts.Locator, deployer common.Address, Challenger: common.HexToAddress("0x15d34AAf54267DB7D7c367839AAf71A00a2C6A65"), }, CustomGasToken: &state.CustomGasToken{ - Enabled: false, - Name: "", - Symbol: "", + Enabled: false, + Name: "", + Symbol: "", + NativeAssetLiquidityAmount: nil, }, AdditionalDisputeGames: []state.AdditionalDisputeGame{ { diff --git a/op-e2e/e2eutils/intentbuilder/builder.go b/op-e2e/e2eutils/intentbuilder/builder.go index b75d25fc9a3d5..47daff25d8266 100644 --- a/op-e2e/e2eutils/intentbuilder/builder.go +++ b/op-e2e/e2eutils/intentbuilder/builder.go @@ -2,6 +2,7 @@ package intentbuilder import ( "fmt" + "math/big" "github.com/holiman/uint256" "github.com/stretchr/testify/require" @@ -48,7 +49,7 @@ type L2Configurator interface { WithL1StartBlockHash(hash common.Hash) WithAdditionalDisputeGames(games []state.AdditionalDisputeGame) WithFinalizationPeriodSeconds(value uint64) - WithCustomGasToken(enabled bool, name, symbol string) + WithCustomGasToken(enabled bool, name string, symbol string, nativeAssetLiquidityAmount *big.Int) ContractsConfigurator L2VaultsConfigurator L2RolesConfigurator @@ -388,11 +389,12 @@ func (c *l2Configurator) WithEIP1559Denominator(value uint64) { c.builder.intent.Chains[c.chainIndex].Eip1559Denominator = value } -func (c *l2Configurator) WithCustomGasToken(enabled bool, name, symbol string) { +func (c *l2Configurator) WithCustomGasToken(enabled bool, name, symbol string, nativeAssetLiquidityAmount *big.Int) { c.builder.intent.Chains[c.chainIndex].CustomGasToken = &state.CustomGasToken{ - Enabled: enabled, - Name: name, - Symbol: symbol, + Enabled: enabled, + Name: name, + Symbol: symbol, + NativeAssetLiquidityAmount: (*hexutil.Big)(nativeAssetLiquidityAmount), } } diff --git a/op-e2e/e2eutils/intentbuilder/builder_test.go b/op-e2e/e2eutils/intentbuilder/builder_test.go index c2b40da9b8385..15b50d83f5fb3 100644 --- a/op-e2e/e2eutils/intentbuilder/builder_test.go +++ b/op-e2e/e2eutils/intentbuilder/builder_test.go @@ -2,6 +2,7 @@ package intentbuilder import ( "encoding/json" + "math/big" "net/url" "testing" @@ -69,7 +70,7 @@ func TestBuilder(t *testing.T) { require.Equal(t, eth.ChainIDFromUInt64(420), l2Config.ChainID()) l2Config.WithBlockTime(2) l2Config.WithL1StartBlockHash(common.HexToHash("0x5678")) - l2Config.WithCustomGasToken(false, "", "") + l2Config.WithCustomGasToken(false, "", "", (*big.Int)(big.NewInt(0))) // Test ContractsConfigurator methods l2Config.WithL1ContractsLocator("http://l1.example.com") @@ -163,9 +164,10 @@ func TestBuilder(t *testing.T) { OperatorFeeScalar: 100, OperatorFeeConstant: 200, CustomGasToken: &state.CustomGasToken{ - Enabled: false, - Name: "", - Symbol: "", + Enabled: false, + Name: "", + Symbol: "", + NativeAssetLiquidityAmount: (*hexutil.Big)(big.NewInt(0)), }, DeployOverrides: map[string]any{ "l2BlockTime": uint64(2), diff --git a/packages/contracts-bedrock/deploy-config/hardhat.json b/packages/contracts-bedrock/deploy-config/hardhat.json index e85334e767742..d330d1345955f 100644 --- a/packages/contracts-bedrock/deploy-config/hardhat.json +++ b/packages/contracts-bedrock/deploy-config/hardhat.json @@ -65,5 +65,6 @@ "daResolverRefundPercentage": 50, "useCustomGasToken": false, "gasPayingTokenName": "", - "gasPayingTokenSymbol": "" + "gasPayingTokenSymbol": "", + "nativeAssetLiquidityAmount": null } diff --git a/packages/contracts-bedrock/deploy-config/internal-devnet.json b/packages/contracts-bedrock/deploy-config/internal-devnet.json index 6e862b3bdffc5..e74050bb76c70 100644 --- a/packages/contracts-bedrock/deploy-config/internal-devnet.json +++ b/packages/contracts-bedrock/deploy-config/internal-devnet.json @@ -41,5 +41,6 @@ "recommendedProtocolVersion": "0x0000000000000000000000000000000000000000000000000000000000000000", "useCustomGasToken": false, "gasPayingTokenName": "", - "gasPayingTokenSymbol": "" + "gasPayingTokenSymbol": "", + "nativeAssetLiquidityAmount": null } diff --git a/packages/contracts-bedrock/deploy-config/mainnet.json b/packages/contracts-bedrock/deploy-config/mainnet.json index 9f1888f7c89c6..ae9b04ec3a464 100644 --- a/packages/contracts-bedrock/deploy-config/mainnet.json +++ b/packages/contracts-bedrock/deploy-config/mainnet.json @@ -58,5 +58,6 @@ "useFaultProofs": true, "useCustomGasToken": false, "gasPayingTokenName": "", - "gasPayingTokenSymbol": "" + "gasPayingTokenSymbol": "", + "nativeAssetLiquidityAmount": null } diff --git a/packages/contracts-bedrock/deploy-config/sepolia-devnet-0.json b/packages/contracts-bedrock/deploy-config/sepolia-devnet-0.json index fd698f334e455..78575879084bf 100644 --- a/packages/contracts-bedrock/deploy-config/sepolia-devnet-0.json +++ b/packages/contracts-bedrock/deploy-config/sepolia-devnet-0.json @@ -82,5 +82,6 @@ "recommendedProtocolVersion": "0x0000000000000000000000000000000000000005000000000000000000000000", "useCustomGasToken": false, "gasPayingTokenName": "", - "gasPayingTokenSymbol": "" + "gasPayingTokenSymbol": "", + "nativeAssetLiquidityAmount": null } diff --git a/packages/contracts-bedrock/deploy-config/sepolia.json b/packages/contracts-bedrock/deploy-config/sepolia.json index 87db17dbda262..22ad35b14806b 100644 --- a/packages/contracts-bedrock/deploy-config/sepolia.json +++ b/packages/contracts-bedrock/deploy-config/sepolia.json @@ -57,5 +57,6 @@ "useFaultProofs": true, "useCustomGasToken": false, "gasPayingTokenName": "", - "gasPayingTokenSymbol": "" + "gasPayingTokenSymbol": "", + "nativeAssetLiquidityAmount": null } diff --git a/packages/contracts-bedrock/scripts/deploy/DeployOPChain.s.sol b/packages/contracts-bedrock/scripts/deploy/DeployOPChain.s.sol index b8eac8177e2d4..9db32e7c5b928 100644 --- a/packages/contracts-bedrock/scripts/deploy/DeployOPChain.s.sol +++ b/packages/contracts-bedrock/scripts/deploy/DeployOPChain.s.sol @@ -111,7 +111,7 @@ contract DeployOPChainInput is BaseDeployIO { if (_sel == this.disputeAbsolutePrestate.selector) { _disputeAbsolutePrestate = Claim.wrap(_value); } else { - revert("DeployImplementationsInput: unknown selector"); + revert("DeployOPChainInput: unknown selector"); } } From eaf29df179556b26818ca8f485e7a90f054ca496 Mon Sep 17 00:00:00 2001 From: AgusDuha <81362284+agusduha@users.noreply.github.com> Date: Tue, 16 Sep 2025 20:49:45 -0300 Subject: [PATCH 3/5] fix: l2 genesis pipeline (#554) --- op-deployer/pkg/deployer/pipeline/l2genesis.go | 8 ++++---- op-deployer/pkg/deployer/state/chain_intent.go | 11 +++++++++++ 2 files changed, 15 insertions(+), 4 deletions(-) diff --git a/op-deployer/pkg/deployer/pipeline/l2genesis.go b/op-deployer/pkg/deployer/pipeline/l2genesis.go index f2f312dc0a691..cdafc262b4228 100644 --- a/op-deployer/pkg/deployer/pipeline/l2genesis.go +++ b/op-deployer/pkg/deployer/pipeline/l2genesis.go @@ -102,10 +102,10 @@ func GenerateL2Genesis(pEnv *Env, intent *state.Intent, bundle ArtifactsBundle, EnableGovernance: overrides.EnableGovernance, FundDevAccounts: overrides.FundDevAccounts, // Custom Gas Token (CGT) configuration passed to L2Genesis script - UseCustomGasToken: thisIntent.CustomGasToken.Enabled, // CGT: Enable/disable custom gas token - GasPayingTokenName: thisIntent.CustomGasToken.Name, // CGT: Token name (e.g., "Custom Gas Token") - GasPayingTokenSymbol: thisIntent.CustomGasToken.Symbol, // CGT: Token symbol (e.g., "CGT") - NativeAssetLiquidityAmount: thisIntent.CustomGasToken.NativeAssetLiquidityAmount.ToInt(), // CGT: Liquidity amount for NativeAssetLiquidity contract + UseCustomGasToken: thisIntent.CustomGasToken.Enabled, // CGT: Enable/disable custom gas token + GasPayingTokenName: thisIntent.CustomGasToken.Name, // CGT: Token name (e.g., "Custom Gas Token") + GasPayingTokenSymbol: thisIntent.CustomGasToken.Symbol, // CGT: Token symbol (e.g., "CGT") + NativeAssetLiquidityAmount: thisIntent.GetNativeAssetLiquidityAmount(), // CGT: Liquidity amount for NativeAssetLiquidity contract }); err != nil { return fmt.Errorf("failed to call L2Genesis script: %w", err) } diff --git a/op-deployer/pkg/deployer/state/chain_intent.go b/op-deployer/pkg/deployer/state/chain_intent.go index 71497dfed3888..7b4e6727ad753 100644 --- a/op-deployer/pkg/deployer/state/chain_intent.go +++ b/op-deployer/pkg/deployer/state/chain_intent.go @@ -2,6 +2,7 @@ package state import ( "fmt" + "math/big" "github.com/ethereum/go-ethereum/common" "github.com/ethereum/go-ethereum/common/hexutil" @@ -145,3 +146,13 @@ func (c *ChainIntent) Check() error { return nil } + +// GetNativeAssetLiquidityAmount returns the native asset liquidity amount for the chain. +// If not set, returns the default value of zero. +func (c *ChainIntent) GetNativeAssetLiquidityAmount() *big.Int { + if c.CustomGasToken != nil && c.CustomGasToken.NativeAssetLiquidityAmount != nil { + return c.CustomGasToken.NativeAssetLiquidityAmount.ToInt() + } + + return (*hexutil.Big)(big.NewInt(0)).ToInt() +} From 6ac24baf379744aff1d1e23f5ff4a067e8921f49 Mon Sep 17 00:00:00 2001 From: niha <205694301+0xniha@users.noreply.github.com> Date: Tue, 16 Sep 2025 23:40:01 -0300 Subject: [PATCH 4/5] fix: add nativeAssetLiquidityAmount in e2e apply test (#555) --- op-deployer/pkg/deployer/integration_test/apply_test.go | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/op-deployer/pkg/deployer/integration_test/apply_test.go b/op-deployer/pkg/deployer/integration_test/apply_test.go index e53ffc4bdffe8..2e0fc48208fb5 100644 --- a/op-deployer/pkg/deployer/integration_test/apply_test.go +++ b/op-deployer/pkg/deployer/integration_test/apply_test.go @@ -243,10 +243,13 @@ func TestEndToEndApply(t *testing.T) { t.Run("with custom gas token", func(t *testing.T) { intent, st := newIntent(t, l1ChainID, dk, l2ChainID1, loc, loc) + amount := new(big.Int) + amount.SetString("1000000000000000000000", 10) intent.Chains[0].CustomGasToken = &state.CustomGasToken{ - Enabled: true, - Name: "Custom Gas Token", - Symbol: "CGT", + Enabled: true, + Name: "Custom Gas Token", + Symbol: "CGT", + NativeAssetLiquidityAmount: (*hexutil.Big)(amount), } require.NoError(t, deployer.ApplyPipeline(ctx, deployer.ApplyPipelineOpts{ From fc201ed365bf101eb998bc5ef147421f100968cb Mon Sep 17 00:00:00 2001 From: Hex <165055168+hexshire@users.noreply.github.com> Date: Tue, 16 Sep 2025 23:54:37 -0300 Subject: [PATCH 5/5] fix: failing test --- .../test/L1/OptimismPortal2.t.sol | 58 ++- .../test/L1/OptimismPortal2CGT.t.sol | 434 ------------------ 2 files changed, 56 insertions(+), 436 deletions(-) delete mode 100644 packages/contracts-bedrock/test/L1/OptimismPortal2CGT.t.sol diff --git a/packages/contracts-bedrock/test/L1/OptimismPortal2.t.sol b/packages/contracts-bedrock/test/L1/OptimismPortal2.t.sol index 26bb9501a8d9d..dadd779c8f5d3 100644 --- a/packages/contracts-bedrock/test/L1/OptimismPortal2.t.sol +++ b/packages/contracts-bedrock/test/L1/OptimismPortal2.t.sol @@ -241,7 +241,7 @@ contract OptimismPortal2_Initialize_Test is OptimismPortal2_TestInit { } if (isUsingCustomGasToken()) { assertTrue(OptimismPortal2(payable(address(optimismPortal2))).isCustomGasToken()); - } else { + } else if (!isUsingLockbox()) { assertFalse(OptimismPortal2(payable(address(optimismPortal2))).isCustomGasToken()); } @@ -588,8 +588,9 @@ contract OptimismPortal2_NumProofSubmitters_Test is OptimismPortal2_TestInit { /// @title OptimismPortal2_Receive_Test /// @notice Test contract for OptimismPortal2 `receive` function. contract OptimismPortal2_Receive_Test is OptimismPortal2_TestInit { - /// @notice Tests that `receive` successdully deposits ETH. + /// @notice Tests that `receive` successfully deposits ETH. function testFuzz_receive_succeeds(uint256 _value) external { + skipIfSysFeatureEnabled(Features.CUSTOM_GAS_TOKEN); // Prevent overflow on an upgrade context _value = bound(_value, 0, type(uint256).max - address(ethLockbox).balance); uint256 balanceBefore = address(optimismPortal2).balance; @@ -628,6 +629,7 @@ contract OptimismPortal2_Receive_Test is OptimismPortal2_TestInit { } function testFuzz_receive_withLockbox_succeeds(uint256 _value) external { + skipIfSysFeatureEnabled(Features.CUSTOM_GAS_TOKEN); // Prevent overflow on an upgrade context. // We use a dummy lockbox here because the real one won't work for upgrade tests. address dummyLockbox = address(0xdeadbeef); @@ -663,6 +665,21 @@ contract OptimismPortal2_Receive_Test is OptimismPortal2_TestInit { assertEq(address(optimismPortal2).balance, balanceBefore); assertEq(address(dummyLockbox).balance, lockboxBalanceBefore + _value); } + + /// @notice Tests that `receive` reverts when custom gas token is enabled + function testFuzz_receive_customGasToken_reverts(uint256 _value) external virtual { + skipIfSysFeatureDisabled(Features.CUSTOM_GAS_TOKEN); + _value = bound(_value, 1, type(uint128).max); + vm.deal(alice, _value); + + address portal = address(optimismPortal2); + + vm.prank(alice); + vm.expectRevert(IOptimismPortal.OptimismPortal_NotAllowedOnCGTMode.selector); + assembly { + pop(call(gas(), portal, _value, 0, 0, 0, 0)) + } + } } /// @title OptimismPortal2_DonateETH_Test @@ -1822,6 +1839,21 @@ contract OptimismPortal2_FinalizeWithdrawalTransaction_Test is OptimismPortal2_T assert(address(bob).balance == bobBalanceBefore); } + /// @notice Tests that `finalizeWithdrawalTransaction` reverts when the custom gas token mode + /// is enabled and the withdrawal transaction has a value. + function test_finalizeWithdrawalTransaction_withValueAndCustomGasToken_reverts() external { + skipIfSysFeatureDisabled(Features.CUSTOM_GAS_TOKEN); + skipIfForkTest( + "OptimismPortal2_FinalizeWithdrawalTransaction_Test: isCustomGasToken() not available on forked networks" + ); + // Set the withdrawal transaction value to a non-zero value. + _defaultTx.value = bound(uint256(1), 1, type(uint256).max); + + // Finalize the withdrawal transaction. This should revert. + vm.expectRevert(IOptimismPortal.OptimismPortal_NotAllowedOnCGTMode.selector); + optimismPortal2.finalizeWithdrawalTransaction(_defaultTx); + } + /// @notice Tests that `finalizeWithdrawalTransaction` succeeds. function testDiff_finalizeWithdrawalTransaction_succeeds( address _sender, @@ -2415,6 +2447,28 @@ contract OptimismPortal2_DepositTransaction_Test is OptimismPortal2_TestInit { optimismPortal2.depositTransaction({ _to: address(1), _value: 0, _gasLimit: 0, _isCreation: false, _data: hex"" }); } + /// @notice Tests that `depositTransaction` reverts when the value is greater than 0 and the + /// custom gas token is active. + function test_depositTransaction_withCustomGasTokenAndValue_reverts(bytes memory _data, uint256 _value) external { + skipIfSysFeatureDisabled(Features.CUSTOM_GAS_TOKEN); + skipIfForkTest("OptimismPortal2_DepositTransaction_Test: isCustomGasToken() not available on forked networks"); + + // Prevent overflow on an upgrade context + _value = bound(_value, 1, type(uint256).max - address(optimismPortal2).balance); + uint64 gasLimit = optimismPortal2.minimumGasLimit(uint64(_data.length)); + + vm.deal(alice, _value); + vm.prank(alice); + vm.expectRevert(IOptimismPortal.OptimismPortal_NotAllowedOnCGTMode.selector); + optimismPortal2.depositTransaction{ value: _value }({ + _to: address(0x40), + _value: _value, + _gasLimit: gasLimit, + _isCreation: false, + _data: _data + }); + } + /// @notice Tests that `depositTransaction` succeeds for small, but sufficient, gas limits. function testFuzz_depositTransaction_smallGasLimit_succeeds(bytes memory _data, bool _shouldFail) external { uint64 gasLimit = optimismPortal2.minimumGasLimit(uint64(_data.length)); diff --git a/packages/contracts-bedrock/test/L1/OptimismPortal2CGT.t.sol b/packages/contracts-bedrock/test/L1/OptimismPortal2CGT.t.sol deleted file mode 100644 index 29833626a5864..0000000000000 --- a/packages/contracts-bedrock/test/L1/OptimismPortal2CGT.t.sol +++ /dev/null @@ -1,434 +0,0 @@ -// SPDX-License-Identifier: MIT -pragma solidity 0.8.15; - -// Testing -import { - OptimismPortal2_TestInit, - OptimismPortal2_Version_Test, - OptimismPortal2_Initialize_Test, - OptimismPortal2_Constructor_Test, - OptimismPortal2_UpgradeInterop_Test, - OptimismPortal2_MinimumGasLimit_Test, - OptimismPortal2_Paused_Test, - OptimismPortal2_ProofMaturityDelaySeconds_Test, - OptimismPortal2_DisputeGameFactory_Test, - OptimismPortal2_SuperchainConfig_Test, - OptimismPortal2_Guardian_Test, - OptimismPortal2_DisputeGameFinalityDelaySeconds_Test, - OptimismPortal2_RespectedGameType_Test, - OptimismPortal2_RespectedGameTypeUpdatedAt_Test, - OptimismPortal2_DisputeGameBlacklist_Test, - OptimismPortal2_NumProofSubmitters_Test, - OptimismPortal2_DonateETH_Test, - OptimismPortal2_MigrateLiquidity_Test, - OptimismPortal2_MigrateToSuperRoots_Test, - OptimismPortal2_ProveWithdrawalTransaction_Test, - OptimismPortal2_FinalizeWithdrawalTransaction_Test, - OptimismPortal2_FinalizeWithdrawalTransactionExternalProof_Test, - OptimismPortal2_CheckWithdrawal_Test, - OptimismPortal2_DepositTransaction_Test, - OptimismPortal2_Params_Test -} from "test/L1/OptimismPortal2.t.sol"; - -// Libraries -import { Types } from "src/libraries/Types.sol"; -import { Hashing } from "src/libraries/Hashing.sol"; - -// Interfaces -import { IOptimismPortal2 as IOptimismPortal } from "interfaces/L1/IOptimismPortal2.sol"; -import { IDisputeGame } from "interfaces/dispute/IDisputeGame.sol"; - -/// @title OptimismPortal2CGT_TestInit -/// @notice Reusable test initialization for `OptimismPortal2` tests with custom gas token enabled. -contract OptimismPortal2CGT_TestInit is OptimismPortal2_TestInit { - /// @notice Sets up the test suite with custom gas token enabled. - function setUp() public virtual override { - super.enableCustomGasToken(); - super.setUp(); - } -} - -/// @title OptimismPortal2_CGT_Version_Test -/// @notice Tests the `version` function of the `OptimismPortal2` contract with custom gas token -/// enabled. -contract OptimismPortal2_CGT_Version_Test is OptimismPortal2_Version_Test { - function setUp() public override { - super.enableCustomGasToken(); - super.setUp(); - } -} - -/// @title OptimismPortal2_CGT_Constructor_Test -/// @notice Tests the constructor of the `OptimismPortal2` contract with custom gas token enabled. -contract OptimismPortal2_CGT_Constructor_Test is OptimismPortal2_Constructor_Test { - function setUp() public override { - super.enableCustomGasToken(); - super.setUp(); - } -} - -/// @title OptimismPortal2_Initialize_Test -/// @notice Test contract for OptimismPortal2 `initialize` function. -contract OptimismPortal2_CGT_Initialize_Test is OptimismPortal2_Initialize_Test { - function setUp() public override { - super.enableCustomGasToken(); - super.setUp(); - } - - /// @notice Tests that the initializer sets the correct values. - /// @dev Marked virtual to be overridden in - /// test/kontrol/deployment/DeploymentSummary.t.sol - function test_initialize_succeeds() public override { - skipIfForkTest("OptimismPortal2_Initialize_Test: isCustomGasToken() not available on forked networks"); - super.test_initialize_succeeds(); - } -} - -/// @title OptimismPortal2_CGT_UpgradeInterop_Test -/// @notice Tests the upgrade functionality of the `OptimismPortal2` contract with custom gas token -/// enabled. -contract OptimismPortal2_CGT_UpgradeInterop_Test is OptimismPortal2_UpgradeInterop_Test { - function setUp() public override { - super.enableCustomGasToken(); - super.setUp(); - } -} - -/// @title OptimismPortal2_CGT_MinimumGasLimit_Test -/// @notice Tests the `minimumGasLimit` function of the `OptimismPortal2` contract with custom gas -/// token enabled. -contract OptimismPortal2_CGT_MinimumGasLimit_Test is OptimismPortal2_MinimumGasLimit_Test { - function setUp() public override { - super.enableCustomGasToken(); - super.setUp(); - } -} - -/// @title OptimismPortal2_CGT_Paused_Test -/// @notice Tests the paused state of the `OptimismPortal2` contract with custom gas token enabled. -contract OptimismPortal2_CGT_Paused_Test is OptimismPortal2_Paused_Test { - function setUp() public override { - super.enableCustomGasToken(); - super.setUp(); - } -} - -/// @title OptimismPortal2_CGT_ProofMaturityDelaySeconds_Test -/// @notice Tests the `proofMaturityDelaySeconds` function of the `OptimismPortal2` contract with -/// custom gas token enabled. -contract OptimismPortal2_CGT_ProofMaturityDelaySeconds_Test is OptimismPortal2_ProofMaturityDelaySeconds_Test { - function setUp() public override { - super.enableCustomGasToken(); - super.setUp(); - } -} - -/// @title OptimismPortal2_CGT_DisputeGameFactory_Test -/// @notice Tests the `disputeGameFactory` function of the `OptimismPortal2` contract with custom -/// gas token enabled. -contract OptimismPortal2_CGT_DisputeGameFactory_Test is OptimismPortal2_DisputeGameFactory_Test { - function setUp() public override { - super.enableCustomGasToken(); - super.setUp(); - } -} - -/// @title OptimismPortal2_CGT_SuperchainConfig_Test -/// @notice Tests the `superchainConfig` function of the `OptimismPortal2` contract with custom gas -/// token enabled. -contract OptimismPortal2_CGT_SuperchainConfig_Test is OptimismPortal2_SuperchainConfig_Test { - function setUp() public override { - super.enableCustomGasToken(); - super.setUp(); - } -} - -/// @title OptimismPortal2_CGT_Guardian_Test -/// @notice Tests the `guardian` function of the `OptimismPortal2` contract with custom gas token -/// enabled. -contract OptimismPortal2_CGT_Guardian_Test is OptimismPortal2_Guardian_Test { - function setUp() public override { - super.enableCustomGasToken(); - super.setUp(); - } -} - -/// @title OptimismPortal2_CGT_DisputeGameFinalityDelaySeconds_Test -/// @notice Tests the `disputeGameFinalityDelaySeconds` function of the `OptimismPortal2` contract -/// with custom gas token enabled. -contract OptimismPortal2_CGT_DisputeGameFinalityDelaySeconds_Test is - OptimismPortal2_DisputeGameFinalityDelaySeconds_Test -{ - function setUp() public override { - super.enableCustomGasToken(); - super.setUp(); - } -} - -/// @title OptimismPortal2_CGT_RespectedGameType_Test -/// @notice Tests the `respectedGameType` function of the `OptimismPortal2` contract with custom gas -/// token enabled. -contract OptimismPortal2_CGT_RespectedGameType_Test is OptimismPortal2_RespectedGameType_Test { - function setUp() public override { - super.enableCustomGasToken(); - super.setUp(); - } -} - -/// @title OptimismPortal2_CGT_RespectedGameTypeUpdatedAt_Test -/// @notice Tests the `respectedGameTypeUpdatedAt` function of the `OptimismPortal2` contract with -/// custom gas token enabled. -contract OptimismPortal2_CGT_RespectedGameTypeUpdatedAt_Test is OptimismPortal2_RespectedGameTypeUpdatedAt_Test { - function setUp() public override { - super.enableCustomGasToken(); - super.setUp(); - } -} - -/// @title OptimismPortal2_CGT_DisputeGameBlacklist_Test -/// @notice Tests the `disputeGameBlacklist` function of the `OptimismPortal2` contract with custom -/// gas token enabled. -contract OptimismPortal2_CGT_DisputeGameBlacklist_Test is OptimismPortal2_DisputeGameBlacklist_Test { - function setUp() public override { - super.enableCustomGasToken(); - super.setUp(); - } -} - -/// @title OptimismPortal2_CGT_NumProofSubmitters_Test -/// @notice Tests the `numProofSubmitters` function of the `OptimismPortal2` contract with custom -/// gas token enabled. -contract OptimismPortal2_CGT_NumProofSubmitters_Test is OptimismPortal2_NumProofSubmitters_Test { - function setUp() public override { - super.enableCustomGasToken(); - super.setUp(); - } -} - -/// @title OptimismPortal2_CGT_DonateETH_Test -/// @notice Tests the `donateETH` function of the `OptimismPortal2` contract with custom gas token -/// enabled. -contract OptimismPortal2_CGT_DonateETH_Test is OptimismPortal2_DonateETH_Test { - function setUp() public override { - super.enableCustomGasToken(); - super.setUp(); - } -} - -/// @title OptimismPortal2_CGT_Receive_Test -/// @notice Test contract for OptimismPortal2 `receive` function. -contract OptimismPortal2_CGT_Receive_Test is OptimismPortal2CGT_TestInit { - /// @notice Tests that receive() reverts when custom gas token is enabled - function testFuzz_receive_customGasToken_reverts(uint256 _value) external virtual { - _value = bound(_value, 1, type(uint128).max); - vm.deal(alice, _value); - - address portal = address(optimismPortal2); - - vm.prank(alice); - vm.expectRevert(IOptimismPortal.OptimismPortal_NotAllowedOnCGTMode.selector); - assembly { - pop(call(gas(), portal, _value, 0, 0, 0, 0)) - } - } -} - -/// @title OptimismPortal2_CGT_MigrateLiquidity_Test -/// @notice Tests the `migrateLiquidity` function of the `OptimismPortal2` contract with custom gas -/// token enabled. -contract OptimismPortal2_CGT_MigrateLiquidity_Test is OptimismPortal2_MigrateLiquidity_Test { - function setUp() public override { - super.enableCustomGasToken(); - super.setUp(); - } -} - -/// @title OptimismPortal2_CGT_MigrateToSuperRoots_Test -/// @notice Tests the `migrateToSuperRoots` function of the `OptimismPortal2` contract with custom -/// gas token enabled. -contract OptimismPortal2_CGT_MigrateToSuperRoots_Test is OptimismPortal2_MigrateToSuperRoots_Test { - function setUp() public override { - super.enableCustomGasToken(); - super.setUp(); - } -} - -/// @title OptimismPortal2_CGT_ProveWithdrawalTransaction_Test -/// @notice Tests the `proveWithdrawalTransaction` function of the `OptimismPortal2` contract with -/// custom gas token enabled. -contract OptimismPortal2_CGT_ProveWithdrawalTransaction_Test is OptimismPortal2_ProveWithdrawalTransaction_Test { - function setUp() public override { - super.enableCustomGasToken(); - super.setUp(); - } -} - -/// @title OptimismPortal2_CGT_FinalizeWithdrawalTransaction_Test -/// @notice Tests the `finalizeWithdrawalTransaction` function of the `OptimismPortal2` contract with -/// custom gas token enabled. -contract OptimismPortal2_CGT_FinalizeWithdrawalTransaction_Test is - OptimismPortal2_FinalizeWithdrawalTransaction_Test -{ - function setUp() public override { - super.enableCustomGasToken(); - super.setUp(); - } - - /// @notice Tests that `finalizeWithdrawalTransaction` succeeds when the custom gas token mode - /// is enabled and the withdrawal transaction has no value. - function test_finalizeWithdrawalTransaction_withoutValueAndCustomGasToken_succeeds( - address _sender, - address _target, - uint256 _gasLimit, - bytes memory _data - ) - external - { - skipIfForkTest("Skipping on forked tests because of the L2ToL1MessageParser call below"); - - vm.assume( - _target != address(optimismPortal2) // Cannot call the optimism portal or a contract - && _target.code.length == 0 // No accounts with code - && _target != CONSOLE // The console has no code but behaves like a contract - && uint160(_target) > 9 // No precompiles (or zero address) - ); - - uint256 gasLimit = bound(_gasLimit, 0, 50_000_000); - uint256 nonce = l2ToL1MessagePasser.messageNonce(); - - // Get a withdrawal transaction and mock proof from the differential testing script. - Types.WithdrawalTransaction memory _tx = Types.WithdrawalTransaction({ - nonce: nonce, - sender: _sender, - target: _target, - value: 0, - gasLimit: gasLimit, - data: _data - }); - ( - bytes32 stateRoot, - bytes32 storageRoot, - bytes32 outputRoot, - bytes32 withdrawalHash, - bytes[] memory withdrawalProof - ) = ffi.getProveWithdrawalTransactionInputs(_tx); - - // Create the output root proof - Types.OutputRootProof memory outputProof = Types.OutputRootProof({ - version: bytes32(uint256(0)), - stateRoot: stateRoot, - messagePasserStorageRoot: storageRoot, - latestBlockhash: bytes32(uint256(0)) - }); - - // Ensure the values returned from ffi are correct - assertEq(outputRoot, Hashing.hashOutputRootProof(outputProof)); - assertEq(withdrawalHash, Hashing.hashWithdrawal(_tx)); - - // Setup the dispute game to return the output root - vm.mockCall(address(game), abi.encodeCall(game.rootClaim, ()), abi.encode(outputRoot)); - - // Prove the withdrawal transaction - optimismPortal2.proveWithdrawalTransaction(_tx, _proposedGameIndex, outputProof, withdrawalProof); - (IDisputeGame _game,) = optimismPortal2.provenWithdrawals(withdrawalHash, address(this)); - assertTrue(_game.rootClaim().raw() != bytes32(0)); - - // Resolve the dispute game - game.resolveClaim(0, 0); - game.resolve(); - - // Warp past the finalization period - vm.warp(block.timestamp + optimismPortal2.proofMaturityDelaySeconds() + 1); - - // Finalize the withdrawal transaction - vm.expectCallMinGas(_tx.target, _tx.value, uint64(_tx.gasLimit), _tx.data); - optimismPortal2.finalizeWithdrawalTransaction(_tx); - assertTrue(optimismPortal2.finalizedWithdrawals(withdrawalHash)); - } - - /// @notice Tests that `finalizeWithdrawalTransaction` reverts when the custom gas token mode - /// is enabled and the withdrawal transaction has a value. - function test_finalizeWithdrawalTransaction_withValueAndCustomGasToken_reverts() external { - skipIfForkTest("OptimismPortal2_Initialize_Test: isCustomGasToken() not available on forked networks"); - - // Set the withdrawal transaction value to a non-zero value. - _defaultTx.value = bound(uint256(1), 1, type(uint256).max); - - // Finalize the withdrawal transaction. This should revert. - vm.expectRevert(IOptimismPortal.OptimismPortal_NotAllowedOnCGTMode.selector); - optimismPortal2.finalizeWithdrawalTransaction(_defaultTx); - } -} - -/// @title OptimismPortal2_CGT_FinalizeWithdrawalTransactionExternalProof_Test -/// @notice Tests the `finalizeWithdrawalTransactionExternalProof` function of the `OptimismPortal2` -/// contract with custom gas token enabled. -contract OptimismPortal2_CGT_FinalizeWithdrawalTransactionExternalProof_Test is - OptimismPortal2_FinalizeWithdrawalTransactionExternalProof_Test -{ - function setUp() public override { - super.enableCustomGasToken(); - super.setUp(); - } -} - -/// @title OptimismPortal2_CGT_CheckWithdrawal_Test -/// @notice Tests the `checkWithdrawal` function of the `OptimismPortal2` contract with custom gas -/// token enabled. -contract OptimismPortal2_CGT_CheckWithdrawal_Test is OptimismPortal2_CheckWithdrawal_Test { - function setUp() public override { - super.enableCustomGasToken(); - super.setUp(); - } -} - -/// @title OptimismPortal2_CGT_DepositTransaction_Test -/// @notice Tests the `depositTransaction` function of the `OptimismPortal2` contract with custom gas -/// token enabled. -contract OptimismPortal2_CGT_DepositTransaction_Test is OptimismPortal2_DepositTransaction_Test { - function setUp() public override { - super.enableCustomGasToken(); - super.setUp(); - } - - /// @notice Tests that depositTransaction succeeds when value = 0 and custom gas token is enabled - function testFuzz_depositTransaction_withZeroValue_succeeds(bytes memory _data, address _to) external { - uint64 gasLimit = optimismPortal2.minimumGasLimit(uint64(_data.length)); - assumeNotForgeAddress(_to); - assumeNotZeroAddress(_to); - - vm.prank(alice); - optimismPortal2.depositTransaction({ _to: _to, _value: 0, _gasLimit: gasLimit, _isCreation: false, _data: hex"" }); - } - - /// @notice Tests that `depositTransaction` reverts when the value is greater than 0 and the - /// custom gas token is active. - function test_depositTransaction_withValue_reverts(bytes memory _data, uint256 _value) external { - skipIfForkTest("OptimismPortal2_Initialize_Test: isCustomGasToken() not available on forked networks"); - - // Prevent overflow on an upgrade context - _value = bound(_value, 1, type(uint256).max - address(optimismPortal2).balance); - uint64 gasLimit = optimismPortal2.minimumGasLimit(uint64(_data.length)); - - vm.deal(alice, _value); - vm.prank(alice); - vm.expectRevert(IOptimismPortal.OptimismPortal_NotAllowedOnCGTMode.selector); - optimismPortal2.depositTransaction{ value: _value }({ - _to: address(0x40), - _value: _value, - _gasLimit: gasLimit, - _isCreation: false, - _data: _data - }); - } -} - -/// @title OptimismPortal2_CGT_Params_Test -/// @notice Tests the parameter functions of the `OptimismPortal2` contract with custom gas token -/// enabled. -contract OptimismPortal2_CGT_Params_Test is OptimismPortal2_Params_Test { - function setUp() public override { - super.enableCustomGasToken(); - super.setUp(); - } -}