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

     1  // SPDX-License-Identifier: MIT
     2  pragma solidity ^0.8.0;
     3  
     4  import { Types } from "src/libraries/Types.sol";
     5  import { Hashing } from "src/libraries/Hashing.sol";
     6  import { RLPWriter } from "src/libraries/rlp/RLPWriter.sol";
     7  
     8  /// @title Encoding
     9  /// @notice Encoding handles Optimism's various different encoding schemes.
    10  library Encoding {
    11      /// @notice RLP encodes the L2 transaction that would be generated when a given deposit is sent
    12      ///         to the L2 system. Useful for searching for a deposit in the L2 system. The
    13      ///         transaction is prefixed with 0x7e to identify its EIP-2718 type.
    14      /// @param _tx User deposit transaction to encode.
    15      /// @return RLP encoded L2 deposit transaction.
    16      function encodeDepositTransaction(Types.UserDepositTransaction memory _tx) internal pure returns (bytes memory) {
    17          bytes32 source = Hashing.hashDepositSource(_tx.l1BlockHash, _tx.logIndex);
    18          bytes[] memory raw = new bytes[](8);
    19          raw[0] = RLPWriter.writeBytes(abi.encodePacked(source));
    20          raw[1] = RLPWriter.writeAddress(_tx.from);
    21          raw[2] = _tx.isCreation ? RLPWriter.writeBytes("") : RLPWriter.writeAddress(_tx.to);
    22          raw[3] = RLPWriter.writeUint(_tx.mint);
    23          raw[4] = RLPWriter.writeUint(_tx.value);
    24          raw[5] = RLPWriter.writeUint(uint256(_tx.gasLimit));
    25          raw[6] = RLPWriter.writeBool(false);
    26          raw[7] = RLPWriter.writeBytes(_tx.data);
    27          return abi.encodePacked(uint8(0x7e), RLPWriter.writeList(raw));
    28      }
    29  
    30      /// @notice Encodes the cross domain message based on the version that is encoded into the
    31      ///         message nonce.
    32      /// @param _nonce    Message nonce with version encoded into the first two bytes.
    33      /// @param _sender   Address of the sender of the message.
    34      /// @param _target   Address of the target of the message.
    35      /// @param _value    ETH value to send to the target.
    36      /// @param _gasLimit Gas limit to use for the message.
    37      /// @param _data     Data to send with the message.
    38      /// @return Encoded cross domain message.
    39      function encodeCrossDomainMessage(
    40          uint256 _nonce,
    41          address _sender,
    42          address _target,
    43          uint256 _value,
    44          uint256 _gasLimit,
    45          bytes memory _data
    46      )
    47          internal
    48          pure
    49          returns (bytes memory)
    50      {
    51          (, uint16 version) = decodeVersionedNonce(_nonce);
    52          if (version == 0) {
    53              return encodeCrossDomainMessageV0(_target, _sender, _data, _nonce);
    54          } else if (version == 1) {
    55              return encodeCrossDomainMessageV1(_nonce, _sender, _target, _value, _gasLimit, _data);
    56          } else {
    57              revert("Encoding: unknown cross domain message version");
    58          }
    59      }
    60  
    61      /// @notice Encodes a cross domain message based on the V0 (legacy) encoding.
    62      /// @param _target Address of the target of the message.
    63      /// @param _sender Address of the sender of the message.
    64      /// @param _data   Data to send with the message.
    65      /// @param _nonce  Message nonce.
    66      /// @return Encoded cross domain message.
    67      function encodeCrossDomainMessageV0(
    68          address _target,
    69          address _sender,
    70          bytes memory _data,
    71          uint256 _nonce
    72      )
    73          internal
    74          pure
    75          returns (bytes memory)
    76      {
    77          return abi.encodeWithSignature("relayMessage(address,address,bytes,uint256)", _target, _sender, _data, _nonce);
    78      }
    79  
    80      /// @notice Encodes a cross domain message based on the V1 (current) encoding.
    81      /// @param _nonce    Message nonce.
    82      /// @param _sender   Address of the sender of the message.
    83      /// @param _target   Address of the target of the message.
    84      /// @param _value    ETH value to send to the target.
    85      /// @param _gasLimit Gas limit to use for the message.
    86      /// @param _data     Data to send with the message.
    87      /// @return Encoded cross domain message.
    88      function encodeCrossDomainMessageV1(
    89          uint256 _nonce,
    90          address _sender,
    91          address _target,
    92          uint256 _value,
    93          uint256 _gasLimit,
    94          bytes memory _data
    95      )
    96          internal
    97          pure
    98          returns (bytes memory)
    99      {
   100          return abi.encodeWithSignature(
   101              "relayMessage(uint256,address,address,uint256,uint256,bytes)",
   102              _nonce,
   103              _sender,
   104              _target,
   105              _value,
   106              _gasLimit,
   107              _data
   108          );
   109      }
   110  
   111      /// @notice Adds a version number into the first two bytes of a message nonce.
   112      /// @param _nonce   Message nonce to encode into.
   113      /// @param _version Version number to encode into the message nonce.
   114      /// @return Message nonce with version encoded into the first two bytes.
   115      function encodeVersionedNonce(uint240 _nonce, uint16 _version) internal pure returns (uint256) {
   116          uint256 nonce;
   117          assembly {
   118              nonce := or(shl(240, _version), _nonce)
   119          }
   120          return nonce;
   121      }
   122  
   123      /// @notice Pulls the version out of a version-encoded nonce.
   124      /// @param _nonce Message nonce with version encoded into the first two bytes.
   125      /// @return Nonce without encoded version.
   126      /// @return Version of the message.
   127      function decodeVersionedNonce(uint256 _nonce) internal pure returns (uint240, uint16) {
   128          uint240 nonce;
   129          uint16 version;
   130          assembly {
   131              nonce := and(_nonce, 0x0000ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff)
   132              version := shr(240, _nonce)
   133          }
   134          return (nonce, version);
   135      }
   136  
   137      /// @notice Returns an appropriately encoded call to L1Block.setL1BlockValuesEcotone
   138      /// @param baseFeeScalar       L1 base fee Scalar
   139      /// @param blobBaseFeeScalar   L1 blob base fee Scalar
   140      /// @param sequenceNumber      Number of L2 blocks since epoch start.
   141      /// @param timestamp           L1 timestamp.
   142      /// @param number              L1 blocknumber.
   143      /// @param baseFee             L1 base fee.
   144      /// @param blobBaseFee         L1 blob base fee.
   145      /// @param hash                L1 blockhash.
   146      /// @param batcherHash         Versioned hash to authenticate batcher by.
   147      function encodeSetL1BlockValuesEcotone(
   148          uint32 baseFeeScalar,
   149          uint32 blobBaseFeeScalar,
   150          uint64 sequenceNumber,
   151          uint64 timestamp,
   152          uint64 number,
   153          uint256 baseFee,
   154          uint256 blobBaseFee,
   155          bytes32 hash,
   156          bytes32 batcherHash
   157      )
   158          internal
   159          pure
   160          returns (bytes memory)
   161      {
   162          bytes4 functionSignature = bytes4(keccak256("setL1BlockValuesEcotone()"));
   163          return abi.encodePacked(
   164              functionSignature,
   165              baseFeeScalar,
   166              blobBaseFeeScalar,
   167              sequenceNumber,
   168              timestamp,
   169              number,
   170              baseFee,
   171              blobBaseFee,
   172              hash,
   173              batcherHash
   174          );
   175      }
   176  }