diff --git a/packages/contracts-bedrock/semver-lock.json b/packages/contracts-bedrock/semver-lock.json index 3c521b63ffab..7759e105d105 100644 --- a/packages/contracts-bedrock/semver-lock.json +++ b/packages/contracts-bedrock/semver-lock.json @@ -108,8 +108,8 @@ "sourceCodeHash": "0xfea53344596d735eff3be945ed1300dc75a6f8b7b2c02c0043af5b0036f5f239" }, "src/L2/OptimismSuperchainERC20.sol": { - "initCodeHash": "0xadeaebb33c1d758d88d7aadd0ad654c9a1f2d59824c5dad19e1d9cf05ea3e516", - "sourceCodeHash": "0xacf5ca4cdebd7e1d52f691db0f873cc026c6336a9ea309af1364a46aba723180" + "initCodeHash": "0x63af128879e18ba6877e36d587b366f1a3c7fceafacde2197e658e1f3fbadd50", + "sourceCodeHash": "0xf32130f0b46333daba062c50ff6dcfadce1f177ff753bed2374d499ea9c2d98a" }, "src/L2/OptimismSuperchainERC20Beacon.sol": { "initCodeHash": "0x99ce8095b23c124850d866cbc144fee6cee05dbc6bb5d83acadfe00b90cf42c7", @@ -125,11 +125,11 @@ }, "src/L2/SuperchainERC20.sol": { "initCodeHash": "0xc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470", - "sourceCodeHash": "0x19f598d3b3e77963f9af395b0102dd9acea0e76f7a0ed6eb937d94d3c054137e" + "sourceCodeHash": "0x3dc9534bbadfa01ad9a2d414adf76c2562b2319c33f74cbae7860b48d023aedf" }, "src/L2/SuperchainTokenBridge.sol": { - "initCodeHash": "0xfeba60d8e17a0c62cc56c7319da323e154ccc6c379e7b72c48c9d0ce1e5b9474", - "sourceCodeHash": "0x7f718c438e8289696fc92d61be612e53e5c5b17f432d109397248e5385076aaa" + "initCodeHash": "0x501741478992b7d97c245674f1ad326f0e09b4b1bb595675d6c1c066f44af424", + "sourceCodeHash": "0x48cf6ba2e53f86345840948c271672489f3fdb484e4ea2c26f94295fdf98bbd8" }, "src/L2/SuperchainWETH.sol": { "initCodeHash": "0x50f6ea9bfe650fcf792e98e44b1bf66c036fd0e6d4b753da680253d7d8609816", diff --git a/packages/contracts-bedrock/snapshots/abi/OptimismSuperchainERC20.json b/packages/contracts-bedrock/snapshots/abi/OptimismSuperchainERC20.json index d2e66cf3a057..af1524b311f4 100644 --- a/packages/contracts-bedrock/snapshots/abi/OptimismSuperchainERC20.json +++ b/packages/contracts-bedrock/snapshots/abi/OptimismSuperchainERC20.json @@ -572,22 +572,17 @@ }, { "inputs": [], - "name": "OnlyL2StandardBridge", - "type": "error" - }, - { - "inputs": [], - "name": "OnlySuperchainTokenBridge", + "name": "PermitExpired", "type": "error" }, { "inputs": [], - "name": "PermitExpired", + "name": "TotalSupplyOverflow", "type": "error" }, { "inputs": [], - "name": "TotalSupplyOverflow", + "name": "Unauthorized", "type": "error" }, { diff --git a/packages/contracts-bedrock/snapshots/abi/SuperchainTokenBridge.json b/packages/contracts-bedrock/snapshots/abi/SuperchainTokenBridge.json index 1eec16f60e3d..36358db1b307 100644 --- a/packages/contracts-bedrock/snapshots/abi/SuperchainTokenBridge.json +++ b/packages/contracts-bedrock/snapshots/abi/SuperchainTokenBridge.json @@ -150,12 +150,12 @@ }, { "inputs": [], - "name": "CallerNotL2ToL2CrossDomainMessenger", + "name": "InvalidCrossDomainSender", "type": "error" }, { "inputs": [], - "name": "InvalidCrossDomainSender", + "name": "Unauthorized", "type": "error" }, { diff --git a/packages/contracts-bedrock/src/L2/OptimismSuperchainERC20.sol b/packages/contracts-bedrock/src/L2/OptimismSuperchainERC20.sol index 6d51f8c094d4..6e8ef9057325 100644 --- a/packages/contracts-bedrock/src/L2/OptimismSuperchainERC20.sol +++ b/packages/contracts-bedrock/src/L2/OptimismSuperchainERC20.sol @@ -6,7 +6,7 @@ import { Predeploys } from "src/libraries/Predeploys.sol"; import { ERC165 } from "@openzeppelin/contracts-v5/utils/introspection/ERC165.sol"; import { SuperchainERC20 } from "src/L2/SuperchainERC20.sol"; import { Initializable } from "@openzeppelin/contracts-v5/proxy/utils/Initializable.sol"; -import { ZeroAddress } from "src/libraries/errors/CommonErrors.sol"; +import { ZeroAddress, Unauthorized } from "src/libraries/errors/CommonErrors.sol"; /// @custom:proxied true /// @title OptimismSuperchainERC20 @@ -17,9 +17,6 @@ import { ZeroAddress } from "src/libraries/errors/CommonErrors.sol"; /// also enables the inverse conversion path. /// Moreover, it builds on top of the L2ToL2CrossDomainMessenger for both replay protection and domain binding. contract OptimismSuperchainERC20 is SuperchainERC20, Initializable, ERC165 { - /// @notice Thrown when attempting to mint or burn tokens and the function caller is not the L2StandardBridge - error OnlyL2StandardBridge(); - /// @notice Emitted whenever tokens are minted for an account. /// @param to Address of the account tokens are being minted for. /// @param amount Amount of tokens minted. @@ -57,9 +54,7 @@ contract OptimismSuperchainERC20 is SuperchainERC20, Initializable, ERC165 { /// @notice A modifier that only allows the L2StandardBridge to call modifier onlyL2StandardBridge() { - if (msg.sender != Predeploys.L2_STANDARD_BRIDGE) { - revert OnlyL2StandardBridge(); - } + if (msg.sender != Predeploys.L2_STANDARD_BRIDGE) revert Unauthorized(); _; } diff --git a/packages/contracts-bedrock/src/L2/SuperchainERC20.sol b/packages/contracts-bedrock/src/L2/SuperchainERC20.sol index e55f4e9a2012..629155a847d7 100644 --- a/packages/contracts-bedrock/src/L2/SuperchainERC20.sol +++ b/packages/contracts-bedrock/src/L2/SuperchainERC20.sol @@ -5,18 +5,16 @@ import { ICrosschainERC20 } from "src/L2/interfaces/ICrosschainERC20.sol"; import { ISemver } from "src/universal/interfaces/ISemver.sol"; import { Predeploys } from "src/libraries/Predeploys.sol"; import { ERC20 } from "@solady/tokens/ERC20.sol"; +import { Unauthorized } from "src/libraries/errors/CommonErrors.sol"; /// @title SuperchainERC20 /// @notice SuperchainERC20 is a standard extension of the base ERC20 token contract that unifies ERC20 token /// bridging to make it fungible across the Superchain. This construction allows the SuperchainTokenBridge to /// burn and mint tokens. abstract contract SuperchainERC20 is ERC20, ICrosschainERC20, ISemver { - /// @notice Thrown when attempting to mint or burn tokens and the function caller is not the SuperchainTokenBridge. - error OnlySuperchainTokenBridge(); - /// @notice A modifier that only allows the SuperchainTokenBridge to call modifier onlySuperchainTokenBridge() { - if (msg.sender != Predeploys.SUPERCHAIN_TOKEN_BRIDGE) revert OnlySuperchainTokenBridge(); + if (msg.sender != Predeploys.SUPERCHAIN_TOKEN_BRIDGE) revert Unauthorized(); _; } diff --git a/packages/contracts-bedrock/src/L2/SuperchainTokenBridge.sol b/packages/contracts-bedrock/src/L2/SuperchainTokenBridge.sol index 49e2fa8a7eca..dd5c464e4bd4 100644 --- a/packages/contracts-bedrock/src/L2/SuperchainTokenBridge.sol +++ b/packages/contracts-bedrock/src/L2/SuperchainTokenBridge.sol @@ -3,7 +3,7 @@ pragma solidity 0.8.25; // Libraries import { Predeploys } from "src/libraries/Predeploys.sol"; -import { ZeroAddress } from "src/libraries/errors/CommonErrors.sol"; +import { ZeroAddress, Unauthorized } from "src/libraries/errors/CommonErrors.sol"; // Interfaces import { ISuperchainERC20 } from "src/L2/interfaces/ISuperchainERC20.sol"; @@ -16,10 +16,6 @@ import { IL2ToL2CrossDomainMessenger } from "src/L2/interfaces/IL2ToL2CrossDomai /// Superchain. It builds on top of the L2ToL2CrossDomainMessenger for both replay protection and domain /// binding. contract SuperchainTokenBridge { - /// @notice Thrown when attempting to relay a message and the function caller (msg.sender) is not - /// L2ToL2CrossDomainMessenger. - error CallerNotL2ToL2CrossDomainMessenger(); - /// @notice Thrown when attempting to relay a message and the cross domain message sender is not the /// SuperchainTokenBridge. error InvalidCrossDomainSender(); @@ -82,7 +78,7 @@ contract SuperchainTokenBridge { /// @param _to Address to relay tokens to. /// @param _amount Amount of tokens to relay. function relayERC20(address _token, address _from, address _to, uint256 _amount) external { - if (msg.sender != MESSENGER) revert CallerNotL2ToL2CrossDomainMessenger(); + if (msg.sender != MESSENGER) revert Unauthorized(); if (IL2ToL2CrossDomainMessenger(MESSENGER).crossDomainMessageSender() != address(this)) { revert InvalidCrossDomainSender(); diff --git a/packages/contracts-bedrock/src/L2/interfaces/IOptimismSuperchainERC20.sol b/packages/contracts-bedrock/src/L2/interfaces/IOptimismSuperchainERC20.sol index f59ffa069a52..a5334ece1fd4 100644 --- a/packages/contracts-bedrock/src/L2/interfaces/IOptimismSuperchainERC20.sol +++ b/packages/contracts-bedrock/src/L2/interfaces/IOptimismSuperchainERC20.sol @@ -8,7 +8,6 @@ import { ISuperchainERC20 } from "src/L2/interfaces/ISuperchainERC20.sol"; /// @notice This interface is available on the OptimismSuperchainERC20 contract. interface IOptimismSuperchainERC20 is ISuperchainERC20 { error ZeroAddress(); - error OnlyL2StandardBridge(); event Mint(address indexed to, uint256 amount); diff --git a/packages/contracts-bedrock/src/L2/interfaces/ISuperchainERC20.sol b/packages/contracts-bedrock/src/L2/interfaces/ISuperchainERC20.sol index ceca21546919..4aad888535a7 100644 --- a/packages/contracts-bedrock/src/L2/interfaces/ISuperchainERC20.sol +++ b/packages/contracts-bedrock/src/L2/interfaces/ISuperchainERC20.sol @@ -8,8 +8,9 @@ import { ISemver } from "src/universal/interfaces/ISemver.sol"; /// @title ISuperchainERC20 /// @notice This interface is available on the SuperchainERC20 contract. +/// @dev This interface is needed for the abstract SuperchainERC20 implementation but is not part of the standard interface ISuperchainERC20 is ICrosschainERC20, IERC20Solady, ISemver { - error OnlySuperchainTokenBridge(); + error Unauthorized(); function __constructor__() external; } diff --git a/packages/contracts-bedrock/src/L2/interfaces/ISuperchainTokenBridge.sol b/packages/contracts-bedrock/src/L2/interfaces/ISuperchainTokenBridge.sol index a99d188d1c55..f2a61d02d555 100644 --- a/packages/contracts-bedrock/src/L2/interfaces/ISuperchainTokenBridge.sol +++ b/packages/contracts-bedrock/src/L2/interfaces/ISuperchainTokenBridge.sol @@ -7,7 +7,7 @@ import { ISemver } from "src/universal/interfaces/ISemver.sol"; /// @notice Interface for the SuperchainTokenBridge contract. interface ISuperchainTokenBridge is ISemver { error ZeroAddress(); - error CallerNotL2ToL2CrossDomainMessenger(); + error Unauthorized(); error InvalidCrossDomainSender(); event SendERC20( diff --git a/packages/contracts-bedrock/test/L2/OptimismSuperchainERC20.t.sol b/packages/contracts-bedrock/test/L2/OptimismSuperchainERC20.t.sol index 0213cb0c0a1d..87d5cbb74b23 100644 --- a/packages/contracts-bedrock/test/L2/OptimismSuperchainERC20.t.sol +++ b/packages/contracts-bedrock/test/L2/OptimismSuperchainERC20.t.sol @@ -12,6 +12,7 @@ import { Initializable } from "@openzeppelin/contracts-v5/proxy/utils/Initializa import { IERC165 } from "@openzeppelin/contracts-v5/utils/introspection/IERC165.sol"; import { IBeacon } from "@openzeppelin/contracts-v5/proxy/beacon/IBeacon.sol"; import { BeaconProxy } from "@openzeppelin/contracts-v5/proxy/beacon/BeaconProxy.sol"; +import { Unauthorized } from "src/libraries/errors/CommonErrors.sol"; // Target contract import { OptimismSuperchainERC20 } from "src/L2/OptimismSuperchainERC20.sol"; @@ -117,8 +118,8 @@ contract OptimismSuperchainERC20Test is Test { // Ensure the caller is not the bridge vm.assume(_caller != L2_BRIDGE); - // Expect the revert with `OnlyL2StandardBridge` selector - vm.expectRevert(IOptimismSuperchainERC20.OnlyL2StandardBridge.selector); + // Expect the revert with `Unauthorized` selector + vm.expectRevert(Unauthorized.selector); // Call the `mint` function with the non-bridge caller vm.prank(_caller); @@ -166,8 +167,8 @@ contract OptimismSuperchainERC20Test is Test { // Ensure the caller is not the bridge vm.assume(_caller != L2_BRIDGE); - // Expect the revert with `OnlyL2StandardBridge` selector - vm.expectRevert(IOptimismSuperchainERC20.OnlyL2StandardBridge.selector); + // Expect the revert with `Unauthorized` selector + vm.expectRevert(Unauthorized.selector); // Call the `burn` function with the non-bridge caller vm.prank(_caller); diff --git a/packages/contracts-bedrock/test/L2/SuperchainERC20.t.sol b/packages/contracts-bedrock/test/L2/SuperchainERC20.t.sol index 7ccde9c51a3b..399938349c69 100644 --- a/packages/contracts-bedrock/test/L2/SuperchainERC20.t.sol +++ b/packages/contracts-bedrock/test/L2/SuperchainERC20.t.sol @@ -39,8 +39,8 @@ contract SuperchainERC20Test is Test { // Ensure the caller is not the bridge vm.assume(_caller != SUPERCHAIN_TOKEN_BRIDGE); - // Expect the revert with `OnlySuperchainTokenBridge` selector - vm.expectRevert(ISuperchainERC20.OnlySuperchainTokenBridge.selector); + // Expect the revert with `Unauthorized` selector + vm.expectRevert(ISuperchainERC20.Unauthorized.selector); // Call the `mint` function with the non-bridge caller vm.prank(_caller); @@ -84,8 +84,8 @@ contract SuperchainERC20Test is Test { // Ensure the caller is not the bridge vm.assume(_caller != SUPERCHAIN_TOKEN_BRIDGE); - // Expect the revert with `OnlySuperchainTokenBridge` selector - vm.expectRevert(ISuperchainERC20.OnlySuperchainTokenBridge.selector); + // Expect the revert with `Unauthorized` selector + vm.expectRevert(ISuperchainERC20.Unauthorized.selector); // Call the `burn` function with the non-bridge caller vm.prank(_caller); diff --git a/packages/contracts-bedrock/test/L2/SuperchainTokenBridge.t.sol b/packages/contracts-bedrock/test/L2/SuperchainTokenBridge.t.sol index 37f8e4b7e567..8aa533558fe5 100644 --- a/packages/contracts-bedrock/test/L2/SuperchainTokenBridge.t.sol +++ b/packages/contracts-bedrock/test/L2/SuperchainTokenBridge.t.sol @@ -126,8 +126,8 @@ contract SuperchainTokenBridgeTest is Bridge_Initializer { // Ensure the caller is not the messenger vm.assume(_caller != Predeploys.L2_TO_L2_CROSS_DOMAIN_MESSENGER); - // Expect the revert with `CallerNotL2ToL2CrossDomainMessenger` selector - vm.expectRevert(ISuperchainTokenBridge.CallerNotL2ToL2CrossDomainMessenger.selector); + // Expect the revert with `Unauthorized` selector + vm.expectRevert(ISuperchainTokenBridge.Unauthorized.selector); // Call the `relayERC20` function with the non-messenger caller vm.prank(_caller);