Skip to content

Commit

Permalink
Reapply "feat: custom gas token (#10143)" (#10384)
Browse files Browse the repository at this point in the history
Now that the fault proof contracts release has happened, we
can merge in the custom gas token changes.

This reverts commit 2b1c99b.
  • Loading branch information
tynes committed May 3, 2024
1 parent a6d4eed commit e71e97d
Show file tree
Hide file tree
Showing 69 changed files with 5,006 additions and 1,370 deletions.
318 changes: 316 additions & 2 deletions op-bindings/bindings/l1block.go

Large diffs are not rendered by default.

59 changes: 45 additions & 14 deletions op-bindings/bindings/l1crossdomainmessenger.go

Large diffs are not rendered by default.

59 changes: 45 additions & 14 deletions op-bindings/bindings/l1standardbridge.go

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion op-bindings/bindings/l2crossdomainmessenger.go

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion op-bindings/bindings/l2standardbridge.go

Large diffs are not rendered by default.

122 changes: 120 additions & 2 deletions op-bindings/bindings/optimismportal.go

Large diffs are not rendered by default.

155 changes: 147 additions & 8 deletions op-bindings/bindings/systemconfig.go

Large diffs are not rendered by default.

1,133 changes: 1,133 additions & 0 deletions op-bindings/bindings/weth.go

Large diffs are not rendered by default.

6 changes: 3 additions & 3 deletions op-bindings/predeploys/addresses.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ import "github.com/ethereum/go-ethereum/common"
const (
L2ToL1MessagePasser = "0x4200000000000000000000000000000000000016"
DeployerWhitelist = "0x4200000000000000000000000000000000000002"
WETH9 = "0x4200000000000000000000000000000000000006"
WETH = "0x4200000000000000000000000000000000000006"
L2CrossDomainMessenger = "0x4200000000000000000000000000000000000007"
L2StandardBridge = "0x4200000000000000000000000000000000000010"
SequencerFeeVault = "0x4200000000000000000000000000000000000011"
Expand Down Expand Up @@ -41,7 +41,7 @@ const (
var (
L2ToL1MessagePasserAddr = common.HexToAddress(L2ToL1MessagePasser)
DeployerWhitelistAddr = common.HexToAddress(DeployerWhitelist)
WETH9Addr = common.HexToAddress(WETH9)
WETHAddr = common.HexToAddress(WETH)
L2CrossDomainMessengerAddr = common.HexToAddress(L2CrossDomainMessenger)
L2StandardBridgeAddr = common.HexToAddress(L2StandardBridge)
SequencerFeeVaultAddr = common.HexToAddress(SequencerFeeVault)
Expand Down Expand Up @@ -77,7 +77,7 @@ var (
func init() {
Predeploys["L2ToL1MessagePasser"] = &Predeploy{Address: L2ToL1MessagePasserAddr}
Predeploys["DeployerWhitelist"] = &Predeploy{Address: DeployerWhitelistAddr}
Predeploys["WETH9"] = &Predeploy{Address: WETH9Addr, ProxyDisabled: true}
Predeploys["WETH"] = &Predeploy{Address: WETHAddr, ProxyDisabled: true}
Predeploys["L2CrossDomainMessenger"] = &Predeploy{Address: L2CrossDomainMessengerAddr}
Predeploys["L2StandardBridge"] = &Predeploy{Address: L2StandardBridgeAddr}
Predeploys["SequencerFeeVault"] = &Predeploy{Address: SequencerFeeVaultAddr}
Expand Down
11 changes: 10 additions & 1 deletion op-chain-ops/genesis/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -247,7 +247,10 @@ type DeployConfig struct {
// UseFaultProofs is a flag that indicates if the system is using fault
// proofs instead of the older output oracle mechanism.
UseFaultProofs bool `json:"useFaultProofs"`

// UseCustomGasToken is a flag to indicate that a custom gas token should be used
UseCustomGasToken bool `json:"useCustomGasToken"`
// CustomGasTokenAddress is the address of the ERC20 token to be used to pay for gas on L2.
CustomGasTokenAddress common.Address `json:"customGasTokenAddress"`
// UsePlasma is a flag that indicates if the system is using op-plasma
UsePlasma bool `json:"usePlasma"`
// DAChallengeWindow represents the block interval during which the availability of a data commitment can be challenged.
Expand Down Expand Up @@ -426,6 +429,12 @@ func (d *DeployConfig) Check() error {
return fmt.Errorf("%w: DAResolveWindow cannot be 0 when using plasma mode", ErrInvalidDeployConfig)
}
}
if d.UseCustomGasToken {
if d.CustomGasTokenAddress == (common.Address{}) {
return fmt.Errorf("%w: CustomGasTokenAddress cannot be address(0)", ErrInvalidDeployConfig)
}
log.Info("Using custom gas token", "address", d.CustomGasTokenAddress)
}
// checkFork checks that fork A is before or at the same time as fork B
checkFork := func(a, b *hexutil.Uint64, aName, bName string) error {
if a == nil && b == nil {
Expand Down
2 changes: 2 additions & 0 deletions op-chain-ops/genesis/testdata/test-deploy-config-full.json
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
"channelTimeout": 30,
"l1UseClique": false,
"cliqueSignerAddress": "0x0000000000000000000000000000000000000000",
"customGasTokenAddress": "0x0000000000000000000000000000000000000000",
"p2pSequencerAddress": "0x9965507d1a55bcc2695c58ba16fb37d819b0a4dc",
"batchInboxAddress": "0x42000000000000000000000000000000000000ff",
"batchSenderAddress": "0x3c44cdddb6a900fa2b585dd299e03d12fa4293bc",
Expand Down Expand Up @@ -83,6 +84,7 @@
"proofMaturityDelaySeconds": 12,
"disputeGameFinalityDelaySeconds": 6,
"respectedGameType": 0,
"useCustomGasToken": false,
"useFaultProofs": false,
"usePlasma": false,
"daBondSize": 0,
Expand Down
20 changes: 10 additions & 10 deletions op-e2e/bridge_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -40,47 +40,47 @@ func TestERC20BridgeDeposits(t *testing.T) {
opts, err := bind.NewKeyedTransactorWithChainID(sys.Cfg.Secrets.Alice, cfg.L1ChainIDBig())
require.Nil(t, err)

// Deploy WETH9
weth9Address, tx, WETH9, err := bindings.DeployWETH9(opts, l1Client)
// Deploy WETH
wethAddress, tx, WETH, err := bindings.DeployWETH(opts, l1Client)
require.NoError(t, err)
_, err = wait.ForReceiptOK(context.Background(), l1Client, tx.Hash())
require.NoError(t, err, "Waiting for deposit tx on L1")

// Get some WETH
opts.Value = big.NewInt(params.Ether)
tx, err = WETH9.Deposit(opts)
tx, err = WETH.Deposit(opts)
require.NoError(t, err)
_, err = wait.ForReceiptOK(context.Background(), l1Client, tx.Hash())
require.NoError(t, err)
opts.Value = nil
wethBalance, err := WETH9.BalanceOf(&bind.CallOpts{}, opts.From)
wethBalance, err := WETH.BalanceOf(&bind.CallOpts{}, opts.From)
require.NoError(t, err)
require.Equal(t, big.NewInt(params.Ether), wethBalance)

// Deploy L2 WETH9
// Deploy L2 WETH
l2Opts, err := bind.NewKeyedTransactorWithChainID(sys.Cfg.Secrets.Alice, cfg.L2ChainIDBig())
require.NoError(t, err)
optimismMintableTokenFactory, err := bindings.NewOptimismMintableERC20Factory(predeploys.OptimismMintableERC20FactoryAddr, l2Client)
require.NoError(t, err)
tx, err = optimismMintableTokenFactory.CreateOptimismMintableERC20(l2Opts, weth9Address, "L2-WETH", "L2-WETH")
tx, err = optimismMintableTokenFactory.CreateOptimismMintableERC20(l2Opts, wethAddress, "L2-WETH", "L2-WETH")
require.NoError(t, err)
rcpt, err := wait.ForReceiptOK(context.Background(), l2Client, tx.Hash())
require.NoError(t, err)

event, err := receipts.FindLog(rcpt.Logs, optimismMintableTokenFactory.ParseOptimismMintableERC20Created)
require.NoError(t, err, "Should emit ERC20Created event")

// Approve WETH9 with the bridge
tx, err = WETH9.Approve(opts, cfg.L1Deployments.L1StandardBridgeProxy, new(big.Int).SetUint64(math.MaxUint64))
// Approve WETH with the bridge
tx, err = WETH.Approve(opts, cfg.L1Deployments.L1StandardBridgeProxy, new(big.Int).SetUint64(math.MaxUint64))
require.NoError(t, err)
_, err = wait.ForReceiptOK(context.Background(), l1Client, tx.Hash())
require.NoError(t, err)

// Bridge the WETH9
// Bridge the WETH
l1StandardBridge, err := bindings.NewL1StandardBridge(cfg.L1Deployments.L1StandardBridgeProxy, l1Client)
require.NoError(t, err)
tx, err = transactions.PadGasEstimate(opts, 1.1, func(opts *bind.TransactOpts) (*types.Transaction, error) {
return l1StandardBridge.BridgeERC20(opts, weth9Address, event.LocalToken, big.NewInt(100), 100000, []byte{})
return l1StandardBridge.BridgeERC20(opts, wethAddress, event.LocalToken, big.NewInt(100), 100000, []byte{})
})
require.NoError(t, err)
depositReceipt, err := wait.ForReceiptOK(context.Background(), l1Client, tx.Hash())
Expand Down
20 changes: 10 additions & 10 deletions packages/contracts-bedrock/.gas-snapshot
Original file line number Diff line number Diff line change
@@ -1,11 +1,11 @@
GasBenchMark_L1CrossDomainMessenger:test_sendMessage_benchmark_0() (gas: 356538)
GasBenchMark_L1CrossDomainMessenger:test_sendMessage_benchmark_1() (gas: 2954723)
GasBenchMark_L1StandardBridge_Deposit:test_depositERC20_benchmark_0() (gas: 549153)
GasBenchMark_L1StandardBridge_Deposit:test_depositERC20_benchmark_1() (gas: 4061129)
GasBenchMark_L1StandardBridge_Deposit:test_depositETH_benchmark_0() (gas: 450282)
GasBenchMark_L1StandardBridge_Deposit:test_depositETH_benchmark_1() (gas: 3496031)
GasBenchMark_L1StandardBridge_Finalize:test_finalizeETHWithdrawal_benchmark() (gas: 59809)
GasBenchMark_L2OutputOracle:test_proposeL2Output_benchmark() (gas: 92950)
GasBenchMark_OptimismPortal:test_depositTransaction_benchmark() (gas: 68354)
GasBenchMark_OptimismPortal:test_depositTransaction_benchmark_1() (gas: 69018)
GasBenchMark_L1CrossDomainMessenger:test_sendMessage_benchmark_0() (gas: 369398)
GasBenchMark_L1CrossDomainMessenger:test_sendMessage_benchmark_1() (gas: 2967433)
GasBenchMark_L1StandardBridge_Deposit:test_depositERC20_benchmark_0() (gas: 562077)
GasBenchMark_L1StandardBridge_Deposit:test_depositERC20_benchmark_1() (gas: 4074053)
GasBenchMark_L1StandardBridge_Deposit:test_depositETH_benchmark_0() (gas: 467008)
GasBenchMark_L1StandardBridge_Deposit:test_depositETH_benchmark_1() (gas: 3512757)
GasBenchMark_L1StandardBridge_Finalize:test_finalizeETHWithdrawal_benchmark() (gas: 72627)
GasBenchMark_L2OutputOracle:test_proposeL2Output_benchmark() (gas: 92973)
GasBenchMark_OptimismPortal:test_depositTransaction_benchmark() (gas: 68453)
GasBenchMark_OptimismPortal:test_depositTransaction_benchmark_1() (gas: 68945)
GasBenchMark_OptimismPortal:test_proveWithdrawalTransaction_benchmark() (gas: 155567)
1 change: 0 additions & 1 deletion packages/contracts-bedrock/foundry.toml
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,6 @@ line_length=120
multiline_func_header='all'
bracket_spacing=true
wrap_comments=true
ignore = ['src/vendor/WETH9.sol']

################################################################
# PROFILE: CI #
Expand Down
2 changes: 1 addition & 1 deletion packages/contracts-bedrock/invariant-docs/SystemConfig.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
# `SystemConfig` Invariants

## The gas limit of the `SystemConfig` contract can never be lower than the hard-coded lower bound.
**Test:** [`SystemConfig.t.sol#L68`](../test/invariants/SystemConfig.t.sol#L68)
**Test:** [`SystemConfig.t.sol#L69`](../test/invariants/SystemConfig.t.sol#L69)

4 changes: 2 additions & 2 deletions packages/contracts-bedrock/scripts/Artifacts.s.sol
Original file line number Diff line number Diff line change
Expand Up @@ -129,8 +129,8 @@ abstract contract Artifacts {
return payable(Predeploys.L1_MESSAGE_SENDER);
} else if (digest == keccak256(bytes("DeployerWhitelist"))) {
return payable(Predeploys.DEPLOYER_WHITELIST);
} else if (digest == keccak256(bytes("WETH9"))) {
return payable(Predeploys.WETH9);
} else if (digest == keccak256(bytes("WETH"))) {
return payable(Predeploys.WETH);
} else if (digest == keccak256(bytes("LegacyERC20ETH"))) {
return payable(Predeploys.LEGACY_ERC20_ETH);
} else if (digest == keccak256(bytes("L1BlockNumber"))) {
Expand Down
42 changes: 29 additions & 13 deletions packages/contracts-bedrock/scripts/Deploy.s.sol
Original file line number Diff line number Diff line change
Expand Up @@ -387,16 +387,6 @@ contract Deploy is Deployer {
/// @notice Initialize all of the implementations
function initializeImplementations() public {
console.log("Initializing implementations");
initializeSystemConfig();
initializeL1StandardBridge();
initializeL1ERC721Bridge();
initializeOptimismMintableERC20Factory();
initializeL1CrossDomainMessenger();
initializeL2OutputOracle();
initializeDisputeGameFactory();
initializeDelayedWETH();
initializeAnchorStateRegistry();

// Selectively initialize either the original OptimismPortal or the new OptimismPortal2. Since this will upgrade
// the proxy, we cannot initialize both. FPAC warning can be removed once we're done with the old OptimismPortal
// contract.
Expand All @@ -406,6 +396,16 @@ contract Deploy is Deployer {
} else {
initializeOptimismPortal();
}

initializeSystemConfig();
initializeL1StandardBridge();
initializeL1ERC721Bridge();
initializeOptimismMintableERC20Factory();
initializeL1CrossDomainMessenger();
initializeL2OutputOracle();
initializeDisputeGameFactory();
initializeDelayedWETH();
initializeAnchorStateRegistry();
}

/// @notice Add Plasma setup to the OP chain
Expand Down Expand Up @@ -973,6 +973,11 @@ contract Deploy is Deployer {

bytes32 batcherHash = bytes32(uint256(uint160(cfg.batchSenderAddress())));

address customGasTokenAddress = Constants.ETHER;
if (cfg.useCustomGasToken()) {
customGasTokenAddress = cfg.customGasTokenAddress();
}

_upgradeAndCallViaSafe({
_proxy: payable(systemConfigProxy),
_implementation: systemConfig,
Expand All @@ -993,7 +998,8 @@ contract Deploy is Deployer {
l1StandardBridge: mustGetAddress("L1StandardBridgeProxy"),
disputeGameFactory: mustGetAddress("DisputeGameFactoryProxy"),
optimismPortal: mustGetAddress("OptimismPortalProxy"),
optimismMintableERC20Factory: mustGetAddress("OptimismMintableERC20FactoryProxy")
optimismMintableERC20Factory: mustGetAddress("OptimismMintableERC20FactoryProxy"),
gasPayingToken: customGasTokenAddress
})
)
)
Expand All @@ -1014,6 +1020,7 @@ contract Deploy is Deployer {
address l1StandardBridge = mustGetAddress("L1StandardBridge");
address l1CrossDomainMessengerProxy = mustGetAddress("L1CrossDomainMessengerProxy");
address superchainConfigProxy = mustGetAddress("SuperchainConfigProxy");
address systemConfigProxy = mustGetAddress("SystemConfigProxy");

uint256 proxyType = uint256(proxyAdmin.proxyType(l1StandardBridgeProxy));
Safe safe = Safe(mustGetAddress("SystemOwnerSafe"));
Expand All @@ -1031,7 +1038,11 @@ contract Deploy is Deployer {
_implementation: l1StandardBridge,
_innerCallData: abi.encodeCall(
L1StandardBridge.initialize,
(L1CrossDomainMessenger(l1CrossDomainMessengerProxy), SuperchainConfig(superchainConfigProxy))
(
L1CrossDomainMessenger(l1CrossDomainMessengerProxy),
SuperchainConfig(superchainConfigProxy),
SystemConfig(systemConfigProxy)
)
)
});

Expand Down Expand Up @@ -1093,6 +1104,7 @@ contract Deploy is Deployer {
address l1CrossDomainMessenger = mustGetAddress("L1CrossDomainMessenger");
address superchainConfigProxy = mustGetAddress("SuperchainConfigProxy");
address optimismPortalProxy = mustGetAddress("OptimismPortalProxy");
address systemConfigProxy = mustGetAddress("SystemConfigProxy");

uint256 proxyType = uint256(proxyAdmin.proxyType(l1CrossDomainMessengerProxy));
Safe safe = Safe(mustGetAddress("SystemOwnerSafe"));
Expand Down Expand Up @@ -1124,7 +1136,11 @@ contract Deploy is Deployer {
_implementation: l1CrossDomainMessenger,
_innerCallData: abi.encodeCall(
L1CrossDomainMessenger.initialize,
(SuperchainConfig(superchainConfigProxy), OptimismPortal(payable(optimismPortalProxy)))
(
SuperchainConfig(superchainConfigProxy),
OptimismPortal(payable(optimismPortalProxy)),
SystemConfig(systemConfigProxy)
)
)
});

Expand Down
16 changes: 16 additions & 0 deletions packages/contracts-bedrock/scripts/DeployConfig.s.sol
Original file line number Diff line number Diff line change
Expand Up @@ -74,6 +74,9 @@ contract DeployConfig is Script {
uint256 public daBondSize;
uint256 public daResolverRefundPercentage;

bool public useCustomGasToken;
address public customGasTokenAddress;

function read(string memory _path) public {
console.log("DeployConfig: reading file %s", _path);
try vm.readFile(_path) returns (string memory data) {
Expand Down Expand Up @@ -145,6 +148,9 @@ contract DeployConfig is Script {
daResolveWindow = _readOr(_json, "$.daResolveWindow", 1000);
daBondSize = _readOr(_json, "$.daBondSize", 1000000000);
daResolverRefundPercentage = _readOr(_json, "$.daResolverRefundPercentage", 0);

useCustomGasToken = _readOr(_json, "$.useCustomGasToken", false);
customGasTokenAddress = _readOr(_json, "$.customGasTokenAddress", address(0));
}

function l1StartingBlockTag() public returns (bytes32) {
Expand Down Expand Up @@ -190,6 +196,12 @@ contract DeployConfig is Script {
fundDevAccounts = _fundDevAccounts;
}

/// @notice Allow the `useCustomGasToken` config to be overridden in testing environments
function setUseCustomGasToken(address _token) public {
useCustomGasToken = true;
customGasTokenAddress = _token;
}

function _getBlockByTag(string memory _tag) internal returns (bytes32) {
string[] memory cmd = new string[](3);
cmd[0] = Executables.bash;
Expand All @@ -206,4 +218,8 @@ contract DeployConfig is Script {
function _readOr(string memory json, string memory key, uint256 defaultValue) internal view returns (uint256) {
return vm.keyExists(json, key) ? stdJson.readUint(json, key) : defaultValue;
}

function _readOr(string memory json, string memory key, address defaultValue) internal view returns (address) {
return vm.keyExists(json, key) ? stdJson.readAddress(json, key) : defaultValue;
}
}
30 changes: 4 additions & 26 deletions packages/contracts-bedrock/scripts/L2Genesis.s.sol
Original file line number Diff line number Diff line change
Expand Up @@ -212,7 +212,7 @@ contract L2Genesis is Deployer {
// 01: legacy, not used in OP-Stack
setDeployerWhitelist(); // 2
// 3,4,5: legacy, not used in OP-Stack.
setWETH9(); // 6: WETH9 (not behind a proxy)
setWETH(); // 6: WETH (not behind a proxy)
setL2CrossDomainMessenger(_l1Dependencies.l1CrossDomainMessengerProxy); // 7
// 8,9,A,B,C,D,E: legacy, not used in OP-Stack.
setGasPriceOracle(); // f
Expand Down Expand Up @@ -342,31 +342,9 @@ contract L2Genesis is Deployer {
/// @notice This predeploy is following the safety invariant #1.
/// This contract is NOT proxied and the state that is set
/// in the constructor is set manually.
function setWETH9() public {
console.log("Setting %s implementation at: %s", "WETH9", Predeploys.WETH9);
vm.etch(Predeploys.WETH9, vm.getDeployedCode("WETH9.sol:WETH9"));

vm.store(
Predeploys.WETH9,
/// string public name
hex"0000000000000000000000000000000000000000000000000000000000000000",
/// "Wrapped Ether"
hex"577261707065642045746865720000000000000000000000000000000000001a"
);
vm.store(
Predeploys.WETH9,
/// string public symbol
hex"0000000000000000000000000000000000000000000000000000000000000001",
/// "WETH"
hex"5745544800000000000000000000000000000000000000000000000000000008"
);
vm.store(
Predeploys.WETH9,
// uint8 public decimals
hex"0000000000000000000000000000000000000000000000000000000000000002",
/// 18
hex"0000000000000000000000000000000000000000000000000000000000000012"
);
function setWETH() public {
console.log("Setting %s implementation at: %s", "WETH", Predeploys.WETH);
vm.etch(Predeploys.WETH, vm.getDeployedCode("WETH.sol:WETH"));
}

/// @notice This predeploy is following the safety invariant #1.
Expand Down
Loading

0 comments on commit e71e97d

Please sign in to comment.