Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 5 additions & 5 deletions packages/contracts-bedrock/semver-lock.json
Original file line number Diff line number Diff line change
Expand Up @@ -108,8 +108,8 @@
"sourceCodeHash": "0xfea53344596d735eff3be945ed1300dc75a6f8b7b2c02c0043af5b0036f5f239"
},
"src/L2/OptimismSuperchainERC20.sol": {
"initCodeHash": "0xadeaebb33c1d758d88d7aadd0ad654c9a1f2d59824c5dad19e1d9cf05ea3e516",
"sourceCodeHash": "0xacf5ca4cdebd7e1d52f691db0f873cc026c6336a9ea309af1364a46aba723180"
"initCodeHash": "0x63af128879e18ba6877e36d587b366f1a3c7fceafacde2197e658e1f3fbadd50",
"sourceCodeHash": "0xf32130f0b46333daba062c50ff6dcfadce1f177ff753bed2374d499ea9c2d98a"
},
"src/L2/OptimismSuperchainERC20Beacon.sol": {
"initCodeHash": "0x99ce8095b23c124850d866cbc144fee6cee05dbc6bb5d83acadfe00b90cf42c7",
Expand All @@ -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",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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"
},
{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -150,12 +150,12 @@
},
{
"inputs": [],
"name": "CallerNotL2ToL2CrossDomainMessenger",
"name": "InvalidCrossDomainSender",
"type": "error"
},
{
"inputs": [],
"name": "InvalidCrossDomainSender",
"name": "Unauthorized",
"type": "error"
},
{
Expand Down
9 changes: 2 additions & 7 deletions packages/contracts-bedrock/src/L2/OptimismSuperchainERC20.sol
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand All @@ -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.
Expand Down Expand Up @@ -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();
_;
}

Expand Down
6 changes: 2 additions & 4 deletions packages/contracts-bedrock/src/L2/SuperchainERC20.sol
Original file line number Diff line number Diff line change
Expand Up @@ -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();
_;
}

Expand Down
8 changes: 2 additions & 6 deletions packages/contracts-bedrock/src/L2/SuperchainTokenBridge.sol
Original file line number Diff line number Diff line change
Expand Up @@ -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";
Expand All @@ -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();
Expand Down Expand Up @@ -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();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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);

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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;
}
Original file line number Diff line number Diff line change
Expand Up @@ -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(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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";
Expand Down Expand Up @@ -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);
Expand Down Expand Up @@ -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);
Expand Down
8 changes: 4 additions & 4 deletions packages/contracts-bedrock/test/L2/SuperchainERC20.t.sol
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand Down Expand Up @@ -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);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand Down