Skip to content
Open
Show file tree
Hide file tree
Changes from 91 commits
Commits
Show all changes
96 commits
Select commit Hold shift + click to select a range
0b5940a
feat(cgt): custom gas token
hexshire Sep 2, 2025
5d807c7
feat: add gasPayingTokenName and gasPayingTokenSymbol on json config …
0xniha Sep 3, 2025
2c9c7b9
fix: contracts semver
0xniha Sep 3, 2025
4ddd49f
fix: remove system config bool
ashitakah Sep 3, 2025
1a9acec
test: add OptimismPortal2CGT tests
0xniha Sep 3, 2025
170cede
chore(cgt): set cgt flag l1block & fixes
0xniha Sep 4, 2025
ef98d54
fix(linter): resolve goimports formatting issue
hexshire Sep 4, 2025
1f223a4
feat: add separate l2 contracts for cgt (#530)
0xniha Sep 4, 2025
53a7501
test(cgt): fix failing tests (#529)
hexshire Sep 5, 2025
52d4840
fix(cgt): revert weth
hexshire Sep 7, 2025
c64cbe5
cgt: feature flag integration
tynes Sep 10, 2025
01b018c
config: make backwards compatible
tynes Sep 10, 2025
2b5fdf2
fix: build issue
tynes Sep 10, 2025
c1e9f38
fix: better backwards compatibility
tynes Sep 10, 2025
736e33d
build: fix
tynes Sep 10, 2025
e759aae
lint: fix
tynes Sep 10, 2025
38404d5
snapshots: update
tynes Sep 10, 2025
2175502
op-deployer: apply test with CGT
tynes Sep 10, 2025
5fc88e1
contracts-bedrock: fix versioning
tynes Sep 10, 2025
4db9ecc
lint: fix
tynes Sep 10, 2025
47b0d81
deployer: remove standard values
tynes Sep 10, 2025
75798b4
contracts: semver lock
tynes Sep 10, 2025
787e880
contracts-bedrock: fix semver + abis
tynes Sep 10, 2025
47bd311
cgt: solidity test cleanup
tynes Sep 10, 2025
70f90c4
solidity: fmt
tynes Sep 10, 2025
fe0f5ab
tests: remove dead imports
tynes Sep 10, 2025
0461d07
tests: fixup
tynes Sep 10, 2025
8d2240f
cgt: configurable liquidity amount
tynes Sep 11, 2025
fd8b11d
feat: configurable native asset liquidity balance
tynes Sep 11, 2025
11e3e4c
cleanup: merge L1Block logic so that we inherit
tynes Sep 11, 2025
bccbdb8
snapshots: update
tynes Sep 11, 2025
2652a3f
cgt: inherit logic for L2ToL1MessagePasser
tynes Sep 11, 2025
c865863
semver-lock: update
tynes Sep 11, 2025
8209fb1
lint: fix
tynes Sep 11, 2025
3aedcdc
lint: fixup
tynes Sep 11, 2025
82305b5
interfaces: fix
tynes Sep 11, 2025
da28e87
fixes: smol
tynes Sep 11, 2025
152afcc
deploy-config: sane default
tynes Sep 11, 2025
d159627
lint: fix
tynes Sep 11, 2025
3a876e1
linting: fix
tynes Sep 11, 2025
fbbbba2
lint: fix
tynes Sep 11, 2025
330bb60
semgrep: fix
tynes Sep 11, 2025
b423844
lint: fix
tynes Sep 11, 2025
ca929cb
tests: fix
tynes Sep 12, 2025
8de8477
tests: fix fuzz
tynes Sep 12, 2025
dfe5282
fix: custom gas token rebase (#17484)
agusduha Sep 17, 2025
b54c6b5
Merge branch 'develop' into sc-feat/custom-gas-token-rebase
agusduha Sep 17, 2025
cbdda0f
fix: semver lock
agusduha Sep 17, 2025
9bb50bd
fix: CGT review fixes (#17534)
agusduha Sep 19, 2025
872d409
Merge branch 'develop' into sc-feat/custom-gas-token-rebase
agusduha Sep 19, 2025
ed4c79b
fix: semver
agusduha Sep 19, 2025
01020a3
fix: opcm version
agusduha Sep 19, 2025
244a734
Merge branch 'develop' into sc-feat/custom-gas-token-rebase
agusduha Sep 22, 2025
c8060eb
fix: tests
agusduha Sep 22, 2025
ee87ecd
feat(op-acceptance-tests): add acceptance tests for native CGT across…
scharissis Sep 22, 2025
4ad8a30
fix: custom gas token rebase review comments (#17577)
agusduha Sep 24, 2025
4f01447
fix: cgt review (#17612)
agusduha Sep 25, 2025
c83d058
test: custom gas token invariants (#17489)
simon-something Sep 25, 2025
882ca7a
refactor: use skipIfDevFeatureDisabled for cgt predeploys test (#614)…
agusduha Sep 25, 2025
2da84c8
Merge branch 'develop' into sc-feat/custom-gas-token-rebase
agusduha Sep 25, 2025
bf72a8c
fix: tests
agusduha Sep 25, 2025
f033db8
fix: auth minter helper & bound _mint in depositTransaction tests (#1…
0xniha Sep 26, 2025
52d462f
Merge branch 'develop' into chore/custom-gas-token-opt-1157
hexshire Oct 28, 2025
ad85105
chore: run pre-pr
hexshire Oct 28, 2025
82dcd17
Merge pull request #652 from defi-wonderland/chore/custom-gas-token-o…
hexshire Oct 29, 2025
33727dd
Merge branch 'develop' into chore/cgt-sync
hexshire Oct 29, 2025
f3106ab
Merge pull request #654 from defi-wonderland/chore/cgt-sync
hexshire Oct 29, 2025
a8151e9
chore: address ci errors
hexshire Oct 29, 2025
2c4533c
Merge pull request #657 from defi-wonderland/chore/run-checks
hexshire Oct 30, 2025
5472f9a
chore: fix go tests
hexshire Oct 30, 2025
1b0c1e7
chore: fix go tests
hexshire Oct 30, 2025
78512b9
Merge branch 'develop' into chore/cgt-sync-2
hexshire Oct 30, 2025
702fa9f
chore: run checks
hexshire Oct 30, 2025
4a56665
Merge pull request #661 from defi-wonderland/chore/cgt-sync-2
hexshire Oct 30, 2025
7a214c0
Merge branch 'develop' into chore/cgt-sync-3
hexshire Oct 30, 2025
1f888ed
Merge pull request #662 from defi-wonderland/chore/cgt-sync-3
hexshire Oct 30, 2025
a9c2592
Merge branch 'develop' into chore/cgt-sync-4
hexshire Nov 7, 2025
d6e298e
test(wip): fix failing tests
hexshire Nov 7, 2025
dc6894a
chore: run pre-pr
hexshire Nov 7, 2025
92575bb
fix: cgt flag tests
agusduha Nov 10, 2025
0446411
Merge pull request #670 from defi-wonderland/chore/cgt-sync-4
agusduha Nov 10, 2025
5800632
test: skip fee split invriant when CGT enabled
agusduha Nov 10, 2025
e77879b
test: skip fee split invariant when CGT enabled
ashitakah Nov 10, 2025
5cd4942
test: fix l2 genesis override test (#673)
agusduha Nov 10, 2025
2e44c5f
feat: add ownable liquidity (#671)
ashitakah Nov 14, 2025
6237fa4
Merge branch 'develop' into fix/cgt-develop-sync
agusduha Nov 14, 2025
a8e9aa1
fix: semver
agusduha Nov 14, 2025
8111f55
Merge pull request #677 from defi-wonderland/fix/cgt-develop-sync
agusduha Nov 14, 2025
d6d0a9b
test: fix cgt fork tests (#676)
agusduha Nov 14, 2025
d17478a
fix: go linter (#679)
agusduha Nov 14, 2025
ab05944
test: fix go fuzz (#680)
agusduha Nov 14, 2025
fb15c2f
fix: cgt config jsons (#681)
agusduha Nov 14, 2025
5e0a657
fix: zero owner and sepolia address (#685)
agusduha Nov 14, 2025
fd6865e
feat: predeploys (#684)
ashitakah Nov 14, 2025
67705cc
Merge branch 'develop' into fix/cgt-develop-sync-2
agusduha Nov 14, 2025
adbdcb0
Merge pull request #688 from defi-wonderland/fix/cgt-develop-sync-2
agusduha Nov 14, 2025
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
18 changes: 15 additions & 3 deletions .circleci/config.yml
Original file line number Diff line number Diff line change
Expand Up @@ -1912,7 +1912,7 @@ jobs:
jq -c '{blocks: .}' /tmp/blocks.json > /tmp/slack_template.json
echo 'export SLACK_TEMPLATE=$(cat /tmp/slack_template.json)' >> $BASH_ENV
- slack/notify:
channel: C03N11M0BBN # "notify-ci" channel
channel: C03N11M0BBN # "notify-ci" channel
event: always
retries: 1
retry_delay: 3
Expand Down Expand Up @@ -2462,7 +2462,11 @@ workflows:
or:
- equal: [build_daily, <<pipeline.schedule.name>>]
- and:
- equal: [true, << pipeline.parameters.kurtosis_acceptance_tests_dispatch >>]
- equal:
[
true,
<< pipeline.parameters.kurtosis_acceptance_tests_dispatch >>,
]
- equal: ["api", << pipeline.trigger_source >>]
jobs:
- contracts-bedrock-build: # needed for in-process tests that some suites may use
Expand Down Expand Up @@ -2546,6 +2550,7 @@ workflows:
- main
- OPTIMISM_PORTAL_INTEROP
- CANNON_KONA,DEPLOY_V2_DISPUTE_GAMES
- CUSTOM_GAS_TOKEN
context:
- circleci-repo-readonly-authenticated-github-token
check_changed_patterns: contracts-bedrock,op-node
Expand Down Expand Up @@ -3184,7 +3189,14 @@ workflows:
- cannon-prestate-quick
matrix:
parameters:
network_preset: ["op-sepolia", "base-sepolia", "unichain-sepolia", "op-mainnet", "base-mainnet"]
network_preset:
[
"op-sepolia",
"base-sepolia",
"unichain-sepolia",
"op-mainnet",
"base-mainnet",
]
l2_cl_syncmode: ["consensus-layer", "execution-layer"]

scheduled-heavy-fuzz-tests:
Expand Down
6 changes: 6 additions & 0 deletions op-acceptance-tests/acceptance-tests.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -109,3 +109,9 @@ gates:
tests:
- package: github.com/ethereum-optimism/optimism/op-acceptance-tests/tests/jovian/...
timeout: 10m

- id: cgt
description: "Custom Gas Token (CGT) network tests."
tests:
- package: github.com/ethereum-optimism/optimism/op-acceptance-tests/tests/custom_gas_token
timeout: 10m
3 changes: 3 additions & 0 deletions op-acceptance-tests/justfile
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,9 @@ jovian:
interop:
@just acceptance-test "" interop

cgt:
@just acceptance-test "" cgt


# Run acceptance tests with mise-managed binary
# Usage: just acceptance-test [devnet] [gate]
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
package custom_gas_token

import (
"testing"

"github.com/ethereum-optimism/optimism/op-devstack/devtest"
"github.com/ethereum-optimism/optimism/op-devstack/presets"
)

// TestCGT_IntrospectionViaL1Block verifies that the L2 L1Block predeploy reports
// that CGT mode is enabled and exposes non-empty token metadata (name, symbol).
func TestCGT_IntrospectionViaL1Block(gt *testing.T) {
t := devtest.SerialT(gt)
sys := presets.NewMinimal(t)

name, symbol := ensureCGTOrSkip(t, sys)

// Metadata should be non-empty.
if name == "" {
t.Require().Fail("gasPayingTokenName() returned empty string")
}
if symbol == "" {
t.Require().Fail("gasPayingTokenSymbol() returned empty string")
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
package custom_gas_token

import (
"context"
"testing"
"time"

"github.com/ethereum-optimism/optimism/op-devstack/devtest"
"github.com/ethereum-optimism/optimism/op-devstack/presets"

"github.com/ethereum/go-ethereum"
"github.com/ethereum/go-ethereum/common"
"github.com/ethereum/go-ethereum/rpc"
"github.com/lmittmann/w3"
)

// TestCGT_L1PortalIntrospection checks that the L1 OptimismPortal exposes
// a valid SystemConfig address via its systemConfig() view.
func TestCGT_L1PortalIntrospection(gt *testing.T) {
t := devtest.SerialT(gt)
sys := presets.NewMinimal(t)

// Skip if this devnet is not CGT-enabled (uses your existing gate).
ensureCGTOrSkip(t, sys)

l1c := sys.L1EL.EthClient()
portal := sys.L2Chain.DepositContractAddr()

ctx, cancel := context.WithTimeout(t.Ctx(), 20*time.Second)
defer cancel()

// Portal exposes systemConfig() -> address
systemConfigFunc := w3.MustNewFunc("systemConfig()", "address")

data, err := systemConfigFunc.EncodeArgs()
if err != nil {
t.Require().Fail("encode systemConfig() args: %v", err)
}

out, err := l1c.Call(ctx, ethereum.CallMsg{To: &portal, Data: data}, rpc.LatestBlockNumber)
if err != nil {
t.Require().Fail("portal.systemConfig() call failed: %v", err)
}

var sysCfg common.Address
if err := systemConfigFunc.DecodeReturns(out, &sysCfg); err != nil {
t.Require().Fail("decode portal.systemConfig() returns: %v", err)
}

if sysCfg == (common.Address{}) {
t.Require().Fail("portal.systemConfig() returned zero address")
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
package custom_gas_token

import (
"testing"

"github.com/ethereum-optimism/optimism/op-devstack/devtest"
"github.com/ethereum-optimism/optimism/op-devstack/presets"
"github.com/ethereum-optimism/optimism/op-service/eth"
)

// TestCGT_ValueTransferPaysGasInToken verifies that on CGT chains a simple L2
// value transfer charges gas in the native ERC-20, and balances reflect
// recipient +amount and sender > amount decrease (amount + gas).
func TestCGT_ValueTransferPaysGasInToken(gt *testing.T) {
t := devtest.SerialT(gt)
sys := presets.NewMinimal(t)

ensureCGTOrSkip(t, sys)

sender := sys.FunderL2.NewFundedEOA(eth.OneTenthEther)
recipient := sys.Wallet.NewEOA(sys.L2EL)

amount := eth.OneHundredthEther
beforeS := sender.GetBalance()
beforeR := recipient.GetBalance()

// This sends L2 native (CGT) value.
sender.Transfer(recipient.Address(), amount)

// Wait until recipient reflects the transfer.
// We don't wait on sender balance; it includes gas and is non-deterministic.
recipient.WaitForBalance(beforeR.Add(amount))

afterS := sender.GetBalance()
afterR := recipient.GetBalance()

// Recipient increased by amount
wantR := beforeR.Add(amount)
if afterR != wantR {
t.Require().Fail("recipient balance mismatch: got %s, want %s", afterR, wantR)
}

// Sender decreased by at least amount (amount + gas). Strict inequality:
if !(beforeS.Sub(afterS)).Gt(amount) {
t.Require().Fail("sender delta must exceed transferred amount (gas must be paid): before=%s after=%s amount=%s",
beforeS, afterS, amount)
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
package custom_gas_token

import (
"context"
"testing"
"time"

"github.com/ethereum-optimism/optimism/op-devstack/devtest"
"github.com/ethereum-optimism/optimism/op-devstack/presets"
"github.com/ethereum/go-ethereum"
"github.com/ethereum/go-ethereum/common"
)

// TestCGT_PortalReceiveReverts asserts that sending ETH to the L1 OptimismPortal
// (receive() -> depositTransaction) reverts under CGT, preventing ETH from getting stuck.
func TestCGT_PortalReceiveReverts(gt *testing.T) {
t := devtest.SerialT(gt)
sys := presets.NewMinimal(t)
ensureCGTOrSkip(t, sys)

l1c := sys.L1EL.EthClient()
portal := sys.L2Chain.DepositContractAddr()

// Try to send 1 wei to the Portal (receive() -> depositTransaction); should revert in CGT mode.
ctx, cancel := context.WithTimeout(t.Ctx(), 20*time.Second)
defer cancel()
_, err := l1c.EstimateGas(ctx, ethereum.CallMsg{
To: &portal,
Value: common.Big1,
})
if err == nil {
t.Require().Fail("expected L1 Portal to revert on direct ETH send in CGT mode, but estimator returned no error")
}
}
68 changes: 68 additions & 0 deletions op-acceptance-tests/tests/custom_gas_token/cgt_reverts_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,68 @@
package custom_gas_token

import (
"context"
"testing"
"time"

"github.com/ethereum-optimism/optimism/op-devstack/devtest"
"github.com/ethereum-optimism/optimism/op-devstack/presets"
"github.com/ethereum-optimism/optimism/op-service/eth"

"math/big"

"github.com/ethereum/go-ethereum"
"github.com/lmittmann/w3"
)

// TestCGT_MessengerRejectsValue ensures that sending native value to the
// L2CrossDomainMessenger reverts under CGT (non-payable path).
func TestCGT_MessengerRejectsValue(gt *testing.T) {
t := devtest.SerialT(gt)
sys := presets.NewMinimal(t)
ensureCGTOrSkip(t, sys)

ctx, cancel := context.WithTimeout(t.Ctx(), 30*time.Second)
defer cancel()

from := sys.FunderL2.NewFundedEOA(eth.OneHundredthEther).Address()
_, err := sys.L2EL.Escape().L2EthClient().EstimateGas(ctx, ethereum.CallMsg{
From: from,
To: &l2XDMAddr,
Value: big.NewInt(1), // 1 wei native
Data: nil,
})
if err == nil {
t.Require().Fail("expected estimation error when sending value to L2CrossDomainMessenger in CGT mode")
}
}

// TestCGT_L2StandardBridge_LegacyWithdrawReverts verifies that the legacy
// ETH-specific withdraw path on L2StandardBridge reverts under CGT.
func TestCGT_L2StandardBridge_LegacyWithdrawReverts(gt *testing.T) {
t := devtest.SerialT(gt)
sys := presets.NewMinimal(t)
ensureCGTOrSkip(t, sys)

ctx, cancel := context.WithTimeout(t.Ctx(), 30*time.Second)
defer cancel()

withdrawFunc := w3.MustNewFunc("withdraw(address,uint256,uint32,bytes)", "")

// Any address is fine; the ETH-specific legacy path should be disabled under CGT.
anyAddress := l2XDMAddr
data, err := withdrawFunc.EncodeArgs(anyAddress, big.NewInt(1), uint32(100_000), []byte{})
if err != nil {
t.Require().Fail("%v", err)
}

from := sys.FunderL2.NewFundedEOA(eth.OneHundredthEther).Address()
_, err = sys.L2EL.Escape().L2EthClient().EstimateGas(ctx, ethereum.CallMsg{
From: from,
To: &l2BridgeAddr,
Data: data,
})
if err == nil {
t.Require().Fail("expected estimation error for L2StandardBridge.withdraw under CGT")
}
}
Loading