From 3af1faf18d42ad7a5e6fe3a0f913638b65f6fb82 Mon Sep 17 00:00:00 2001 From: AgusDuha <81362284+agusduha@users.noreply.github.com> Date: Thu, 17 Oct 2024 18:01:12 -0300 Subject: [PATCH] fix: remove immutables from superchain erc20 beacon (#12207) * fix: remove immutables from superchain erc20 beacon (#67) * fix: remove immutables from superchain erc20 beacon * test: add superchain erc20 beacon tests * fix: superchain erc20 beacon interface (#99) --- .../contracts-bedrock/scripts/L2Genesis.s.sol | 22 +++------------- packages/contracts-bedrock/semver-lock.json | 4 +-- .../abi/OptimismSuperchainERC20Beacon.json | 13 +--------- .../src/L2/OptimismSuperchainERC20Beacon.sol | 18 +++++-------- .../IOptimismSuperchainERC20Beacon.sol | 8 +++--- .../L2/OptimismSuperchainERC20Beacon.t.sol | 25 +++++++++++++++++++ .../test/L2/Predeploys.t.sol | 2 +- 7 files changed, 41 insertions(+), 51 deletions(-) create mode 100644 packages/contracts-bedrock/test/L2/OptimismSuperchainERC20Beacon.t.sol diff --git a/packages/contracts-bedrock/scripts/L2Genesis.s.sol b/packages/contracts-bedrock/scripts/L2Genesis.s.sol index 2dd0e906dbeb..965b77100861 100644 --- a/packages/contracts-bedrock/scripts/L2Genesis.s.sol +++ b/packages/contracts-bedrock/scripts/L2Genesis.s.sol @@ -21,7 +21,6 @@ import { Types } from "src/libraries/Types.sol"; import { ISequencerFeeVault } from "src/L2/interfaces/ISequencerFeeVault.sol"; import { IBaseFeeVault } from "src/L2/interfaces/IBaseFeeVault.sol"; import { IL1FeeVault } from "src/L2/interfaces/IL1FeeVault.sol"; -import { IOptimismSuperchainERC20Beacon } from "src/L2/interfaces/IOptimismSuperchainERC20Beacon.sol"; import { IOptimismMintableERC721Factory } from "src/universal/interfaces/IOptimismMintableERC721Factory.sol"; import { IGovernanceToken } from "src/governance/interfaces/IGovernanceToken.sol"; import { IOptimismMintableERC20Factory } from "src/universal/interfaces/IOptimismMintableERC20Factory.sol"; @@ -577,29 +576,14 @@ contract L2Genesis is Deployer { _setImplementationCode(Predeploys.OPTIMISM_SUPERCHAIN_ERC20_FACTORY); } - /// @notice This predeploy is following the safety invariant #2. + /// @notice This predeploy is following the safety invariant #1. + /// This contract has no initializer. function setOptimismSuperchainERC20Beacon() internal { address superchainERC20Impl = Predeploys.OPTIMISM_SUPERCHAIN_ERC20; console.log("Setting %s implementation at: %s", "OptimismSuperchainERC20", superchainERC20Impl); vm.etch(superchainERC20Impl, vm.getDeployedCode("OptimismSuperchainERC20.sol:OptimismSuperchainERC20")); - IOptimismSuperchainERC20Beacon beacon = IOptimismSuperchainERC20Beacon( - DeployUtils.create1( - "OptimismSuperchainERC20Beacon", - DeployUtils.encodeConstructor( - abi.encodeCall(IOptimismSuperchainERC20Beacon.__constructor__, (superchainERC20Impl)) - ) - ) - ); - - address beaconImpl = Predeploys.predeployToCodeNamespace(Predeploys.OPTIMISM_SUPERCHAIN_ERC20_BEACON); - - console.log("Setting %s implementation at: %s", "OptimismSuperchainERC20Beacon", beaconImpl); - vm.etch(beaconImpl, address(beacon).code); - - /// Reset so its not included state dump - vm.etch(address(beacon), ""); - vm.resetNonce(address(beacon)); + _setImplementationCode(Predeploys.OPTIMISM_SUPERCHAIN_ERC20_BEACON); } /// @notice This predeploy is following the safety invariant #1. diff --git a/packages/contracts-bedrock/semver-lock.json b/packages/contracts-bedrock/semver-lock.json index 6f5563da54ce..61a067d80987 100644 --- a/packages/contracts-bedrock/semver-lock.json +++ b/packages/contracts-bedrock/semver-lock.json @@ -112,8 +112,8 @@ "sourceCodeHash": "0xf32130f0b46333daba062c50ff6dcfadce1f177ff753bed2374d499ea9c2d98a" }, "src/L2/OptimismSuperchainERC20Beacon.sol": { - "initCodeHash": "0x99ce8095b23c124850d866cbc144fee6cee05dbc6bb5d83acadfe00b90cf42c7", - "sourceCodeHash": "0x5e58b7c867fafa49fe39d68d83875425e9cf94f05f2835bdcdaa08fc8bc6b68e" + "initCodeHash": "0x23dba3ceb9e58646695c306996c9e15251ac79acc6339c1a93d10a4c79da6dab", + "sourceCodeHash": "0xf4379e49665823c877f5732f35068435ce06e2394fce6910a5e113d16cdc9f95" }, "src/L2/OptimismSuperchainERC20Factory.sol": { "initCodeHash": "0x18a362c57f08b611db98dfde96121385e938f995c84e3547c1c03fd49f9db2fd", diff --git a/packages/contracts-bedrock/snapshots/abi/OptimismSuperchainERC20Beacon.json b/packages/contracts-bedrock/snapshots/abi/OptimismSuperchainERC20Beacon.json index 0bdfc64ed2fe..a06b5b5d140e 100644 --- a/packages/contracts-bedrock/snapshots/abi/OptimismSuperchainERC20Beacon.json +++ b/packages/contracts-bedrock/snapshots/abi/OptimismSuperchainERC20Beacon.json @@ -1,15 +1,4 @@ [ - { - "inputs": [ - { - "internalType": "address", - "name": "_implementation", - "type": "address" - } - ], - "stateMutability": "nonpayable", - "type": "constructor" - }, { "inputs": [], "name": "implementation", @@ -20,7 +9,7 @@ "type": "address" } ], - "stateMutability": "view", + "stateMutability": "pure", "type": "function" }, { diff --git a/packages/contracts-bedrock/src/L2/OptimismSuperchainERC20Beacon.sol b/packages/contracts-bedrock/src/L2/OptimismSuperchainERC20Beacon.sol index d1160819a2ec..e2b3dc437b0f 100644 --- a/packages/contracts-bedrock/src/L2/OptimismSuperchainERC20Beacon.sol +++ b/packages/contracts-bedrock/src/L2/OptimismSuperchainERC20Beacon.sol @@ -3,25 +3,19 @@ pragma solidity 0.8.15; import { IBeacon } from "@openzeppelin/contracts/proxy/beacon/IBeacon.sol"; import { ISemver } from "src/universal/interfaces/ISemver.sol"; +import { Predeploys } from "src/libraries/Predeploys.sol"; -/// @custom:proxied +/// @custom:proxied true /// @custom:predeployed 0x4200000000000000000000000000000000000027 /// @title OptimismSuperchainERC20Beacon /// @notice OptimismSuperchainERC20Beacon is the beacon proxy for the OptimismSuperchainERC20 implementation. contract OptimismSuperchainERC20Beacon is IBeacon, ISemver { - /// @notice Address of the OptimismSuperchainERC20 implementation. - address internal immutable IMPLEMENTATION; - /// @notice Semantic version. - /// @custom:semver 1.0.0-beta.1 - string public constant version = "1.0.0-beta.1"; - - constructor(address _implementation) { - IMPLEMENTATION = _implementation; - } + /// @custom:semver 1.0.0-beta.2 + string public constant version = "1.0.0-beta.2"; /// @inheritdoc IBeacon - function implementation() external view override returns (address) { - return IMPLEMENTATION; + function implementation() external pure override returns (address) { + return Predeploys.OPTIMISM_SUPERCHAIN_ERC20; } } diff --git a/packages/contracts-bedrock/src/L2/interfaces/IOptimismSuperchainERC20Beacon.sol b/packages/contracts-bedrock/src/L2/interfaces/IOptimismSuperchainERC20Beacon.sol index a0da4e5d230a..fccb56b715f8 100644 --- a/packages/contracts-bedrock/src/L2/interfaces/IOptimismSuperchainERC20Beacon.sol +++ b/packages/contracts-bedrock/src/L2/interfaces/IOptimismSuperchainERC20Beacon.sol @@ -1,14 +1,12 @@ // SPDX-License-Identifier: MIT pragma solidity ^0.8.0; -import { IBeacon } from "@openzeppelin/contracts/proxy/beacon/IBeacon.sol"; import { ISemver } from "src/universal/interfaces/ISemver.sol"; /// @title IOptimismSuperchainERC20Beacon /// @notice Interface for the OptimismSuperchainERC20Beacon contract -interface IOptimismSuperchainERC20Beacon is IBeacon, ISemver { - function version() external view returns (string memory); - function implementation() external view override returns (address); +interface IOptimismSuperchainERC20Beacon is ISemver { + function implementation() external pure returns (address); - function __constructor__(address _implementation) external; + function __constructor__() external; } diff --git a/packages/contracts-bedrock/test/L2/OptimismSuperchainERC20Beacon.t.sol b/packages/contracts-bedrock/test/L2/OptimismSuperchainERC20Beacon.t.sol new file mode 100644 index 000000000000..68217127e0cb --- /dev/null +++ b/packages/contracts-bedrock/test/L2/OptimismSuperchainERC20Beacon.t.sol @@ -0,0 +1,25 @@ +// SPDX-License-Identifier: MIT +pragma solidity 0.8.15; + +// Testing utilities +import { Bridge_Initializer } from "test/setup/Bridge_Initializer.sol"; + +// Libraries +import { Predeploys } from "src/libraries/Predeploys.sol"; +import { IBeacon } from "@openzeppelin/contracts/proxy/beacon/IBeacon.sol"; + +/// @title OptimismSuperchainERC20BeaconTest +/// @notice Contract for testing the OptimismSuperchainERC20Beacon contract. +contract OptimismSuperchainERC20BeaconTest is Bridge_Initializer { + /// @notice Sets up the test suite. + function setUp() public override { + super.enableInterop(); + super.setUp(); + } + + /// @notice Test that calling the implementation function returns the correct implementation address. + function test_implementation_is_correct() public view { + IBeacon beacon = IBeacon(Predeploys.OPTIMISM_SUPERCHAIN_ERC20_BEACON); + assertEq(beacon.implementation(), Predeploys.OPTIMISM_SUPERCHAIN_ERC20); + } +} diff --git a/packages/contracts-bedrock/test/L2/Predeploys.t.sol b/packages/contracts-bedrock/test/L2/Predeploys.t.sol index 5baa22534ecf..27e3d75b2fdc 100644 --- a/packages/contracts-bedrock/test/L2/Predeploys.t.sol +++ b/packages/contracts-bedrock/test/L2/Predeploys.t.sol @@ -31,7 +31,7 @@ contract PredeploysBaseTest is CommonTest { function _usesImmutables(address _addr) internal pure returns (bool) { return _addr == Predeploys.OPTIMISM_MINTABLE_ERC721_FACTORY || _addr == Predeploys.SEQUENCER_FEE_WALLET || _addr == Predeploys.BASE_FEE_VAULT || _addr == Predeploys.L1_FEE_VAULT || _addr == Predeploys.EAS - || _addr == Predeploys.GOVERNANCE_TOKEN || _addr == Predeploys.OPTIMISM_SUPERCHAIN_ERC20_BEACON; + || _addr == Predeploys.GOVERNANCE_TOKEN; } function test_predeployToCodeNamespace() external pure {