diff --git a/packages/contracts-bedrock/interfaces/L1/IOptimismPortal2.sol b/packages/contracts-bedrock/interfaces/L1/IOptimismPortal2.sol index 436a467ce2916..e1223d7d0f75a 100644 --- a/packages/contracts-bedrock/interfaces/L1/IOptimismPortal2.sol +++ b/packages/contracts-bedrock/interfaces/L1/IOptimismPortal2.sol @@ -9,7 +9,6 @@ import { ISystemConfig } from "interfaces/L1/ISystemConfig.sol"; import { ISuperchainConfig } from "interfaces/L1/ISuperchainConfig.sol"; interface IOptimismPortal2 { - error CustomGasTokenNotSupported(); error AlreadyFinalized(); error BadTarget(); error Blacklisted(); @@ -24,13 +23,10 @@ interface IOptimismPortal2 { error InvalidMerkleProof(); error InvalidProof(); error LargeCalldata(); - error NoValue(); error NonReentrant(); - error OnlyCustomGasToken(); error OutOfGas(); error ProposalNotValidated(); error SmallGasLimit(); - error TransferFailed(); error Unauthorized(); error UnexpectedList(); error UnexpectedString(); @@ -46,18 +42,8 @@ interface IOptimismPortal2 { receive() external payable; - function balance() external view returns (uint256); function blacklistDisputeGame(IDisputeGame _disputeGame) external; function checkWithdrawal(bytes32 _withdrawalHash, address _proofSubmitter) external view; - function depositERC20Transaction( - address _to, - uint256 _mint, - uint256 _value, - uint64 _gasLimit, - bool _isCreation, - bytes memory _data - ) - external; function depositTransaction( address _to, uint256 _value, @@ -109,7 +95,6 @@ interface IOptimismPortal2 { returns (IDisputeGame disputeGameProxy, uint64 timestamp); // nosemgrep function respectedGameType() external view returns (GameType); function respectedGameTypeUpdatedAt() external view returns (uint64); - function setGasPayingToken(address _token, uint8 _decimals, bytes32 _name, bytes32 _symbol) external; function setRespectedGameType(GameType _gameType) external; function superchainConfig() external view returns (ISuperchainConfig); function systemConfig() external view returns (ISystemConfig); diff --git a/packages/contracts-bedrock/interfaces/L1/IOptimismPortalInterop.sol b/packages/contracts-bedrock/interfaces/L1/IOptimismPortalInterop.sol index 3de6e5eea4754..ed5f980e1839f 100644 --- a/packages/contracts-bedrock/interfaces/L1/IOptimismPortalInterop.sol +++ b/packages/contracts-bedrock/interfaces/L1/IOptimismPortalInterop.sol @@ -25,13 +25,10 @@ interface IOptimismPortalInterop { error InvalidMerkleProof(); error InvalidProof(); error LargeCalldata(); - error NoValue(); error NonReentrant(); - error OnlyCustomGasToken(); error OutOfGas(); error ProposalNotValidated(); error SmallGasLimit(); - error TransferFailed(); error Unauthorized(); error UnexpectedList(); error UnexpectedString(); @@ -47,18 +44,8 @@ interface IOptimismPortalInterop { receive() external payable; - function balance() external view returns (uint256); function blacklistDisputeGame(IDisputeGame _disputeGame) external; function checkWithdrawal(bytes32 _withdrawalHash, address _proofSubmitter) external view; - function depositERC20Transaction( - address _to, - uint256 _mint, - uint256 _value, - uint64 _gasLimit, - bool _isCreation, - bytes memory _data - ) - external; function depositTransaction( address _to, uint256 _value, @@ -111,7 +98,6 @@ interface IOptimismPortalInterop { function respectedGameType() external view returns (GameType); function respectedGameTypeUpdatedAt() external view returns (uint64); function setConfig(ConfigType _type, bytes memory _value) external; - function setGasPayingToken(address _token, uint8 _decimals, bytes32 _name, bytes32 _symbol) external; function setRespectedGameType(GameType _gameType) external; function superchainConfig() external view returns (ISuperchainConfig); function systemConfig() external view returns (ISystemConfig); diff --git a/packages/contracts-bedrock/interfaces/L1/ISystemConfig.sol b/packages/contracts-bedrock/interfaces/L1/ISystemConfig.sol index 7ed0138ec5bd3..d8c4a6a19e61f 100644 --- a/packages/contracts-bedrock/interfaces/L1/ISystemConfig.sol +++ b/packages/contracts-bedrock/interfaces/L1/ISystemConfig.sol @@ -5,8 +5,6 @@ import { IResourceMetering } from "interfaces/L1/IResourceMetering.sol"; /// @notice This interface corresponds to the Custom Gas Token version of the SystemConfig contract. interface ISystemConfig { - error CustomGasTokenNotSupported(); - enum UpdateType { BATCHER, FEE_SCALARS, @@ -22,7 +20,6 @@ interface ISystemConfig { address disputeGameFactory; address optimismPortal; address optimismMintableERC20Factory; - address gasPayingToken; } event ConfigUpdate(uint256 indexed version, UpdateType indexed updateType, bytes data); @@ -47,9 +44,6 @@ interface ISystemConfig { function gasLimit() external view returns (uint64); function eip1559Denominator() external view returns (uint32); function eip1559Elasticity() external view returns (uint32); - function gasPayingToken() external view returns (address addr_, uint8 decimals_); - function gasPayingTokenName() external view returns (string memory name_); - function gasPayingTokenSymbol() external view returns (string memory symbol_); function initialize( address _owner, uint32 _basefeeScalar, @@ -62,7 +56,6 @@ interface ISystemConfig { Addresses memory _addresses ) external; - function isCustomGasToken() external view returns (bool); function l1CrossDomainMessenger() external view returns (address addr_); function l1ERC721Bridge() external view returns (address addr_); function l1StandardBridge() external view returns (address addr_); diff --git a/packages/contracts-bedrock/interfaces/L1/ISystemConfigInterop.sol b/packages/contracts-bedrock/interfaces/L1/ISystemConfigInterop.sol index 59950cc353608..c9b63db2b1df0 100644 --- a/packages/contracts-bedrock/interfaces/L1/ISystemConfigInterop.sol +++ b/packages/contracts-bedrock/interfaces/L1/ISystemConfigInterop.sol @@ -5,8 +5,6 @@ import { ISystemConfig } from "interfaces/L1/ISystemConfig.sol"; import { IResourceMetering } from "interfaces/L1/IResourceMetering.sol"; interface ISystemConfigInterop { - error CustomGasTokenNotSupported(); - event ConfigUpdate(uint256 indexed version, ISystemConfig.UpdateType indexed updateType, bytes data); event Initialized(uint8 version); event OwnershipTransferred(address indexed previousOwner, address indexed newOwner); @@ -29,10 +27,6 @@ interface ISystemConfigInterop { function gasLimit() external view returns (uint64); function eip1559Denominator() external view returns (uint32); function eip1559Elasticity() external view returns (uint32); - function gasPayingToken() external view returns (address addr_, uint8 decimals_); - function gasPayingTokenName() external view returns (string memory name_); - function gasPayingTokenSymbol() external view returns (string memory symbol_); - function isCustomGasToken() external view returns (bool); function l1CrossDomainMessenger() external view returns (address addr_); function l1ERC721Bridge() external view returns (address addr_); function l1StandardBridge() external view returns (address addr_); diff --git a/packages/contracts-bedrock/scripts/deploy/Deploy.s.sol b/packages/contracts-bedrock/scripts/deploy/Deploy.s.sol index a053fafe4938d..a9f9796844cc5 100644 --- a/packages/contracts-bedrock/scripts/deploy/Deploy.s.sol +++ b/packages/contracts-bedrock/scripts/deploy/Deploy.s.sol @@ -530,8 +530,7 @@ contract Deploy is Deployer { l1StandardBridge: artifacts.mustGetAddress("L1StandardBridgeProxy"), disputeGameFactory: artifacts.mustGetAddress("DisputeGameFactoryProxy"), optimismPortal: artifacts.mustGetAddress("OptimismPortalProxy"), - optimismMintableERC20Factory: artifacts.mustGetAddress("OptimismMintableERC20FactoryProxy"), - gasPayingToken: customGasTokenAddress + optimismMintableERC20Factory: artifacts.mustGetAddress("OptimismMintableERC20FactoryProxy") }) ) ) diff --git a/packages/contracts-bedrock/scripts/deploy/DeployOPChain.s.sol b/packages/contracts-bedrock/scripts/deploy/DeployOPChain.s.sol index 1bae1e6eefaf4..633fa5bedfd7b 100644 --- a/packages/contracts-bedrock/scripts/deploy/DeployOPChain.s.sol +++ b/packages/contracts-bedrock/scripts/deploy/DeployOPChain.s.sol @@ -563,8 +563,6 @@ contract DeployOPChain is Script { systemConfig.optimismMintableERC20Factory() == address(_doo.optimismMintableERC20FactoryProxy()), "SYSCON-210" ); - (address gasPayingToken,) = systemConfig.gasPayingToken(); - require(gasPayingToken == Constants.ETHER, "SYSCON-220"); } function assertValidL1CrossDomainMessenger(DeployOPChainInput _doi, DeployOPChainOutput _doo) internal { diff --git a/packages/contracts-bedrock/snapshots/.gas-snapshot b/packages/contracts-bedrock/snapshots/.gas-snapshot index f4258caa9d69b..438d98f55c8b7 100644 --- a/packages/contracts-bedrock/snapshots/.gas-snapshot +++ b/packages/contracts-bedrock/snapshots/.gas-snapshot @@ -4,10 +4,10 @@ GasBenchMark_L1BlockInterop_SetValuesInterop:test_setL1BlockValuesInterop_benchm GasBenchMark_L1BlockInterop_SetValuesInterop_Warm:test_setL1BlockValuesInterop_benchmark() (gas: 5144) GasBenchMark_L1Block_SetValuesEcotone:test_setL1BlockValuesEcotone_benchmark() (gas: 158531) GasBenchMark_L1Block_SetValuesEcotone_Warm:test_setL1BlockValuesEcotone_benchmark() (gas: 7597) -GasBenchMark_L1CrossDomainMessenger:test_sendMessage_benchmark_0() (gas: 369264) -GasBenchMark_L1CrossDomainMessenger:test_sendMessage_benchmark_1() (gas: 2967493) -GasBenchMark_L1StandardBridge_Deposit:test_depositERC20_benchmark_0() (gas: 564413) -GasBenchMark_L1StandardBridge_Deposit:test_depositERC20_benchmark_1() (gas: 4076606) -GasBenchMark_L1StandardBridge_Deposit:test_depositETH_benchmark_0() (gas: 467092) -GasBenchMark_L1StandardBridge_Deposit:test_depositETH_benchmark_1() (gas: 3512819) -GasBenchMark_L1StandardBridge_Finalize:test_finalizeETHWithdrawal_benchmark() (gas: 72667) \ No newline at end of file +GasBenchMark_L1CrossDomainMessenger:test_sendMessage_benchmark_0() (gas: 356487) +GasBenchMark_L1CrossDomainMessenger:test_sendMessage_benchmark_1() (gas: 2954716) +GasBenchMark_L1StandardBridge_Deposit:test_depositERC20_benchmark_0() (gas: 551636) +GasBenchMark_L1StandardBridge_Deposit:test_depositERC20_benchmark_1() (gas: 4063829) +GasBenchMark_L1StandardBridge_Deposit:test_depositETH_benchmark_0() (gas: 450322) +GasBenchMark_L1StandardBridge_Deposit:test_depositETH_benchmark_1() (gas: 3496221) +GasBenchMark_L1StandardBridge_Finalize:test_finalizeETHWithdrawal_benchmark() (gas: 59849) \ No newline at end of file diff --git a/packages/contracts-bedrock/snapshots/abi/OptimismPortal2.json b/packages/contracts-bedrock/snapshots/abi/OptimismPortal2.json index 99f31298fe631..00c7a4061e35a 100644 --- a/packages/contracts-bedrock/snapshots/abi/OptimismPortal2.json +++ b/packages/contracts-bedrock/snapshots/abi/OptimismPortal2.json @@ -19,19 +19,6 @@ "stateMutability": "payable", "type": "receive" }, - { - "inputs": [], - "name": "balance", - "outputs": [ - { - "internalType": "uint256", - "name": "", - "type": "uint256" - } - ], - "stateMutability": "view", - "type": "function" - }, { "inputs": [ { @@ -63,44 +50,6 @@ "stateMutability": "view", "type": "function" }, - { - "inputs": [ - { - "internalType": "address", - "name": "_to", - "type": "address" - }, - { - "internalType": "uint256", - "name": "_mint", - "type": "uint256" - }, - { - "internalType": "uint256", - "name": "_value", - "type": "uint256" - }, - { - "internalType": "uint64", - "name": "_gasLimit", - "type": "uint64" - }, - { - "internalType": "bool", - "name": "_isCreation", - "type": "bool" - }, - { - "internalType": "bytes", - "name": "_data", - "type": "bytes" - } - ], - "name": "depositERC20Transaction", - "outputs": [], - "stateMutability": "nonpayable", - "type": "function" - }, { "inputs": [ { @@ -602,34 +551,6 @@ "stateMutability": "view", "type": "function" }, - { - "inputs": [ - { - "internalType": "address", - "name": "_token", - "type": "address" - }, - { - "internalType": "uint8", - "name": "_decimals", - "type": "uint8" - }, - { - "internalType": "bytes32", - "name": "_name", - "type": "bytes32" - }, - { - "internalType": "bytes32", - "name": "_symbol", - "type": "bytes32" - } - ], - "name": "setGasPayingToken", - "outputs": [], - "stateMutability": "nonpayable", - "type": "function" - }, { "inputs": [ { @@ -846,11 +767,6 @@ "name": "ContentLengthMismatch", "type": "error" }, - { - "inputs": [], - "name": "CustomGasTokenNotSupported", - "type": "error" - }, { "inputs": [], "name": "EmptyItem", @@ -896,21 +812,11 @@ "name": "LargeCalldata", "type": "error" }, - { - "inputs": [], - "name": "NoValue", - "type": "error" - }, { "inputs": [], "name": "NonReentrant", "type": "error" }, - { - "inputs": [], - "name": "OnlyCustomGasToken", - "type": "error" - }, { "inputs": [], "name": "OutOfGas", @@ -926,11 +832,6 @@ "name": "SmallGasLimit", "type": "error" }, - { - "inputs": [], - "name": "TransferFailed", - "type": "error" - }, { "inputs": [], "name": "Unauthorized", diff --git a/packages/contracts-bedrock/snapshots/abi/OptimismPortalInterop.json b/packages/contracts-bedrock/snapshots/abi/OptimismPortalInterop.json index 1509831f4f184..3a22e3528dd18 100644 --- a/packages/contracts-bedrock/snapshots/abi/OptimismPortalInterop.json +++ b/packages/contracts-bedrock/snapshots/abi/OptimismPortalInterop.json @@ -19,19 +19,6 @@ "stateMutability": "payable", "type": "receive" }, - { - "inputs": [], - "name": "balance", - "outputs": [ - { - "internalType": "uint256", - "name": "", - "type": "uint256" - } - ], - "stateMutability": "view", - "type": "function" - }, { "inputs": [ { @@ -63,44 +50,6 @@ "stateMutability": "view", "type": "function" }, - { - "inputs": [ - { - "internalType": "address", - "name": "_to", - "type": "address" - }, - { - "internalType": "uint256", - "name": "_mint", - "type": "uint256" - }, - { - "internalType": "uint256", - "name": "_value", - "type": "uint256" - }, - { - "internalType": "uint64", - "name": "_gasLimit", - "type": "uint64" - }, - { - "internalType": "bool", - "name": "_isCreation", - "type": "bool" - }, - { - "internalType": "bytes", - "name": "_data", - "type": "bytes" - } - ], - "name": "depositERC20Transaction", - "outputs": [], - "stateMutability": "nonpayable", - "type": "function" - }, { "inputs": [ { @@ -620,34 +569,6 @@ "stateMutability": "nonpayable", "type": "function" }, - { - "inputs": [ - { - "internalType": "address", - "name": "_token", - "type": "address" - }, - { - "internalType": "uint8", - "name": "_decimals", - "type": "uint8" - }, - { - "internalType": "bytes32", - "name": "_name", - "type": "bytes32" - }, - { - "internalType": "bytes32", - "name": "_symbol", - "type": "bytes32" - } - ], - "name": "setGasPayingToken", - "outputs": [], - "stateMutability": "nonpayable", - "type": "function" - }, { "inputs": [ { @@ -914,21 +835,11 @@ "name": "LargeCalldata", "type": "error" }, - { - "inputs": [], - "name": "NoValue", - "type": "error" - }, { "inputs": [], "name": "NonReentrant", "type": "error" }, - { - "inputs": [], - "name": "OnlyCustomGasToken", - "type": "error" - }, { "inputs": [], "name": "OutOfGas", @@ -944,11 +855,6 @@ "name": "SmallGasLimit", "type": "error" }, - { - "inputs": [], - "name": "TransferFailed", - "type": "error" - }, { "inputs": [], "name": "Unauthorized", diff --git a/packages/contracts-bedrock/snapshots/abi/SystemConfig.json b/packages/contracts-bedrock/snapshots/abi/SystemConfig.json index eaa8cb1ecbfde..9cf9533fc7348 100644 --- a/packages/contracts-bedrock/snapshots/abi/SystemConfig.json +++ b/packages/contracts-bedrock/snapshots/abi/SystemConfig.json @@ -238,50 +238,6 @@ "stateMutability": "view", "type": "function" }, - { - "inputs": [], - "name": "gasPayingToken", - "outputs": [ - { - "internalType": "address", - "name": "addr_", - "type": "address" - }, - { - "internalType": "uint8", - "name": "decimals_", - "type": "uint8" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [], - "name": "gasPayingTokenName", - "outputs": [ - { - "internalType": "string", - "name": "name_", - "type": "string" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [], - "name": "gasPayingTokenSymbol", - "outputs": [ - { - "internalType": "string", - "name": "symbol_", - "type": "string" - } - ], - "stateMutability": "view", - "type": "function" - }, { "inputs": [ { @@ -387,11 +343,6 @@ "internalType": "address", "name": "optimismMintableERC20Factory", "type": "address" - }, - { - "internalType": "address", - "name": "gasPayingToken", - "type": "address" } ], "internalType": "struct SystemConfig.Addresses", @@ -404,19 +355,6 @@ "stateMutability": "nonpayable", "type": "function" }, - { - "inputs": [], - "name": "isCustomGasToken", - "outputs": [ - { - "internalType": "bool", - "name": "", - "type": "bool" - } - ], - "stateMutability": "view", - "type": "function" - }, { "inputs": [], "name": "l1CrossDomainMessenger", @@ -800,10 +738,5 @@ ], "name": "OwnershipTransferred", "type": "event" - }, - { - "inputs": [], - "name": "CustomGasTokenNotSupported", - "type": "error" } ] \ No newline at end of file diff --git a/packages/contracts-bedrock/snapshots/abi/SystemConfigInterop.json b/packages/contracts-bedrock/snapshots/abi/SystemConfigInterop.json index c7dae3c2b8e4e..1657176ad563d 100644 --- a/packages/contracts-bedrock/snapshots/abi/SystemConfigInterop.json +++ b/packages/contracts-bedrock/snapshots/abi/SystemConfigInterop.json @@ -259,50 +259,6 @@ "stateMutability": "view", "type": "function" }, - { - "inputs": [], - "name": "gasPayingToken", - "outputs": [ - { - "internalType": "address", - "name": "addr_", - "type": "address" - }, - { - "internalType": "uint8", - "name": "decimals_", - "type": "uint8" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [], - "name": "gasPayingTokenName", - "outputs": [ - { - "internalType": "string", - "name": "name_", - "type": "string" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [], - "name": "gasPayingTokenSymbol", - "outputs": [ - { - "internalType": "string", - "name": "symbol_", - "type": "string" - } - ], - "stateMutability": "view", - "type": "function" - }, { "inputs": [ { @@ -408,21 +364,11 @@ "internalType": "address", "name": "optimismMintableERC20Factory", "type": "address" - }, - { - "internalType": "address", - "name": "gasPayingToken", - "type": "address" } ], "internalType": "struct SystemConfig.Addresses", "name": "_addresses", "type": "tuple" - }, - { - "internalType": "address", - "name": "_dependencyManager", - "type": "address" } ], "name": "initialize", @@ -535,16 +481,16 @@ "internalType": "address", "name": "optimismMintableERC20Factory", "type": "address" - }, - { - "internalType": "address", - "name": "gasPayingToken", - "type": "address" } ], "internalType": "struct SystemConfig.Addresses", "name": "_addresses", "type": "tuple" + }, + { + "internalType": "address", + "name": "_dependencyManager", + "type": "address" } ], "name": "initialize", @@ -552,19 +498,6 @@ "stateMutability": "nonpayable", "type": "function" }, - { - "inputs": [], - "name": "isCustomGasToken", - "outputs": [ - { - "internalType": "bool", - "name": "", - "type": "bool" - } - ], - "stateMutability": "view", - "type": "function" - }, { "inputs": [], "name": "l1CrossDomainMessenger", @@ -961,10 +894,5 @@ ], "name": "OwnershipTransferred", "type": "event" - }, - { - "inputs": [], - "name": "CustomGasTokenNotSupported", - "type": "error" } ] \ No newline at end of file diff --git a/packages/contracts-bedrock/snapshots/semver-lock.json b/packages/contracts-bedrock/snapshots/semver-lock.json index db00d81884ef8..24d8b23d28249 100644 --- a/packages/contracts-bedrock/snapshots/semver-lock.json +++ b/packages/contracts-bedrock/snapshots/semver-lock.json @@ -4,28 +4,28 @@ "sourceCodeHash": "0xae49c741c8cd546981ab59b85b88e9fc1055c4fae085e7078d601b42464f86e6" }, "src/L1/L1CrossDomainMessenger.sol": { - "initCodeHash": "0x192b98a93759f2044ee1ea56270cd203d4f16210c06be388f29b8c1114b9329d", - "sourceCodeHash": "0xfa18fb2e6ac73a143303b07735239a383ae84bd0d0042cceb8253f4784e07afb" + "initCodeHash": "0x4b045c9e0fcfa37838edf154e6e75be4a60406204eccf0d606dfd55da80d266d", + "sourceCodeHash": "0xc92887952f5108a770c3fee8a61c70f740a0a55c2e9ed0aebe266a7c53c71dc3" }, "src/L1/L1ERC721Bridge.sol": { "initCodeHash": "0x280488bce8b4fb364740c59de14c423851902088f384e077bccc79b9df48528a", "sourceCodeHash": "0xe12b9e6c4e4ac2e2c9a03f07c7689f6bf2231922536072812cf1f37a5a276e73" }, "src/L1/L1StandardBridge.sol": { - "initCodeHash": "0x7d7030359826f64714ef0c2a5198901812fb0a99e949f23fe54ccf87a0df2e67", - "sourceCodeHash": "0xa91b445bdc666a02ba18e3b91ba94b6d54bbe65da714002fc734814201319d57" + "initCodeHash": "0xe5f5ab77cc5586ecd94cc687b98f25d8fd7f9bb146a942653a2ec9be7e68f070", + "sourceCodeHash": "0x51f0876ab8410ce32838483f8f59ad6d1c5b4a368e47415b30e44baf291a394b" }, "src/L1/OPContractsManager.sol": { - "initCodeHash": "0xe0c14a8fee7ad4c4e28a3ff6ca4e726721a6c3fea0a74ab7eac7ef07fe4da0ae", - "sourceCodeHash": "0xe0f5413e0a0a335016d773f02ef6bd25551416635981e83b7a4da601b9b65bc4" + "initCodeHash": "0x8bef0b53e7102491957d3ea12ff4857d735dada6af3ef122376bcf3f5489c9b9", + "sourceCodeHash": "0x819e5e9867e09d16346daf81cfc9c129bf9026308055d1fbb6623b4f8818e613" }, "src/L1/OptimismPortal2.sol": { - "initCodeHash": "0x7e533474310583593c2d57d30fcd1ec11e1568dbaaf37a2dd28c5cc574068bac", - "sourceCodeHash": "0xe67f0c01c9c9ba67d279304f9db84eebeb2e93d9f2728fea95c7a194f0ae338a" + "initCodeHash": "0x2121a97875875150106a54a71c6c4c03afe90b3364e416be047f55fdeab57204", + "sourceCodeHash": "0x96e3de3ef0025a6def702eeb481acd2d2d88971fd418be657472f51a98029773" }, "src/L1/OptimismPortalInterop.sol": { - "initCodeHash": "0x917b3b31a149b5aab96539208f4810d207875f6f2563a45c50ed13a7940066c0", - "sourceCodeHash": "0xae2fbe02c0f8685692babeed0252ae8a624dc6d3bfb082fc3807d7b84869004b" + "initCodeHash": "0x09ffe45f91bf59315b9fd4a2941b819ed8b1bb0d8643a630c6193bd67acea0ed", + "sourceCodeHash": "0xbb6acc3e88af9594ffcb8a2f30860511b76e09024330e70052316668fe55fd1f" }, "src/L1/ProtocolVersions.sol": { "initCodeHash": "0x0000ec89712d8b4609873f1ba76afffd4205bf9110818995c90134dbec12e91e", @@ -36,12 +36,12 @@ "sourceCodeHash": "0xafa784ea78818a382ff3a61e2d84be58c7978110c06b9273db68c0213ead02d3" }, "src/L1/SystemConfig.sol": { - "initCodeHash": "0xbb18eef17cdc1d0d307b0241e818820063e3ce3c7021ea3bb3a85ff6e79659e1", - "sourceCodeHash": "0x5d6a9ef41fed54479f742345368e693ec1fcabdb60118081c03fe9da3a5d27ed" + "initCodeHash": "0xf0bfbb889687af7d4e006f40b269bbd9e4d967cdd9c1f29900017ff11b1f5095", + "sourceCodeHash": "0x2dde897735c0cd699f15a1927bf6f75c2da220c1934021ee93315708d5b5f995" }, "src/L1/SystemConfigInterop.sol": { - "initCodeHash": "0x0d61e2a95122417e9bf074a8fc0bce6f2b03268985d09580a83099dc9016c72d", - "sourceCodeHash": "0x673ec83b89680b44945af89229b286f26df07a5938d497df5def47872d331cf3" + "initCodeHash": "0xd89526ba331c24f8ca5ce1eef1554ad573e3aa9e6845a5b0ec23ee8f3497a84a", + "sourceCodeHash": "0x10806bbaa0d0e1dca571b720bd9690dd55cbf57038ab5887ecfdce689b0ae94e" }, "src/L2/BaseFeeVault.sol": { "initCodeHash": "0xc403d4c555d8e69a2699e01d192ae7327136701fa02da10a6d75a584b3c364c9", diff --git a/packages/contracts-bedrock/snapshots/storageLayout/OptimismPortal2.json b/packages/contracts-bedrock/snapshots/storageLayout/OptimismPortal2.json index 0fdd65b3e88fb..654695522e049 100644 --- a/packages/contracts-bedrock/snapshots/storageLayout/OptimismPortal2.json +++ b/packages/contracts-bedrock/snapshots/storageLayout/OptimismPortal2.json @@ -120,7 +120,7 @@ }, { "bytes": "32", - "label": "_balance", + "label": "spacer_61_0_32", "offset": 0, "slot": "61", "type": "uint256" diff --git a/packages/contracts-bedrock/snapshots/storageLayout/OptimismPortalInterop.json b/packages/contracts-bedrock/snapshots/storageLayout/OptimismPortalInterop.json index 0fdd65b3e88fb..654695522e049 100644 --- a/packages/contracts-bedrock/snapshots/storageLayout/OptimismPortalInterop.json +++ b/packages/contracts-bedrock/snapshots/storageLayout/OptimismPortalInterop.json @@ -120,7 +120,7 @@ }, { "bytes": "32", - "label": "_balance", + "label": "spacer_61_0_32", "offset": 0, "slot": "61", "type": "uint256" diff --git a/packages/contracts-bedrock/src/L1/L1CrossDomainMessenger.sol b/packages/contracts-bedrock/src/L1/L1CrossDomainMessenger.sol index 60d69de403bb0..1946c2a9fc09d 100644 --- a/packages/contracts-bedrock/src/L1/L1CrossDomainMessenger.sol +++ b/packages/contracts-bedrock/src/L1/L1CrossDomainMessenger.sol @@ -6,6 +6,7 @@ import { CrossDomainMessenger } from "src/universal/CrossDomainMessenger.sol"; // Libraries import { Predeploys } from "src/libraries/Predeploys.sol"; +import { Constants } from "src/libraries/Constants.sol"; // Interfaces import { ISemver } from "interfaces/universal/ISemver.sol"; @@ -30,8 +31,8 @@ contract L1CrossDomainMessenger is CrossDomainMessenger, ISemver { ISystemConfig public systemConfig; /// @notice Semantic version. - /// @custom:semver 2.4.1-beta.5 - string public constant version = "2.4.1-beta.5"; + /// @custom:semver 2.4.1-beta.6 + string public constant version = "2.4.1-beta.6"; /// @notice Constructs the L1CrossDomainMessenger contract. constructor() { @@ -57,8 +58,10 @@ contract L1CrossDomainMessenger is CrossDomainMessenger, ISemver { } /// @inheritdoc CrossDomainMessenger - function gasPayingToken() internal view override returns (address addr_, uint8 decimals_) { - (addr_, decimals_) = systemConfig.gasPayingToken(); + /// @dev This is added to maintain compatibility with the CrossDomainMessenger abstract contract and should always + /// return the ether address and 18 decimals. + function gasPayingToken() internal pure override returns (address addr_, uint8 decimals_) { + return (Constants.ETHER, 18); } /// @notice Getter function for the OptimismPortal contract on this chain. diff --git a/packages/contracts-bedrock/src/L1/L1StandardBridge.sol b/packages/contracts-bedrock/src/L1/L1StandardBridge.sol index a9299ce9aa83b..61cd481e27129 100644 --- a/packages/contracts-bedrock/src/L1/L1StandardBridge.sol +++ b/packages/contracts-bedrock/src/L1/L1StandardBridge.sol @@ -6,6 +6,7 @@ import { StandardBridge } from "src/universal/StandardBridge.sol"; // Libraries import { Predeploys } from "src/libraries/Predeploys.sol"; +import { Constants } from "src/libraries/Constants.sol"; // Interfaces import { ISemver } from "interfaces/universal/ISemver.sol"; @@ -75,8 +76,8 @@ contract L1StandardBridge is StandardBridge, ISemver { ); /// @notice Semantic version. - /// @custom:semver 2.2.1-beta.5 - string public constant version = "2.2.1-beta.5"; + /// @custom:semver 2.2.1-beta.6 + string public constant version = "2.2.1-beta.6"; /// @notice Address of the SuperchainConfig contract. ISuperchainConfig public superchainConfig; @@ -119,8 +120,10 @@ contract L1StandardBridge is StandardBridge, ISemver { } /// @inheritdoc StandardBridge - function gasPayingToken() internal view override returns (address addr_, uint8 decimals_) { - (addr_, decimals_) = systemConfig.gasPayingToken(); + /// @dev This is added to maintain compatibility with the CrossDomainMessenger abstract contract and should always + /// return the ether address and 18 decimals. + function gasPayingToken() internal pure override returns (address addr_, uint8 decimals_) { + return (Constants.ETHER, 18); } /// @custom:legacy diff --git a/packages/contracts-bedrock/src/L1/OPContractsManager.sol b/packages/contracts-bedrock/src/L1/OPContractsManager.sol index ac1dd3e3efb6f..c5d01a81155b9 100644 --- a/packages/contracts-bedrock/src/L1/OPContractsManager.sol +++ b/packages/contracts-bedrock/src/L1/OPContractsManager.sol @@ -138,8 +138,8 @@ contract OPContractsManager is ISemver { // -------- Constants and Variables -------- - /// @custom:semver 1.0.0-beta.28 - string public constant version = "1.0.0-beta.28"; + /// @custom:semver 1.0.0-beta.29 + string public constant version = "1.0.0-beta.29"; /// @notice Represents the interface version so consumers know how to decode the DeployOutput struct /// that's emitted in the `Deployed` event. Whenever that struct changes, a new version should be used. @@ -750,8 +750,7 @@ contract OPContractsManager is ISemver { l1StandardBridge: address(_output.l1StandardBridgeProxy), disputeGameFactory: address(_output.disputeGameFactoryProxy), optimismPortal: address(_output.optimismPortalProxy), - optimismMintableERC20Factory: address(_output.optimismMintableERC20FactoryProxy), - gasPayingToken: Constants.ETHER + optimismMintableERC20Factory: address(_output.optimismMintableERC20FactoryProxy) }); assertValidContractAddress(opChainAddrs_.l1CrossDomainMessenger); diff --git a/packages/contracts-bedrock/src/L1/OptimismPortal2.sol b/packages/contracts-bedrock/src/L1/OptimismPortal2.sol index 7447a4a3592fe..1456e19cc18b8 100644 --- a/packages/contracts-bedrock/src/L1/OptimismPortal2.sol +++ b/packages/contracts-bedrock/src/L1/OptimismPortal2.sol @@ -12,15 +12,11 @@ import { Constants } from "src/libraries/Constants.sol"; import { Types } from "src/libraries/Types.sol"; import { Hashing } from "src/libraries/Hashing.sol"; import { SecureMerkleTrie } from "src/libraries/trie/SecureMerkleTrie.sol"; -import { Predeploys } from "src/libraries/Predeploys.sol"; import { AddressAliasHelper } from "src/vendor/AddressAliasHelper.sol"; import { BadTarget, LargeCalldata, SmallGasLimit, - TransferFailed, - OnlyCustomGasToken, - NoValue, Unauthorized, CallPaused, GasEstimation, @@ -44,10 +40,6 @@ import { IResourceMetering } from "interfaces/L1/IResourceMetering.sol"; import { ISuperchainConfig } from "interfaces/L1/ISuperchainConfig.sol"; import { IDisputeGameFactory } from "interfaces/dispute/IDisputeGameFactory.sol"; import { IDisputeGame } from "interfaces/dispute/IDisputeGame.sol"; -import { IL1Block } from "interfaces/L2/IL1Block.sol"; - -/// @notice This is temporary. Error thrown when a chain uses a custom gas token. -error CustomGasTokenNotSupported(); /// @custom:proxied true /// @title OptimismPortal2 @@ -137,12 +129,10 @@ contract OptimismPortal2 is Initializable, ResourceMetering, ISemver { /// proof submission should be used when finalizing a withdrawal. mapping(bytes32 => address[]) public proofSubmitters; - /// @notice Represents the amount of native asset minted in L2. This may not - /// be 100% accurate due to the ability to send ether to the contract - /// without triggering a deposit transaction. It also is used to prevent - /// overflows for L2 account balances when custom gas tokens are used. - /// It is not safe to trust `ERC20.balanceOf` as it may lie. - uint256 internal _balance; + /// @custom:legacy + /// @custom:spacer _balance + /// @notice Spacer taking up the legacy `_balance` slot. + uint256 private spacer_61_0_32; /// @notice Emitted when a transaction is deposited from L1 to L2. /// The parameters of this event are read by the rollup node and used to derive deposit @@ -186,9 +176,9 @@ contract OptimismPortal2 is Initializable, ResourceMetering, ISemver { } /// @notice Semantic version. - /// @custom:semver 3.11.0-beta.10 + /// @custom:semver 3.11.0-beta.11 function version() public pure virtual returns (string memory) { - return "3.11.0-beta.10"; + return "3.11.0-beta.11"; } /// @notice Constructs the OptimismPortal contract. @@ -232,19 +222,6 @@ contract OptimismPortal2 is Initializable, ResourceMetering, ISemver { __ResourceMetering_init(); } - /// @notice Getter for the balance of the contract. - function balance() public view returns (uint256) { - (address token,) = gasPayingToken(); - if (token == Constants.ETHER) { - return address(this).balance; - } else { - // Temporary revert till we support custom gas tokens - if (true) revert CustomGasTokenNotSupported(); - - return _balance; - } - } - /// @notice Getter function for the address of the guardian. /// Public getter is legacy and will be removed in the future. Use `SuperchainConfig.guardian()` instead. /// @return Address of the guardian. @@ -294,11 +271,6 @@ contract OptimismPortal2 is Initializable, ResourceMetering, ISemver { // Intentionally empty. } - /// @notice Returns the gas paying token and its decimals. - function gasPayingToken() internal view returns (address addr_, uint8 decimals_) { - (addr_, decimals_) = systemConfig.gasPayingToken(); - } - /// @notice Getter for the resource config. /// Used internally by the ResourceMetering contract. /// The SystemConfig is the source of truth for the resource config. @@ -417,53 +389,14 @@ contract OptimismPortal2 is Initializable, ResourceMetering, ISemver { // Set the l2Sender so contracts know who triggered this withdrawal on L2. l2Sender = _tx.sender; - bool success; - (address token,) = gasPayingToken(); - if (token == Constants.ETHER) { - // Trigger the call to the target contract. We use a custom low level method - // SafeCall.callWithMinGas to ensure two key properties - // 1. Target contracts cannot force this call to run out of gas by returning a very large - // amount of data (and this is OK because we don't care about the returndata here). - // 2. The amount of gas provided to the execution context of the target is at least the - // gas limit specified by the user. If there is not enough gas in the current context - // to accomplish this, `callWithMinGas` will revert. - success = SafeCall.callWithMinGas(_tx.target, _tx.gasLimit, _tx.value, _tx.data); - } else { - // Temporary revert till we support custom gas tokens - if (true) revert CustomGasTokenNotSupported(); - - // Cannot call the token contract directly from the portal. This would allow an attacker - // to call approve from a withdrawal and drain the balance of the portal. - if (_tx.target == token) revert BadTarget(); - - // Only transfer value when a non zero value is specified. This saves gas in the case of - // using the standard bridge or arbitrary message passing. - if (_tx.value != 0) { - // Update the contracts internal accounting of the amount of native asset in L2. - _balance -= _tx.value; - - // Read the balance of the target contract before the transfer so the consistency - // of the transfer can be checked afterwards. - uint256 startBalance = IERC20(token).balanceOf(address(this)); - - // Transfer the ERC20 balance to the target, accounting for non standard ERC20 - // implementations that may not return a boolean. This reverts if the low level - // call is not successful. - IERC20(token).safeTransfer({ to: _tx.target, value: _tx.value }); - - // The balance must be transferred exactly. - if (IERC20(token).balanceOf(address(this)) != startBalance - _tx.value) { - revert TransferFailed(); - } - } - - // Make a call to the target contract only if there is calldata. - if (_tx.data.length != 0) { - success = SafeCall.callWithMinGas(_tx.target, _tx.gasLimit, 0, _tx.data); - } else { - success = true; - } - } + // Trigger the call to the target contract. We use a custom low level method + // SafeCall.callWithMinGas to ensure two key properties + // 1. Target contracts cannot force this call to run out of gas by returning a very large + // amount of data (and this is OK because we don't care about the returndata here). + // 2. The amount of gas provided to the execution context of the target is at least the + // gas limit specified by the user. If there is not enough gas in the current context + // to accomplish this, `callWithMinGas` will revert. + bool success = SafeCall.callWithMinGas(_tx.target, _tx.gasLimit, _tx.value, _tx.data); // Reset the l2Sender back to the default value. l2Sender = Constants.DEFAULT_L2_SENDER; @@ -480,58 +413,6 @@ contract OptimismPortal2 is Initializable, ResourceMetering, ISemver { } } - /// @notice Entrypoint to depositing an ERC20 token as a custom gas token. - /// This function depends on a well formed ERC20 token. There are only - /// so many checks that can be done on chain for this so it is assumed - /// that chain operators will deploy chains with well formed ERC20 tokens. - /// @param _to Target address on L2. - /// @param _mint Units of ERC20 token to deposit into L2. - /// @param _value Units of ERC20 token to send on L2 to the recipient. - /// @param _gasLimit Amount of L2 gas to purchase by burning gas on L1. - /// @param _isCreation Whether or not the transaction is a contract creation. - /// @param _data Data to trigger the recipient with. - function depositERC20Transaction( - address _to, - uint256 _mint, - uint256 _value, - uint64 _gasLimit, - bool _isCreation, - bytes memory _data - ) - public - metered(_gasLimit) - { - // Temporary revert till we support custom gas tokens - if (true) revert CustomGasTokenNotSupported(); - - // Can only be called if an ERC20 token is used for gas paying on L2 - (address token,) = gasPayingToken(); - if (token == Constants.ETHER) revert OnlyCustomGasToken(); - - // Gives overflow protection for L2 account balances. - _balance += _mint; - - // Get the balance of the portal before the transfer. - uint256 startBalance = IERC20(token).balanceOf(address(this)); - - // Take ownership of the token. It is assumed that the user has given the portal an approval. - IERC20(token).safeTransferFrom({ from: msg.sender, to: address(this), value: _mint }); - - // Double check that the portal now has the exact amount of token. - if (IERC20(token).balanceOf(address(this)) != startBalance + _mint) { - revert TransferFailed(); - } - - _depositTransaction({ - _to: _to, - _mint: _mint, - _value: _value, - _gasLimit: _gasLimit, - _isCreation: _isCreation, - _data: _data - }); - } - /// @notice Accepts deposits of ETH and data, and emits a TransactionDeposited event for use in /// deriving deposit transactions. Note that if a deposit is made by a contract, its /// address will be aliased when retrieved using `tx.origin` or `msg.sender`. Consider @@ -551,40 +432,6 @@ contract OptimismPortal2 is Initializable, ResourceMetering, ISemver { public payable metered(_gasLimit) - { - (address token,) = gasPayingToken(); - - // Temporary revert till we support custom gas tokens - if (token != Constants.ETHER) revert CustomGasTokenNotSupported(); - - if (token != Constants.ETHER && msg.value != 0) revert NoValue(); - - _depositTransaction({ - _to: _to, - _mint: msg.value, - _value: _value, - _gasLimit: _gasLimit, - _isCreation: _isCreation, - _data: _data - }); - } - - /// @notice Common logic for creating deposit transactions. - /// @param _to Target address on L2. - /// @param _mint Units of asset to deposit into L2. - /// @param _value Units of asset to send on L2 to the recipient. - /// @param _gasLimit Amount of L2 gas to purchase by burning gas on L1. - /// @param _isCreation Whether or not the transaction is a contract creation. - /// @param _data Data to trigger the recipient with. - function _depositTransaction( - address _to, - uint256 _mint, - uint256 _value, - uint64 _gasLimit, - bool _isCreation, - bytes memory _data - ) - internal { // Just to be safe, make sure that people specify address(0) as the target when doing // contract creations. @@ -609,41 +456,13 @@ contract OptimismPortal2 is Initializable, ResourceMetering, ISemver { // Compute the opaque data that will be emitted as part of the TransactionDeposited event. // We use opaque data so that we can update the TransactionDeposited event in the future // without breaking the current interface. - bytes memory opaqueData = abi.encodePacked(_mint, _value, _gasLimit, _isCreation, _data); + bytes memory opaqueData = abi.encodePacked(msg.value, _value, _gasLimit, _isCreation, _data); // Emit a TransactionDeposited event so that the rollup node can derive a deposit // transaction for this deposit. emit TransactionDeposited(from, _to, DEPOSIT_VERSION, opaqueData); } - /// @notice Sets the gas paying token for the L2 system. This token is used as the - /// L2 native asset. Only the SystemConfig contract can call this function. - function setGasPayingToken(address _token, uint8 _decimals, bytes32 _name, bytes32 _symbol) external { - // Temporary revert till we support custom gas tokens - if (true) revert CustomGasTokenNotSupported(); - - if (msg.sender != address(systemConfig)) revert Unauthorized(); - - // Set L2 deposit gas as used without paying burning gas. Ensures that deposits cannot use too much L2 gas. - // This value must be large enough to cover the cost of calling `L1Block.setGasPayingToken`. - useGas(SYSTEM_DEPOSIT_GAS_LIMIT); - - // Emit the special deposit transaction directly that sets the gas paying - // token in the L1Block predeploy contract. - emit TransactionDeposited( - Constants.DEPOSITOR_ACCOUNT, - Predeploys.L1_BLOCK_ATTRIBUTES, - DEPOSIT_VERSION, - abi.encodePacked( - uint256(0), // mint - uint256(0), // value - uint64(SYSTEM_DEPOSIT_GAS_LIMIT), // gasLimit - false, // isCreation, - abi.encodeCall(IL1Block.setGasPayingToken, (_token, _decimals, _name, _symbol)) - ) - ); - } - /// @notice Blacklists a dispute game. Should only be used in the event that a dispute game resolves incorrectly. /// @param _disputeGame Dispute game to blacklist. function blacklistDisputeGame(IDisputeGame _disputeGame) external { diff --git a/packages/contracts-bedrock/src/L1/OptimismPortalInterop.sol b/packages/contracts-bedrock/src/L1/OptimismPortalInterop.sol index 811c7136191eb..eb691e6f1bf8e 100644 --- a/packages/contracts-bedrock/src/L1/OptimismPortalInterop.sol +++ b/packages/contracts-bedrock/src/L1/OptimismPortalInterop.sol @@ -12,6 +12,9 @@ import { Unauthorized } from "src/libraries/PortalErrors.sol"; // Interfaces import { IL1BlockInterop, ConfigType } from "interfaces/L2/IL1BlockInterop.sol"; +/// @notice Error thrown when attempting to use custom gas token specific actions. +error CustomGasTokenNotSupported(); + /// @custom:proxied true /// @title OptimismPortalInterop /// @notice The OptimismPortal is a low-level contract responsible for passing messages between L1 @@ -25,9 +28,9 @@ contract OptimismPortalInterop is OptimismPortal2 { OptimismPortal2(_proofMaturityDelaySeconds, _disputeGameFinalityDelaySeconds) { } - /// @custom:semver +interop-beta.7 + /// @custom:semver +interop-beta.8 function version() public pure override returns (string memory) { - return string.concat(super.version(), "+interop-beta.7"); + return string.concat(super.version(), "+interop-beta.8"); } /// @notice Sets static configuration options for the L2 system. @@ -35,6 +38,7 @@ contract OptimismPortalInterop is OptimismPortal2 { /// @param _value Encoded value of the configuration. function setConfig(ConfigType _type, bytes memory _value) external { if (msg.sender != address(systemConfig)) revert Unauthorized(); + if (_type == ConfigType.SET_GAS_PAYING_TOKEN) revert CustomGasTokenNotSupported(); // Set L2 deposit gas as used without paying burning gas. Ensures that deposits cannot use too much L2 gas. // This value must be large enough to cover the cost of calling `L1Block.setConfig`. diff --git a/packages/contracts-bedrock/src/L1/SystemConfig.sol b/packages/contracts-bedrock/src/L1/SystemConfig.sol index 8a9279bd92294..8d36a591812de 100644 --- a/packages/contracts-bedrock/src/L1/SystemConfig.sol +++ b/packages/contracts-bedrock/src/L1/SystemConfig.sol @@ -3,27 +3,20 @@ pragma solidity 0.8.15; // Contracts import { OwnableUpgradeable } from "@openzeppelin/contracts-upgradeable/access/OwnableUpgradeable.sol"; -import { ERC20 } from "@openzeppelin/contracts/token/ERC20/ERC20.sol"; // Libraries import { Storage } from "src/libraries/Storage.sol"; -import { Constants } from "src/libraries/Constants.sol"; -import { GasPayingToken, IGasToken } from "src/libraries/GasPayingToken.sol"; // Interfaces import { ISemver } from "interfaces/universal/ISemver.sol"; -import { IOptimismPortal2 } from "interfaces/L1/IOptimismPortal2.sol"; import { IResourceMetering } from "interfaces/L1/IResourceMetering.sol"; -/// @dev This is temporary. Error thrown when a chain uses a custom gas token. -error CustomGasTokenNotSupported(); - /// @custom:proxied true /// @title SystemConfig /// @notice The SystemConfig contract is used to manage configuration of an Optimism network. /// All configuration is stored on L1 and picked up by L2 as part of the derviation of /// the L2 chain. -contract SystemConfig is OwnableUpgradeable, ISemver, IGasToken { +contract SystemConfig is OwnableUpgradeable, ISemver { /// @notice Enum representing different types of updates. /// @custom:value BATCHER Represents an update to the batcher hash. /// @custom:value FEE_SCALARS Represents an update to l1 data fee scalars. @@ -48,7 +41,6 @@ contract SystemConfig is OwnableUpgradeable, ISemver, IGasToken { address disputeGameFactory; address optimismPortal; address optimismMintableERC20Factory; - address gasPayingToken; } /// @notice Version identifier, used for upgrades. @@ -91,9 +83,6 @@ contract SystemConfig is OwnableUpgradeable, ISemver, IGasToken { bytes32 public constant DISPUTE_GAME_FACTORY_SLOT = bytes32(uint256(keccak256("systemconfig.disputegamefactory")) - 1); - /// @notice The number of decimals that the gas paying token has. - uint8 internal constant GAS_PAYING_TOKEN_DECIMALS = 18; - /// @notice The maximum gas limit that can be set for L2 blocks. This limit is used to enforce that the blocks /// on L2 are not too large to process and prove. Over time, this value can be increased as various /// optimizations and improvements are made to the system at large. @@ -140,9 +129,9 @@ contract SystemConfig is OwnableUpgradeable, ISemver, IGasToken { event ConfigUpdate(uint256 indexed version, UpdateType indexed updateType, bytes data); /// @notice Semantic version. - /// @custom:semver 2.3.0-beta.10 + /// @custom:semver 2.3.0-beta.11 function version() public pure virtual returns (string memory) { - return "2.3.0-beta.10"; + return "2.3.0-beta.11"; } /// @notice Constructs the SystemConfig contract. @@ -197,7 +186,6 @@ contract SystemConfig is OwnableUpgradeable, ISemver, IGasToken { Storage.setAddress(OPTIMISM_MINTABLE_ERC20_FACTORY_SLOT, _addresses.optimismMintableERC20Factory); _setStartBlock(); - _setGasPayingToken(_addresses.gasPayingToken); _setResourceConfig(_config); } @@ -268,55 +256,6 @@ contract SystemConfig is OwnableUpgradeable, ISemver, IGasToken { startBlock_ = Storage.getUint(START_BLOCK_SLOT); } - /// @notice Getter for the gas paying asset address. - function gasPayingToken() public view returns (address addr_, uint8 decimals_) { - (addr_, decimals_) = GasPayingToken.getToken(); - } - - /// @notice Getter for custom gas token paying networks. Returns true if the - /// network uses a custom gas token. - function isCustomGasToken() public view returns (bool) { - (address token,) = gasPayingToken(); - return token != Constants.ETHER; - } - - /// @notice Getter for the gas paying token name. - function gasPayingTokenName() external view returns (string memory name_) { - name_ = GasPayingToken.getName(); - } - - /// @notice Getter for the gas paying token symbol. - function gasPayingTokenSymbol() external view returns (string memory symbol_) { - symbol_ = GasPayingToken.getSymbol(); - } - - /// @notice Internal setter for the gas paying token address, includes validation. - /// The token must not already be set and must be non zero and not the ether address - /// to set the token address. This prevents the token address from being changed - /// and makes it explicitly opt-in to use custom gas token. - /// @param _token Address of the gas paying token. - function _setGasPayingToken(address _token) internal virtual { - if (_token != address(0) && _token != Constants.ETHER && !isCustomGasToken()) { - // Temporary revert till we support custom gas tokens - if (true) revert CustomGasTokenNotSupported(); - - require( - ERC20(_token).decimals() == GAS_PAYING_TOKEN_DECIMALS, "SystemConfig: bad decimals of gas paying token" - ); - bytes32 name = GasPayingToken.sanitize(ERC20(_token).name()); - bytes32 symbol = GasPayingToken.sanitize(ERC20(_token).symbol()); - - // Set the gas paying token in storage and in the OptimismPortal. - GasPayingToken.set({ _token: _token, _decimals: GAS_PAYING_TOKEN_DECIMALS, _name: name, _symbol: symbol }); - IOptimismPortal2(payable(optimismPortal())).setGasPayingToken({ - _token: _token, - _decimals: GAS_PAYING_TOKEN_DECIMALS, - _name: name, - _symbol: symbol - }); - } - } - /// @notice Updates the unsafe block signer address. Can only be called by the owner. /// @param _unsafeBlockSigner New unsafe block signer address. function setUnsafeBlockSigner(address _unsafeBlockSigner) external onlyOwner { diff --git a/packages/contracts-bedrock/src/L1/SystemConfigInterop.sol b/packages/contracts-bedrock/src/L1/SystemConfigInterop.sol index 2034054619033..fbc09531efdcb 100644 --- a/packages/contracts-bedrock/src/L1/SystemConfigInterop.sol +++ b/packages/contracts-bedrock/src/L1/SystemConfigInterop.sol @@ -2,12 +2,9 @@ pragma solidity 0.8.15; // Contracts -import { ERC20 } from "@openzeppelin/contracts/token/ERC20/ERC20.sol"; import { SystemConfig } from "src/L1/SystemConfig.sol"; // Libraries -import { Constants } from "src/libraries/Constants.sol"; -import { GasPayingToken } from "src/libraries/GasPayingToken.sol"; import { StaticConfig } from "src/libraries/StaticConfig.sol"; import { Storage } from "src/libraries/Storage.sol"; @@ -16,9 +13,6 @@ import { IOptimismPortalInterop as IOptimismPortal } from "interfaces/L1/IOptimi import { IResourceMetering } from "interfaces/L1/IResourceMetering.sol"; import { ConfigType } from "interfaces/L2/IL1BlockInterop.sol"; -/// @dev This is temporary. Error thrown when a chain uses a custom gas token. -error CustomGasTokenNotSupported(); - /// @custom:proxied true /// @title SystemConfigInterop /// @notice The SystemConfig contract is used to manage configuration of an Optimism network. @@ -71,41 +65,9 @@ contract SystemConfigInterop is SystemConfig { Storage.setAddress(DEPENDENCY_MANAGER_SLOT, _dependencyManager); } - /// @custom:semver +interop-beta.9 + /// @custom:semver +interop-beta.10 function version() public pure override returns (string memory) { - return string.concat(super.version(), "+interop-beta.9"); - } - - /// @notice Internal setter for the gas paying token address, includes validation. - /// The token must not already be set and must be non zero and not the ether address - /// to set the token address. This prevents the token address from being changed - /// and makes it explicitly opt-in to use custom gas token. Additionally, - /// OptimismPortal's address must be non zero, since otherwise the call to set the - /// config for the gas paying token to OptimismPortal will fail. - /// @param _token Address of the gas paying token. - function _setGasPayingToken(address _token) internal override { - if (_token != address(0) && _token != Constants.ETHER && !isCustomGasToken()) { - // Temporary revert till we support custom gas tokens - if (true) revert CustomGasTokenNotSupported(); - - require( - ERC20(_token).decimals() == GAS_PAYING_TOKEN_DECIMALS, "SystemConfig: bad decimals of gas paying token" - ); - bytes32 name = GasPayingToken.sanitize(ERC20(_token).name()); - bytes32 symbol = GasPayingToken.sanitize(ERC20(_token).symbol()); - - // Set the gas paying token in storage and in the OptimismPortal. - GasPayingToken.set({ _token: _token, _decimals: GAS_PAYING_TOKEN_DECIMALS, _name: name, _symbol: symbol }); - IOptimismPortal(payable(optimismPortal())).setConfig( - ConfigType.SET_GAS_PAYING_TOKEN, - StaticConfig.encodeSetGasPayingToken({ - _token: _token, - _decimals: GAS_PAYING_TOKEN_DECIMALS, - _name: name, - _symbol: symbol - }) - ); - } + return string.concat(super.version(), "+interop-beta.10"); } /// @notice Adds a chain to the interop dependency set. Can only be called by the dependency manager. diff --git a/packages/contracts-bedrock/test/L1/L1CrossDomainMessenger.t.sol b/packages/contracts-bedrock/test/L1/L1CrossDomainMessenger.t.sol index 23c9cee7ccc8f..568ce28bf527a 100644 --- a/packages/contracts-bedrock/test/L1/L1CrossDomainMessenger.t.sol +++ b/packages/contracts-bedrock/test/L1/L1CrossDomainMessenger.t.sol @@ -697,147 +697,6 @@ contract L1CrossDomainMessenger_Test is CommonTest { assertTrue(l1CrossDomainMessenger.paused()); assertEq(l1CrossDomainMessenger.paused(), superchainConfig.paused()); } - - /// @dev Temporary test that checks that correct calls to sendMessage when using a custom gas token revert with the - /// expected error. - /// @dev Should be removed when/if Custom Gas Token functionality is allowed again. - function test_sendMessage_customGasToken_reverts() external { - skipIfForkTest("Custom gas token is still supported on forked tests"); - - // Mock the gasPayingToken function to return a custom gas token - vm.mockCall( - address(systemConfig), abi.encodeCall(systemConfig.gasPayingToken, ()), abi.encode(address(1), uint8(18)) - ); - - vm.prank(alice); - vm.expectRevert(IOptimismPortal2.CustomGasTokenNotSupported.selector); - l1CrossDomainMessenger.sendMessage(recipient, hex"ff", uint32(100)); - } - - /// @dev Tests that sendMessage succeeds with a custom gas token when the call value is zero. - function test_sendMessage_customGasTokenButNoValue_succeeds() external { - vm.skip(true, "Custom gas token not supported"); - - // Mock the gasPayingToken function to return a custom gas token - vm.mockCall( - address(systemConfig), abi.encodeCall(systemConfig.gasPayingToken, ()), abi.encode(address(1), uint8(18)) - ); - - // deposit transaction on the optimism portal should be called - vm.expectCall( - address(optimismPortal2), - abi.encodeCall( - IOptimismPortal2.depositTransaction, - ( - Predeploys.L2_CROSS_DOMAIN_MESSENGER, - 0, - l1CrossDomainMessenger.baseGas(hex"ff", 100), - false, - Encoding.encodeCrossDomainMessage( - l1CrossDomainMessenger.messageNonce(), alice, recipient, 0, 100, hex"ff" - ) - ) - ) - ); - - // TransactionDeposited event - vm.expectEmit(address(optimismPortal2)); - emitTransactionDeposited( - AddressAliasHelper.applyL1ToL2Alias(address(l1CrossDomainMessenger)), - Predeploys.L2_CROSS_DOMAIN_MESSENGER, - 0, - 0, - l1CrossDomainMessenger.baseGas(hex"ff", 100), - false, - Encoding.encodeCrossDomainMessage(l1CrossDomainMessenger.messageNonce(), alice, recipient, 0, 100, hex"ff") - ); - - // SentMessage event - vm.expectEmit(address(l1CrossDomainMessenger)); - emit SentMessage(recipient, alice, hex"ff", l1CrossDomainMessenger.messageNonce(), 100); - - // SentMessageExtension1 event - vm.expectEmit(address(l1CrossDomainMessenger)); - emit SentMessageExtension1(alice, 0); - - vm.prank(alice); - l1CrossDomainMessenger.sendMessage(recipient, hex"ff", uint32(100)); - } - - /// @dev Tests that the sendMessage reverts when call value is non-zero with custom gas token. - function test_sendMessage_customGasTokenWithValue_reverts() external { - // TODO(opcm upgrades): remove skip once upgrade path is implemented - skipIfForkTest("L1CrossDomainMessenger_Test: gas paying token functionality DNE on op mainnet"); - - // Mock the gasPayingToken function to return a custom gas token - vm.mockCall( - address(systemConfig), abi.encodeCall(systemConfig.gasPayingToken, ()), abi.encode(address(1), uint8(2)) - ); - - vm.expectRevert("CrossDomainMessenger: cannot send value with custom gas token"); - l1CrossDomainMessenger.sendMessage{ value: 1 }(recipient, hex"aa", uint32(500_000)); - } - - /// @dev Tests that the relayMessage succeeds with a custom gas token when the call value is zero. - function test_relayMessage_customGasTokenAndNoValue_succeeds() external { - // TODO(opcm upgrades): remove skip once upgrade path is implemented - skipIfForkTest("L1CrossDomainMessenger_Test: gas paying token functionality DNE on op mainnet"); - - // Mock the gasPayingToken function to return a custom gas token - vm.mockCall( - address(systemConfig), abi.encodeCall(systemConfig.gasPayingToken, ()), abi.encode(address(1), uint8(2)) - ); - - address target = address(0xabcd); - address sender = Predeploys.L2_CROSS_DOMAIN_MESSENGER; - - vm.expectCall(target, hex"1111"); - - // set the value of op.l2Sender() to be the L2 Cross Domain Messenger. - vm.store(address(optimismPortal2), bytes32(senderSlotIndex), bytes32(abi.encode(sender))); - vm.prank(address(optimismPortal2)); - - vm.expectEmit(address(l1CrossDomainMessenger)); - - bytes32 hash = Hashing.hashCrossDomainMessage( - Encoding.encodeVersionedNonce({ _nonce: 0, _version: 1 }), sender, target, 0, 0, hex"1111" - ); - - emit RelayedMessage(hash); - - l1CrossDomainMessenger.relayMessage( - Encoding.encodeVersionedNonce({ _nonce: 0, _version: 1 }), // nonce - sender, - target, - 0, // value - 0, - hex"1111" - ); - - // the message hash is in the successfulMessages mapping - assertTrue(l1CrossDomainMessenger.successfulMessages(hash)); - // it is not in the received messages mapping - assertEq(l1CrossDomainMessenger.failedMessages(hash), false); - } - - /// @dev Tests that the relayMessage reverts when call value is non-zero with custom gas token. - /// The L2CrossDomainMessenger contract cannot `sendMessage` with value when using a custom gas token. - function test_relayMessage_customGasTokenWithValue_reverts() external virtual { - // Mock the gasPayingToken function to return a custom gas token - vm.mockCall( - address(systemConfig), abi.encodeCall(systemConfig.gasPayingToken, ()), abi.encode(address(1), uint8(2)) - ); - vm.expectRevert("CrossDomainMessenger: value must be zero unless message is from a system address"); - - l1CrossDomainMessenger.relayMessage{ value: 1 }( - Encoding.encodeVersionedNonce({ _nonce: 0, _version: 1 }), - address(0xabcd), - address(0xabcd), - 1, // value - 0, - hex"1111" - ); - } } /// @dev A regression test against a reentrancy vulnerability in the CrossDomainMessenger contract, which diff --git a/packages/contracts-bedrock/test/L1/L1StandardBridge.t.sol b/packages/contracts-bedrock/test/L1/L1StandardBridge.t.sol index d9ccc15245406..bf7e73607ba05 100644 --- a/packages/contracts-bedrock/test/L1/L1StandardBridge.t.sol +++ b/packages/contracts-bedrock/test/L1/L1StandardBridge.t.sol @@ -198,26 +198,6 @@ contract L1StandardBridge_Receive_Test is CommonTest { } } -contract L1StandardBridge_Receive_TestFail is CommonTest { - /// @dev Tests receive function reverts with custom gas token. - function testFuzz_receive_customGasToken_reverts(uint256 _value) external { - // TODO(opcm upgrades): remove skip once upgrade path is implemented - skipIfForkTest("L1StandardBridge_Receive_TestFail: gas paying token functionality DNE on op mainnet"); - - vm.prank(alice, alice); - vm.mockCall( - address(systemConfig), abi.encodeCall(systemConfig.gasPayingToken, ()), abi.encode(address(1), uint8(18)) - ); - vm.deal(alice, _value); - (bool success, bytes memory data) = address(l1StandardBridge).call{ value: _value }(hex""); - assertFalse(success); - assembly { - data := add(data, 0x04) - } - assertEq(abi.decode(data, (string)), "StandardBridge: cannot bridge ETH with custom gas token"); - } -} - contract PreBridgeETH is CommonTest { /// @dev Asserts the expected calls and events for bridging ETH depending /// on whether the bridge call is legacy or not. @@ -307,19 +287,6 @@ contract L1StandardBridge_DepositETH_TestFail is CommonTest { vm.prank(alice); l1StandardBridge.depositETH{ value: 1 }(300, hex""); } - - /// @dev Tests that depositing reverts with custom gas token. - function test_depositETH_customGasToken_reverts() external { - // TODO(opcm upgrades): remove skip once upgrade path is implemented - skipIfForkTest("L1StandardBridge_DepositETH_TestFail: gas paying token functionality DNE on op mainnet"); - - vm.mockCall( - address(systemConfig), abi.encodeCall(systemConfig.gasPayingToken, ()), abi.encode(address(1), uint8(2)) - ); - vm.prank(alice, alice); - vm.expectRevert("StandardBridge: cannot bridge ETH with custom gas token"); - l1StandardBridge.depositETH(50000, hex"dead"); - } } contract L1StandardBridge_BridgeETH_Test is PreBridgeETH { @@ -336,22 +303,6 @@ contract L1StandardBridge_BridgeETH_Test is PreBridgeETH { } } -contract L1StandardBridge_BridgeETH_TestFail is PreBridgeETH { - /// @dev Tests that bridging eth reverts with custom gas token. - function test_bridgeETH_customGasToken_reverts() external { - // TODO(opcm upgrades): remove skip once upgrade path is implemented - skipIfForkTest("L1StandardBridge_BridgeETH_TestFail: gas paying token functionality DNE on op mainnet"); - - vm.prank(alice, alice); - vm.mockCall( - address(systemConfig), abi.encodeCall(systemConfig.gasPayingToken, ()), abi.encode(address(1), uint8(2)) - ); - vm.expectRevert("StandardBridge: cannot bridge ETH with custom gas token"); - - l1StandardBridge.bridgeETH(50000, hex"dead"); - } -} - contract PreBridgeETHTo is CommonTest { /// @dev Asserts the expected calls and events for bridging ETH to a different /// address depending on whether the bridge call is legacy or not. @@ -432,29 +383,6 @@ contract L1StandardBridge_DepositETHTo_Test is PreBridgeETHTo { } } -contract L1StandardBridge_DepositETHTo_TestFail is CommonTest { - /// @dev Tests that depositETHTo reverts with custom gas token. - function testFuzz_depositETHTo_customGasToken_reverts( - uint256 _value, - address _to, - uint32 _minGasLimit, - bytes calldata _extraData - ) - external - { - // TODO(opcm upgrades): remove skip once upgrade path is implemented - skipIfForkTest("L1StandardBridge_DepositETHTo_TestFail: gas paying token functionality DNE on op mainnet"); - - vm.mockCall( - address(systemConfig), abi.encodeCall(systemConfig.gasPayingToken, ()), abi.encode(address(1), uint8(2)) - ); - vm.deal(address(this), _value); - vm.expectRevert("StandardBridge: cannot bridge ETH with custom gas token"); - - l1StandardBridge.depositETHTo{ value: _value }(_to, _minGasLimit, _extraData); - } -} - contract L1StandardBridge_BridgeETHTo_Test is PreBridgeETHTo { /// @dev Tests that bridging ETH to a different address succeeds. /// Emits ETHDepositInitiated and ETHBridgeInitiated events. @@ -469,28 +397,6 @@ contract L1StandardBridge_BridgeETHTo_Test is PreBridgeETHTo { } } -contract L1StandardBridge_BridgeETHTo_TestFail is PreBridgeETHTo { - /// @dev Tests that bridging reverts with custom gas token. - function testFuzz_bridgeETHTo_customGasToken_reverts( - uint256 _value, - uint32 _minGasLimit, - bytes calldata _extraData - ) - external - { - // TODO(opcm upgrades): remove skip once upgrade path is implemented - skipIfForkTest("L1StandardBridge_BridgeETHTo_TestFail: gas paying token functionality DNE on op mainnet"); - - vm.mockCall( - address(systemConfig), abi.encodeCall(systemConfig.gasPayingToken, ()), abi.encode(address(1), uint8(2)) - ); - vm.deal(address(this), _value); - vm.expectRevert("StandardBridge: cannot bridge ETH with custom gas token"); - - l1StandardBridge.bridgeETHTo{ value: _value }(bob, _minGasLimit, _extraData); - } -} - contract L1StandardBridge_DepositERC20_Test is CommonTest { using stdStorage for StdStorage; @@ -682,35 +588,6 @@ contract L1StandardBridge_FinalizeETHWithdrawal_Test is CommonTest { } } -contract L1StandardBridge_FinalizeETHWithdrawal_TestFail is CommonTest { - /// @dev Tests that finalizeETHWithdrawal reverts with custom gas token. - function testFuzz_finalizeETHWithdrawal_customGasToken_reverts( - uint256 _value, - bytes calldata _extraData - ) - external - { - // TODO(opcm upgrades): remove skip once upgrade path is implemented - skipIfForkTest( - "L1StandardBridge_FinalizeETHWithdrawal_TestFail: gas paying token functionality DNE on op mainnet" - ); - - vm.mockCall( - address(systemConfig), abi.encodeCall(systemConfig.gasPayingToken, ()), abi.encode(address(1), uint8(2)) - ); - vm.mockCall( - address(l1StandardBridge.messenger()), - abi.encodeCall(ICrossDomainMessenger.xDomainMessageSender, ()), - abi.encode(address(l1StandardBridge.OTHER_BRIDGE())) - ); - vm.deal(address(l1StandardBridge.messenger()), _value); - vm.prank(address(l1StandardBridge.messenger())); - vm.expectRevert("StandardBridge: cannot bridge ETH with custom gas token"); - - l1StandardBridge.finalizeETHWithdrawal{ value: _value }(alice, alice, _value, _extraData); - } -} - contract L1StandardBridge_FinalizeERC20Withdrawal_Test is CommonTest { using stdStorage for StdStorage; @@ -796,26 +673,6 @@ contract L1StandardBridge_FinalizeBridgeETH_Test is CommonTest { } contract L1StandardBridge_FinalizeBridgeETH_TestFail is CommonTest { - /// @dev Tests that finalizing bridged reverts with custom gas token. - function testFuzz_finalizeBridgeETH_customGasToken_reverts(uint256 _value, bytes calldata _extraData) external { - // TODO(opcm upgrades): remove skip once upgrade path is implemented - skipIfForkTest("L1StandardBridge_FinalizeBridgeETH_TestFail: gas paying token functionality DNE on op mainnet"); - - vm.mockCall( - address(l1StandardBridge.messenger()), - abi.encodeCall(ICrossDomainMessenger.xDomainMessageSender, ()), - abi.encode(address(l1StandardBridge.OTHER_BRIDGE())) - ); - vm.deal(address(l1CrossDomainMessenger), _value); - vm.prank(address(l1CrossDomainMessenger)); - vm.mockCall( - address(systemConfig), abi.encodeCall(systemConfig.gasPayingToken, ()), abi.encode(address(1), uint8(2)) - ); - vm.expectRevert("StandardBridge: cannot bridge ETH with custom gas token"); - - l1StandardBridge.finalizeBridgeETH{ value: _value }(alice, alice, _value, _extraData); - } - /// @dev Tests that finalizing bridged ETH reverts if the amount is incorrect. function test_finalizeBridgeETH_incorrectValue_reverts() external { address messenger = address(l1StandardBridge.messenger()); diff --git a/packages/contracts-bedrock/test/L1/OptimismPortal2.t.sol b/packages/contracts-bedrock/test/L1/OptimismPortal2.t.sol index 46e10d0371700..fef3faaddf94c 100644 --- a/packages/contracts-bedrock/test/L1/OptimismPortal2.t.sol +++ b/packages/contracts-bedrock/test/L1/OptimismPortal2.t.sol @@ -2,9 +2,7 @@ pragma solidity 0.8.15; // Testing -import { stdError } from "forge-std/Test.sol"; import { VmSafe } from "forge-std/Vm.sol"; -import { MockERC20 } from "solmate/test/utils/mocks/MockERC20.sol"; import { CommonTest } from "test/setup/CommonTest.sol"; import { NextImpl } from "test/mocks/NextImpl.sol"; import { EIP1967Helper } from "test/mocks/EIP1967Helper.sol"; @@ -16,8 +14,6 @@ import { SuperchainConfig } from "src/L1/SuperchainConfig.sol"; import { Types } from "src/libraries/Types.sol"; import { Hashing } from "src/libraries/Hashing.sol"; import { Constants } from "src/libraries/Constants.sol"; -import { Predeploys } from "src/libraries/Predeploys.sol"; -import { GasPayingToken } from "src/libraries/GasPayingToken.sol"; import { AddressAliasHelper } from "src/vendor/AddressAliasHelper.sol"; import { EIP1967Helper } from "test/mocks/EIP1967Helper.sol"; import "src/dispute/lib/Types.sol"; @@ -25,7 +21,6 @@ import "src/libraries/PortalErrors.sol"; // Interfaces import { IResourceMetering } from "interfaces/L1/IResourceMetering.sol"; -import { IL1Block } from "interfaces/L2/IL1Block.sol"; import { IOptimismPortal2 } from "interfaces/L1/IOptimismPortal2.sol"; import { IDisputeGame } from "interfaces/dispute/IDisputeGame.sol"; import { IFaultDisputeGame } from "interfaces/dispute/IFaultDisputeGame.sol"; @@ -39,6 +34,12 @@ contract OptimismPortal2_Test is CommonTest { depositor = makeAddr("depositor"); } + /// @notice Tests that the version function returns a valid string. We avoid testing the + /// specific value of the string as it changes frequently. + function test_version_succeeds() external view { + assert(bytes(optimismPortal2.version()).length > 0); + } + /// @dev Tests that the constructor sets the correct values. /// @notice Marked virtual to be overridden in /// test/kontrol/deployment/DeploymentSummary.t.sol @@ -310,186 +311,6 @@ contract OptimismPortal2_Test is CommonTest { assertEq(address(optimismPortal2).balance, balanceBefore + _mint); } - /// @dev Temporary test that checks that correct calls to setGasPayingToken when using a custom gas token revert - /// with the expected error. - /// @dev Should be removed when/if Custom Gas Token functionality is allowed again. - function test_setGasPayingToken_customGasToken_reverts( - address _token, - uint8 _decimals, - bytes32 _name, - bytes32 _symbol - ) - external - { - skipIfForkTest("Custom gas token is still supported on forked tests"); - - vm.expectRevert(IOptimismPortal2.CustomGasTokenNotSupported.selector); - optimismPortal2.setGasPayingToken({ _token: _token, _decimals: _decimals, _name: _name, _symbol: _symbol }); - } - - /// @dev Tests that the gas paying token can be set. - function testFuzz_setGasPayingToken_succeeds( - address _token, - uint8 _decimals, - bytes32 _name, - bytes32 _symbol - ) - external - { - vm.skip(true, "Custom gas token not supported"); - - // TODO(opcm upgrades): remove skip once upgrade path is implemented - skipIfForkTest("OptimismPortal2_Test: gas paying token functionality DNE on op mainnet"); - - vm.expectEmit(address(optimismPortal2)); - emit TransactionDeposited( - 0xDeaDDEaDDeAdDeAdDEAdDEaddeAddEAdDEAd0001, - Predeploys.L1_BLOCK_ATTRIBUTES, - 0, - abi.encodePacked( - uint256(0), // mint - uint256(0), // value - uint64(200_000), // gasLimit - false, // isCreation, - abi.encodeCall(IL1Block.setGasPayingToken, (_token, _decimals, _name, _symbol)) - ) - ); - - vm.prank(address(systemConfig)); - optimismPortal2.setGasPayingToken({ _token: _token, _decimals: _decimals, _name: _name, _symbol: _symbol }); - } - - /// @notice Ensures that the deposit event is correct for the `setGasPayingToken` - /// code path that manually emits a deposit transaction outside of the - /// `depositTransaction` function. This is a simple differential test. - function test_setGasPayingToken_correctEvent_succeeds( - address _token, - string calldata _name, - string calldata _symbol - ) - external - { - vm.skip(true, "Custom gas token not supported"); - - // TODO(opcm upgrades): remove skip once upgrade path is implemented - skipIfForkTest("OptimismPortal2_Test: gas paying token functionality DNE on op mainnet"); - - if (bytes(_name).length > 32) { - _name = _name[0:32]; - } - if (bytes(_symbol).length > 32) { - _symbol = _symbol[0:32]; - } - - bytes32 name = GasPayingToken.sanitize(_name); - bytes32 symbol = GasPayingToken.sanitize(_symbol); - - vm.recordLogs(); - - vm.deal(address(systemConfig), 100 ether); - vm.prank(address(systemConfig)); - optimismPortal2.setGasPayingToken({ _token: _token, _decimals: 18, _name: name, _symbol: symbol }); - - vm.prank(Constants.DEPOSITOR_ACCOUNT, Constants.DEPOSITOR_ACCOUNT); - optimismPortal2.depositTransaction({ - _to: Predeploys.L1_BLOCK_ATTRIBUTES, - _value: 0, - _gasLimit: 200_000, - _isCreation: false, - _data: abi.encodeCall(IL1Block.setGasPayingToken, (_token, 18, name, symbol)) - }); - - VmSafe.Log[] memory logs = vm.getRecordedLogs(); - assertEq(logs.length, 2); - - VmSafe.Log memory systemPath = logs[0]; - VmSafe.Log memory userPath = logs[1]; - - assertEq(systemPath.topics.length, 4); - assertEq(systemPath.topics.length, userPath.topics.length); - assertEq(systemPath.topics[0], userPath.topics[0]); - assertEq(systemPath.topics[1], userPath.topics[1]); - assertEq(systemPath.topics[2], userPath.topics[2]); - assertEq(systemPath.topics[3], userPath.topics[3]); - assertEq(systemPath.data, userPath.data); - } - - /// @dev Tests that the gas paying token cannot be set by a non-system config. - function test_setGasPayingToken_notSystemConfig_fails(address _caller) external { - vm.skip(true, "Custom gas token not supported"); - - // TODO(opcm upgrades): remove skip once upgrade path is implemented - skipIfForkTest("OptimismPortal2_Test: gas paying token functionality DNE on op mainnet"); - - vm.assume(_caller != address(systemConfig)); - vm.prank(_caller); - vm.expectRevert(Unauthorized.selector); - optimismPortal2.setGasPayingToken({ _token: address(0), _decimals: 0, _name: "", _symbol: "" }); - } - - /// @dev Temporary test that checks that correct calls to depositERC20Transaction when using a custom gas token - /// revert - /// with the expected error. - /// @dev Should be removed when/if Custom Gas Token functionality is allowed again. - function test_depositERC20Transaction_customGasToken_reverts() external { - skipIfForkTest("Custom gas token is still supported on forked tests"); - - vm.expectRevert(IOptimismPortal2.CustomGasTokenNotSupported.selector); - optimismPortal2.depositERC20Transaction(address(0), 0, 0, 0, false, ""); - } - - /// @dev Tests that `depositERC20Transaction` reverts when the gas paying token is ether. - function test_depositERC20Transaction_noCustomGasToken_reverts() external { - vm.skip(true, "Custom gas token not supported"); - - // TODO(opcm upgrades): remove skip once upgrade path is implemented - skipIfForkTest("OptimismPortal2_Test: gas paying token functionality DNE on op mainnet"); - - // Check that the gas paying token is set to ether - (address token,) = systemConfig.gasPayingToken(); - assertEq(token, Constants.ETHER); - - vm.expectRevert(OnlyCustomGasToken.selector); - optimismPortal2.depositERC20Transaction(address(0), 0, 0, 0, false, ""); - } - - function test_depositERC20Transaction_balanceOverflow_reverts() external { - vm.skip(true, "Custom gas token not supported"); - - // TODO(opcm upgrades): remove skip once upgrade path is implemented - skipIfForkTest("OptimismPortal2_Test: gas paying token functionality DNE on op mainnet"); - vm.mockCall(address(systemConfig), abi.encodeCall(systemConfig.gasPayingToken, ()), abi.encode(address(42), 18)); - - // The balance slot - vm.store(address(optimismPortal2), bytes32(uint256(61)), bytes32(type(uint256).max)); - assertEq(optimismPortal2.balance(), type(uint256).max); - - vm.expectRevert(stdError.arithmeticError); - optimismPortal2.depositERC20Transaction({ - _to: address(0), - _mint: 1, - _value: 1, - _gasLimit: 10_000, - _isCreation: false, - _data: "" - }); - } - - /// @dev Tests that `balance()` returns the correct balance when the gas paying token is ether. - function testFuzz_balance_ether_succeeds(uint256 _amount) external { - // TODO(opcm upgrades): remove skip once upgrade path is implemented - skipIfForkTest("OptimismPortal2_Test: gas paying token functionality DNE on op mainnet"); - // Check that the gas paying token is set to ether - (address token,) = systemConfig.gasPayingToken(); - assertEq(token, Constants.ETHER); - - // Increase the balance of the gas paying token - vm.deal(address(optimismPortal2), _amount); - - // Check that the balance has been correctly updated - assertEq(optimismPortal2.balance(), address(optimismPortal2).balance); - } - /// @dev Tests that the donateETH function donates ETH and does no state read/write function test_donateETH_succeeds(uint256 _amount) external { vm.startPrank(alice); @@ -1005,152 +826,6 @@ contract OptimismPortal2_FinalizeWithdrawal_Test is CommonTest { assert(bob.balance == bobBalanceBefore + 100); } - /// @dev Tests that `finalizeWithdrawalTransaction` reverts when using a custom gas token. - /// @dev Should be removed when/if Custom Gas Token functionality is allowed again. - function test_finalizeWithdrawalTransaction_customGasToken_reverts() external { - Types.WithdrawalTransaction memory _defaultTx_noData = Types.WithdrawalTransaction({ - nonce: 0, - sender: alice, - target: bob, - value: 100, - gasLimit: 100_000, - data: hex"" - }); - // Get withdrawal proof data we can use for testing. - ( - bytes32 _stateRoot_noData, - bytes32 _storageRoot_noData, - bytes32 _outputRoot_noData, - bytes32 _withdrawalHash_noData, - bytes[] memory _withdrawalProof_noData - ) = ffi.getProveWithdrawalTransactionInputs(_defaultTx_noData); - // Setup a dummy output root proof for reuse. - Types.OutputRootProof memory _outputRootProof_noData = Types.OutputRootProof({ - version: bytes32(uint256(0)), - stateRoot: _stateRoot_noData, - messagePasserStorageRoot: _storageRoot_noData, - latestBlockhash: bytes32(uint256(0)) - }); - uint256 _proposedBlockNumber_noData = 0xFF; - IFaultDisputeGame game_noData = IFaultDisputeGame( - payable( - address( - disputeGameFactory.create( - optimismPortal2.respectedGameType(), - Claim.wrap(_outputRoot_noData), - abi.encode(_proposedBlockNumber_noData) - ) - ) - ) - ); - uint256 _proposedGameIndex_noData = disputeGameFactory.gameCount() - 1; - // Warp beyond the chess clocks and finalize the game. - vm.warp(block.timestamp + game_noData.maxClockDuration().raw() + 1 seconds); - // Fund the portal so that we can withdraw ETH. - vm.store(address(optimismPortal2), bytes32(uint256(61)), bytes32(uint256(0xFFFFFFFF))); - deal(address(L1Token), address(optimismPortal2), 0xFFFFFFFF); - - // modify the gas token to be non ether - vm.mockCall( - address(systemConfig), abi.encodeCall(systemConfig.gasPayingToken, ()), abi.encode(address(L1Token), 18) - ); - - vm.expectEmit(address(optimismPortal2)); - emit WithdrawalProven(_withdrawalHash_noData, alice, bob); - vm.expectEmit(address(optimismPortal2)); - emit WithdrawalProvenExtension1(_withdrawalHash_noData, address(this)); - optimismPortal2.proveWithdrawalTransaction({ - _tx: _defaultTx_noData, - _disputeGameIndex: _proposedGameIndex_noData, - _outputRootProof: _outputRootProof_noData, - _withdrawalProof: _withdrawalProof_noData - }); - - // Warp and resolve the dispute game. - game_noData.resolveClaim(0, 0); - game_noData.resolve(); - vm.warp(block.timestamp + optimismPortal2.proofMaturityDelaySeconds() + 1 seconds); - - vm.expectRevert(IOptimismPortal2.CustomGasTokenNotSupported.selector); - optimismPortal2.finalizeWithdrawalTransaction(_defaultTx_noData); - } - - /// @dev Tests that `finalizeWithdrawalTransaction` succeeds when _tx.data is empty and with a custom gas token. - function test_finalizeWithdrawalTransaction_noTxDataNonEtherGasToken_succeeds() external { - vm.skip(true, "Custom gas token not supported"); - - Types.WithdrawalTransaction memory _defaultTx_noData = Types.WithdrawalTransaction({ - nonce: 0, - sender: alice, - target: bob, - value: 100, - gasLimit: 100_000, - data: hex"" - }); - // Get withdrawal proof data we can use for testing. - ( - bytes32 _stateRoot_noData, - bytes32 _storageRoot_noData, - bytes32 _outputRoot_noData, - bytes32 _withdrawalHash_noData, - bytes[] memory _withdrawalProof_noData - ) = ffi.getProveWithdrawalTransactionInputs(_defaultTx_noData); - // Setup a dummy output root proof for reuse. - Types.OutputRootProof memory _outputRootProof_noData = Types.OutputRootProof({ - version: bytes32(uint256(0)), - stateRoot: _stateRoot_noData, - messagePasserStorageRoot: _storageRoot_noData, - latestBlockhash: bytes32(uint256(0)) - }); - uint256 _proposedBlockNumber_noData = 0xFF; - IFaultDisputeGame game_noData = IFaultDisputeGame( - payable( - address( - disputeGameFactory.create( - optimismPortal2.respectedGameType(), - Claim.wrap(_outputRoot_noData), - abi.encode(_proposedBlockNumber_noData) - ) - ) - ) - ); - uint256 _proposedGameIndex_noData = disputeGameFactory.gameCount() - 1; - // Warp beyond the chess clocks and finalize the game. - vm.warp(block.timestamp + game_noData.maxClockDuration().raw() + 1 seconds); - // Fund the portal so that we can withdraw ETH. - vm.store(address(optimismPortal2), bytes32(uint256(61)), bytes32(uint256(0xFFFFFFFF))); - deal(address(L1Token), address(optimismPortal2), 0xFFFFFFFF); - - // modify the gas token to be non ether - vm.mockCall( - address(systemConfig), abi.encodeCall(systemConfig.gasPayingToken, ()), abi.encode(address(L1Token), 18) - ); - - uint256 bobBalanceBefore = L1Token.balanceOf(bob); - - vm.expectEmit(address(optimismPortal2)); - emit WithdrawalProven(_withdrawalHash_noData, alice, bob); - vm.expectEmit(address(optimismPortal2)); - emit WithdrawalProvenExtension1(_withdrawalHash_noData, address(this)); - optimismPortal2.proveWithdrawalTransaction({ - _tx: _defaultTx_noData, - _disputeGameIndex: _proposedGameIndex_noData, - _outputRootProof: _outputRootProof_noData, - _withdrawalProof: _withdrawalProof_noData - }); - - // Warp and resolve the dispute game. - game_noData.resolveClaim(0, 0); - game_noData.resolve(); - vm.warp(block.timestamp + optimismPortal2.proofMaturityDelaySeconds() + 1 seconds); - - vm.expectEmit(true, true, false, true); - emit WithdrawalFinalized(_withdrawalHash_noData, true); - optimismPortal2.finalizeWithdrawalTransaction(_defaultTx_noData); - - assert(L1Token.balanceOf(bob) == bobBalanceBefore + 100); - } - /// @dev Tests that `finalizeWithdrawalTransaction` succeeds. function test_finalizeWithdrawalTransaction_provenWithdrawalHashEther_succeeds() external { uint256 bobBalanceBefore = address(bob).balance; @@ -1239,32 +914,6 @@ contract OptimismPortal2_FinalizeWithdrawal_Test is CommonTest { assert(address(bob).balance == bobBalanceBefore + 100); } - /// @dev Tests that `finalizeWithdrawalTransaction` succeeds. - function test_finalizeWithdrawalTransaction_provenWithdrawalHashNonEtherTargetToken_reverts() external { - vm.skip(true, "Custom gas token not supported"); - - vm.mockCall( - address(systemConfig), - abi.encodeCall(systemConfig.gasPayingToken, ()), - abi.encode(address(_defaultTx.target), 18) - ); - - optimismPortal2.proveWithdrawalTransaction({ - _tx: _defaultTx, - _disputeGameIndex: _proposedGameIndex, - _outputRootProof: _outputRootProof, - _withdrawalProof: _withdrawalProof - }); - - // Warp to after the finalization period - game.resolveClaim(0, 0); - game.resolve(); - vm.warp(block.timestamp + optimismPortal2.proofMaturityDelaySeconds() + 1); - - vm.expectRevert(BadTarget.selector); - optimismPortal2.finalizeWithdrawalTransaction(_defaultTx); - } - /// @dev Tests that `finalizeWithdrawalTransaction` reverts if the contract is paused. function test_finalizeWithdrawalTransaction_paused_reverts() external { vm.prank(optimismPortal2.guardian()); @@ -1886,381 +1535,3 @@ contract OptimismPortal2_ResourceFuzz_Test is CommonTest { }); } } - -contract OptimismPortal2WithMockERC20_Test is OptimismPortal2_FinalizeWithdrawal_Test { - MockERC20 token; - - function setUp() public virtual override { - super.setUp(); - token = new MockERC20("Test", "TST", 18); - - // TODO(opcm upgrades): remove skip once upgrade path is implemented - skipIfForkTest("OptimismPortal2_Test: gas paying token functionality DNE on op mainnet"); - } - - function depositERC20Transaction( - address _from, - address _to, - uint256 _mint, - uint256 _value, - uint64 _gasLimit, - bool _isCreation, - bytes calldata _data - ) - internal - { - if (_isCreation) { - _to = address(0); - } - if (_data.length > 120_000) { - _data = _data[0:120_000]; - } - IResourceMetering.ResourceConfig memory rcfg = systemConfig.resourceConfig(); - _gasLimit = - uint64(bound(_gasLimit, optimismPortal2.minimumGasLimit(uint64(_data.length)), rcfg.maxResourceLimit)); - - // Mint the token to the contract and approve the token for the portal - token.mint(address(this), _mint); - token.approve(address(optimismPortal2), _mint); - - // Mock the gas paying token to be the ERC20 token - vm.mockCall( - address(systemConfig), abi.encodeCall(systemConfig.gasPayingToken, ()), abi.encode(address(token), 18) - ); - - bytes memory opaqueData = abi.encodePacked(_mint, _value, _gasLimit, _isCreation, _data); - - vm.expectEmit(address(optimismPortal2)); - emit TransactionDeposited( - _from, // from - _to, - uint256(0), // DEPOSIT_VERSION - opaqueData - ); - - // Deposit the token into the portal - optimismPortal2.depositERC20Transaction(_to, _mint, _value, _gasLimit, _isCreation, _data); - - // Assert final balance equals the deposited amount - assertEq(token.balanceOf(address(optimismPortal2)), _mint); - assertEq(optimismPortal2.balance(), _mint); - } - - /// @dev Tests that `depositERC20Transaction` succeeds when msg.sender == tx.origin. - function testFuzz_depositERC20Transaction_senderIsOrigin_succeeds( - address _to, - uint256 _mint, - uint256 _value, - uint64 _gasLimit, - bool _isCreation, - bytes calldata _data - ) - external - { - vm.skip(true, "Custom gas token not supported"); - - // Ensure that msg.sender == tx.origin - vm.startPrank(address(this), address(this)); - - depositERC20Transaction({ - _from: address(this), - _to: _to, - _mint: _mint, - _value: _value, - _gasLimit: _gasLimit, - _isCreation: _isCreation, - _data: _data - }); - } - - /// @dev Tests that `depositERC20Transaction` succeeds when msg.sender != tx.origin. - function testFuzz_depositERC20Transaction_senderNotOrigin_succeeds( - address _to, - uint256 _mint, - uint256 _value, - uint64 _gasLimit, - bool _isCreation, - bytes calldata _data - ) - external - { - vm.skip(true, "Custom gas token not supported"); - - // Ensure that msg.sender != tx.origin - vm.startPrank(address(this), address(1)); - - depositERC20Transaction({ - _from: AddressAliasHelper.applyL1ToL2Alias(address(this)), - _to: _to, - _mint: _mint, - _value: _value, - _gasLimit: _gasLimit, - _isCreation: _isCreation, - _data: _data - }); - } - - /// @dev Tests that `depositERC20Transaction` reverts when not enough of the token is approved. - function test_depositERC20Transaction_notEnoughAmount_reverts() external { - vm.skip(true, "Custom gas token not supported"); - - // Mock the gas paying token to be the ERC20 token - vm.mockCall( - address(systemConfig), abi.encodeCall(systemConfig.gasPayingToken, ()), abi.encode(address(token), 18) - ); - vm.expectRevert(stdError.arithmeticError); - // Deposit the token into the portal - optimismPortal2.depositERC20Transaction(address(0), 1, 0, 0, false, ""); - } - - /// @dev Tests that `depositERC20Transaction` reverts when token balance does not update correctly after transfer. - function test_depositERC20Transaction_incorrectTokenBalance_reverts() external { - vm.skip(true, "Custom gas token not supported"); - - // Mint the token to the contract and approve the token for the portal - token.mint(address(this), 100); - token.approve(address(optimismPortal2), 100); - - // Mock the gas paying token to be the ERC20 token - vm.mockCall( - address(systemConfig), abi.encodeCall(systemConfig.gasPayingToken, ()), abi.encode(address(token), 18) - ); - - // Mock the token balance - vm.mockCall(address(token), abi.encodeCall(token.balanceOf, (address(optimismPortal2))), abi.encode(0)); - - // Call minimumGasLimit(0) before vm.expectRevert to ensure vm.expectRevert is for depositERC20Transaction - uint64 gasLimit = optimismPortal2.minimumGasLimit(0); - - vm.expectRevert(TransferFailed.selector); - - // Deposit the token into the portal - optimismPortal2.depositERC20Transaction(address(1), 100, 0, gasLimit, false, ""); - } - - /// @dev Tests that `depositERC20Transaction` reverts when creating a contract with a non-zero target. - function test_depositERC20Transaction_isCreationNotZeroTarget_reverts() external { - vm.skip(true, "Custom gas token not supported"); - - // Mock the gas paying token to be the ERC20 token - vm.mockCall( - address(systemConfig), abi.encodeCall(systemConfig.gasPayingToken, ()), abi.encode(address(token), 18) - ); - - // Call minimumGasLimit(0) before vm.expectRevert to ensure vm.expectRevert is for depositERC20Transaction - uint64 gasLimit = optimismPortal2.minimumGasLimit(0); - - vm.expectRevert(BadTarget.selector); - // Deposit the token into the portal - optimismPortal2.depositERC20Transaction(address(1), 0, 0, gasLimit, true, ""); - } - - /// @dev Tests that `depositERC20Transaction` reverts when the gas limit is too low. - function test_depositERC20Transaction_gasLimitTooLow_reverts() external { - vm.skip(true, "Custom gas token not supported"); - - // Mock the gas paying token to be the ERC20 token - vm.mockCall( - address(systemConfig), abi.encodeCall(systemConfig.gasPayingToken, ()), abi.encode(address(token), 18) - ); - - vm.expectRevert(SmallGasLimit.selector); - // Deposit the token into the portal - optimismPortal2.depositERC20Transaction(address(0), 0, 0, 0, false, ""); - } - - /// @dev Tests that `depositERC20Transaction` reverts when the data is too large. - function test_depositERC20Transaction_dataTooLarge_reverts() external { - vm.skip(true, "Custom gas token not supported"); - - bytes memory data = new bytes(120_001); - data[120_000] = 0x01; - - // Mock the gas paying token to be the ERC20 token - vm.mockCall( - address(systemConfig), abi.encodeCall(systemConfig.gasPayingToken, ()), abi.encode(address(token), 18) - ); - - uint64 gasLimit = optimismPortal2.minimumGasLimit(120_001); - vm.expectRevert(LargeCalldata.selector); - // Deposit the token into the portal - optimismPortal2.depositERC20Transaction(address(0), 0, 0, gasLimit, false, data); - } - - /// @dev Tests that `balance()` returns the correct balance when the gas paying token is not ether. - function testFuzz_balance_nonEther_succeeds(uint256 _amount) external { - vm.skip(true, "Custom gas token not supported"); - - // Mint the token to the contract and approve the token for the portal - token.mint(address(this), _amount); - token.approve(address(optimismPortal2), _amount); - - // Mock the gas paying token to be the ERC20 token - vm.mockCall( - address(systemConfig), abi.encodeCall(systemConfig.gasPayingToken, ()), abi.encode(address(token), 18) - ); - - // Deposit the token into the portal - optimismPortal2.depositERC20Transaction(address(0), _amount, 0, optimismPortal2.minimumGasLimit(0), false, ""); - - // Check that the balance has been correctly updated - assertEq(optimismPortal2.balance(), _amount); - } - - /// @dev Tests that `finalizeWithdrawalTransaction` succeeds. - function test_finalizeWithdrawalTransaction_provenWithdrawalHashWithNonEther_succeeds() external { - vm.skip(true, "Custom gas token not supported"); - - // Mint the token to the contract and approve the token for the portal - token.mint(address(this), _defaultTx.value); - token.approve(address(optimismPortal2), _defaultTx.value); - - // Mock the gas paying token to be the ERC20 token - vm.mockCall( - address(systemConfig), abi.encodeCall(systemConfig.gasPayingToken, ()), abi.encode(address(token), 18) - ); - - // Deposit the token into the portal - optimismPortal2.depositERC20Transaction( - address(bob), _defaultTx.value, 0, optimismPortal2.minimumGasLimit(0), false, "" - ); - - assertEq(optimismPortal2.balance(), _defaultTx.value); - - vm.expectEmit(address(optimismPortal2)); - emit WithdrawalProven(_withdrawalHash, alice, bob); - optimismPortal2.proveWithdrawalTransaction({ - _tx: _defaultTx, - _disputeGameIndex: _proposedGameIndex, - _outputRootProof: _outputRootProof, - _withdrawalProof: _withdrawalProof - }); - - // Warp past the finalization period. - game.resolveClaim(0, 0); - game.resolve(); - vm.warp(block.timestamp + optimismPortal2.proofMaturityDelaySeconds() + 1); - - vm.expectEmit(address(optimismPortal2)); - emit WithdrawalFinalized(_withdrawalHash, true); - - vm.expectCall(_defaultTx.target, 0, _defaultTx.data); - - vm.expectCall(address(token), 0, abi.encodeCall(token.transfer, (_defaultTx.target, _defaultTx.value))); - - optimismPortal2.finalizeWithdrawalTransaction(_defaultTx); - - assertEq(optimismPortal2.balance(), 0); - assertEq(token.balanceOf(address(bob)), 100); - } - - /// @dev Helper for depositing a transaction. - function depositTransaction( - address _from, - address _to, - uint256 _value, - uint64 _gasLimit, - bool _isCreation, - bytes calldata _data - ) - internal - { - if (_isCreation) { - _to = address(0); - } - if (_data.length > 120_000) { - _data = _data[0:120_000]; - } - - IResourceMetering.ResourceConfig memory rcfg = systemConfig.resourceConfig(); - _gasLimit = - uint64(bound(_gasLimit, optimismPortal2.minimumGasLimit(uint64(_data.length)), rcfg.maxResourceLimit)); - - // Mock the gas paying token to be the ERC20 token - vm.mockCall( - address(systemConfig), abi.encodeCall(systemConfig.gasPayingToken, ()), abi.encode(address(token), 18) - ); - - bytes memory opaqueData = abi.encodePacked(uint256(0), _value, _gasLimit, _isCreation, _data); - - vm.expectEmit(address(optimismPortal2)); - emit TransactionDeposited( - _from, // from - _to, - uint256(0), // DEPOSIT_VERSION - opaqueData - ); - - // Deposit the token into the portal - optimismPortal2.depositTransaction(_to, _value, _gasLimit, _isCreation, _data); - - // Assert final balance equals the deposited amount - assertEq(token.balanceOf(address(optimismPortal2)), 0); - assertEq(optimismPortal2.balance(), 0); - } - - /// @dev Tests that `depositTransaction` succeeds when a custom gas token is used but the msg.value is zero. - function testFuzz_depositTransaction_customGasTokenWithNoValueAndSenderIsOrigin_succeeds( - address _to, - uint256 _value, - uint64 _gasLimit, - bool _isCreation, - bytes calldata _data - ) - external - { - vm.skip(true, "Custom gas token not supported"); - - // Ensure that msg.sender == tx.origin - vm.startPrank(address(this), address(this)); - - depositTransaction({ - _from: address(this), - _to: _to, - _value: _value, - _gasLimit: _gasLimit, - _isCreation: _isCreation, - _data: _data - }); - } - - /// @dev Tests that `depositTransaction` succeeds when a custom gas token is used but the msg.value is zero. - function testFuzz_depositTransaction_customGasTokenWithNoValueAndSenderNotOrigin_succeeds( - address _to, - uint256 _value, - uint64 _gasLimit, - bool _isCreation, - bytes calldata _data - ) - external - { - vm.skip(true, "Custom gas token not supported"); - - // Ensure that msg.sender != tx.origin - vm.startPrank(address(this), address(1)); - - depositTransaction({ - _from: AddressAliasHelper.applyL1ToL2Alias(address(this)), - _to: _to, - _value: _value, - _gasLimit: _gasLimit, - _isCreation: _isCreation, - _data: _data - }); - } - - /// @dev Tests that `depositTransaction` fails when a custom gas token is used and msg.value is non-zero. - function test_depositTransaction_customGasTokenWithValue_reverts() external { - vm.skip(true, "Custom gas token not supported"); - - // Mock the gas paying token to be the ERC20 token - vm.mockCall( - address(systemConfig), abi.encodeCall(systemConfig.gasPayingToken, ()), abi.encode(address(token), 18) - ); - - vm.expectRevert(NoValue.selector); - - // Deposit the token into the portal - optimismPortal2.depositTransaction{ value: 100 }(address(0), 0, 0, false, ""); - } -} diff --git a/packages/contracts-bedrock/test/L1/OptimismPortalInterop.t.sol b/packages/contracts-bedrock/test/L1/OptimismPortalInterop.t.sol index 1e395b3279c4f..07ca34969cd2f 100644 --- a/packages/contracts-bedrock/test/L1/OptimismPortalInterop.t.sol +++ b/packages/contracts-bedrock/test/L1/OptimismPortalInterop.t.sol @@ -21,20 +21,16 @@ contract OptimismPortalInterop_Test is CommonTest { super.setUp(); } - /// @dev Tests that the config for the gas paying token can be set. - function testFuzz_setConfig_gasPayingToken_succeeds(bytes calldata _value) public { - vm.expectEmit(address(optimismPortal2)); - emitTransactionDeposited({ - _from: Constants.DEPOSITOR_ACCOUNT, - _to: Predeploys.L1_BLOCK_ATTRIBUTES, - _value: 0, - _mint: 0, - _gasLimit: 200_000, - _isCreation: false, - _data: abi.encodeCall(IL1BlockInterop.setConfig, (ConfigType.SET_GAS_PAYING_TOKEN, _value)) - }); + /// @notice Tests that the version function returns a valid string. We avoid testing the + /// specific value of the string as it changes frequently. + function test_version_succeeds() external view { + assert(bytes(_optimismPortalInterop().version()).length > 0); + } + /// @dev Tests that the config for the gas paying token cannot be set. + function testFuzz_setConfig_gasPayingToken_reverts(bytes calldata _value) public { vm.prank(address(_optimismPortalInterop().systemConfig())); + vm.expectRevert(IOptimismPortalInterop.CustomGasTokenNotSupported.selector); _optimismPortalInterop().setConfig(ConfigType.SET_GAS_PAYING_TOKEN, _value); } diff --git a/packages/contracts-bedrock/test/L1/SystemConfig.t.sol b/packages/contracts-bedrock/test/L1/SystemConfig.t.sol index a5ca2594f04b6..a1d2a22f427a1 100644 --- a/packages/contracts-bedrock/test/L1/SystemConfig.t.sol +++ b/packages/contracts-bedrock/test/L1/SystemConfig.t.sol @@ -4,19 +4,13 @@ pragma solidity 0.8.15; // Testing import { CommonTest } from "test/setup/CommonTest.sol"; -// Contracts -import { ERC20 } from "@openzeppelin/contracts/token/ERC20/ERC20.sol"; - // Libraries import { Constants } from "src/libraries/Constants.sol"; -import { Predeploys } from "src/libraries/Predeploys.sol"; -import { GasPayingToken } from "src/libraries/GasPayingToken.sol"; import { EIP1967Helper } from "test/mocks/EIP1967Helper.sol"; // Interfaces import { IResourceMetering } from "interfaces/L1/IResourceMetering.sol"; import { ISystemConfig } from "interfaces/L1/ISystemConfig.sol"; -import { IL1Block } from "interfaces/L2/IL1Block.sol"; contract SystemConfig_Init is CommonTest { event ConfigUpdate(uint256 indexed version, ISystemConfig.UpdateType indexed updateType, bytes data); @@ -47,6 +41,12 @@ contract SystemConfig_Initialize_Test is SystemConfig_Init { optimismMintableERC20Factory = artifacts.mustGetAddress("OptimismMintableERC20FactoryProxy"); } + /// @notice Tests that the version function returns a valid string. We avoid testing the + /// specific value of the string as it changes frequently. + function test_version_succeeds() external view { + assert(bytes(systemConfig.version()).length > 0); + } + /// @dev Tests that constructor sets the correct values. function test_constructor_succeeds() external view { ISystemConfig impl = ISystemConfig(systemConfigImpl); @@ -74,10 +74,6 @@ contract SystemConfig_Initialize_Test is SystemConfig_Init { assertEq(address(impl.disputeGameFactory()), address(0)); assertEq(address(impl.optimismPortal()), address(0)); assertEq(address(impl.optimismMintableERC20Factory()), address(0)); - // Check gas paying token - (address token, uint8 decimals) = impl.gasPayingToken(); - assertEq(token, Constants.ETHER); - assertEq(decimals, 18); } /// @dev Tests that initialization sets the correct values. @@ -110,10 +106,6 @@ contract SystemConfig_Initialize_Test is SystemConfig_Init { assertEq(address(systemConfig.disputeGameFactory()), address(disputeGameFactory)); assertEq(address(systemConfig.optimismPortal()), address(optimismPortal2)); assertEq(address(systemConfig.optimismMintableERC20Factory()), address(optimismMintableERC20Factory)); - // Check gas paying token - (address token, uint8 decimals) = systemConfig.gasPayingToken(); - assertEq(token, Constants.ETHER); - assertEq(decimals, 18); } } @@ -144,8 +136,7 @@ contract SystemConfig_Initialize_TestFail is SystemConfig_Initialize_Test { l1StandardBridge: address(0), disputeGameFactory: address(0), optimismPortal: address(0), - optimismMintableERC20Factory: address(0), - gasPayingToken: Constants.ETHER + optimismMintableERC20Factory: address(0) }) }); } @@ -174,8 +165,7 @@ contract SystemConfig_Initialize_TestFail is SystemConfig_Initialize_Test { l1StandardBridge: address(0), disputeGameFactory: address(0), optimismPortal: address(0), - optimismMintableERC20Factory: address(0), - gasPayingToken: Constants.ETHER + optimismMintableERC20Factory: address(0) }) }); assertEq(systemConfig.startBlock(), block.number); @@ -205,8 +195,7 @@ contract SystemConfig_Initialize_TestFail is SystemConfig_Initialize_Test { l1StandardBridge: address(0), disputeGameFactory: address(0), optimismPortal: address(0), - optimismMintableERC20Factory: address(0), - gasPayingToken: Constants.ETHER + optimismMintableERC20Factory: address(0) }) }); assertEq(systemConfig.startBlock(), 1); @@ -315,193 +304,12 @@ contract SystemConfig_Init_ResourceConfig is SystemConfig_Init { l1StandardBridge: address(0), disputeGameFactory: address(0), optimismPortal: address(0), - optimismMintableERC20Factory: address(0), - gasPayingToken: address(0) + optimismMintableERC20Factory: address(0) }) }); } } -contract SystemConfig_Init_CustomGasToken is SystemConfig_Init { - ERC20 token; - - function setUp() public override { - vm.skip(true, "Custom gas token not supported"); - - token = new ERC20("Silly", "SIL"); - super.enableCustomGasToken(address(token)); - - super.setUp(); - } - - /// @dev Helper to clean storage and then initialize the system config with an arbitrary gas token address. - function cleanStorageAndInit(address _gasPayingToken) internal { - vm.store(address(systemConfig), bytes32(0), bytes32(0)); // initailizer - vm.store(address(systemConfig), GasPayingToken.GAS_PAYING_TOKEN_SLOT, bytes32(0)); - vm.store(address(systemConfig), GasPayingToken.GAS_PAYING_TOKEN_NAME_SLOT, bytes32(0)); - vm.store(address(systemConfig), GasPayingToken.GAS_PAYING_TOKEN_SYMBOL_SLOT, bytes32(0)); - - systemConfig.initialize({ - _owner: alice, - _basefeeScalar: 2100, - _blobbasefeeScalar: 1000000, - _batcherHash: bytes32(hex"abcd"), - _gasLimit: 30_000_000, - _unsafeBlockSigner: address(1), - _config: Constants.DEFAULT_RESOURCE_CONFIG(), - _batchInbox: address(0), - _addresses: ISystemConfig.Addresses({ - l1CrossDomainMessenger: address(0), - l1ERC721Bridge: address(0), - disputeGameFactory: address(0), - l1StandardBridge: address(0), - optimismPortal: address(optimismPortal2), - optimismMintableERC20Factory: address(0), - gasPayingToken: _gasPayingToken - }) - }); - } - - /// @dev Tests that initialization sets the correct values and getters work. - function test_initialize_customGasToken_succeeds() external view { - (address addr, uint8 decimals) = systemConfig.gasPayingToken(); - assertEq(addr, address(token)); - assertEq(decimals, 18); - - assertEq(systemConfig.gasPayingTokenName(), token.name()); - assertEq(systemConfig.gasPayingTokenSymbol(), token.symbol()); - } - - /// @dev Tests that initialization sets the correct values and getters work. - function testFuzz_initialize_customGasToken_succeeds( - address _token, - string calldata _name, - string calldata _symbol - ) - external - { - // don't use vm's address - vm.assume(_token != address(vm)); - // don't use console's address - vm.assume(_token != CONSOLE); - // don't use create2 deployer's address - vm.assume(_token != CREATE2_FACTORY); - // don't use default test's address - vm.assume(_token != DEFAULT_TEST_CONTRACT); - // don't use multicall3's address - vm.assume(_token != MULTICALL3_ADDRESS); - - // Using vm.assume() would cause too many test rejections. - string memory name = _name; - if (bytes(_name).length > 32) { - name = _name[:32]; - } - - // Using vm.assume() would cause too many test rejections. - string memory symbol = _symbol; - if (bytes(_symbol).length > 32) { - symbol = _symbol[:32]; - } - - vm.mockCall(_token, abi.encodeCall(token.decimals, ()), abi.encode(18)); - vm.mockCall(_token, abi.encodeCall(token.name, ()), abi.encode(name)); - vm.mockCall(_token, abi.encodeCall(token.symbol, ()), abi.encode(symbol)); - - cleanStorageAndInit(_token); - - (address addr, uint8 decimals) = systemConfig.gasPayingToken(); - assertEq(decimals, 18); - - if (_token == address(0) || _token == Constants.ETHER) { - assertEq(addr, Constants.ETHER); - assertEq(systemConfig.gasPayingTokenName(), "Ether"); - assertEq(systemConfig.gasPayingTokenSymbol(), "ETH"); - } else { - assertEq(addr, _token); - assertEq(systemConfig.gasPayingTokenName(), name); - assertEq(systemConfig.gasPayingTokenSymbol(), symbol); - } - } - - /// @dev Tests that initialization sets the correct values and getters work when token address passed is 0. - function test_initialize_customGasTokenWithZeroTokenAddress_succeeds() external { - cleanStorageAndInit(address(0)); - - (address addr, uint8 decimals) = systemConfig.gasPayingToken(); - assertEq(addr, address(Constants.ETHER)); - assertEq(decimals, 18); - - assertEq(systemConfig.gasPayingTokenName(), "Ether"); - assertEq(systemConfig.gasPayingTokenSymbol(), "ETH"); - } - - /// @dev Tests that initialization sets the correct values and getters work when token address is Constants.ETHER - function test_initialize_customGasTokenWithEtherTokenAddress_succeeds() external { - cleanStorageAndInit(Constants.ETHER); - - (address addr, uint8 decimals) = systemConfig.gasPayingToken(); - assertEq(addr, address(Constants.ETHER)); - assertEq(decimals, 18); - - assertEq(systemConfig.gasPayingTokenName(), "Ether"); - assertEq(systemConfig.gasPayingTokenSymbol(), "ETH"); - } - - /// @dev Tests that initialization fails if decimals are not 18. - function test_initialize_customGasTokenWrongDecimals_fails() external { - vm.mockCall(address(token), abi.encodeCall(token.decimals, ()), abi.encode(8)); - vm.expectRevert("SystemConfig: bad decimals of gas paying token"); - - cleanStorageAndInit(address(token)); - } - - /// @dev Tests that initialization fails if name is too long. - function test_initialize_customGasTokenNameTooLong_fails() external { - string memory name = new string(32); - name = string.concat(name, "a"); - - vm.mockCall(address(token), abi.encodeCall(token.name, ()), abi.encode(name)); - vm.expectRevert("GasPayingToken: string cannot be greater than 32 bytes"); - - cleanStorageAndInit(address(token)); - } - - /// @dev Tests that initialization fails if symbol is too long. - function test_initialize_customGasTokenSymbolTooLong_fails() external { - string memory symbol = new string(33); - symbol = string.concat(symbol, "a"); - - vm.mockCall(address(token), abi.encodeCall(token.symbol, ()), abi.encode(symbol)); - vm.expectRevert("GasPayingToken: string cannot be greater than 32 bytes"); - - cleanStorageAndInit(address(token)); - } - - /// @dev Tests that initialization works with OptimismPortal. - function test_initialize_customGasTokenCall_succeeds() external { - vm.expectCall( - address(optimismPortal2), - abi.encodeCall(optimismPortal2.setGasPayingToken, (address(token), 18, bytes32("Silly"), bytes32("SIL"))) - ); - - vm.expectEmit(address(optimismPortal2)); - emit TransactionDeposited( - 0xDeaDDEaDDeAdDeAdDEAdDEaddeAddEAdDEAd0001, - Predeploys.L1_BLOCK_ATTRIBUTES, - 0, // deposit version - abi.encodePacked( - uint256(0), // mint - uint256(0), // value - uint64(200_000), // gasLimit - false, // isCreation, - abi.encodeCall(IL1Block.setGasPayingToken, (address(token), 18, bytes32("Silly"), bytes32("SIL"))) - ) - ); - - cleanStorageAndInit(address(token)); - } -} - contract SystemConfig_Setters_TestFail is SystemConfig_Init { /// @dev Tests that `setBatcherHash` reverts if the caller is not the owner. function test_setBatcherHash_notOwner_reverts() external { diff --git a/packages/contracts-bedrock/test/L1/SystemConfigInterop.t.sol b/packages/contracts-bedrock/test/L1/SystemConfigInterop.t.sol index bc01f347c9104..2f953ef7413f4 100644 --- a/packages/contracts-bedrock/test/L1/SystemConfigInterop.t.sol +++ b/packages/contracts-bedrock/test/L1/SystemConfigInterop.t.sol @@ -4,16 +4,10 @@ pragma solidity 0.8.15; // Testing import { CommonTest } from "test/setup/CommonTest.sol"; -// Contracts -import { ERC20 } from "@openzeppelin/contracts/token/ERC20/ERC20.sol"; - // Libraries -import { Constants } from "src/libraries/Constants.sol"; import { StaticConfig } from "src/libraries/StaticConfig.sol"; -import { GasPayingToken } from "src/libraries/GasPayingToken.sol"; // Interfaces -import { ISystemConfig } from "interfaces/L1/ISystemConfig.sol"; import { ISystemConfigInterop } from "interfaces/L1/ISystemConfigInterop.sol"; import { IOptimismPortalInterop } from "interfaces/L1/IOptimismPortalInterop.sol"; import { ConfigType } from "interfaces/L2/IL1BlockInterop.sol"; @@ -26,110 +20,10 @@ contract SystemConfigInterop_Test is CommonTest { super.setUp(); } - /// @dev Temporary test that checks that correct calls to initialize when using a custom gas token revert with the - /// expected error. - /// @dev Should be removed when/if Custom Gas Token functionality is allowed again. - function test_initialize_customGasToken_reverts() external { - vm.expectRevert(ISystemConfig.CustomGasTokenNotSupported.selector); - _cleanStorageAndInit(address(L1Token)); - } - - /// @dev Tests that when the decimals is not 18, initialization reverts. - function test_initialize_decimalsIsNot18_reverts(uint8 decimals) external { - vm.skip(true, "Custom gas token not supported"); - - vm.assume(decimals != 18); - address _token = address(L1Token); - - vm.mockCall(_token, abi.encodeCall(ERC20.name, ()), abi.encode("Token")); - vm.mockCall(_token, abi.encodeCall(ERC20.symbol, ()), abi.encode("TKN")); - vm.mockCall(_token, abi.encodeCall(ERC20.decimals, ()), abi.encode(decimals)); - - vm.expectRevert("SystemConfig: bad decimals of gas paying token"); - _cleanStorageAndInit(_token); - } - - /// @dev Temporary test that checks that correct calls to setGasPayingToken when using a custom gas token revert - /// with the expected error. - /// @dev Should be removed when/if Custom Gas Token functionality is allowed again. - function test_setGasPayingToken_customGasToken_reverts( - address _token, - string calldata _name, - string calldata _symbol - ) - external - { - assumeNotForgeAddress(_token); - vm.assume(_token != address(0)); - vm.assume(_token != Constants.ETHER); - - // Using vm.assume() would cause too many test rejections. - string memory name = _name; - if (bytes(_name).length > 32) { - name = _name[:32]; - } - - // Using vm.assume() would cause too many test rejections. - string memory symbol = _symbol; - if (bytes(_symbol).length > 32) { - symbol = _symbol[:32]; - } - - vm.mockCall(_token, abi.encodeCall(ERC20.decimals, ()), abi.encode(18)); - vm.mockCall(_token, abi.encodeCall(ERC20.name, ()), abi.encode(name)); - vm.mockCall(_token, abi.encodeCall(ERC20.symbol, ()), abi.encode(symbol)); - - vm.expectRevert(ISystemConfig.CustomGasTokenNotSupported.selector); - _cleanStorageAndInit(_token); - } - - /// @dev Tests that the gas paying token can be set. - function testFuzz_setGasPayingToken_succeeds( - address _token, - string calldata _name, - string calldata _symbol - ) - public - { - vm.skip(true, "Custom gas token not supported"); - - assumeNotForgeAddress(_token); - vm.assume(_token != address(0)); - vm.assume(_token != Constants.ETHER); - - // Using vm.assume() would cause too many test rejections. - string memory name = _name; - if (bytes(_name).length > 32) { - name = _name[:32]; - } - - // Using vm.assume() would cause too many test rejections. - string memory symbol = _symbol; - if (bytes(_symbol).length > 32) { - symbol = _symbol[:32]; - } - - vm.mockCall(_token, abi.encodeCall(ERC20.decimals, ()), abi.encode(18)); - vm.mockCall(_token, abi.encodeCall(ERC20.name, ()), abi.encode(name)); - vm.mockCall(_token, abi.encodeCall(ERC20.symbol, ()), abi.encode(symbol)); - - vm.expectCall( - address(optimismPortal2), - abi.encodeCall( - IOptimismPortalInterop.setConfig, - ( - ConfigType.SET_GAS_PAYING_TOKEN, - StaticConfig.encodeSetGasPayingToken({ - _token: _token, - _decimals: 18, - _name: GasPayingToken.sanitize(name), - _symbol: GasPayingToken.sanitize(symbol) - }) - ) - ) - ); - - _cleanStorageAndInit(_token); + /// @notice Tests that the version function returns a valid string. We avoid testing the + /// specific value of the string as it changes frequently. + function test_version_succeeds() external view { + assert(bytes(_systemConfigInterop().version()).length > 0); } /// @dev Tests that a dependency can be added. @@ -176,35 +70,6 @@ contract SystemConfigInterop_Test is CommonTest { _systemConfigInterop().removeDependency(_chainId); } - /// @dev Helper to clean storage and then initialize the system config with an arbitrary gas token address. - function _cleanStorageAndInit(address _token) internal { - // Wipe out the initialized slot so the proxy can be initialized again - vm.store(address(systemConfig), bytes32(0), bytes32(0)); - vm.store(address(systemConfig), GasPayingToken.GAS_PAYING_TOKEN_SLOT, bytes32(0)); - vm.store(address(systemConfig), GasPayingToken.GAS_PAYING_TOKEN_NAME_SLOT, bytes32(0)); - vm.store(address(systemConfig), GasPayingToken.GAS_PAYING_TOKEN_SYMBOL_SLOT, bytes32(0)); - - systemConfig.initialize({ - _owner: alice, - _basefeeScalar: 2100, - _blobbasefeeScalar: 1000000, - _batcherHash: bytes32(hex"abcd"), - _gasLimit: 30_000_000, - _unsafeBlockSigner: address(1), - _config: Constants.DEFAULT_RESOURCE_CONFIG(), - _batchInbox: address(0), - _addresses: ISystemConfig.Addresses({ - l1CrossDomainMessenger: address(0), - l1ERC721Bridge: address(0), - disputeGameFactory: address(0), - l1StandardBridge: address(0), - optimismPortal: address(optimismPortal2), - optimismMintableERC20Factory: address(0), - gasPayingToken: _token - }) - }); - } - /// @dev Returns the SystemConfigInterop instance. function _systemConfigInterop() internal view returns (ISystemConfigInterop) { return ISystemConfigInterop(address(systemConfig)); diff --git a/packages/contracts-bedrock/test/L2/L2CrossDomainMessenger.t.sol b/packages/contracts-bedrock/test/L2/L2CrossDomainMessenger.t.sol index bb673d7304cc8..ca1fd3c2d2d55 100644 --- a/packages/contracts-bedrock/test/L2/L2CrossDomainMessenger.t.sol +++ b/packages/contracts-bedrock/test/L2/L2CrossDomainMessenger.t.sol @@ -16,6 +16,7 @@ import { AddressAliasHelper } from "src/vendor/AddressAliasHelper.sol"; // Interfaces import { IL2CrossDomainMessenger } from "interfaces/L2/IL2CrossDomainMessenger.sol"; import { IL2ToL1MessagePasser } from "interfaces/L2/IL2ToL1MessagePasser.sol"; +import { IGasToken } from "src/libraries/GasPayingToken.sol"; contract L2CrossDomainMessenger_Test is CommonTest { /// @dev Receiver address for testing @@ -315,7 +316,7 @@ contract L2CrossDomainMessenger_Test is CommonTest { /// @dev Tests that sendMessage succeeds with a custom gas token when the call value is zero. function test_sendMessage_customGasTokenButNoValue_succeeds() external { // Mock the gasPayingToken function to return a custom gas token - vm.mockCall(address(l1Block), abi.encodeCall(systemConfig.gasPayingToken, ()), abi.encode(address(1), uint8(2))); + vm.mockCall(address(l1Block), abi.encodeCall(IGasToken.gasPayingToken, ()), abi.encode(address(1), uint8(2))); bytes memory xDomainCallData = Encoding.encodeCrossDomainMessage(l2CrossDomainMessenger.messageNonce(), alice, recipient, 0, 100, hex"ff"); @@ -355,7 +356,7 @@ contract L2CrossDomainMessenger_Test is CommonTest { /// @dev Tests that the sendMessage reverts when call value is non-zero with custom gas token. function test_sendMessage_customGasTokenWithValue_reverts() external { // Mock the gasPayingToken function to return a custom gas token - vm.mockCall(address(l1Block), abi.encodeCall(systemConfig.gasPayingToken, ()), abi.encode(address(1), uint8(2))); + vm.mockCall(address(l1Block), abi.encodeCall(IGasToken.gasPayingToken, ()), abi.encode(address(1), uint8(2))); vm.expectRevert("CrossDomainMessenger: cannot send value with custom gas token"); l2CrossDomainMessenger.sendMessage{ value: 1 }(recipient, hex"ff", uint32(100)); @@ -364,7 +365,7 @@ contract L2CrossDomainMessenger_Test is CommonTest { /// @dev Tests that the relayMessage succeeds with a custom gas token when the call value is zero. function test_relayMessage_customGasTokenAndNoValue_succeeds() external { // Mock the gasPayingToken function to return a custom gas token - vm.mockCall(address(l1Block), abi.encodeCall(systemConfig.gasPayingToken, ()), abi.encode(address(1), uint8(2))); + vm.mockCall(address(l1Block), abi.encodeCall(IGasToken.gasPayingToken, ()), abi.encode(address(1), uint8(2))); address target = address(0xabcd); address sender = address(l1CrossDomainMessenger); @@ -400,7 +401,7 @@ contract L2CrossDomainMessenger_Test is CommonTest { /// The L1CrossDomainMessenger `sendMessage` function cannot send value with a custom gas token. function test_relayMessage_customGasTokenWithValue_reverts() external virtual { // Mock the gasPayingToken function to return a custom gas token - vm.mockCall(address(l1Block), abi.encodeCall(systemConfig.gasPayingToken, ()), abi.encode(address(1), uint8(2))); + vm.mockCall(address(l1Block), abi.encodeCall(IGasToken.gasPayingToken, ()), abi.encode(address(1), uint8(2))); vm.expectRevert("CrossDomainMessenger: value must be zero unless message is from a system address"); l2CrossDomainMessenger.relayMessage{ value: 1 }( diff --git a/packages/contracts-bedrock/test/L2/L2StandardBridge.t.sol b/packages/contracts-bedrock/test/L2/L2StandardBridge.t.sol index 43a22f6a95f5a..70ccc5122e7d3 100644 --- a/packages/contracts-bedrock/test/L2/L2StandardBridge.t.sol +++ b/packages/contracts-bedrock/test/L2/L2StandardBridge.t.sol @@ -20,6 +20,7 @@ import { ICrossDomainMessenger } from "interfaces/universal/ICrossDomainMessenge import { IStandardBridge } from "interfaces/universal/IStandardBridge.sol"; import { IL2ToL1MessagePasser } from "interfaces/L2/IL2ToL1MessagePasser.sol"; import { IL2StandardBridge } from "interfaces/L2/IL2StandardBridge.sol"; +import { IGasToken } from "src/libraries/GasPayingToken.sol"; contract L2StandardBridge_Test is CommonTest { using stdStorage for StdStorage; @@ -130,7 +131,7 @@ contract L2StandardBridge_Test is CommonTest { /// @dev Tests that the receive function reverts with custom gas token. function testFuzz_receive_customGasToken_reverts(uint256 _value) external { vm.prank(alice, alice); - vm.mockCall(address(l1Block), abi.encodeCall(systemConfig.gasPayingToken, ()), abi.encode(address(1), uint8(2))); + vm.mockCall(address(l1Block), abi.encodeCall(IGasToken.gasPayingToken, ()), abi.encode(address(1), uint8(2))); vm.deal(alice, _value); (bool success, bytes memory data) = address(l2StandardBridge).call{ value: _value }(hex""); assertFalse(success); @@ -169,9 +170,7 @@ contract L2StandardBridge_Test is CommonTest { /// @dev Tests that `withdraw` reverts with custom gas token. function test_withdraw_customGasToken_reverts() external { - vm.mockCall( - address(l1Block), abi.encodeCall(systemConfig.gasPayingToken, ()), abi.encode(address(1), uint8(18)) - ); + vm.mockCall(address(l1Block), abi.encodeCall(IGasToken.gasPayingToken, ()), abi.encode(address(1), uint8(18))); vm.expectRevert("L2StandardBridge: not supported with custom gas token"); vm.prank(alice, alice); l2StandardBridge.withdraw(address(Predeploys.LEGACY_ERC20_ETH), 1, 1, hex""); @@ -179,9 +178,7 @@ contract L2StandardBridge_Test is CommonTest { /// @dev Tests that `withdraw` reverts with custom gas token. function test_withdrawERC20_customGasToken_reverts() external { - vm.mockCall( - address(l1Block), abi.encodeCall(systemConfig.gasPayingToken, ()), abi.encode(address(1), uint8(18)) - ); + vm.mockCall(address(l1Block), abi.encodeCall(IGasToken.gasPayingToken, ()), abi.encode(address(1), uint8(18))); vm.expectRevert("L2StandardBridge: not supported with custom gas token"); vm.prank(alice, alice); l2StandardBridge.withdraw(address(L1Token), 1, 1, hex""); @@ -190,9 +187,7 @@ contract L2StandardBridge_Test is CommonTest { /// @dev Tests that `withdraw` reverts with custom gas token. function test_withdrawERC20WithValue_customGasToken_reverts() external { vm.deal(alice, 1 ether); - vm.mockCall( - address(l1Block), abi.encodeCall(systemConfig.gasPayingToken, ()), abi.encode(address(1), uint8(18)) - ); + vm.mockCall(address(l1Block), abi.encodeCall(IGasToken.gasPayingToken, ()), abi.encode(address(1), uint8(18))); vm.expectRevert("L2StandardBridge: not supported with custom gas token"); vm.prank(alice, alice); l2StandardBridge.withdraw{ value: 1 ether }(address(L1Token), 1, 1, hex""); @@ -201,9 +196,7 @@ contract L2StandardBridge_Test is CommonTest { /// @dev Tests that `withdraw` with value reverts with custom gas token. function test_withdraw_customGasTokenWithValue_reverts() external { vm.deal(alice, 1 ether); - vm.mockCall( - address(l1Block), abi.encodeCall(systemConfig.gasPayingToken, ()), abi.encode(address(1), uint8(18)) - ); + vm.mockCall(address(l1Block), abi.encodeCall(IGasToken.gasPayingToken, ()), abi.encode(address(1), uint8(18))); vm.expectRevert("L2StandardBridge: not supported with custom gas token"); vm.prank(alice, alice); l2StandardBridge.withdraw{ value: 1 ether }(address(Predeploys.LEGACY_ERC20_ETH), 1, 1, hex""); @@ -211,9 +204,7 @@ contract L2StandardBridge_Test is CommonTest { /// @dev Tests that `withdrawTo` reverts with custom gas token. function test_withdrawTo_customGasToken_reverts() external { - vm.mockCall( - address(l1Block), abi.encodeCall(systemConfig.gasPayingToken, ()), abi.encode(address(1), uint8(18)) - ); + vm.mockCall(address(l1Block), abi.encodeCall(IGasToken.gasPayingToken, ()), abi.encode(address(1), uint8(18))); vm.expectRevert("L2StandardBridge: not supported with custom gas token"); vm.prank(alice, alice); l2StandardBridge.withdrawTo(address(Predeploys.LEGACY_ERC20_ETH), bob, 1, 1, hex""); @@ -221,9 +212,7 @@ contract L2StandardBridge_Test is CommonTest { /// @dev Tests that `withdrawTo` reverts with custom gas token. function test_withdrawToERC20_customGasToken_reverts() external { - vm.mockCall( - address(l1Block), abi.encodeCall(systemConfig.gasPayingToken, ()), abi.encode(address(1), uint8(18)) - ); + vm.mockCall(address(l1Block), abi.encodeCall(IGasToken.gasPayingToken, ()), abi.encode(address(1), uint8(18))); vm.expectRevert("L2StandardBridge: not supported with custom gas token"); vm.prank(alice, alice); l2StandardBridge.withdrawTo(address(L2Token), bob, 1, 1, hex""); @@ -232,9 +221,7 @@ contract L2StandardBridge_Test is CommonTest { /// @dev Tests that `withdrawTo` reverts with custom gas token. function test_withdrawToERC20WithValue_customGasToken_reverts() external { vm.deal(alice, 1 ether); - vm.mockCall( - address(l1Block), abi.encodeCall(systemConfig.gasPayingToken, ()), abi.encode(address(1), uint8(18)) - ); + vm.mockCall(address(l1Block), abi.encodeCall(IGasToken.gasPayingToken, ()), abi.encode(address(1), uint8(18))); vm.expectRevert("L2StandardBridge: not supported with custom gas token"); vm.prank(alice, alice); l2StandardBridge.withdrawTo{ value: 1 ether }(address(L2Token), bob, 1, 1, hex""); @@ -243,9 +230,7 @@ contract L2StandardBridge_Test is CommonTest { /// @dev Tests that `withdrawTo` with value reverts with custom gas token. function test_withdrawTo_customGasTokenWithValue_reverts() external { vm.deal(alice, 1 ether); - vm.mockCall( - address(l1Block), abi.encodeCall(systemConfig.gasPayingToken, ()), abi.encode(address(1), uint8(18)) - ); + vm.mockCall(address(l1Block), abi.encodeCall(IGasToken.gasPayingToken, ()), abi.encode(address(1), uint8(18))); vm.expectRevert("L2StandardBridge: not supported with custom gas token"); vm.prank(alice, alice); l2StandardBridge.withdrawTo{ value: 1 ether }(address(Predeploys.LEGACY_ERC20_ETH), bob, 1, 1, hex""); @@ -577,7 +562,7 @@ contract L2StandardBridge_Bridge_Test is CommonTest { /// @dev Tests that bridging reverts with custom gas token. function test_bridgeETH_customGasToken_reverts() external { vm.prank(alice, alice); - vm.mockCall(address(l1Block), abi.encodeCall(systemConfig.gasPayingToken, ()), abi.encode(address(1), uint8(2))); + vm.mockCall(address(l1Block), abi.encodeCall(IGasToken.gasPayingToken, ()), abi.encode(address(1), uint8(2))); vm.expectRevert("StandardBridge: cannot bridge ETH with custom gas token"); l2StandardBridge.bridgeETH(50000, hex"dead"); @@ -628,7 +613,7 @@ contract L2StandardBridge_Bridge_Test is CommonTest { ) external { - vm.mockCall(address(l1Block), abi.encodeCall(systemConfig.gasPayingToken, ()), abi.encode(address(1), uint8(2))); + vm.mockCall(address(l1Block), abi.encodeCall(IGasToken.gasPayingToken, ()), abi.encode(address(1), uint8(2))); vm.expectRevert("StandardBridge: cannot bridge ETH with custom gas token"); vm.deal(address(this), _value); l2StandardBridge.bridgeETHTo{ value: _value }(bob, _minGasLimit, _extraData); @@ -655,22 +640,6 @@ contract L2StandardBridge_FinalizeBridgeETH_Test is CommonTest { l2StandardBridge.finalizeBridgeETH{ value: 100 }(alice, alice, 100, hex""); } - - /// @dev Tests that finalizing bridged reverts with custom gas token. - function test_finalizeBridgeETH_customGasToken_reverts() external { - address messenger = address(l2StandardBridge.messenger()); - vm.mockCall( - messenger, - abi.encodeCall(ICrossDomainMessenger.xDomainMessageSender, ()), - abi.encode(address(l2StandardBridge.OTHER_BRIDGE())) - ); - vm.deal(address(l2CrossDomainMessenger), 1); - vm.prank(address(l2CrossDomainMessenger)); - vm.mockCall(address(l1Block), abi.encodeCall(systemConfig.gasPayingToken, ()), abi.encode(address(1), uint8(2))); - vm.expectRevert("StandardBridge: cannot bridge ETH with custom gas token"); - - l2StandardBridge.finalizeBridgeETH(alice, alice, 1, hex""); - } } contract L2StandardBridge_FinalizeBridgeERC20_Test is CommonTest { diff --git a/packages/contracts-bedrock/test/invariants/SystemConfig.t.sol b/packages/contracts-bedrock/test/invariants/SystemConfig.t.sol index 68add058f60dd..4ca84d96b0209 100644 --- a/packages/contracts-bedrock/test/invariants/SystemConfig.t.sol +++ b/packages/contracts-bedrock/test/invariants/SystemConfig.t.sol @@ -44,8 +44,7 @@ contract SystemConfig_GasLimitBoundaries_Invariant is Test { l1StandardBridge: address(0), disputeGameFactory: address(0), optimismPortal: address(0), - optimismMintableERC20Factory: address(0), - gasPayingToken: Constants.ETHER + optimismMintableERC20Factory: address(0) }) ) ) diff --git a/packages/contracts-bedrock/test/universal/Specs.t.sol b/packages/contracts-bedrock/test/universal/Specs.t.sol index 60da8c58ba507..ccafd6bd7e165 100644 --- a/packages/contracts-bedrock/test/universal/Specs.t.sol +++ b/packages/contracts-bedrock/test/universal/Specs.t.sol @@ -261,12 +261,6 @@ contract Specification_Test is CommonTest { _addSpec({ _name: "OptimismPortalInterop", _sel: _getSel("respectedGameTypeUpdatedAt()") }); _addSpec({ _name: "OptimismPortalInterop", _sel: _getSel("proofSubmitters(bytes32,uint256)") }); _addSpec({ _name: "OptimismPortalInterop", _sel: _getSel("numProofSubmitters(bytes32)") }); - _addSpec({ _name: "OptimismPortalInterop", _sel: _getSel("balance()") }); - _addSpec({ - _name: "OptimismPortalInterop", - _sel: _getSel("depositERC20Transaction(address,uint256,uint256,uint64,bool,bytes)") - }); - _addSpec({ _name: "OptimismPortalInterop", _sel: _getSel("setGasPayingToken(address,uint8,bytes32,bytes32)") }); _addSpec({ _name: "OptimismPortalInterop", _sel: IOptimismPortalInterop.setConfig.selector, @@ -313,12 +307,6 @@ contract Specification_Test is CommonTest { _addSpec({ _name: "OptimismPortal2", _sel: _getSel("respectedGameTypeUpdatedAt()") }); _addSpec({ _name: "OptimismPortal2", _sel: _getSel("proofSubmitters(bytes32,uint256)") }); _addSpec({ _name: "OptimismPortal2", _sel: _getSel("numProofSubmitters(bytes32)") }); - _addSpec({ _name: "OptimismPortal2", _sel: _getSel("balance()") }); - _addSpec({ - _name: "OptimismPortal2", - _sel: _getSel("depositERC20Transaction(address,uint256,uint256,uint64,bool,bytes)") - }); - _addSpec({ _name: "OptimismPortal2", _sel: _getSel("setGasPayingToken(address,uint8,bytes32,bytes32)") }); // ProtocolVersions _addSpec({ _name: "ProtocolVersions", _sel: _getSel("RECOMMENDED_SLOT()") }); @@ -395,10 +383,6 @@ contract Specification_Test is CommonTest { _addSpec({ _name: "SystemConfig", _sel: _getSel("OPTIMISM_PORTAL_SLOT()") }); _addSpec({ _name: "SystemConfig", _sel: _getSel("OPTIMISM_MINTABLE_ERC20_FACTORY_SLOT()") }); _addSpec({ _name: "SystemConfig", _sel: _getSel("BATCH_INBOX_SLOT()") }); - _addSpec({ _name: "SystemConfig", _sel: _getSel("gasPayingToken()") }); - _addSpec({ _name: "SystemConfig", _sel: _getSel("gasPayingTokenName()") }); - _addSpec({ _name: "SystemConfig", _sel: _getSel("gasPayingTokenSymbol()") }); - _addSpec({ _name: "SystemConfig", _sel: _getSel("isCustomGasToken()") }); _addSpec({ _name: "SystemConfig", _sel: _getSel("DISPUTE_GAME_FACTORY_SLOT()") }); _addSpec({ _name: "SystemConfig", _sel: _getSel("disputeGameFactory()") }); _addSpec({ @@ -471,10 +455,6 @@ contract Specification_Test is CommonTest { _addSpec({ _name: "SystemConfigInterop", _sel: _getSel("OPTIMISM_PORTAL_SLOT()") }); _addSpec({ _name: "SystemConfigInterop", _sel: _getSel("OPTIMISM_MINTABLE_ERC20_FACTORY_SLOT()") }); _addSpec({ _name: "SystemConfigInterop", _sel: _getSel("BATCH_INBOX_SLOT()") }); - _addSpec({ _name: "SystemConfigInterop", _sel: _getSel("gasPayingToken()") }); - _addSpec({ _name: "SystemConfigInterop", _sel: _getSel("gasPayingTokenName()") }); - _addSpec({ _name: "SystemConfigInterop", _sel: _getSel("gasPayingTokenSymbol()") }); - _addSpec({ _name: "SystemConfigInterop", _sel: _getSel("isCustomGasToken()") }); _addSpec({ _name: "SystemConfigInterop", _sel: _getSel("DISPUTE_GAME_FACTORY_SLOT()") }); _addSpec({ _name: "SystemConfigInterop", _sel: _getSel("disputeGameFactory()") }); _addSpec({ diff --git a/packages/contracts-bedrock/test/vendor/Initializable.t.sol b/packages/contracts-bedrock/test/vendor/Initializable.t.sol index f8984c5f72d22..968db70b89130 100644 --- a/packages/contracts-bedrock/test/vendor/Initializable.t.sol +++ b/packages/contracts-bedrock/test/vendor/Initializable.t.sol @@ -10,7 +10,6 @@ import { Process } from "scripts/libraries/Process.sol"; // Libraries import { LibString } from "@solady/utils/LibString.sol"; -import { Constants } from "src/libraries/Constants.sol"; import { GameType } from "src/dispute/lib/Types.sol"; import { EIP1967Helper } from "test/mocks/EIP1967Helper.sol"; @@ -183,8 +182,7 @@ contract Initializer_Test is CommonTest { l1StandardBridge: address(0), disputeGameFactory: address(0), optimismPortal: address(0), - optimismMintableERC20Factory: address(0), - gasPayingToken: Constants.ETHER + optimismMintableERC20Factory: address(0) }) ) ) @@ -219,8 +217,7 @@ contract Initializer_Test is CommonTest { l1StandardBridge: address(0), disputeGameFactory: address(0), optimismPortal: address(0), - optimismMintableERC20Factory: address(0), - gasPayingToken: Constants.ETHER + optimismMintableERC20Factory: address(0) }) ) )