github.com/ethereum-optimism/optimism@v1.7.2/packages/contracts-bedrock/src/L1/L1StandardBridge.sol (about)

     1  // SPDX-License-Identifier: MIT
     2  pragma solidity 0.8.15;
     3  
     4  import { Predeploys } from "src/libraries/Predeploys.sol";
     5  import { StandardBridge } from "src/universal/StandardBridge.sol";
     6  import { ISemver } from "src/universal/ISemver.sol";
     7  import { CrossDomainMessenger } from "src/universal/CrossDomainMessenger.sol";
     8  import { SuperchainConfig } from "src/L1/SuperchainConfig.sol";
     9  import { Constants } from "src/libraries/Constants.sol";
    10  
    11  /// @custom:proxied
    12  /// @title L1StandardBridge
    13  /// @notice The L1StandardBridge is responsible for transfering ETH and ERC20 tokens between L1 and
    14  ///         L2. In the case that an ERC20 token is native to L1, it will be escrowed within this
    15  ///         contract. If the ERC20 token is native to L2, it will be burnt. Before Bedrock, ETH was
    16  ///         stored within this contract. After Bedrock, ETH is instead stored inside the
    17  ///         OptimismPortal contract.
    18  ///         NOTE: this contract is not intended to support all variations of ERC20 tokens. Examples
    19  ///         of some token types that may not be properly supported by this contract include, but are
    20  ///         not limited to: tokens with transfer fees, rebasing tokens, and tokens with blocklists.
    21  contract L1StandardBridge is StandardBridge, ISemver {
    22      /// @custom:legacy
    23      /// @notice Emitted whenever a deposit of ETH from L1 into L2 is initiated.
    24      /// @param from      Address of the depositor.
    25      /// @param to        Address of the recipient on L2.
    26      /// @param amount    Amount of ETH deposited.
    27      /// @param extraData Extra data attached to the deposit.
    28      event ETHDepositInitiated(address indexed from, address indexed to, uint256 amount, bytes extraData);
    29  
    30      /// @custom:legacy
    31      /// @notice Emitted whenever a withdrawal of ETH from L2 to L1 is finalized.
    32      /// @param from      Address of the withdrawer.
    33      /// @param to        Address of the recipient on L1.
    34      /// @param amount    Amount of ETH withdrawn.
    35      /// @param extraData Extra data attached to the withdrawal.
    36      event ETHWithdrawalFinalized(address indexed from, address indexed to, uint256 amount, bytes extraData);
    37  
    38      /// @custom:legacy
    39      /// @notice Emitted whenever an ERC20 deposit is initiated.
    40      /// @param l1Token   Address of the token on L1.
    41      /// @param l2Token   Address of the corresponding token on L2.
    42      /// @param from      Address of the depositor.
    43      /// @param to        Address of the recipient on L2.
    44      /// @param amount    Amount of the ERC20 deposited.
    45      /// @param extraData Extra data attached to the deposit.
    46      event ERC20DepositInitiated(
    47          address indexed l1Token,
    48          address indexed l2Token,
    49          address indexed from,
    50          address to,
    51          uint256 amount,
    52          bytes extraData
    53      );
    54  
    55      /// @custom:legacy
    56      /// @notice Emitted whenever an ERC20 withdrawal is finalized.
    57      /// @param l1Token   Address of the token on L1.
    58      /// @param l2Token   Address of the corresponding token on L2.
    59      /// @param from      Address of the withdrawer.
    60      /// @param to        Address of the recipient on L1.
    61      /// @param amount    Amount of the ERC20 withdrawn.
    62      /// @param extraData Extra data attached to the withdrawal.
    63      event ERC20WithdrawalFinalized(
    64          address indexed l1Token,
    65          address indexed l2Token,
    66          address indexed from,
    67          address to,
    68          uint256 amount,
    69          bytes extraData
    70      );
    71  
    72      /// @notice Semantic version.
    73      /// @custom:semver 2.1.0
    74      string public constant version = "2.1.0";
    75  
    76      /// @notice Address of the SuperchainConfig contract.
    77      SuperchainConfig public superchainConfig;
    78  
    79      /// @notice Constructs the L1StandardBridge contract.
    80      constructor() StandardBridge() {
    81          initialize({ _messenger: CrossDomainMessenger(address(0)), _superchainConfig: SuperchainConfig(address(0)) });
    82      }
    83  
    84      /// @notice Initializer.
    85      /// @param _messenger        Contract for the CrossDomainMessenger on this network.
    86      /// @param _superchainConfig Contract for the SuperchainConfig on this network.
    87      function initialize(CrossDomainMessenger _messenger, SuperchainConfig _superchainConfig) public initializer {
    88          superchainConfig = _superchainConfig;
    89          __StandardBridge_init({
    90              _messenger: _messenger,
    91              _otherBridge: StandardBridge(payable(Predeploys.L2_STANDARD_BRIDGE))
    92          });
    93      }
    94  
    95      /// @inheritdoc StandardBridge
    96      function paused() public view override returns (bool) {
    97          return superchainConfig.paused();
    98      }
    99  
   100      /// @notice Allows EOAs to bridge ETH by sending directly to the bridge.
   101      receive() external payable override onlyEOA {
   102          _initiateETHDeposit(msg.sender, msg.sender, RECEIVE_DEFAULT_GAS_LIMIT, bytes(""));
   103      }
   104  
   105      /// @custom:legacy
   106      /// @notice Deposits some amount of ETH into the sender's account on L2.
   107      /// @param _minGasLimit Minimum gas limit for the deposit message on L2.
   108      /// @param _extraData   Optional data to forward to L2.
   109      ///                     Data supplied here will not be used to execute any code on L2 and is
   110      ///                     only emitted as extra data for the convenience of off-chain tooling.
   111      function depositETH(uint32 _minGasLimit, bytes calldata _extraData) external payable onlyEOA {
   112          _initiateETHDeposit(msg.sender, msg.sender, _minGasLimit, _extraData);
   113      }
   114  
   115      /// @custom:legacy
   116      /// @notice Deposits some amount of ETH into a target account on L2.
   117      ///         Note that if ETH is sent to a contract on L2 and the call fails, then that ETH will
   118      ///         be locked in the L2StandardBridge. ETH may be recoverable if the call can be
   119      ///         successfully replayed by increasing the amount of gas supplied to the call. If the
   120      ///         call will fail for any amount of gas, then the ETH will be locked permanently.
   121      /// @param _to          Address of the recipient on L2.
   122      /// @param _minGasLimit Minimum gas limit for the deposit message on L2.
   123      /// @param _extraData   Optional data to forward to L2.
   124      ///                     Data supplied here will not be used to execute any code on L2 and is
   125      ///                     only emitted as extra data for the convenience of off-chain tooling.
   126      function depositETHTo(address _to, uint32 _minGasLimit, bytes calldata _extraData) external payable {
   127          _initiateETHDeposit(msg.sender, _to, _minGasLimit, _extraData);
   128      }
   129  
   130      /// @custom:legacy
   131      /// @notice Deposits some amount of ERC20 tokens into the sender's account on L2.
   132      /// @param _l1Token     Address of the L1 token being deposited.
   133      /// @param _l2Token     Address of the corresponding token on L2.
   134      /// @param _amount      Amount of the ERC20 to deposit.
   135      /// @param _minGasLimit Minimum gas limit for the deposit message on L2.
   136      /// @param _extraData   Optional data to forward to L2.
   137      ///                     Data supplied here will not be used to execute any code on L2 and is
   138      ///                     only emitted as extra data for the convenience of off-chain tooling.
   139      function depositERC20(
   140          address _l1Token,
   141          address _l2Token,
   142          uint256 _amount,
   143          uint32 _minGasLimit,
   144          bytes calldata _extraData
   145      )
   146          external
   147          virtual
   148          onlyEOA
   149      {
   150          _initiateERC20Deposit(_l1Token, _l2Token, msg.sender, msg.sender, _amount, _minGasLimit, _extraData);
   151      }
   152  
   153      /// @custom:legacy
   154      /// @notice Deposits some amount of ERC20 tokens into a target account on L2.
   155      /// @param _l1Token     Address of the L1 token being deposited.
   156      /// @param _l2Token     Address of the corresponding token on L2.
   157      /// @param _to          Address of the recipient on L2.
   158      /// @param _amount      Amount of the ERC20 to deposit.
   159      /// @param _minGasLimit Minimum gas limit for the deposit message on L2.
   160      /// @param _extraData   Optional data to forward to L2.
   161      ///                     Data supplied here will not be used to execute any code on L2 and is
   162      ///                     only emitted as extra data for the convenience of off-chain tooling.
   163      function depositERC20To(
   164          address _l1Token,
   165          address _l2Token,
   166          address _to,
   167          uint256 _amount,
   168          uint32 _minGasLimit,
   169          bytes calldata _extraData
   170      )
   171          external
   172          virtual
   173      {
   174          _initiateERC20Deposit(_l1Token, _l2Token, msg.sender, _to, _amount, _minGasLimit, _extraData);
   175      }
   176  
   177      /// @custom:legacy
   178      /// @notice Finalizes a withdrawal of ETH from L2.
   179      /// @param _from      Address of the withdrawer on L2.
   180      /// @param _to        Address of the recipient on L1.
   181      /// @param _amount    Amount of ETH to withdraw.
   182      /// @param _extraData Optional data forwarded from L2.
   183      function finalizeETHWithdrawal(
   184          address _from,
   185          address _to,
   186          uint256 _amount,
   187          bytes calldata _extraData
   188      )
   189          external
   190          payable
   191      {
   192          finalizeBridgeETH(_from, _to, _amount, _extraData);
   193      }
   194  
   195      /// @custom:legacy
   196      /// @notice Finalizes a withdrawal of ERC20 tokens from L2.
   197      /// @param _l1Token   Address of the token on L1.
   198      /// @param _l2Token   Address of the corresponding token on L2.
   199      /// @param _from      Address of the withdrawer on L2.
   200      /// @param _to        Address of the recipient on L1.
   201      /// @param _amount    Amount of the ERC20 to withdraw.
   202      /// @param _extraData Optional data forwarded from L2.
   203      function finalizeERC20Withdrawal(
   204          address _l1Token,
   205          address _l2Token,
   206          address _from,
   207          address _to,
   208          uint256 _amount,
   209          bytes calldata _extraData
   210      )
   211          external
   212      {
   213          finalizeBridgeERC20(_l1Token, _l2Token, _from, _to, _amount, _extraData);
   214      }
   215  
   216      /// @custom:legacy
   217      /// @notice Retrieves the access of the corresponding L2 bridge contract.
   218      /// @return Address of the corresponding L2 bridge contract.
   219      function l2TokenBridge() external view returns (address) {
   220          return address(otherBridge);
   221      }
   222  
   223      /// @notice Internal function for initiating an ETH deposit.
   224      /// @param _from        Address of the sender on L1.
   225      /// @param _to          Address of the recipient on L2.
   226      /// @param _minGasLimit Minimum gas limit for the deposit message on L2.
   227      /// @param _extraData   Optional data to forward to L2.
   228      function _initiateETHDeposit(address _from, address _to, uint32 _minGasLimit, bytes memory _extraData) internal {
   229          _initiateBridgeETH(_from, _to, msg.value, _minGasLimit, _extraData);
   230      }
   231  
   232      /// @notice Internal function for initiating an ERC20 deposit.
   233      /// @param _l1Token     Address of the L1 token being deposited.
   234      /// @param _l2Token     Address of the corresponding token on L2.
   235      /// @param _from        Address of the sender on L1.
   236      /// @param _to          Address of the recipient on L2.
   237      /// @param _amount      Amount of the ERC20 to deposit.
   238      /// @param _minGasLimit Minimum gas limit for the deposit message on L2.
   239      /// @param _extraData   Optional data to forward to L2.
   240      function _initiateERC20Deposit(
   241          address _l1Token,
   242          address _l2Token,
   243          address _from,
   244          address _to,
   245          uint256 _amount,
   246          uint32 _minGasLimit,
   247          bytes memory _extraData
   248      )
   249          internal
   250      {
   251          _initiateBridgeERC20(_l1Token, _l2Token, _from, _to, _amount, _minGasLimit, _extraData);
   252      }
   253  
   254      /// @inheritdoc StandardBridge
   255      /// @notice Emits the legacy ETHDepositInitiated event followed by the ETHBridgeInitiated event.
   256      ///         This is necessary for backwards compatibility with the legacy bridge.
   257      function _emitETHBridgeInitiated(
   258          address _from,
   259          address _to,
   260          uint256 _amount,
   261          bytes memory _extraData
   262      )
   263          internal
   264          override
   265      {
   266          emit ETHDepositInitiated(_from, _to, _amount, _extraData);
   267          super._emitETHBridgeInitiated(_from, _to, _amount, _extraData);
   268      }
   269  
   270      /// @inheritdoc StandardBridge
   271      /// @notice Emits the legacy ERC20DepositInitiated event followed by the ERC20BridgeInitiated
   272      ///         event. This is necessary for backwards compatibility with the legacy bridge.
   273      function _emitETHBridgeFinalized(
   274          address _from,
   275          address _to,
   276          uint256 _amount,
   277          bytes memory _extraData
   278      )
   279          internal
   280          override
   281      {
   282          emit ETHWithdrawalFinalized(_from, _to, _amount, _extraData);
   283          super._emitETHBridgeFinalized(_from, _to, _amount, _extraData);
   284      }
   285  
   286      /// @inheritdoc StandardBridge
   287      /// @notice Emits the legacy ERC20WithdrawalFinalized event followed by the ERC20BridgeFinalized
   288      ///         event. This is necessary for backwards compatibility with the legacy bridge.
   289      function _emitERC20BridgeInitiated(
   290          address _localToken,
   291          address _remoteToken,
   292          address _from,
   293          address _to,
   294          uint256 _amount,
   295          bytes memory _extraData
   296      )
   297          internal
   298          override
   299      {
   300          emit ERC20DepositInitiated(_localToken, _remoteToken, _from, _to, _amount, _extraData);
   301          super._emitERC20BridgeInitiated(_localToken, _remoteToken, _from, _to, _amount, _extraData);
   302      }
   303  
   304      /// @inheritdoc StandardBridge
   305      /// @notice Emits the legacy ERC20WithdrawalFinalized event followed by the ERC20BridgeFinalized
   306      ///         event. This is necessary for backwards compatibility with the legacy bridge.
   307      function _emitERC20BridgeFinalized(
   308          address _localToken,
   309          address _remoteToken,
   310          address _from,
   311          address _to,
   312          uint256 _amount,
   313          bytes memory _extraData
   314      )
   315          internal
   316          override
   317      {
   318          emit ERC20WithdrawalFinalized(_localToken, _remoteToken, _from, _to, _amount, _extraData);
   319          super._emitERC20BridgeFinalized(_localToken, _remoteToken, _from, _to, _amount, _extraData);
   320      }
   321  }