ETH Price: $3,251.98 (+4.39%)
Gas: 2 Gwei

Contract

0x370D05C1F7e88312056bF2df462976219CA0FED4
 

Overview

ETH Balance

0 ETH

Eth Value

$0.00

Multichain Info

No addresses found
Transaction Hash
Method
Block
From
To
0x60808060195835042024-04-04 16:11:47113 days ago1712247107IN
 Create: TransceiverStructs
0 ETH0.0931159478.18410792

View more zero value Internal Transactions in Advanced View mode

Advanced mode:
Loading...
Loading

Contract Source Code Verified (Exact Match)

Contract Name:
TransceiverStructs

Compiler Version
v0.8.19+commit.7dd6d404

Optimization Enabled:
Yes with 200 runs

Other Settings:
london EvmVersion
File 1 of 4 : TransceiverStructs.sol
// SPDX-License-Identifier: Apache 2
pragma solidity >=0.8.8 <0.9.0;

import "wormhole-solidity-sdk/libraries/BytesParsing.sol";
import "./TrimmedAmount.sol";

library TransceiverStructs {
    using BytesParsing for bytes;
    using TrimmedAmountLib for TrimmedAmount;

    /// @notice Error thrown when the payload length exceeds the allowed maximum.
    /// @dev Selector 0xa3419691.
    /// @param size The size of the payload.
    error PayloadTooLong(uint256 size);

    /// @notice Error thrown when the prefix of an encoded message
    ///         does not match the expected value.
    /// @dev Selector 0x56d2569d.
    /// @param prefix The prefix that was found in the encoded message.
    error IncorrectPrefix(bytes4 prefix);

    /// @notice Error thrown when the transceiver instructions aren't
    ///         encoded with strictly increasing indices
    /// @dev Selector 0x0555a4b9.
    /// @param lastIndex Last parsed instruction index
    /// @param instructionIndex The instruction index that was unordered
    error UnorderedInstructions(uint256 lastIndex, uint256 instructionIndex);

    /// @notice Error thrown when a transceiver instruction index
    ///         is greater than the number of registered transceivers
    /// @dev We index from 0 so if providedIndex == numTransceivers then we're out-of-bounds too
    /// @dev Selector 0x689f5016.
    /// @param providedIndex The index specified in the instruction
    /// @param numTransceivers The number of registered transceivers
    error InvalidInstructionIndex(uint256 providedIndex, uint256 numTransceivers);

    /// @dev Prefix for all NativeTokenTransfer payloads
    ///      This is 0x99'N''T''T'
    bytes4 constant NTT_PREFIX = 0x994E5454;

    /// @dev Message emitted and received by the nttManager contract.
    ///      The wire format is as follows:
    ///      - id - 32 bytes
    ///      - sender - 32 bytes
    ///      - payloadLength - 2 bytes
    ///      - payload - `payloadLength` bytes
    struct NttManagerMessage {
        /// @notice unique message identifier
        /// @dev This is incrementally assigned on EVM chains, but this is not
        /// guaranteed on other runtimes.
        bytes32 id;
        /// @notice original message sender address.
        bytes32 sender;
        /// @notice payload that corresponds to the type.
        bytes payload;
    }

    function nttManagerMessageDigest(
        uint16 sourceChainId,
        NttManagerMessage memory m
    ) public pure returns (bytes32) {
        return keccak256(abi.encodePacked(sourceChainId, encodeNttManagerMessage(m)));
    }

    function encodeNttManagerMessage(NttManagerMessage memory m)
        public
        pure
        returns (bytes memory encoded)
    {
        if (m.payload.length > type(uint16).max) {
            revert PayloadTooLong(m.payload.length);
        }
        uint16 payloadLength = uint16(m.payload.length);
        return abi.encodePacked(m.id, m.sender, payloadLength, m.payload);
    }

    /// @notice Parse a NttManagerMessage.
    /// @param encoded The byte array corresponding to the encoded message
    /// @return nttManagerMessage The parsed NttManagerMessage struct.
    function parseNttManagerMessage(bytes memory encoded)
        public
        pure
        returns (NttManagerMessage memory nttManagerMessage)
    {
        uint256 offset = 0;
        (nttManagerMessage.id, offset) = encoded.asBytes32Unchecked(offset);
        (nttManagerMessage.sender, offset) = encoded.asBytes32Unchecked(offset);
        uint256 payloadLength;
        (payloadLength, offset) = encoded.asUint16Unchecked(offset);
        (nttManagerMessage.payload, offset) = encoded.sliceUnchecked(offset, payloadLength);
        encoded.checkLength(offset);
    }

    /// @dev Native Token Transfer payload.
    ///      The wire format is as follows:
    ///      - NTT_PREFIX - 4 bytes
    ///      - numDecimals - 1 byte
    ///      - amount - 8 bytes
    ///      - sourceToken - 32 bytes
    ///      - to - 32 bytes
    ///      - toChain - 2 bytes
    struct NativeTokenTransfer {
        /// @notice Amount being transferred (big-endian u64 and u8 for decimals)
        TrimmedAmount amount;
        /// @notice Source chain token address.
        bytes32 sourceToken;
        /// @notice Address of the recipient.
        bytes32 to;
        /// @notice Chain ID of the recipient
        uint16 toChain;
    }

    function encodeNativeTokenTransfer(NativeTokenTransfer memory m)
        public
        pure
        returns (bytes memory encoded)
    {
        // The `amount` and `decimals` fields are encoded in reverse order compared to how they are declared in the
        // `TrimmedAmount` type. This is consistent with the Rust NTT implementation.
        TrimmedAmount transferAmount = m.amount;
        return abi.encodePacked(
            NTT_PREFIX,
            transferAmount.getDecimals(),
            transferAmount.getAmount(),
            m.sourceToken,
            m.to,
            m.toChain
        );
    }

    /// @dev Parse a NativeTokenTransfer.
    /// @param encoded The byte array corresponding to the encoded message
    /// @return nativeTokenTransfer The parsed NativeTokenTransfer struct.
    function parseNativeTokenTransfer(bytes memory encoded)
        public
        pure
        returns (NativeTokenTransfer memory nativeTokenTransfer)
    {
        uint256 offset = 0;
        bytes4 prefix;
        (prefix, offset) = encoded.asBytes4Unchecked(offset);
        if (prefix != NTT_PREFIX) {
            revert IncorrectPrefix(prefix);
        }

        // The `amount` and `decimals` fields are parsed in reverse order compared to how they are declared in the
        // `TrimmedAmount` struct. This is consistent with the Rust NTT implementation.
        uint8 numDecimals;
        (numDecimals, offset) = encoded.asUint8Unchecked(offset);
        uint64 amount;
        (amount, offset) = encoded.asUint64Unchecked(offset);
        nativeTokenTransfer.amount = packTrimmedAmount(amount, numDecimals);

        (nativeTokenTransfer.sourceToken, offset) = encoded.asBytes32Unchecked(offset);
        (nativeTokenTransfer.to, offset) = encoded.asBytes32Unchecked(offset);
        (nativeTokenTransfer.toChain, offset) = encoded.asUint16Unchecked(offset);
        encoded.checkLength(offset);
    }

    /// @dev Message emitted by Transceiver implementations.
    ///      Each message includes an Transceiver-specified 4-byte prefix.
    ///      The wire format is as follows:
    ///      - prefix - 4 bytes
    ///      - sourceNttManagerAddress - 32 bytes
    ///      - recipientNttManagerAddress - 32 bytes
    ///      - nttManagerPayloadLength - 2 bytes
    ///      - nttManagerPayload - `nttManagerPayloadLength` bytes
    ///      - transceiverPayloadLength - 2 bytes
    ///      - transceiverPayload - `transceiverPayloadLength` bytes
    struct TransceiverMessage {
        /// @notice Address of the NttManager contract that emitted this message.
        bytes32 sourceNttManagerAddress;
        /// @notice Address of the NttManager contract that receives this message.
        bytes32 recipientNttManagerAddress;
        /// @notice Payload provided to the Transceiver contract by the NttManager contract.
        bytes nttManagerPayload;
        /// @notice Optional payload that the transceiver can encode and use for its own message passing purposes.
        bytes transceiverPayload;
    }

    // @notice Encodes an Transceiver message for communication between the
    //         NttManager and the Transceiver.
    // @param m The TransceiverMessage struct containing the message details.
    // @return encoded The byte array corresponding to the encoded message.
    // @custom:throw PayloadTooLong if the length of transceiverId, nttManagerPayload,
    //         or transceiverPayload exceeds the allowed maximum.
    function encodeTransceiverMessage(
        bytes4 prefix,
        TransceiverMessage memory m
    ) public pure returns (bytes memory encoded) {
        if (m.nttManagerPayload.length > type(uint16).max) {
            revert PayloadTooLong(m.nttManagerPayload.length);
        }
        uint16 nttManagerPayloadLength = uint16(m.nttManagerPayload.length);

        if (m.transceiverPayload.length > type(uint16).max) {
            revert PayloadTooLong(m.transceiverPayload.length);
        }
        uint16 transceiverPayloadLength = uint16(m.transceiverPayload.length);

        return abi.encodePacked(
            prefix,
            m.sourceNttManagerAddress,
            m.recipientNttManagerAddress,
            nttManagerPayloadLength,
            m.nttManagerPayload,
            transceiverPayloadLength,
            m.transceiverPayload
        );
    }

    function buildAndEncodeTransceiverMessage(
        bytes4 prefix,
        bytes32 sourceNttManagerAddress,
        bytes32 recipientNttManagerAddress,
        bytes memory nttManagerMessage,
        bytes memory transceiverPayload
    ) public pure returns (TransceiverMessage memory, bytes memory) {
        TransceiverMessage memory transceiverMessage = TransceiverMessage({
            sourceNttManagerAddress: sourceNttManagerAddress,
            recipientNttManagerAddress: recipientNttManagerAddress,
            nttManagerPayload: nttManagerMessage,
            transceiverPayload: transceiverPayload
        });
        bytes memory encoded = encodeTransceiverMessage(prefix, transceiverMessage);
        return (transceiverMessage, encoded);
    }

    /// @dev Parses an encoded message and extracts information into an TransceiverMessage struct.
    /// @param encoded The encoded bytes containing information about the TransceiverMessage.
    /// @return transceiverMessage The parsed TransceiverMessage struct.
    /// @custom:throw IncorrectPrefix if the prefix of the encoded message does not
    ///         match the expected prefix.
    function parseTransceiverMessage(
        bytes4 expectedPrefix,
        bytes memory encoded
    ) internal pure returns (TransceiverMessage memory transceiverMessage) {
        uint256 offset = 0;
        bytes4 prefix;

        (prefix, offset) = encoded.asBytes4Unchecked(offset);

        if (prefix != expectedPrefix) {
            revert IncorrectPrefix(prefix);
        }

        (transceiverMessage.sourceNttManagerAddress, offset) = encoded.asBytes32Unchecked(offset);
        (transceiverMessage.recipientNttManagerAddress, offset) = encoded.asBytes32Unchecked(offset);
        uint16 nttManagerPayloadLength;
        (nttManagerPayloadLength, offset) = encoded.asUint16Unchecked(offset);
        (transceiverMessage.nttManagerPayload, offset) =
            encoded.sliceUnchecked(offset, nttManagerPayloadLength);
        uint16 transceiverPayloadLength;
        (transceiverPayloadLength, offset) = encoded.asUint16Unchecked(offset);
        (transceiverMessage.transceiverPayload, offset) =
            encoded.sliceUnchecked(offset, transceiverPayloadLength);

        // Check if the entire byte array has been processed
        encoded.checkLength(offset);
    }

    /// @dev Parses the payload of an Transceiver message and returns
    ///      the parsed NttManagerMessage struct.
    /// @param expectedPrefix The prefix that should be encoded in the nttManager message.
    /// @param payload The payload sent across the wire.
    function parseTransceiverAndNttManagerMessage(
        bytes4 expectedPrefix,
        bytes memory payload
    ) public pure returns (TransceiverMessage memory, NttManagerMessage memory) {
        // parse the encoded message payload from the Transceiver
        TransceiverMessage memory parsedTransceiverMessage =
            parseTransceiverMessage(expectedPrefix, payload);

        // parse the encoded message payload from the NttManager
        NttManagerMessage memory parsedNttManagerMessage =
            parseNttManagerMessage(parsedTransceiverMessage.nttManagerPayload);

        return (parsedTransceiverMessage, parsedNttManagerMessage);
    }

    /// @dev Variable-length transceiver-specific instruction that can be passed by the caller to the nttManager.
    ///      The index field refers to the index of the registeredTransceiver that this instruction should be passed to.
    ///      The serialization format is:
    ///      - index - 1 byte
    ///      - payloadLength - 1 byte
    ///      - payload - `payloadLength` bytes
    struct TransceiverInstruction {
        uint8 index;
        bytes payload;
    }

    function encodeTransceiverInstruction(TransceiverInstruction memory instruction)
        public
        pure
        returns (bytes memory)
    {
        if (instruction.payload.length > type(uint8).max) {
            revert PayloadTooLong(instruction.payload.length);
        }
        uint8 payloadLength = uint8(instruction.payload.length);
        return abi.encodePacked(instruction.index, payloadLength, instruction.payload);
    }

    function parseTransceiverInstructionUnchecked(
        bytes memory encoded,
        uint256 offset
    ) public pure returns (TransceiverInstruction memory instruction, uint256 nextOffset) {
        (instruction.index, nextOffset) = encoded.asUint8Unchecked(offset);
        uint8 instructionLength;
        (instructionLength, nextOffset) = encoded.asUint8Unchecked(nextOffset);
        (instruction.payload, nextOffset) = encoded.sliceUnchecked(nextOffset, instructionLength);
    }

    function parseTransceiverInstructionChecked(bytes memory encoded)
        public
        pure
        returns (TransceiverInstruction memory instruction)
    {
        uint256 offset = 0;
        (instruction, offset) = parseTransceiverInstructionUnchecked(encoded, offset);
        encoded.checkLength(offset);
    }

    /// @dev Encode an array of multiple variable-length transceiver-specific instructions.
    ///      The serialization format is:
    ///      - instructionsLength - 1 byte
    ///      - `instructionsLength` number of serialized `TransceiverInstruction` types.
    function encodeTransceiverInstructions(TransceiverInstruction[] memory instructions)
        public
        pure
        returns (bytes memory)
    {
        if (instructions.length > type(uint8).max) {
            revert PayloadTooLong(instructions.length);
        }
        uint256 instructionsLength = instructions.length;

        bytes memory encoded;
        for (uint256 i = 0; i < instructionsLength; i++) {
            bytes memory innerEncoded = encodeTransceiverInstruction(instructions[i]);
            encoded = bytes.concat(encoded, innerEncoded);
        }
        return abi.encodePacked(uint8(instructionsLength), encoded);
    }

    function parseTransceiverInstructions(
        bytes memory encoded,
        uint256 numRegisteredTransceivers
    ) public pure returns (TransceiverInstruction[] memory) {
        uint256 offset = 0;
        uint256 instructionsLength;
        (instructionsLength, offset) = encoded.asUint8Unchecked(offset);

        // We allocate an array with the length of the number of registered transceivers
        // This gives us the flexibility to not have to pass instructions for transceivers that
        // don't need them
        TransceiverInstruction[] memory instructions =
            new TransceiverInstruction[](numRegisteredTransceivers);

        uint256 lastIndex = 0;
        for (uint256 i = 0; i < instructionsLength; i++) {
            TransceiverInstruction memory instruction;
            (instruction, offset) = parseTransceiverInstructionUnchecked(encoded, offset);

            uint8 instructionIndex = instruction.index;

            // The instructions passed in have to be strictly increasing in terms of transceiver index
            if (i != 0 && instructionIndex <= lastIndex) {
                revert UnorderedInstructions(lastIndex, instructionIndex);
            }

            // Instruction index is out of bounds
            if (instructionIndex >= numRegisteredTransceivers) {
                revert InvalidInstructionIndex(instructionIndex, numRegisteredTransceivers);
            }

            lastIndex = instructionIndex;

            instructions[instructionIndex] = instruction;
        }

        encoded.checkLength(offset);

        return instructions;
    }

    struct TransceiverInit {
        bytes4 transceiverIdentifier;
        bytes32 nttManagerAddress;
        uint8 nttManagerMode;
        bytes32 tokenAddress;
        uint8 tokenDecimals;
    }

    function encodeTransceiverInit(TransceiverInit memory init)
        public
        pure
        returns (bytes memory)
    {
        return abi.encodePacked(
            init.transceiverIdentifier,
            init.nttManagerAddress,
            init.nttManagerMode,
            init.tokenAddress,
            init.tokenDecimals
        );
    }

    function decodeTransceiverInit(bytes memory encoded)
        public
        pure
        returns (TransceiverInit memory init)
    {
        uint256 offset = 0;
        (init.transceiverIdentifier, offset) = encoded.asBytes4Unchecked(offset);
        (init.nttManagerAddress, offset) = encoded.asBytes32Unchecked(offset);
        (init.nttManagerMode, offset) = encoded.asUint8Unchecked(offset);
        (init.tokenAddress, offset) = encoded.asBytes32Unchecked(offset);
        (init.tokenDecimals, offset) = encoded.asUint8Unchecked(offset);
        encoded.checkLength(offset);
    }

    struct TransceiverRegistration {
        bytes4 transceiverIdentifier;
        uint16 transceiverChainId;
        bytes32 transceiverAddress;
    }

    function encodeTransceiverRegistration(TransceiverRegistration memory registration)
        public
        pure
        returns (bytes memory)
    {
        return abi.encodePacked(
            registration.transceiverIdentifier,
            registration.transceiverChainId,
            registration.transceiverAddress
        );
    }

    function decodeTransceiverRegistration(bytes memory encoded)
        public
        pure
        returns (TransceiverRegistration memory registration)
    {
        uint256 offset = 0;
        (registration.transceiverIdentifier, offset) = encoded.asBytes4Unchecked(offset);
        (registration.transceiverChainId, offset) = encoded.asUint16Unchecked(offset);
        (registration.transceiverAddress, offset) = encoded.asBytes32Unchecked(offset);
        encoded.checkLength(offset);
    }
}

File 2 of 4 : BytesParsing.sol
// SPDX-License-Identifier: Apache 2
pragma solidity ^0.8.13;

library BytesParsing {
  uint256 private constant freeMemoryPtr = 0x40;
  uint256 private constant wordSize = 32;

  error OutOfBounds(uint256 offset, uint256 length);
  error LengthMismatch(uint256 encodedLength, uint256 expectedLength);
  error InvalidBoolVal(uint8 val);

  function checkBound(uint offset, uint length) internal pure {
    if (offset > length)
      revert OutOfBounds(offset, length);
  }

  function checkLength(bytes memory encoded, uint256 expected) internal pure {
    if (encoded.length != expected)
      revert LengthMismatch(encoded.length, expected);
  }

  function sliceUnchecked(
    bytes memory encoded,
    uint offset,
    uint length
  ) internal pure returns (bytes memory ret, uint nextOffset) {
    //bail early for degenerate case
    if (length == 0)
      return (new bytes(0), offset);

    assembly ("memory-safe") {
      nextOffset := add(offset, length)
      ret := mload(freeMemoryPtr)

      //Explanation on how we copy data here:
      //  The bytes type has the following layout in memory:
      //    [length: 32 bytes, data: length bytes]
      //  So if we allocate `bytes memory foo = new bytes(1);` then `foo` will be a pointer to 33
      //    bytes where the first 32 bytes contain the length and the last byte is the actual data.
      //  Since mload always loads 32 bytes of memory at once, we use our shift variable to align
      //    our reads so that our last read lines up exactly with the last 32 bytes of `encoded`.
      //  However this also means that if the length of `encoded` is not a multiple of 32 bytes, our
      //    first read will necessarily partly contain bytes from `encoded`'s 32 length bytes that
      //    will be written into the length part of our `ret` slice.
      //  We remedy this issue by writing the length of our `ret` slice at the end, thus
      //    overwritting those garbage bytes.
      let shift := and(length, 31) //equivalent to `mod(length, 32)` but 2 gas cheaper
      if iszero(shift) {
        shift := wordSize
      }

      let dest := add(ret, shift)
      let end := add(dest, length)
      for {
        let src := add(add(encoded, shift), offset)
      } lt(dest, end) {
        src := add(src, wordSize)
        dest := add(dest, wordSize)
      } {
        mstore(dest, mload(src))
      }

      mstore(ret, length)
      //When compiling with --via-ir then normally allocated memory (i.e. via new) will have 32 byte
      //  memory alignment and so we enforce the same memory alignment here.
      mstore(freeMemoryPtr, and(add(dest, 31), not(31)))
    }
  }

  function slice(
    bytes memory encoded,
    uint offset,
    uint length
  ) internal pure returns (bytes memory ret, uint nextOffset) {
    (ret, nextOffset) = sliceUnchecked(encoded, offset, length);
    checkBound(nextOffset, encoded.length);
  }

  function asAddressUnchecked(
    bytes memory encoded,
    uint offset
  ) internal pure returns (address, uint) {
    (uint160 ret, uint nextOffset) = asUint160(encoded, offset);
    return (address(ret), nextOffset);
  }

  function asAddress(
    bytes memory encoded,
    uint offset
  ) internal pure returns (address ret, uint nextOffset) {
    (ret, nextOffset) = asAddressUnchecked(encoded, offset);
    checkBound(nextOffset, encoded.length);
  }

  function asBoolUnchecked(
    bytes memory encoded,
    uint offset
  ) internal pure returns (bool, uint) {
    (uint8 val, uint nextOffset) = asUint8Unchecked(encoded, offset);
    if (val & 0xfe != 0)
      revert InvalidBoolVal(val);

    uint cleanedVal = uint(val);
    bool ret;
    //skip 2x iszero opcode
    assembly ("memory-safe") {
      ret := cleanedVal
    }
    return (ret, nextOffset);
  }

  function asBool(
    bytes memory encoded,
    uint offset
  ) internal pure returns (bool ret, uint nextOffset) {
    (ret, nextOffset) = asBoolUnchecked(encoded, offset);
    checkBound(nextOffset, encoded.length);
  }

/* -------------------------------------------------------------------------------------------------
Remaining library code below was auto-generated by via the following js/node code:

for (let bytes = 1; bytes <= 32; ++bytes) {
  const bits = bytes*8;
  console.log(
`function asUint${bits}Unchecked(
  bytes memory encoded,
  uint offset
) internal pure returns (uint${bits} ret, uint nextOffset) {
  assembly ("memory-safe") {
    nextOffset := add(offset, ${bytes})
    ret := mload(add(encoded, nextOffset))
  }
  return (ret, nextOffset);
}

function asUint${bits}(
  bytes memory encoded,
  uint offset
) internal pure returns (uint${bits} ret, uint nextOffset) {
  (ret, nextOffset) = asUint${bits}Unchecked(encoded, offset);
  checkBound(nextOffset, encoded.length);
}

function asBytes${bytes}Unchecked(
  bytes memory encoded,
  uint offset
) internal pure returns (bytes${bytes}, uint) {
  (uint${bits} ret, uint nextOffset) = asUint${bits}Unchecked(encoded, offset);
  return (bytes${bytes}(ret), nextOffset);
}

function asBytes${bytes}(
  bytes memory encoded,
  uint offset
) internal pure returns (bytes${bytes}, uint) {
  (uint${bits} ret, uint nextOffset) = asUint${bits}(encoded, offset);
  return (bytes${bytes}(ret), nextOffset);
}
`
  );
}
------------------------------------------------------------------------------------------------- */

  function asUint8Unchecked(
    bytes memory encoded,
    uint offset
  ) internal pure returns (uint8 ret, uint nextOffset) {
    assembly ("memory-safe") {
      nextOffset := add(offset, 1)
      ret := mload(add(encoded, nextOffset))
    }
    return (ret, nextOffset);
  }

  function asUint8(
    bytes memory encoded,
    uint offset
  ) internal pure returns (uint8 ret, uint nextOffset) {
    (ret, nextOffset) = asUint8Unchecked(encoded, offset);
    checkBound(nextOffset, encoded.length);
  }

  function asBytes1Unchecked(
    bytes memory encoded,
    uint offset
  ) internal pure returns (bytes1, uint) {
    (uint8 ret, uint nextOffset) = asUint8Unchecked(encoded, offset);
    return (bytes1(ret), nextOffset);
  }

  function asBytes1(
    bytes memory encoded,
    uint offset
  ) internal pure returns (bytes1, uint) {
    (uint8 ret, uint nextOffset) = asUint8(encoded, offset);
    return (bytes1(ret), nextOffset);
  }

  function asUint16Unchecked(
    bytes memory encoded,
    uint offset
  ) internal pure returns (uint16 ret, uint nextOffset) {
    assembly ("memory-safe") {
      nextOffset := add(offset, 2)
      ret := mload(add(encoded, nextOffset))
    }
    return (ret, nextOffset);
  }

  function asUint16(
    bytes memory encoded,
    uint offset
  ) internal pure returns (uint16 ret, uint nextOffset) {
    (ret, nextOffset) = asUint16Unchecked(encoded, offset);
    checkBound(nextOffset, encoded.length);
  }

  function asBytes2Unchecked(
    bytes memory encoded,
    uint offset
  ) internal pure returns (bytes2, uint) {
    (uint16 ret, uint nextOffset) = asUint16Unchecked(encoded, offset);
    return (bytes2(ret), nextOffset);
  }

  function asBytes2(
    bytes memory encoded,
    uint offset
  ) internal pure returns (bytes2, uint) {
    (uint16 ret, uint nextOffset) = asUint16(encoded, offset);
    return (bytes2(ret), nextOffset);
  }

  function asUint24Unchecked(
    bytes memory encoded,
    uint offset
  ) internal pure returns (uint24 ret, uint nextOffset) {
    assembly ("memory-safe") {
      nextOffset := add(offset, 3)
      ret := mload(add(encoded, nextOffset))
    }
    return (ret, nextOffset);
  }

  function asUint24(
    bytes memory encoded,
    uint offset
  ) internal pure returns (uint24 ret, uint nextOffset) {
    (ret, nextOffset) = asUint24Unchecked(encoded, offset);
    checkBound(nextOffset, encoded.length);
  }

  function asBytes3Unchecked(
    bytes memory encoded,
    uint offset
  ) internal pure returns (bytes3, uint) {
    (uint24 ret, uint nextOffset) = asUint24Unchecked(encoded, offset);
    return (bytes3(ret), nextOffset);
  }

  function asBytes3(
    bytes memory encoded,
    uint offset
  ) internal pure returns (bytes3, uint) {
    (uint24 ret, uint nextOffset) = asUint24(encoded, offset);
    return (bytes3(ret), nextOffset);
  }

  function asUint32Unchecked(
    bytes memory encoded,
    uint offset
  ) internal pure returns (uint32 ret, uint nextOffset) {
    assembly ("memory-safe") {
      nextOffset := add(offset, 4)
      ret := mload(add(encoded, nextOffset))
    }
    return (ret, nextOffset);
  }

  function asUint32(
    bytes memory encoded,
    uint offset
  ) internal pure returns (uint32 ret, uint nextOffset) {
    (ret, nextOffset) = asUint32Unchecked(encoded, offset);
    checkBound(nextOffset, encoded.length);
  }

  function asBytes4Unchecked(
    bytes memory encoded,
    uint offset
  ) internal pure returns (bytes4, uint) {
    (uint32 ret, uint nextOffset) = asUint32Unchecked(encoded, offset);
    return (bytes4(ret), nextOffset);
  }

  function asBytes4(
    bytes memory encoded,
    uint offset
  ) internal pure returns (bytes4, uint) {
    (uint32 ret, uint nextOffset) = asUint32(encoded, offset);
    return (bytes4(ret), nextOffset);
  }

  function asUint40Unchecked(
    bytes memory encoded,
    uint offset
  ) internal pure returns (uint40 ret, uint nextOffset) {
    assembly ("memory-safe") {
      nextOffset := add(offset, 5)
      ret := mload(add(encoded, nextOffset))
    }
    return (ret, nextOffset);
  }

  function asUint40(
    bytes memory encoded,
    uint offset
  ) internal pure returns (uint40 ret, uint nextOffset) {
    (ret, nextOffset) = asUint40Unchecked(encoded, offset);
    checkBound(nextOffset, encoded.length);
  }

  function asBytes5Unchecked(
    bytes memory encoded,
    uint offset
  ) internal pure returns (bytes5, uint) {
    (uint40 ret, uint nextOffset) = asUint40Unchecked(encoded, offset);
    return (bytes5(ret), nextOffset);
  }

  function asBytes5(
    bytes memory encoded,
    uint offset
  ) internal pure returns (bytes5, uint) {
    (uint40 ret, uint nextOffset) = asUint40(encoded, offset);
    return (bytes5(ret), nextOffset);
  }

  function asUint48Unchecked(
    bytes memory encoded,
    uint offset
  ) internal pure returns (uint48 ret, uint nextOffset) {
    assembly ("memory-safe") {
      nextOffset := add(offset, 6)
      ret := mload(add(encoded, nextOffset))
    }
    return (ret, nextOffset);
  }

  function asUint48(
    bytes memory encoded,
    uint offset
  ) internal pure returns (uint48 ret, uint nextOffset) {
    (ret, nextOffset) = asUint48Unchecked(encoded, offset);
    checkBound(nextOffset, encoded.length);
  }

  function asBytes6Unchecked(
    bytes memory encoded,
    uint offset
  ) internal pure returns (bytes6, uint) {
    (uint48 ret, uint nextOffset) = asUint48Unchecked(encoded, offset);
    return (bytes6(ret), nextOffset);
  }

  function asBytes6(
    bytes memory encoded,
    uint offset
  ) internal pure returns (bytes6, uint) {
    (uint48 ret, uint nextOffset) = asUint48(encoded, offset);
    return (bytes6(ret), nextOffset);
  }

  function asUint56Unchecked(
    bytes memory encoded,
    uint offset
  ) internal pure returns (uint56 ret, uint nextOffset) {
    assembly ("memory-safe") {
      nextOffset := add(offset, 7)
      ret := mload(add(encoded, nextOffset))
    }
    return (ret, nextOffset);
  }

  function asUint56(
    bytes memory encoded,
    uint offset
  ) internal pure returns (uint56 ret, uint nextOffset) {
    (ret, nextOffset) = asUint56Unchecked(encoded, offset);
    checkBound(nextOffset, encoded.length);
  }

  function asBytes7Unchecked(
    bytes memory encoded,
    uint offset
  ) internal pure returns (bytes7, uint) {
    (uint56 ret, uint nextOffset) = asUint56Unchecked(encoded, offset);
    return (bytes7(ret), nextOffset);
  }

  function asBytes7(
    bytes memory encoded,
    uint offset
  ) internal pure returns (bytes7, uint) {
    (uint56 ret, uint nextOffset) = asUint56(encoded, offset);
    return (bytes7(ret), nextOffset);
  }

  function asUint64Unchecked(
    bytes memory encoded,
    uint offset
  ) internal pure returns (uint64 ret, uint nextOffset) {
    assembly ("memory-safe") {
      nextOffset := add(offset, 8)
      ret := mload(add(encoded, nextOffset))
    }
    return (ret, nextOffset);
  }

  function asUint64(
    bytes memory encoded,
    uint offset
  ) internal pure returns (uint64 ret, uint nextOffset) {
    (ret, nextOffset) = asUint64Unchecked(encoded, offset);
    checkBound(nextOffset, encoded.length);
  }

  function asBytes8Unchecked(
    bytes memory encoded,
    uint offset
  ) internal pure returns (bytes8, uint) {
    (uint64 ret, uint nextOffset) = asUint64Unchecked(encoded, offset);
    return (bytes8(ret), nextOffset);
  }

  function asBytes8(
    bytes memory encoded,
    uint offset
  ) internal pure returns (bytes8, uint) {
    (uint64 ret, uint nextOffset) = asUint64(encoded, offset);
    return (bytes8(ret), nextOffset);
  }

  function asUint72Unchecked(
    bytes memory encoded,
    uint offset
  ) internal pure returns (uint72 ret, uint nextOffset) {
    assembly ("memory-safe") {
      nextOffset := add(offset, 9)
      ret := mload(add(encoded, nextOffset))
    }
    return (ret, nextOffset);
  }

  function asUint72(
    bytes memory encoded,
    uint offset
  ) internal pure returns (uint72 ret, uint nextOffset) {
    (ret, nextOffset) = asUint72Unchecked(encoded, offset);
    checkBound(nextOffset, encoded.length);
  }

  function asBytes9Unchecked(
    bytes memory encoded,
    uint offset
  ) internal pure returns (bytes9, uint) {
    (uint72 ret, uint nextOffset) = asUint72Unchecked(encoded, offset);
    return (bytes9(ret), nextOffset);
  }

  function asBytes9(
    bytes memory encoded,
    uint offset
  ) internal pure returns (bytes9, uint) {
    (uint72 ret, uint nextOffset) = asUint72(encoded, offset);
    return (bytes9(ret), nextOffset);
  }

  function asUint80Unchecked(
    bytes memory encoded,
    uint offset
  ) internal pure returns (uint80 ret, uint nextOffset) {
    assembly ("memory-safe") {
      nextOffset := add(offset, 10)
      ret := mload(add(encoded, nextOffset))
    }
    return (ret, nextOffset);
  }

  function asUint80(
    bytes memory encoded,
    uint offset
  ) internal pure returns (uint80 ret, uint nextOffset) {
    (ret, nextOffset) = asUint80Unchecked(encoded, offset);
    checkBound(nextOffset, encoded.length);
  }

  function asBytes10Unchecked(
    bytes memory encoded,
    uint offset
  ) internal pure returns (bytes10, uint) {
    (uint80 ret, uint nextOffset) = asUint80Unchecked(encoded, offset);
    return (bytes10(ret), nextOffset);
  }

  function asBytes10(
    bytes memory encoded,
    uint offset
  ) internal pure returns (bytes10, uint) {
    (uint80 ret, uint nextOffset) = asUint80(encoded, offset);
    return (bytes10(ret), nextOffset);
  }

  function asUint88Unchecked(
    bytes memory encoded,
    uint offset
  ) internal pure returns (uint88 ret, uint nextOffset) {
    assembly ("memory-safe") {
      nextOffset := add(offset, 11)
      ret := mload(add(encoded, nextOffset))
    }
    return (ret, nextOffset);
  }

  function asUint88(
    bytes memory encoded,
    uint offset
  ) internal pure returns (uint88 ret, uint nextOffset) {
    (ret, nextOffset) = asUint88Unchecked(encoded, offset);
    checkBound(nextOffset, encoded.length);
  }

  function asBytes11Unchecked(
    bytes memory encoded,
    uint offset
  ) internal pure returns (bytes11, uint) {
    (uint88 ret, uint nextOffset) = asUint88Unchecked(encoded, offset);
    return (bytes11(ret), nextOffset);
  }

  function asBytes11(
    bytes memory encoded,
    uint offset
  ) internal pure returns (bytes11, uint) {
    (uint88 ret, uint nextOffset) = asUint88(encoded, offset);
    return (bytes11(ret), nextOffset);
  }

  function asUint96Unchecked(
    bytes memory encoded,
    uint offset
  ) internal pure returns (uint96 ret, uint nextOffset) {
    assembly ("memory-safe") {
      nextOffset := add(offset, 12)
      ret := mload(add(encoded, nextOffset))
    }
    return (ret, nextOffset);
  }

  function asUint96(
    bytes memory encoded,
    uint offset
  ) internal pure returns (uint96 ret, uint nextOffset) {
    (ret, nextOffset) = asUint96Unchecked(encoded, offset);
    checkBound(nextOffset, encoded.length);
  }

  function asBytes12Unchecked(
    bytes memory encoded,
    uint offset
  ) internal pure returns (bytes12, uint) {
    (uint96 ret, uint nextOffset) = asUint96Unchecked(encoded, offset);
    return (bytes12(ret), nextOffset);
  }

  function asBytes12(
    bytes memory encoded,
    uint offset
  ) internal pure returns (bytes12, uint) {
    (uint96 ret, uint nextOffset) = asUint96(encoded, offset);
    return (bytes12(ret), nextOffset);
  }

  function asUint104Unchecked(
    bytes memory encoded,
    uint offset
  ) internal pure returns (uint104 ret, uint nextOffset) {
    assembly ("memory-safe") {
      nextOffset := add(offset, 13)
      ret := mload(add(encoded, nextOffset))
    }
    return (ret, nextOffset);
  }

  function asUint104(
    bytes memory encoded,
    uint offset
  ) internal pure returns (uint104 ret, uint nextOffset) {
    (ret, nextOffset) = asUint104Unchecked(encoded, offset);
    checkBound(nextOffset, encoded.length);
  }

  function asBytes13Unchecked(
    bytes memory encoded,
    uint offset
  ) internal pure returns (bytes13, uint) {
    (uint104 ret, uint nextOffset) = asUint104Unchecked(encoded, offset);
    return (bytes13(ret), nextOffset);
  }

  function asBytes13(
    bytes memory encoded,
    uint offset
  ) internal pure returns (bytes13, uint) {
    (uint104 ret, uint nextOffset) = asUint104(encoded, offset);
    return (bytes13(ret), nextOffset);
  }

  function asUint112Unchecked(
    bytes memory encoded,
    uint offset
  ) internal pure returns (uint112 ret, uint nextOffset) {
    assembly ("memory-safe") {
      nextOffset := add(offset, 14)
      ret := mload(add(encoded, nextOffset))
    }
    return (ret, nextOffset);
  }

  function asUint112(
    bytes memory encoded,
    uint offset
  ) internal pure returns (uint112 ret, uint nextOffset) {
    (ret, nextOffset) = asUint112Unchecked(encoded, offset);
    checkBound(nextOffset, encoded.length);
  }

  function asBytes14Unchecked(
    bytes memory encoded,
    uint offset
  ) internal pure returns (bytes14, uint) {
    (uint112 ret, uint nextOffset) = asUint112Unchecked(encoded, offset);
    return (bytes14(ret), nextOffset);
  }

  function asBytes14(
    bytes memory encoded,
    uint offset
  ) internal pure returns (bytes14, uint) {
    (uint112 ret, uint nextOffset) = asUint112(encoded, offset);
    return (bytes14(ret), nextOffset);
  }

  function asUint120Unchecked(
    bytes memory encoded,
    uint offset
  ) internal pure returns (uint120 ret, uint nextOffset) {
    assembly ("memory-safe") {
      nextOffset := add(offset, 15)
      ret := mload(add(encoded, nextOffset))
    }
    return (ret, nextOffset);
  }

  function asUint120(
    bytes memory encoded,
    uint offset
  ) internal pure returns (uint120 ret, uint nextOffset) {
    (ret, nextOffset) = asUint120Unchecked(encoded, offset);
    checkBound(nextOffset, encoded.length);
  }

  function asBytes15Unchecked(
    bytes memory encoded,
    uint offset
  ) internal pure returns (bytes15, uint) {
    (uint120 ret, uint nextOffset) = asUint120Unchecked(encoded, offset);
    return (bytes15(ret), nextOffset);
  }

  function asBytes15(
    bytes memory encoded,
    uint offset
  ) internal pure returns (bytes15, uint) {
    (uint120 ret, uint nextOffset) = asUint120(encoded, offset);
    return (bytes15(ret), nextOffset);
  }

  function asUint128Unchecked(
    bytes memory encoded,
    uint offset
  ) internal pure returns (uint128 ret, uint nextOffset) {
    assembly ("memory-safe") {
      nextOffset := add(offset, 16)
      ret := mload(add(encoded, nextOffset))
    }
    return (ret, nextOffset);
  }

  function asUint128(
    bytes memory encoded,
    uint offset
  ) internal pure returns (uint128 ret, uint nextOffset) {
    (ret, nextOffset) = asUint128Unchecked(encoded, offset);
    checkBound(nextOffset, encoded.length);
  }

  function asBytes16Unchecked(
    bytes memory encoded,
    uint offset
  ) internal pure returns (bytes16, uint) {
    (uint128 ret, uint nextOffset) = asUint128Unchecked(encoded, offset);
    return (bytes16(ret), nextOffset);
  }

  function asBytes16(
    bytes memory encoded,
    uint offset
  ) internal pure returns (bytes16, uint) {
    (uint128 ret, uint nextOffset) = asUint128(encoded, offset);
    return (bytes16(ret), nextOffset);
  }

  function asUint136Unchecked(
    bytes memory encoded,
    uint offset
  ) internal pure returns (uint136 ret, uint nextOffset) {
    assembly ("memory-safe") {
      nextOffset := add(offset, 17)
      ret := mload(add(encoded, nextOffset))
    }
    return (ret, nextOffset);
  }

  function asUint136(
    bytes memory encoded,
    uint offset
  ) internal pure returns (uint136 ret, uint nextOffset) {
    (ret, nextOffset) = asUint136Unchecked(encoded, offset);
    checkBound(nextOffset, encoded.length);
  }

  function asBytes17Unchecked(
    bytes memory encoded,
    uint offset
  ) internal pure returns (bytes17, uint) {
    (uint136 ret, uint nextOffset) = asUint136Unchecked(encoded, offset);
    return (bytes17(ret), nextOffset);
  }

  function asBytes17(
    bytes memory encoded,
    uint offset
  ) internal pure returns (bytes17, uint) {
    (uint136 ret, uint nextOffset) = asUint136(encoded, offset);
    return (bytes17(ret), nextOffset);
  }

  function asUint144Unchecked(
    bytes memory encoded,
    uint offset
  ) internal pure returns (uint144 ret, uint nextOffset) {
    assembly ("memory-safe") {
      nextOffset := add(offset, 18)
      ret := mload(add(encoded, nextOffset))
    }
    return (ret, nextOffset);
  }

  function asUint144(
    bytes memory encoded,
    uint offset
  ) internal pure returns (uint144 ret, uint nextOffset) {
    (ret, nextOffset) = asUint144Unchecked(encoded, offset);
    checkBound(nextOffset, encoded.length);
  }

  function asBytes18Unchecked(
    bytes memory encoded,
    uint offset
  ) internal pure returns (bytes18, uint) {
    (uint144 ret, uint nextOffset) = asUint144Unchecked(encoded, offset);
    return (bytes18(ret), nextOffset);
  }

  function asBytes18(
    bytes memory encoded,
    uint offset
  ) internal pure returns (bytes18, uint) {
    (uint144 ret, uint nextOffset) = asUint144(encoded, offset);
    return (bytes18(ret), nextOffset);
  }

  function asUint152Unchecked(
    bytes memory encoded,
    uint offset
  ) internal pure returns (uint152 ret, uint nextOffset) {
    assembly ("memory-safe") {
      nextOffset := add(offset, 19)
      ret := mload(add(encoded, nextOffset))
    }
    return (ret, nextOffset);
  }

  function asUint152(
    bytes memory encoded,
    uint offset
  ) internal pure returns (uint152 ret, uint nextOffset) {
    (ret, nextOffset) = asUint152Unchecked(encoded, offset);
    checkBound(nextOffset, encoded.length);
  }

  function asBytes19Unchecked(
    bytes memory encoded,
    uint offset
  ) internal pure returns (bytes19, uint) {
    (uint152 ret, uint nextOffset) = asUint152Unchecked(encoded, offset);
    return (bytes19(ret), nextOffset);
  }

  function asBytes19(
    bytes memory encoded,
    uint offset
  ) internal pure returns (bytes19, uint) {
    (uint152 ret, uint nextOffset) = asUint152(encoded, offset);
    return (bytes19(ret), nextOffset);
  }

  function asUint160Unchecked(
    bytes memory encoded,
    uint offset
  ) internal pure returns (uint160 ret, uint nextOffset) {
    assembly ("memory-safe") {
      nextOffset := add(offset, 20)
      ret := mload(add(encoded, nextOffset))
    }
    return (ret, nextOffset);
  }

  function asUint160(
    bytes memory encoded,
    uint offset
  ) internal pure returns (uint160 ret, uint nextOffset) {
    (ret, nextOffset) = asUint160Unchecked(encoded, offset);
    checkBound(nextOffset, encoded.length);
  }

  function asBytes20Unchecked(
    bytes memory encoded,
    uint offset
  ) internal pure returns (bytes20, uint) {
    (uint160 ret, uint nextOffset) = asUint160Unchecked(encoded, offset);
    return (bytes20(ret), nextOffset);
  }

  function asBytes20(
    bytes memory encoded,
    uint offset
  ) internal pure returns (bytes20, uint) {
    (uint160 ret, uint nextOffset) = asUint160(encoded, offset);
    return (bytes20(ret), nextOffset);
  }

  function asUint168Unchecked(
    bytes memory encoded,
    uint offset
  ) internal pure returns (uint168 ret, uint nextOffset) {
    assembly ("memory-safe") {
      nextOffset := add(offset, 21)
      ret := mload(add(encoded, nextOffset))
    }
    return (ret, nextOffset);
  }

  function asUint168(
    bytes memory encoded,
    uint offset
  ) internal pure returns (uint168 ret, uint nextOffset) {
    (ret, nextOffset) = asUint168Unchecked(encoded, offset);
    checkBound(nextOffset, encoded.length);
  }

  function asBytes21Unchecked(
    bytes memory encoded,
    uint offset
  ) internal pure returns (bytes21, uint) {
    (uint168 ret, uint nextOffset) = asUint168Unchecked(encoded, offset);
    return (bytes21(ret), nextOffset);
  }

  function asBytes21(
    bytes memory encoded,
    uint offset
  ) internal pure returns (bytes21, uint) {
    (uint168 ret, uint nextOffset) = asUint168(encoded, offset);
    return (bytes21(ret), nextOffset);
  }

  function asUint176Unchecked(
    bytes memory encoded,
    uint offset
  ) internal pure returns (uint176 ret, uint nextOffset) {
    assembly ("memory-safe") {
      nextOffset := add(offset, 22)
      ret := mload(add(encoded, nextOffset))
    }
    return (ret, nextOffset);
  }

  function asUint176(
    bytes memory encoded,
    uint offset
  ) internal pure returns (uint176 ret, uint nextOffset) {
    (ret, nextOffset) = asUint176Unchecked(encoded, offset);
    checkBound(nextOffset, encoded.length);
  }

  function asBytes22Unchecked(
    bytes memory encoded,
    uint offset
  ) internal pure returns (bytes22, uint) {
    (uint176 ret, uint nextOffset) = asUint176Unchecked(encoded, offset);
    return (bytes22(ret), nextOffset);
  }

  function asBytes22(
    bytes memory encoded,
    uint offset
  ) internal pure returns (bytes22, uint) {
    (uint176 ret, uint nextOffset) = asUint176(encoded, offset);
    return (bytes22(ret), nextOffset);
  }

  function asUint184Unchecked(
    bytes memory encoded,
    uint offset
  ) internal pure returns (uint184 ret, uint nextOffset) {
    assembly ("memory-safe") {
      nextOffset := add(offset, 23)
      ret := mload(add(encoded, nextOffset))
    }
    return (ret, nextOffset);
  }

  function asUint184(
    bytes memory encoded,
    uint offset
  ) internal pure returns (uint184 ret, uint nextOffset) {
    (ret, nextOffset) = asUint184Unchecked(encoded, offset);
    checkBound(nextOffset, encoded.length);
  }

  function asBytes23Unchecked(
    bytes memory encoded,
    uint offset
  ) internal pure returns (bytes23, uint) {
    (uint184 ret, uint nextOffset) = asUint184Unchecked(encoded, offset);
    return (bytes23(ret), nextOffset);
  }

  function asBytes23(
    bytes memory encoded,
    uint offset
  ) internal pure returns (bytes23, uint) {
    (uint184 ret, uint nextOffset) = asUint184(encoded, offset);
    return (bytes23(ret), nextOffset);
  }

  function asUint192Unchecked(
    bytes memory encoded,
    uint offset
  ) internal pure returns (uint192 ret, uint nextOffset) {
    assembly ("memory-safe") {
      nextOffset := add(offset, 24)
      ret := mload(add(encoded, nextOffset))
    }
    return (ret, nextOffset);
  }

  function asUint192(
    bytes memory encoded,
    uint offset
  ) internal pure returns (uint192 ret, uint nextOffset) {
    (ret, nextOffset) = asUint192Unchecked(encoded, offset);
    checkBound(nextOffset, encoded.length);
  }

  function asBytes24Unchecked(
    bytes memory encoded,
    uint offset
  ) internal pure returns (bytes24, uint) {
    (uint192 ret, uint nextOffset) = asUint192Unchecked(encoded, offset);
    return (bytes24(ret), nextOffset);
  }

  function asBytes24(
    bytes memory encoded,
    uint offset
  ) internal pure returns (bytes24, uint) {
    (uint192 ret, uint nextOffset) = asUint192(encoded, offset);
    return (bytes24(ret), nextOffset);
  }

  function asUint200Unchecked(
    bytes memory encoded,
    uint offset
  ) internal pure returns (uint200 ret, uint nextOffset) {
    assembly ("memory-safe") {
      nextOffset := add(offset, 25)
      ret := mload(add(encoded, nextOffset))
    }
    return (ret, nextOffset);
  }

  function asUint200(
    bytes memory encoded,
    uint offset
  ) internal pure returns (uint200 ret, uint nextOffset) {
    (ret, nextOffset) = asUint200Unchecked(encoded, offset);
    checkBound(nextOffset, encoded.length);
  }

  function asBytes25Unchecked(
    bytes memory encoded,
    uint offset
  ) internal pure returns (bytes25, uint) {
    (uint200 ret, uint nextOffset) = asUint200Unchecked(encoded, offset);
    return (bytes25(ret), nextOffset);
  }

  function asBytes25(
    bytes memory encoded,
    uint offset
  ) internal pure returns (bytes25, uint) {
    (uint200 ret, uint nextOffset) = asUint200(encoded, offset);
    return (bytes25(ret), nextOffset);
  }

  function asUint208Unchecked(
    bytes memory encoded,
    uint offset
  ) internal pure returns (uint208 ret, uint nextOffset) {
    assembly ("memory-safe") {
      nextOffset := add(offset, 26)
      ret := mload(add(encoded, nextOffset))
    }
    return (ret, nextOffset);
  }

  function asUint208(
    bytes memory encoded,
    uint offset
  ) internal pure returns (uint208 ret, uint nextOffset) {
    (ret, nextOffset) = asUint208Unchecked(encoded, offset);
    checkBound(nextOffset, encoded.length);
  }

  function asBytes26Unchecked(
    bytes memory encoded,
    uint offset
  ) internal pure returns (bytes26, uint) {
    (uint208 ret, uint nextOffset) = asUint208Unchecked(encoded, offset);
    return (bytes26(ret), nextOffset);
  }

  function asBytes26(
    bytes memory encoded,
    uint offset
  ) internal pure returns (bytes26, uint) {
    (uint208 ret, uint nextOffset) = asUint208(encoded, offset);
    return (bytes26(ret), nextOffset);
  }

  function asUint216Unchecked(
    bytes memory encoded,
    uint offset
  ) internal pure returns (uint216 ret, uint nextOffset) {
    assembly ("memory-safe") {
      nextOffset := add(offset, 27)
      ret := mload(add(encoded, nextOffset))
    }
    return (ret, nextOffset);
  }

  function asUint216(
    bytes memory encoded,
    uint offset
  ) internal pure returns (uint216 ret, uint nextOffset) {
    (ret, nextOffset) = asUint216Unchecked(encoded, offset);
    checkBound(nextOffset, encoded.length);
  }

  function asBytes27Unchecked(
    bytes memory encoded,
    uint offset
  ) internal pure returns (bytes27, uint) {
    (uint216 ret, uint nextOffset) = asUint216Unchecked(encoded, offset);
    return (bytes27(ret), nextOffset);
  }

  function asBytes27(
    bytes memory encoded,
    uint offset
  ) internal pure returns (bytes27, uint) {
    (uint216 ret, uint nextOffset) = asUint216(encoded, offset);
    return (bytes27(ret), nextOffset);
  }

  function asUint224Unchecked(
    bytes memory encoded,
    uint offset
  ) internal pure returns (uint224 ret, uint nextOffset) {
    assembly ("memory-safe") {
      nextOffset := add(offset, 28)
      ret := mload(add(encoded, nextOffset))
    }
    return (ret, nextOffset);
  }

  function asUint224(
    bytes memory encoded,
    uint offset
  ) internal pure returns (uint224 ret, uint nextOffset) {
    (ret, nextOffset) = asUint224Unchecked(encoded, offset);
    checkBound(nextOffset, encoded.length);
  }

  function asBytes28Unchecked(
    bytes memory encoded,
    uint offset
  ) internal pure returns (bytes28, uint) {
    (uint224 ret, uint nextOffset) = asUint224Unchecked(encoded, offset);
    return (bytes28(ret), nextOffset);
  }

  function asBytes28(
    bytes memory encoded,
    uint offset
  ) internal pure returns (bytes28, uint) {
    (uint224 ret, uint nextOffset) = asUint224(encoded, offset);
    return (bytes28(ret), nextOffset);
  }

  function asUint232Unchecked(
    bytes memory encoded,
    uint offset
  ) internal pure returns (uint232 ret, uint nextOffset) {
    assembly ("memory-safe") {
      nextOffset := add(offset, 29)
      ret := mload(add(encoded, nextOffset))
    }
    return (ret, nextOffset);
  }

  function asUint232(
    bytes memory encoded,
    uint offset
  ) internal pure returns (uint232 ret, uint nextOffset) {
    (ret, nextOffset) = asUint232Unchecked(encoded, offset);
    checkBound(nextOffset, encoded.length);
  }

  function asBytes29Unchecked(
    bytes memory encoded,
    uint offset
  ) internal pure returns (bytes29, uint) {
    (uint232 ret, uint nextOffset) = asUint232Unchecked(encoded, offset);
    return (bytes29(ret), nextOffset);
  }

  function asBytes29(
    bytes memory encoded,
    uint offset
  ) internal pure returns (bytes29, uint) {
    (uint232 ret, uint nextOffset) = asUint232(encoded, offset);
    return (bytes29(ret), nextOffset);
  }

  function asUint240Unchecked(
    bytes memory encoded,
    uint offset
  ) internal pure returns (uint240 ret, uint nextOffset) {
    assembly ("memory-safe") {
      nextOffset := add(offset, 30)
      ret := mload(add(encoded, nextOffset))
    }
    return (ret, nextOffset);
  }

  function asUint240(
    bytes memory encoded,
    uint offset
  ) internal pure returns (uint240 ret, uint nextOffset) {
    (ret, nextOffset) = asUint240Unchecked(encoded, offset);
    checkBound(nextOffset, encoded.length);
  }

  function asBytes30Unchecked(
    bytes memory encoded,
    uint offset
  ) internal pure returns (bytes30, uint) {
    (uint240 ret, uint nextOffset) = asUint240Unchecked(encoded, offset);
    return (bytes30(ret), nextOffset);
  }

  function asBytes30(
    bytes memory encoded,
    uint offset
  ) internal pure returns (bytes30, uint) {
    (uint240 ret, uint nextOffset) = asUint240(encoded, offset);
    return (bytes30(ret), nextOffset);
  }

  function asUint248Unchecked(
    bytes memory encoded,
    uint offset
  ) internal pure returns (uint248 ret, uint nextOffset) {
    assembly ("memory-safe") {
      nextOffset := add(offset, 31)
      ret := mload(add(encoded, nextOffset))
    }
    return (ret, nextOffset);
  }

  function asUint248(
    bytes memory encoded,
    uint offset
  ) internal pure returns (uint248 ret, uint nextOffset) {
    (ret, nextOffset) = asUint248Unchecked(encoded, offset);
    checkBound(nextOffset, encoded.length);
  }

  function asBytes31Unchecked(
    bytes memory encoded,
    uint offset
  ) internal pure returns (bytes31, uint) {
    (uint248 ret, uint nextOffset) = asUint248Unchecked(encoded, offset);
    return (bytes31(ret), nextOffset);
  }

  function asBytes31(
    bytes memory encoded,
    uint offset
  ) internal pure returns (bytes31, uint) {
    (uint248 ret, uint nextOffset) = asUint248(encoded, offset);
    return (bytes31(ret), nextOffset);
  }

  function asUint256Unchecked(
    bytes memory encoded,
    uint offset
  ) internal pure returns (uint256 ret, uint nextOffset) {
    assembly ("memory-safe") {
      nextOffset := add(offset, 32)
      ret := mload(add(encoded, nextOffset))
    }
    return (ret, nextOffset);
  }

  function asUint256(
    bytes memory encoded,
    uint offset
  ) internal pure returns (uint256 ret, uint nextOffset) {
    (ret, nextOffset) = asUint256Unchecked(encoded, offset);
    checkBound(nextOffset, encoded.length);
  }

  function asBytes32Unchecked(
    bytes memory encoded,
    uint offset
  ) internal pure returns (bytes32, uint) {
    (uint256 ret, uint nextOffset) = asUint256Unchecked(encoded, offset);
    return (bytes32(ret), nextOffset);
  }

  function asBytes32(
    bytes memory encoded,
    uint offset
  ) internal pure returns (bytes32, uint) {
    (uint256 ret, uint nextOffset) = asUint256(encoded, offset);
    return (bytes32(ret), nextOffset);
  }
}

File 3 of 4 : TrimmedAmount.sol
// SPDX-License-Identifier: Apache 2
/// @dev TrimmedAmount is a utility library to handle token amounts with different decimals
pragma solidity >=0.8.8 <0.9.0;

import "openzeppelin-contracts/contracts/utils/math/SafeCast.sol";

/// @dev TrimmedAmount is a bit-packed representation of a token amount and its decimals.
/// @dev 64 bits: [0 - 64] amount
/// @dev 8 bits: [64 - 72] decimals
type TrimmedAmount is uint72;

using {gt as >, lt as <, sub as -, add as +, eq as ==, min, unwrap} for TrimmedAmount global;

function minUint8(uint8 a, uint8 b) pure returns (uint8) {
    return a < b ? a : b;
}

/// @notice Error when the decimals of two TrimmedAmounts are not equal
/// @dev Selector. b9cdb6c2
/// @param decimals the decimals of the first TrimmedAmount
/// @param decimalsOther the decimals of the second TrimmedAmount
error NumberOfDecimalsNotEqual(uint8 decimals, uint8 decimalsOther);

uint8 constant TRIMMED_DECIMALS = 8;

function unwrap(TrimmedAmount a) pure returns (uint72) {
    return TrimmedAmount.unwrap(a);
}

function packTrimmedAmount(uint64 amt, uint8 decimals) pure returns (TrimmedAmount) {
    // cast to u72 first to prevent overflow
    uint72 amount = uint72(amt);
    uint72 dec = uint72(decimals);

    // shift the amount to the left 8 bits
    amount <<= 8;

    return TrimmedAmount.wrap(amount | dec);
}

function eq(TrimmedAmount a, TrimmedAmount b) pure returns (bool) {
    return TrimmedAmountLib.getAmount(a) == TrimmedAmountLib.getAmount(b)
        && TrimmedAmountLib.getDecimals(a) == TrimmedAmountLib.getDecimals(b);
}

function checkDecimals(TrimmedAmount a, TrimmedAmount b) pure {
    uint8 aDecimals = TrimmedAmountLib.getDecimals(a);
    uint8 bDecimals = TrimmedAmountLib.getDecimals(b);
    if (aDecimals != bDecimals) {
        revert NumberOfDecimalsNotEqual(aDecimals, bDecimals);
    }
}

function gt(TrimmedAmount a, TrimmedAmount b) pure returns (bool) {
    checkDecimals(a, b);

    return TrimmedAmountLib.getAmount(a) > TrimmedAmountLib.getAmount(b);
}

function lt(TrimmedAmount a, TrimmedAmount b) pure returns (bool) {
    checkDecimals(a, b);

    return TrimmedAmountLib.getAmount(a) < TrimmedAmountLib.getAmount(b);
}

function sub(TrimmedAmount a, TrimmedAmount b) pure returns (TrimmedAmount) {
    checkDecimals(a, b);

    return packTrimmedAmount(
        TrimmedAmountLib.getAmount(a) - TrimmedAmountLib.getAmount(b),
        TrimmedAmountLib.getDecimals(a)
    );
}

function add(TrimmedAmount a, TrimmedAmount b) pure returns (TrimmedAmount) {
    checkDecimals(a, b);

    return packTrimmedAmount(
        TrimmedAmountLib.getAmount(a) + TrimmedAmountLib.getAmount(b),
        TrimmedAmountLib.getDecimals(b)
    );
}

function min(TrimmedAmount a, TrimmedAmount b) pure returns (TrimmedAmount) {
    checkDecimals(a, b);

    return TrimmedAmountLib.getAmount(a) < TrimmedAmountLib.getAmount(b) ? a : b;
}

library TrimmedAmountLib {
    /// @notice Error when the amount to be trimmed is greater than u64MAX.
    /// @dev Selector 0x08083b2a.
    /// @param amount The amount to be trimmed.
    error AmountTooLarge(uint256 amount);

    function getAmount(TrimmedAmount a) internal pure returns (uint64) {
        // Extract the raw integer value from TrimmedAmount
        uint72 rawValue = TrimmedAmount.unwrap(a);

        // Right shift to keep only the higher 64 bits
        uint64 result = uint64(rawValue >> 8);
        return result;
    }

    function getDecimals(TrimmedAmount a) internal pure returns (uint8) {
        return uint8(TrimmedAmount.unwrap(a) & 0xFF);
    }

    function isNull(TrimmedAmount a) internal pure returns (bool) {
        return (getAmount(a) == 0 && getDecimals(a) == 0);
    }

    function saturatingAdd(
        TrimmedAmount a,
        TrimmedAmount b
    ) internal pure returns (TrimmedAmount) {
        checkDecimals(a, b);

        uint256 saturatedSum;
        uint64 aAmount = getAmount(a);
        uint64 bAmount = getAmount(b);
        unchecked {
            saturatedSum = uint256(aAmount) + uint256(bAmount);
            saturatedSum = saturatedSum > type(uint64).max ? type(uint64).max : saturatedSum;
        }

        return packTrimmedAmount(SafeCast.toUint64(saturatedSum), getDecimals(a));
    }

    /// @dev scale the amount from original decimals to target decimals (base 10)
    function scale(
        uint256 amount,
        uint8 fromDecimals,
        uint8 toDecimals
    ) internal pure returns (uint256) {
        if (fromDecimals == toDecimals) {
            return amount;
        }

        if (fromDecimals > toDecimals) {
            return amount / (10 ** (fromDecimals - toDecimals));
        } else {
            return amount * (10 ** (toDecimals - fromDecimals));
        }
    }

    function shift(TrimmedAmount amount, uint8 toDecimals) internal pure returns (TrimmedAmount) {
        uint8 actualToDecimals = minUint8(TRIMMED_DECIMALS, toDecimals);
        return packTrimmedAmount(
            SafeCast.toUint64(scale(getAmount(amount), getDecimals(amount), actualToDecimals)),
            actualToDecimals
        );
    }

    function max(uint8 decimals) internal pure returns (TrimmedAmount) {
        uint8 actualDecimals = minUint8(TRIMMED_DECIMALS, decimals);
        return packTrimmedAmount(type(uint64).max, actualDecimals);
    }

    /// @dev trim the amount to target decimals.
    ///      The actual resulting decimals is the minimum of TRIMMED_DECIMALS,
    ///      fromDecimals, and toDecimals. This ensures that no dust is
    ///      destroyed on either side of the transfer.
    /// @param amt the amount to be trimmed
    /// @param fromDecimals the original decimals of the amount
    /// @param toDecimals the target decimals of the amount
    /// @return TrimmedAmount uint72 value type bit-packed with decimals
    function trim(
        uint256 amt,
        uint8 fromDecimals,
        uint8 toDecimals
    ) internal pure returns (TrimmedAmount) {
        uint8 actualToDecimals = minUint8(minUint8(TRIMMED_DECIMALS, fromDecimals), toDecimals);
        uint256 amountScaled = scale(amt, fromDecimals, actualToDecimals);

        // NOTE: amt after trimming must fit into uint64 (that's the point of
        // trimming, as Solana only supports uint64 for token amts)
        return packTrimmedAmount(SafeCast.toUint64(amountScaled), actualToDecimals);
    }

    function untrim(TrimmedAmount amt, uint8 toDecimals) internal pure returns (uint256) {
        uint256 deNorm = uint256(getAmount(amt));
        uint8 fromDecimals = getDecimals(amt);
        uint256 amountScaled = scale(deNorm, fromDecimals, toDecimals);

        return amountScaled;
    }
}

File 4 of 4 : SafeCast.sol
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v4.8.0) (utils/math/SafeCast.sol)
// This file was procedurally generated from scripts/generate/templates/SafeCast.js.

pragma solidity ^0.8.0;

/**
 * @dev Wrappers over Solidity's uintXX/intXX casting operators with added overflow
 * checks.
 *
 * Downcasting from uint256/int256 in Solidity does not revert on overflow. This can
 * easily result in undesired exploitation or bugs, since developers usually
 * assume that overflows raise errors. `SafeCast` restores this intuition by
 * reverting the transaction when such an operation overflows.
 *
 * Using this library instead of the unchecked operations eliminates an entire
 * class of bugs, so it's recommended to use it always.
 *
 * Can be combined with {SafeMath} and {SignedSafeMath} to extend it to smaller types, by performing
 * all math on `uint256` and `int256` and then downcasting.
 */
library SafeCast {
    /**
     * @dev Returns the downcasted uint248 from uint256, reverting on
     * overflow (when the input is greater than largest uint248).
     *
     * Counterpart to Solidity's `uint248` operator.
     *
     * Requirements:
     *
     * - input must fit into 248 bits
     *
     * _Available since v4.7._
     */
    function toUint248(uint256 value) internal pure returns (uint248) {
        require(value <= type(uint248).max, "SafeCast: value doesn't fit in 248 bits");
        return uint248(value);
    }

    /**
     * @dev Returns the downcasted uint240 from uint256, reverting on
     * overflow (when the input is greater than largest uint240).
     *
     * Counterpart to Solidity's `uint240` operator.
     *
     * Requirements:
     *
     * - input must fit into 240 bits
     *
     * _Available since v4.7._
     */
    function toUint240(uint256 value) internal pure returns (uint240) {
        require(value <= type(uint240).max, "SafeCast: value doesn't fit in 240 bits");
        return uint240(value);
    }

    /**
     * @dev Returns the downcasted uint232 from uint256, reverting on
     * overflow (when the input is greater than largest uint232).
     *
     * Counterpart to Solidity's `uint232` operator.
     *
     * Requirements:
     *
     * - input must fit into 232 bits
     *
     * _Available since v4.7._
     */
    function toUint232(uint256 value) internal pure returns (uint232) {
        require(value <= type(uint232).max, "SafeCast: value doesn't fit in 232 bits");
        return uint232(value);
    }

    /**
     * @dev Returns the downcasted uint224 from uint256, reverting on
     * overflow (when the input is greater than largest uint224).
     *
     * Counterpart to Solidity's `uint224` operator.
     *
     * Requirements:
     *
     * - input must fit into 224 bits
     *
     * _Available since v4.2._
     */
    function toUint224(uint256 value) internal pure returns (uint224) {
        require(value <= type(uint224).max, "SafeCast: value doesn't fit in 224 bits");
        return uint224(value);
    }

    /**
     * @dev Returns the downcasted uint216 from uint256, reverting on
     * overflow (when the input is greater than largest uint216).
     *
     * Counterpart to Solidity's `uint216` operator.
     *
     * Requirements:
     *
     * - input must fit into 216 bits
     *
     * _Available since v4.7._
     */
    function toUint216(uint256 value) internal pure returns (uint216) {
        require(value <= type(uint216).max, "SafeCast: value doesn't fit in 216 bits");
        return uint216(value);
    }

    /**
     * @dev Returns the downcasted uint208 from uint256, reverting on
     * overflow (when the input is greater than largest uint208).
     *
     * Counterpart to Solidity's `uint208` operator.
     *
     * Requirements:
     *
     * - input must fit into 208 bits
     *
     * _Available since v4.7._
     */
    function toUint208(uint256 value) internal pure returns (uint208) {
        require(value <= type(uint208).max, "SafeCast: value doesn't fit in 208 bits");
        return uint208(value);
    }

    /**
     * @dev Returns the downcasted uint200 from uint256, reverting on
     * overflow (when the input is greater than largest uint200).
     *
     * Counterpart to Solidity's `uint200` operator.
     *
     * Requirements:
     *
     * - input must fit into 200 bits
     *
     * _Available since v4.7._
     */
    function toUint200(uint256 value) internal pure returns (uint200) {
        require(value <= type(uint200).max, "SafeCast: value doesn't fit in 200 bits");
        return uint200(value);
    }

    /**
     * @dev Returns the downcasted uint192 from uint256, reverting on
     * overflow (when the input is greater than largest uint192).
     *
     * Counterpart to Solidity's `uint192` operator.
     *
     * Requirements:
     *
     * - input must fit into 192 bits
     *
     * _Available since v4.7._
     */
    function toUint192(uint256 value) internal pure returns (uint192) {
        require(value <= type(uint192).max, "SafeCast: value doesn't fit in 192 bits");
        return uint192(value);
    }

    /**
     * @dev Returns the downcasted uint184 from uint256, reverting on
     * overflow (when the input is greater than largest uint184).
     *
     * Counterpart to Solidity's `uint184` operator.
     *
     * Requirements:
     *
     * - input must fit into 184 bits
     *
     * _Available since v4.7._
     */
    function toUint184(uint256 value) internal pure returns (uint184) {
        require(value <= type(uint184).max, "SafeCast: value doesn't fit in 184 bits");
        return uint184(value);
    }

    /**
     * @dev Returns the downcasted uint176 from uint256, reverting on
     * overflow (when the input is greater than largest uint176).
     *
     * Counterpart to Solidity's `uint176` operator.
     *
     * Requirements:
     *
     * - input must fit into 176 bits
     *
     * _Available since v4.7._
     */
    function toUint176(uint256 value) internal pure returns (uint176) {
        require(value <= type(uint176).max, "SafeCast: value doesn't fit in 176 bits");
        return uint176(value);
    }

    /**
     * @dev Returns the downcasted uint168 from uint256, reverting on
     * overflow (when the input is greater than largest uint168).
     *
     * Counterpart to Solidity's `uint168` operator.
     *
     * Requirements:
     *
     * - input must fit into 168 bits
     *
     * _Available since v4.7._
     */
    function toUint168(uint256 value) internal pure returns (uint168) {
        require(value <= type(uint168).max, "SafeCast: value doesn't fit in 168 bits");
        return uint168(value);
    }

    /**
     * @dev Returns the downcasted uint160 from uint256, reverting on
     * overflow (when the input is greater than largest uint160).
     *
     * Counterpart to Solidity's `uint160` operator.
     *
     * Requirements:
     *
     * - input must fit into 160 bits
     *
     * _Available since v4.7._
     */
    function toUint160(uint256 value) internal pure returns (uint160) {
        require(value <= type(uint160).max, "SafeCast: value doesn't fit in 160 bits");
        return uint160(value);
    }

    /**
     * @dev Returns the downcasted uint152 from uint256, reverting on
     * overflow (when the input is greater than largest uint152).
     *
     * Counterpart to Solidity's `uint152` operator.
     *
     * Requirements:
     *
     * - input must fit into 152 bits
     *
     * _Available since v4.7._
     */
    function toUint152(uint256 value) internal pure returns (uint152) {
        require(value <= type(uint152).max, "SafeCast: value doesn't fit in 152 bits");
        return uint152(value);
    }

    /**
     * @dev Returns the downcasted uint144 from uint256, reverting on
     * overflow (when the input is greater than largest uint144).
     *
     * Counterpart to Solidity's `uint144` operator.
     *
     * Requirements:
     *
     * - input must fit into 144 bits
     *
     * _Available since v4.7._
     */
    function toUint144(uint256 value) internal pure returns (uint144) {
        require(value <= type(uint144).max, "SafeCast: value doesn't fit in 144 bits");
        return uint144(value);
    }

    /**
     * @dev Returns the downcasted uint136 from uint256, reverting on
     * overflow (when the input is greater than largest uint136).
     *
     * Counterpart to Solidity's `uint136` operator.
     *
     * Requirements:
     *
     * - input must fit into 136 bits
     *
     * _Available since v4.7._
     */
    function toUint136(uint256 value) internal pure returns (uint136) {
        require(value <= type(uint136).max, "SafeCast: value doesn't fit in 136 bits");
        return uint136(value);
    }

    /**
     * @dev Returns the downcasted uint128 from uint256, reverting on
     * overflow (when the input is greater than largest uint128).
     *
     * Counterpart to Solidity's `uint128` operator.
     *
     * Requirements:
     *
     * - input must fit into 128 bits
     *
     * _Available since v2.5._
     */
    function toUint128(uint256 value) internal pure returns (uint128) {
        require(value <= type(uint128).max, "SafeCast: value doesn't fit in 128 bits");
        return uint128(value);
    }

    /**
     * @dev Returns the downcasted uint120 from uint256, reverting on
     * overflow (when the input is greater than largest uint120).
     *
     * Counterpart to Solidity's `uint120` operator.
     *
     * Requirements:
     *
     * - input must fit into 120 bits
     *
     * _Available since v4.7._
     */
    function toUint120(uint256 value) internal pure returns (uint120) {
        require(value <= type(uint120).max, "SafeCast: value doesn't fit in 120 bits");
        return uint120(value);
    }

    /**
     * @dev Returns the downcasted uint112 from uint256, reverting on
     * overflow (when the input is greater than largest uint112).
     *
     * Counterpart to Solidity's `uint112` operator.
     *
     * Requirements:
     *
     * - input must fit into 112 bits
     *
     * _Available since v4.7._
     */
    function toUint112(uint256 value) internal pure returns (uint112) {
        require(value <= type(uint112).max, "SafeCast: value doesn't fit in 112 bits");
        return uint112(value);
    }

    /**
     * @dev Returns the downcasted uint104 from uint256, reverting on
     * overflow (when the input is greater than largest uint104).
     *
     * Counterpart to Solidity's `uint104` operator.
     *
     * Requirements:
     *
     * - input must fit into 104 bits
     *
     * _Available since v4.7._
     */
    function toUint104(uint256 value) internal pure returns (uint104) {
        require(value <= type(uint104).max, "SafeCast: value doesn't fit in 104 bits");
        return uint104(value);
    }

    /**
     * @dev Returns the downcasted uint96 from uint256, reverting on
     * overflow (when the input is greater than largest uint96).
     *
     * Counterpart to Solidity's `uint96` operator.
     *
     * Requirements:
     *
     * - input must fit into 96 bits
     *
     * _Available since v4.2._
     */
    function toUint96(uint256 value) internal pure returns (uint96) {
        require(value <= type(uint96).max, "SafeCast: value doesn't fit in 96 bits");
        return uint96(value);
    }

    /**
     * @dev Returns the downcasted uint88 from uint256, reverting on
     * overflow (when the input is greater than largest uint88).
     *
     * Counterpart to Solidity's `uint88` operator.
     *
     * Requirements:
     *
     * - input must fit into 88 bits
     *
     * _Available since v4.7._
     */
    function toUint88(uint256 value) internal pure returns (uint88) {
        require(value <= type(uint88).max, "SafeCast: value doesn't fit in 88 bits");
        return uint88(value);
    }

    /**
     * @dev Returns the downcasted uint80 from uint256, reverting on
     * overflow (when the input is greater than largest uint80).
     *
     * Counterpart to Solidity's `uint80` operator.
     *
     * Requirements:
     *
     * - input must fit into 80 bits
     *
     * _Available since v4.7._
     */
    function toUint80(uint256 value) internal pure returns (uint80) {
        require(value <= type(uint80).max, "SafeCast: value doesn't fit in 80 bits");
        return uint80(value);
    }

    /**
     * @dev Returns the downcasted uint72 from uint256, reverting on
     * overflow (when the input is greater than largest uint72).
     *
     * Counterpart to Solidity's `uint72` operator.
     *
     * Requirements:
     *
     * - input must fit into 72 bits
     *
     * _Available since v4.7._
     */
    function toUint72(uint256 value) internal pure returns (uint72) {
        require(value <= type(uint72).max, "SafeCast: value doesn't fit in 72 bits");
        return uint72(value);
    }

    /**
     * @dev Returns the downcasted uint64 from uint256, reverting on
     * overflow (when the input is greater than largest uint64).
     *
     * Counterpart to Solidity's `uint64` operator.
     *
     * Requirements:
     *
     * - input must fit into 64 bits
     *
     * _Available since v2.5._
     */
    function toUint64(uint256 value) internal pure returns (uint64) {
        require(value <= type(uint64).max, "SafeCast: value doesn't fit in 64 bits");
        return uint64(value);
    }

    /**
     * @dev Returns the downcasted uint56 from uint256, reverting on
     * overflow (when the input is greater than largest uint56).
     *
     * Counterpart to Solidity's `uint56` operator.
     *
     * Requirements:
     *
     * - input must fit into 56 bits
     *
     * _Available since v4.7._
     */
    function toUint56(uint256 value) internal pure returns (uint56) {
        require(value <= type(uint56).max, "SafeCast: value doesn't fit in 56 bits");
        return uint56(value);
    }

    /**
     * @dev Returns the downcasted uint48 from uint256, reverting on
     * overflow (when the input is greater than largest uint48).
     *
     * Counterpart to Solidity's `uint48` operator.
     *
     * Requirements:
     *
     * - input must fit into 48 bits
     *
     * _Available since v4.7._
     */
    function toUint48(uint256 value) internal pure returns (uint48) {
        require(value <= type(uint48).max, "SafeCast: value doesn't fit in 48 bits");
        return uint48(value);
    }

    /**
     * @dev Returns the downcasted uint40 from uint256, reverting on
     * overflow (when the input is greater than largest uint40).
     *
     * Counterpart to Solidity's `uint40` operator.
     *
     * Requirements:
     *
     * - input must fit into 40 bits
     *
     * _Available since v4.7._
     */
    function toUint40(uint256 value) internal pure returns (uint40) {
        require(value <= type(uint40).max, "SafeCast: value doesn't fit in 40 bits");
        return uint40(value);
    }

    /**
     * @dev Returns the downcasted uint32 from uint256, reverting on
     * overflow (when the input is greater than largest uint32).
     *
     * Counterpart to Solidity's `uint32` operator.
     *
     * Requirements:
     *
     * - input must fit into 32 bits
     *
     * _Available since v2.5._
     */
    function toUint32(uint256 value) internal pure returns (uint32) {
        require(value <= type(uint32).max, "SafeCast: value doesn't fit in 32 bits");
        return uint32(value);
    }

    /**
     * @dev Returns the downcasted uint24 from uint256, reverting on
     * overflow (when the input is greater than largest uint24).
     *
     * Counterpart to Solidity's `uint24` operator.
     *
     * Requirements:
     *
     * - input must fit into 24 bits
     *
     * _Available since v4.7._
     */
    function toUint24(uint256 value) internal pure returns (uint24) {
        require(value <= type(uint24).max, "SafeCast: value doesn't fit in 24 bits");
        return uint24(value);
    }

    /**
     * @dev Returns the downcasted uint16 from uint256, reverting on
     * overflow (when the input is greater than largest uint16).
     *
     * Counterpart to Solidity's `uint16` operator.
     *
     * Requirements:
     *
     * - input must fit into 16 bits
     *
     * _Available since v2.5._
     */
    function toUint16(uint256 value) internal pure returns (uint16) {
        require(value <= type(uint16).max, "SafeCast: value doesn't fit in 16 bits");
        return uint16(value);
    }

    /**
     * @dev Returns the downcasted uint8 from uint256, reverting on
     * overflow (when the input is greater than largest uint8).
     *
     * Counterpart to Solidity's `uint8` operator.
     *
     * Requirements:
     *
     * - input must fit into 8 bits
     *
     * _Available since v2.5._
     */
    function toUint8(uint256 value) internal pure returns (uint8) {
        require(value <= type(uint8).max, "SafeCast: value doesn't fit in 8 bits");
        return uint8(value);
    }

    /**
     * @dev Converts a signed int256 into an unsigned uint256.
     *
     * Requirements:
     *
     * - input must be greater than or equal to 0.
     *
     * _Available since v3.0._
     */
    function toUint256(int256 value) internal pure returns (uint256) {
        require(value >= 0, "SafeCast: value must be positive");
        return uint256(value);
    }

    /**
     * @dev Returns the downcasted int248 from int256, reverting on
     * overflow (when the input is less than smallest int248 or
     * greater than largest int248).
     *
     * Counterpart to Solidity's `int248` operator.
     *
     * Requirements:
     *
     * - input must fit into 248 bits
     *
     * _Available since v4.7._
     */
    function toInt248(int256 value) internal pure returns (int248 downcasted) {
        downcasted = int248(value);
        require(downcasted == value, "SafeCast: value doesn't fit in 248 bits");
    }

    /**
     * @dev Returns the downcasted int240 from int256, reverting on
     * overflow (when the input is less than smallest int240 or
     * greater than largest int240).
     *
     * Counterpart to Solidity's `int240` operator.
     *
     * Requirements:
     *
     * - input must fit into 240 bits
     *
     * _Available since v4.7._
     */
    function toInt240(int256 value) internal pure returns (int240 downcasted) {
        downcasted = int240(value);
        require(downcasted == value, "SafeCast: value doesn't fit in 240 bits");
    }

    /**
     * @dev Returns the downcasted int232 from int256, reverting on
     * overflow (when the input is less than smallest int232 or
     * greater than largest int232).
     *
     * Counterpart to Solidity's `int232` operator.
     *
     * Requirements:
     *
     * - input must fit into 232 bits
     *
     * _Available since v4.7._
     */
    function toInt232(int256 value) internal pure returns (int232 downcasted) {
        downcasted = int232(value);
        require(downcasted == value, "SafeCast: value doesn't fit in 232 bits");
    }

    /**
     * @dev Returns the downcasted int224 from int256, reverting on
     * overflow (when the input is less than smallest int224 or
     * greater than largest int224).
     *
     * Counterpart to Solidity's `int224` operator.
     *
     * Requirements:
     *
     * - input must fit into 224 bits
     *
     * _Available since v4.7._
     */
    function toInt224(int256 value) internal pure returns (int224 downcasted) {
        downcasted = int224(value);
        require(downcasted == value, "SafeCast: value doesn't fit in 224 bits");
    }

    /**
     * @dev Returns the downcasted int216 from int256, reverting on
     * overflow (when the input is less than smallest int216 or
     * greater than largest int216).
     *
     * Counterpart to Solidity's `int216` operator.
     *
     * Requirements:
     *
     * - input must fit into 216 bits
     *
     * _Available since v4.7._
     */
    function toInt216(int256 value) internal pure returns (int216 downcasted) {
        downcasted = int216(value);
        require(downcasted == value, "SafeCast: value doesn't fit in 216 bits");
    }

    /**
     * @dev Returns the downcasted int208 from int256, reverting on
     * overflow (when the input is less than smallest int208 or
     * greater than largest int208).
     *
     * Counterpart to Solidity's `int208` operator.
     *
     * Requirements:
     *
     * - input must fit into 208 bits
     *
     * _Available since v4.7._
     */
    function toInt208(int256 value) internal pure returns (int208 downcasted) {
        downcasted = int208(value);
        require(downcasted == value, "SafeCast: value doesn't fit in 208 bits");
    }

    /**
     * @dev Returns the downcasted int200 from int256, reverting on
     * overflow (when the input is less than smallest int200 or
     * greater than largest int200).
     *
     * Counterpart to Solidity's `int200` operator.
     *
     * Requirements:
     *
     * - input must fit into 200 bits
     *
     * _Available since v4.7._
     */
    function toInt200(int256 value) internal pure returns (int200 downcasted) {
        downcasted = int200(value);
        require(downcasted == value, "SafeCast: value doesn't fit in 200 bits");
    }

    /**
     * @dev Returns the downcasted int192 from int256, reverting on
     * overflow (when the input is less than smallest int192 or
     * greater than largest int192).
     *
     * Counterpart to Solidity's `int192` operator.
     *
     * Requirements:
     *
     * - input must fit into 192 bits
     *
     * _Available since v4.7._
     */
    function toInt192(int256 value) internal pure returns (int192 downcasted) {
        downcasted = int192(value);
        require(downcasted == value, "SafeCast: value doesn't fit in 192 bits");
    }

    /**
     * @dev Returns the downcasted int184 from int256, reverting on
     * overflow (when the input is less than smallest int184 or
     * greater than largest int184).
     *
     * Counterpart to Solidity's `int184` operator.
     *
     * Requirements:
     *
     * - input must fit into 184 bits
     *
     * _Available since v4.7._
     */
    function toInt184(int256 value) internal pure returns (int184 downcasted) {
        downcasted = int184(value);
        require(downcasted == value, "SafeCast: value doesn't fit in 184 bits");
    }

    /**
     * @dev Returns the downcasted int176 from int256, reverting on
     * overflow (when the input is less than smallest int176 or
     * greater than largest int176).
     *
     * Counterpart to Solidity's `int176` operator.
     *
     * Requirements:
     *
     * - input must fit into 176 bits
     *
     * _Available since v4.7._
     */
    function toInt176(int256 value) internal pure returns (int176 downcasted) {
        downcasted = int176(value);
        require(downcasted == value, "SafeCast: value doesn't fit in 176 bits");
    }

    /**
     * @dev Returns the downcasted int168 from int256, reverting on
     * overflow (when the input is less than smallest int168 or
     * greater than largest int168).
     *
     * Counterpart to Solidity's `int168` operator.
     *
     * Requirements:
     *
     * - input must fit into 168 bits
     *
     * _Available since v4.7._
     */
    function toInt168(int256 value) internal pure returns (int168 downcasted) {
        downcasted = int168(value);
        require(downcasted == value, "SafeCast: value doesn't fit in 168 bits");
    }

    /**
     * @dev Returns the downcasted int160 from int256, reverting on
     * overflow (when the input is less than smallest int160 or
     * greater than largest int160).
     *
     * Counterpart to Solidity's `int160` operator.
     *
     * Requirements:
     *
     * - input must fit into 160 bits
     *
     * _Available since v4.7._
     */
    function toInt160(int256 value) internal pure returns (int160 downcasted) {
        downcasted = int160(value);
        require(downcasted == value, "SafeCast: value doesn't fit in 160 bits");
    }

    /**
     * @dev Returns the downcasted int152 from int256, reverting on
     * overflow (when the input is less than smallest int152 or
     * greater than largest int152).
     *
     * Counterpart to Solidity's `int152` operator.
     *
     * Requirements:
     *
     * - input must fit into 152 bits
     *
     * _Available since v4.7._
     */
    function toInt152(int256 value) internal pure returns (int152 downcasted) {
        downcasted = int152(value);
        require(downcasted == value, "SafeCast: value doesn't fit in 152 bits");
    }

    /**
     * @dev Returns the downcasted int144 from int256, reverting on
     * overflow (when the input is less than smallest int144 or
     * greater than largest int144).
     *
     * Counterpart to Solidity's `int144` operator.
     *
     * Requirements:
     *
     * - input must fit into 144 bits
     *
     * _Available since v4.7._
     */
    function toInt144(int256 value) internal pure returns (int144 downcasted) {
        downcasted = int144(value);
        require(downcasted == value, "SafeCast: value doesn't fit in 144 bits");
    }

    /**
     * @dev Returns the downcasted int136 from int256, reverting on
     * overflow (when the input is less than smallest int136 or
     * greater than largest int136).
     *
     * Counterpart to Solidity's `int136` operator.
     *
     * Requirements:
     *
     * - input must fit into 136 bits
     *
     * _Available since v4.7._
     */
    function toInt136(int256 value) internal pure returns (int136 downcasted) {
        downcasted = int136(value);
        require(downcasted == value, "SafeCast: value doesn't fit in 136 bits");
    }

    /**
     * @dev Returns the downcasted int128 from int256, reverting on
     * overflow (when the input is less than smallest int128 or
     * greater than largest int128).
     *
     * Counterpart to Solidity's `int128` operator.
     *
     * Requirements:
     *
     * - input must fit into 128 bits
     *
     * _Available since v3.1._
     */
    function toInt128(int256 value) internal pure returns (int128 downcasted) {
        downcasted = int128(value);
        require(downcasted == value, "SafeCast: value doesn't fit in 128 bits");
    }

    /**
     * @dev Returns the downcasted int120 from int256, reverting on
     * overflow (when the input is less than smallest int120 or
     * greater than largest int120).
     *
     * Counterpart to Solidity's `int120` operator.
     *
     * Requirements:
     *
     * - input must fit into 120 bits
     *
     * _Available since v4.7._
     */
    function toInt120(int256 value) internal pure returns (int120 downcasted) {
        downcasted = int120(value);
        require(downcasted == value, "SafeCast: value doesn't fit in 120 bits");
    }

    /**
     * @dev Returns the downcasted int112 from int256, reverting on
     * overflow (when the input is less than smallest int112 or
     * greater than largest int112).
     *
     * Counterpart to Solidity's `int112` operator.
     *
     * Requirements:
     *
     * - input must fit into 112 bits
     *
     * _Available since v4.7._
     */
    function toInt112(int256 value) internal pure returns (int112 downcasted) {
        downcasted = int112(value);
        require(downcasted == value, "SafeCast: value doesn't fit in 112 bits");
    }

    /**
     * @dev Returns the downcasted int104 from int256, reverting on
     * overflow (when the input is less than smallest int104 or
     * greater than largest int104).
     *
     * Counterpart to Solidity's `int104` operator.
     *
     * Requirements:
     *
     * - input must fit into 104 bits
     *
     * _Available since v4.7._
     */
    function toInt104(int256 value) internal pure returns (int104 downcasted) {
        downcasted = int104(value);
        require(downcasted == value, "SafeCast: value doesn't fit in 104 bits");
    }

    /**
     * @dev Returns the downcasted int96 from int256, reverting on
     * overflow (when the input is less than smallest int96 or
     * greater than largest int96).
     *
     * Counterpart to Solidity's `int96` operator.
     *
     * Requirements:
     *
     * - input must fit into 96 bits
     *
     * _Available since v4.7._
     */
    function toInt96(int256 value) internal pure returns (int96 downcasted) {
        downcasted = int96(value);
        require(downcasted == value, "SafeCast: value doesn't fit in 96 bits");
    }

    /**
     * @dev Returns the downcasted int88 from int256, reverting on
     * overflow (when the input is less than smallest int88 or
     * greater than largest int88).
     *
     * Counterpart to Solidity's `int88` operator.
     *
     * Requirements:
     *
     * - input must fit into 88 bits
     *
     * _Available since v4.7._
     */
    function toInt88(int256 value) internal pure returns (int88 downcasted) {
        downcasted = int88(value);
        require(downcasted == value, "SafeCast: value doesn't fit in 88 bits");
    }

    /**
     * @dev Returns the downcasted int80 from int256, reverting on
     * overflow (when the input is less than smallest int80 or
     * greater than largest int80).
     *
     * Counterpart to Solidity's `int80` operator.
     *
     * Requirements:
     *
     * - input must fit into 80 bits
     *
     * _Available since v4.7._
     */
    function toInt80(int256 value) internal pure returns (int80 downcasted) {
        downcasted = int80(value);
        require(downcasted == value, "SafeCast: value doesn't fit in 80 bits");
    }

    /**
     * @dev Returns the downcasted int72 from int256, reverting on
     * overflow (when the input is less than smallest int72 or
     * greater than largest int72).
     *
     * Counterpart to Solidity's `int72` operator.
     *
     * Requirements:
     *
     * - input must fit into 72 bits
     *
     * _Available since v4.7._
     */
    function toInt72(int256 value) internal pure returns (int72 downcasted) {
        downcasted = int72(value);
        require(downcasted == value, "SafeCast: value doesn't fit in 72 bits");
    }

    /**
     * @dev Returns the downcasted int64 from int256, reverting on
     * overflow (when the input is less than smallest int64 or
     * greater than largest int64).
     *
     * Counterpart to Solidity's `int64` operator.
     *
     * Requirements:
     *
     * - input must fit into 64 bits
     *
     * _Available since v3.1._
     */
    function toInt64(int256 value) internal pure returns (int64 downcasted) {
        downcasted = int64(value);
        require(downcasted == value, "SafeCast: value doesn't fit in 64 bits");
    }

    /**
     * @dev Returns the downcasted int56 from int256, reverting on
     * overflow (when the input is less than smallest int56 or
     * greater than largest int56).
     *
     * Counterpart to Solidity's `int56` operator.
     *
     * Requirements:
     *
     * - input must fit into 56 bits
     *
     * _Available since v4.7._
     */
    function toInt56(int256 value) internal pure returns (int56 downcasted) {
        downcasted = int56(value);
        require(downcasted == value, "SafeCast: value doesn't fit in 56 bits");
    }

    /**
     * @dev Returns the downcasted int48 from int256, reverting on
     * overflow (when the input is less than smallest int48 or
     * greater than largest int48).
     *
     * Counterpart to Solidity's `int48` operator.
     *
     * Requirements:
     *
     * - input must fit into 48 bits
     *
     * _Available since v4.7._
     */
    function toInt48(int256 value) internal pure returns (int48 downcasted) {
        downcasted = int48(value);
        require(downcasted == value, "SafeCast: value doesn't fit in 48 bits");
    }

    /**
     * @dev Returns the downcasted int40 from int256, reverting on
     * overflow (when the input is less than smallest int40 or
     * greater than largest int40).
     *
     * Counterpart to Solidity's `int40` operator.
     *
     * Requirements:
     *
     * - input must fit into 40 bits
     *
     * _Available since v4.7._
     */
    function toInt40(int256 value) internal pure returns (int40 downcasted) {
        downcasted = int40(value);
        require(downcasted == value, "SafeCast: value doesn't fit in 40 bits");
    }

    /**
     * @dev Returns the downcasted int32 from int256, reverting on
     * overflow (when the input is less than smallest int32 or
     * greater than largest int32).
     *
     * Counterpart to Solidity's `int32` operator.
     *
     * Requirements:
     *
     * - input must fit into 32 bits
     *
     * _Available since v3.1._
     */
    function toInt32(int256 value) internal pure returns (int32 downcasted) {
        downcasted = int32(value);
        require(downcasted == value, "SafeCast: value doesn't fit in 32 bits");
    }

    /**
     * @dev Returns the downcasted int24 from int256, reverting on
     * overflow (when the input is less than smallest int24 or
     * greater than largest int24).
     *
     * Counterpart to Solidity's `int24` operator.
     *
     * Requirements:
     *
     * - input must fit into 24 bits
     *
     * _Available since v4.7._
     */
    function toInt24(int256 value) internal pure returns (int24 downcasted) {
        downcasted = int24(value);
        require(downcasted == value, "SafeCast: value doesn't fit in 24 bits");
    }

    /**
     * @dev Returns the downcasted int16 from int256, reverting on
     * overflow (when the input is less than smallest int16 or
     * greater than largest int16).
     *
     * Counterpart to Solidity's `int16` operator.
     *
     * Requirements:
     *
     * - input must fit into 16 bits
     *
     * _Available since v3.1._
     */
    function toInt16(int256 value) internal pure returns (int16 downcasted) {
        downcasted = int16(value);
        require(downcasted == value, "SafeCast: value doesn't fit in 16 bits");
    }

    /**
     * @dev Returns the downcasted int8 from int256, reverting on
     * overflow (when the input is less than smallest int8 or
     * greater than largest int8).
     *
     * Counterpart to Solidity's `int8` operator.
     *
     * Requirements:
     *
     * - input must fit into 8 bits
     *
     * _Available since v3.1._
     */
    function toInt8(int256 value) internal pure returns (int8 downcasted) {
        downcasted = int8(value);
        require(downcasted == value, "SafeCast: value doesn't fit in 8 bits");
    }

    /**
     * @dev Converts an unsigned uint256 into a signed int256.
     *
     * Requirements:
     *
     * - input must be less than or equal to maxInt256.
     *
     * _Available since v3.0._
     */
    function toInt256(uint256 value) internal pure returns (int256) {
        // Note: Unsafe cast below is okay because `type(int256).max` is guaranteed to be positive
        require(value <= uint256(type(int256).max), "SafeCast: value doesn't fit in an int256");
        return int256(value);
    }
}

Settings
{
  "remappings": [
    "ds-test/=lib/forge-std/lib/ds-test/src/",
    "forge-std/=lib/forge-std/src/",
    "openzeppelin-contracts/=lib/openzeppelin-contracts/",
    "wormhole-solidity-sdk/=lib/wormhole-solidity-sdk/src/"
  ],
  "optimizer": {
    "enabled": true,
    "runs": 200
  },
  "metadata": {
    "useLiteralContent": false,
    "bytecodeHash": "ipfs",
    "appendCBOR": true
  },
  "outputSelection": {
    "*": {
      "*": [
        "evm.bytecode",
        "evm.deployedBytecode",
        "devdoc",
        "userdoc",
        "metadata",
        "abi"
      ]
    }
  },
  "evmVersion": "london",
  "viaIR": true,
  "libraries": {}
}

Contract Security Audit

Contract ABI

[{"inputs":[{"internalType":"bytes4","name":"prefix","type":"bytes4"}],"name":"IncorrectPrefix","type":"error"},{"inputs":[{"internalType":"uint256","name":"providedIndex","type":"uint256"},{"internalType":"uint256","name":"numTransceivers","type":"uint256"}],"name":"InvalidInstructionIndex","type":"error"},{"inputs":[{"internalType":"uint256","name":"encodedLength","type":"uint256"},{"internalType":"uint256","name":"expectedLength","type":"uint256"}],"name":"LengthMismatch","type":"error"},{"inputs":[{"internalType":"uint256","name":"size","type":"uint256"}],"name":"PayloadTooLong","type":"error"},{"inputs":[{"internalType":"uint256","name":"lastIndex","type":"uint256"},{"internalType":"uint256","name":"instructionIndex","type":"uint256"}],"name":"UnorderedInstructions","type":"error"},{"inputs":[{"internalType":"bytes4","name":"prefix","type":"bytes4"},{"internalType":"bytes32","name":"sourceNttManagerAddress","type":"bytes32"},{"internalType":"bytes32","name":"recipientNttManagerAddress","type":"bytes32"},{"internalType":"bytes","name":"nttManagerMessage","type":"bytes"},{"internalType":"bytes","name":"transceiverPayload","type":"bytes"}],"name":"buildAndEncodeTransceiverMessage","outputs":[{"components":[{"internalType":"bytes32","name":"sourceNttManagerAddress","type":"bytes32"},{"internalType":"bytes32","name":"recipientNttManagerAddress","type":"bytes32"},{"internalType":"bytes","name":"nttManagerPayload","type":"bytes"},{"internalType":"bytes","name":"transceiverPayload","type":"bytes"}],"internalType":"struct TransceiverStructs.TransceiverMessage","name":"","type":"tuple"},{"internalType":"bytes","name":"","type":"bytes"}],"stateMutability":"pure","type":"function"},{"inputs":[{"internalType":"bytes","name":"encoded","type":"bytes"}],"name":"decodeTransceiverInit","outputs":[{"components":[{"internalType":"bytes4","name":"transceiverIdentifier","type":"bytes4"},{"internalType":"bytes32","name":"nttManagerAddress","type":"bytes32"},{"internalType":"uint8","name":"nttManagerMode","type":"uint8"},{"internalType":"bytes32","name":"tokenAddress","type":"bytes32"},{"internalType":"uint8","name":"tokenDecimals","type":"uint8"}],"internalType":"struct TransceiverStructs.TransceiverInit","name":"init","type":"tuple"}],"stateMutability":"pure","type":"function"},{"inputs":[{"internalType":"bytes","name":"encoded","type":"bytes"}],"name":"decodeTransceiverRegistration","outputs":[{"components":[{"internalType":"bytes4","name":"transceiverIdentifier","type":"bytes4"},{"internalType":"uint16","name":"transceiverChainId","type":"uint16"},{"internalType":"bytes32","name":"transceiverAddress","type":"bytes32"}],"internalType":"struct TransceiverStructs.TransceiverRegistration","name":"registration","type":"tuple"}],"stateMutability":"pure","type":"function"},{"inputs":[{"components":[{"internalType":"TrimmedAmount","name":"amount","type":"uint72"},{"internalType":"bytes32","name":"sourceToken","type":"bytes32"},{"internalType":"bytes32","name":"to","type":"bytes32"},{"internalType":"uint16","name":"toChain","type":"uint16"}],"internalType":"struct TransceiverStructs.NativeTokenTransfer","name":"m","type":"tuple"}],"name":"encodeNativeTokenTransfer","outputs":[{"internalType":"bytes","name":"encoded","type":"bytes"}],"stateMutability":"pure","type":"function"},{"inputs":[{"components":[{"internalType":"bytes32","name":"id","type":"bytes32"},{"internalType":"bytes32","name":"sender","type":"bytes32"},{"internalType":"bytes","name":"payload","type":"bytes"}],"internalType":"struct TransceiverStructs.NttManagerMessage","name":"m","type":"tuple"}],"name":"encodeNttManagerMessage","outputs":[{"internalType":"bytes","name":"encoded","type":"bytes"}],"stateMutability":"pure","type":"function"},{"inputs":[{"components":[{"internalType":"bytes4","name":"transceiverIdentifier","type":"bytes4"},{"internalType":"bytes32","name":"nttManagerAddress","type":"bytes32"},{"internalType":"uint8","name":"nttManagerMode","type":"uint8"},{"internalType":"bytes32","name":"tokenAddress","type":"bytes32"},{"internalType":"uint8","name":"tokenDecimals","type":"uint8"}],"internalType":"struct TransceiverStructs.TransceiverInit","name":"init","type":"tuple"}],"name":"encodeTransceiverInit","outputs":[{"internalType":"bytes","name":"","type":"bytes"}],"stateMutability":"pure","type":"function"},{"inputs":[{"components":[{"internalType":"uint8","name":"index","type":"uint8"},{"internalType":"bytes","name":"payload","type":"bytes"}],"internalType":"struct TransceiverStructs.TransceiverInstruction","name":"instruction","type":"tuple"}],"name":"encodeTransceiverInstruction","outputs":[{"internalType":"bytes","name":"","type":"bytes"}],"stateMutability":"pure","type":"function"},{"inputs":[{"components":[{"internalType":"uint8","name":"index","type":"uint8"},{"internalType":"bytes","name":"payload","type":"bytes"}],"internalType":"struct TransceiverStructs.TransceiverInstruction[]","name":"instructions","type":"tuple[]"}],"name":"encodeTransceiverInstructions","outputs":[{"internalType":"bytes","name":"","type":"bytes"}],"stateMutability":"pure","type":"function"},{"inputs":[{"internalType":"bytes4","name":"prefix","type":"bytes4"},{"components":[{"internalType":"bytes32","name":"sourceNttManagerAddress","type":"bytes32"},{"internalType":"bytes32","name":"recipientNttManagerAddress","type":"bytes32"},{"internalType":"bytes","name":"nttManagerPayload","type":"bytes"},{"internalType":"bytes","name":"transceiverPayload","type":"bytes"}],"internalType":"struct TransceiverStructs.TransceiverMessage","name":"m","type":"tuple"}],"name":"encodeTransceiverMessage","outputs":[{"internalType":"bytes","name":"encoded","type":"bytes"}],"stateMutability":"pure","type":"function"},{"inputs":[{"components":[{"internalType":"bytes4","name":"transceiverIdentifier","type":"bytes4"},{"internalType":"uint16","name":"transceiverChainId","type":"uint16"},{"internalType":"bytes32","name":"transceiverAddress","type":"bytes32"}],"internalType":"struct TransceiverStructs.TransceiverRegistration","name":"registration","type":"tuple"}],"name":"encodeTransceiverRegistration","outputs":[{"internalType":"bytes","name":"","type":"bytes"}],"stateMutability":"pure","type":"function"},{"inputs":[{"internalType":"uint16","name":"sourceChainId","type":"uint16"},{"components":[{"internalType":"bytes32","name":"id","type":"bytes32"},{"internalType":"bytes32","name":"sender","type":"bytes32"},{"internalType":"bytes","name":"payload","type":"bytes"}],"internalType":"struct TransceiverStructs.NttManagerMessage","name":"m","type":"tuple"}],"name":"nttManagerMessageDigest","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"pure","type":"function"},{"inputs":[{"internalType":"bytes","name":"encoded","type":"bytes"}],"name":"parseNativeTokenTransfer","outputs":[{"components":[{"internalType":"TrimmedAmount","name":"amount","type":"uint72"},{"internalType":"bytes32","name":"sourceToken","type":"bytes32"},{"internalType":"bytes32","name":"to","type":"bytes32"},{"internalType":"uint16","name":"toChain","type":"uint16"}],"internalType":"struct TransceiverStructs.NativeTokenTransfer","name":"nativeTokenTransfer","type":"tuple"}],"stateMutability":"pure","type":"function"},{"inputs":[{"internalType":"bytes","name":"encoded","type":"bytes"}],"name":"parseNttManagerMessage","outputs":[{"components":[{"internalType":"bytes32","name":"id","type":"bytes32"},{"internalType":"bytes32","name":"sender","type":"bytes32"},{"internalType":"bytes","name":"payload","type":"bytes"}],"internalType":"struct TransceiverStructs.NttManagerMessage","name":"nttManagerMessage","type":"tuple"}],"stateMutability":"pure","type":"function"},{"inputs":[{"internalType":"bytes4","name":"expectedPrefix","type":"bytes4"},{"internalType":"bytes","name":"payload","type":"bytes"}],"name":"parseTransceiverAndNttManagerMessage","outputs":[{"components":[{"internalType":"bytes32","name":"sourceNttManagerAddress","type":"bytes32"},{"internalType":"bytes32","name":"recipientNttManagerAddress","type":"bytes32"},{"internalType":"bytes","name":"nttManagerPayload","type":"bytes"},{"internalType":"bytes","name":"transceiverPayload","type":"bytes"}],"internalType":"struct TransceiverStructs.TransceiverMessage","name":"","type":"tuple"},{"components":[{"internalType":"bytes32","name":"id","type":"bytes32"},{"internalType":"bytes32","name":"sender","type":"bytes32"},{"internalType":"bytes","name":"payload","type":"bytes"}],"internalType":"struct TransceiverStructs.NttManagerMessage","name":"","type":"tuple"}],"stateMutability":"pure","type":"function"},{"inputs":[{"internalType":"bytes","name":"encoded","type":"bytes"}],"name":"parseTransceiverInstructionChecked","outputs":[{"components":[{"internalType":"uint8","name":"index","type":"uint8"},{"internalType":"bytes","name":"payload","type":"bytes"}],"internalType":"struct TransceiverStructs.TransceiverInstruction","name":"instruction","type":"tuple"}],"stateMutability":"pure","type":"function"},{"inputs":[{"internalType":"bytes","name":"encoded","type":"bytes"},{"internalType":"uint256","name":"offset","type":"uint256"}],"name":"parseTransceiverInstructionUnchecked","outputs":[{"components":[{"internalType":"uint8","name":"index","type":"uint8"},{"internalType":"bytes","name":"payload","type":"bytes"}],"internalType":"struct TransceiverStructs.TransceiverInstruction","name":"instruction","type":"tuple"},{"internalType":"uint256","name":"nextOffset","type":"uint256"}],"stateMutability":"pure","type":"function"},{"inputs":[{"internalType":"bytes","name":"encoded","type":"bytes"},{"internalType":"uint256","name":"numRegisteredTransceivers","type":"uint256"}],"name":"parseTransceiverInstructions","outputs":[{"components":[{"internalType":"uint8","name":"index","type":"uint8"},{"internalType":"bytes","name":"payload","type":"bytes"}],"internalType":"struct TransceiverStructs.TransceiverInstruction[]","name":"","type":"tuple[]"}],"stateMutability":"pure","type":"function"}]

6080806040523461001a5761148e9081610020823930815050f35b600080fdfe608060408181526004918236101561001657600080fd5b600092833560e01c918263054a7d8414610c2c57508163055cedbd14610aac57816308a700d6146109c0578163107383fb146109755781631185b23c146108cb57816322cebdee146108935781632b9f4796146107dc5781633906001d1461073457816340d2f75a14610703578163433e3f29146106525781635f396d4b146105d35781638b4979b81461058d578163a733bdaa14610479578163b3f07bbd146103ee578163b620e87214610262578163c9bc77bb14610178575063eeca1f60146100e057600080fd5b6060366003190112610174578051906100f882610d1b565b610100610d8d565b918281526024359361ffff851685036101715750838161016d95602085940152604435928391015282519363ffffffff60e01b16602085015261ffff60f01b9060f01b16602484015260268301526026825261015b82610d1b565b51918291602083526020830190610dcc565b0390f35b80fd5b5080fd5b9050602036600319011261025e5780356001600160401b03811161025a576101a39036908301610e08565b918051926101b084610ccf565b848452602084018581528285019186835260608601948786526080870197885263ffffffff60e01b91828282015160e01b1688526024810151845260ff60258201511685526045810151875260ff6046820151168952516046810361023d5760a08860ff8b8a8a838b8b8b8451985116885251602088015251169085015251606084015251166080820152f35b85516355c5b3e360e11b8152918201526046602482015260449150fd5b8380fd5b8280fd5b828461026d36610f15565b6001808301519093928492909160ff9081169061028983610df1565b9861029689519a8b610d6c565b838a52601f196102a585610df1565b01875b8181106103d15750508693875b84811061032857505050505050906102cc9161108e565b825192602080850191818652865180935281818701918460051b880101970193905b8382106102fb5786880387f35b90919293948380610317839a603f198b82030186528951610f46565b9997019594939190910191016102ee565b9091929394966103449061033d9c9a9c6113bb565b50876113d5565b97908581511691831515806103c7575b6103ab57508382101561038f5791610381828c989796959461037a82610387969b61142e565b528c61142e565b50611409565b9a989a6102b5565b60448585848f519263344fa80b60e11b84528301526024820152fd5b85836044928f5192630555a4b960e01b84528301526024820152fd5b5080831115610354565b6020906103df9c9a9c6113bb565b82828d010152019a989a6102a8565b8284816003193601126101715782359061ffff8216820361017157602435906001600160401b038211610171575061042e60209461043392369101610f66565b610fb0565b61046f6022845180938782019561ffff60f01b9060f01b16865261045f815180928a8686019101610da9565b8101036002810184520182610d6c565b5190209051908152f35b828460203660031901126101715782356001600160401b038111610174576104a49036908501610e08565b908251926104b184610d00565b8184526020840182815281850183815260608601938452848701519196909160e01b6001600160e01b0319166319ac6aeb60e21b81016105775750600585015168ffffffffffffffff0060ff600d88015192169160081b16178652602d8501518752604d850151825261ffff9485604f82015116855251604f810361055a57505060809568ffffffffffffffffff83519651168652516020860152519084015251166060820152f35b83516355c5b3e360e11b815291820152604f602482015260449150fd5b83516356d2569d60e01b81529182015260249150fd5b82846020366003190112610171578235906001600160401b038211610171575061042e61016d936105c092369101610f66565b9051918291602083526020830190610dcc565b82846020366003190112610171578235906001600160401b038211610171575061016d9261060391369101610e08565b9061060c6113bb565b506106406106186113bb565b9260ff600182015116845261063460ff600283015116826111a9565b9190602086015261108e565b51918291602083526020830190610f46565b838360203660031901126101745782356001600160401b03811161025e5761067d9036908501610e08565b9181519261068a84610d1b565b8184526020840182815283850192835263ffffffff60e01b808784015160e01b16865261ffff92836006820151168352602681015185525196602688036106e557506060965084519551168552511660208401525190820152f35b85516355c5b3e360e11b815290810188905260266024820152604490fd5b8261071661071036610f15565b906113d5565b825183815292839261072a91840190610f46565b9060208301520390f35b9050600319828136011261025a5761074a610d8d565b91602435916001600160401b03908184116107d85760809084360301126107d45784519561077787610d00565b838301358752602484013560208801526044840135828111610174576107a290843691870101610e08565b868801526064840135918211610171575061016d95926105c094926107ca9236920101610e08565b6060830152611295565b8580fd5b8680fd5b83836080366003190112610174578051926107f684610d00565b359168ffffffffffffffffff83168303610171578284526024358060208601526044359081848701526064359261ffff84168403610171575082606061016d970152835194632653951560e21b602087015260ff60f81b8160f81b1660248701526001600160401b0360c01b9060b81b166025860152602d850152604d84015261ffff60f01b9060f01b16606d830152604f825261015b82610d00565b82846020366003190112610171578235906001600160401b03821161017157506108c661016d936105c092369101610e5e565b61136c565b828460a0366003190112610171576108e1610d8d565b926001600160401b0360643581811161025a576109019036908401610e08565b926084359182116101715750916109216109549261016d94369101610e08565b9461092a611346565b50845195869261093984610d00565b60243584526044356020850152868401526060830152611295565b6109678351948486958652850190610ead565b908382036020850152610dcc565b82846020366003190112610171578235906001600160401b03821161017157506109a861016d936109ad92369101610e08565b611050565b9051918291602083526020830190610eee565b90508160031936011261025e576109d5610d8d565b92602435906001600160401b03821161017157506109f69036908301610e08565b906109ff611346565b50610a0861102f565b50610a11611346565b9363ffffffff60e01b808385015160e01b1691168103610577575050610a8b81602461016d930151855260448101516020860152610a8561ffff91610a796002610a6185604685015116846110b9565b919095898b0196875281838601015116910183611221565b9190606089015261108e565b51611050565b610a9e8351948486958652850190610ead565b908382036020850152610eee565b60209291503660031901831361025a578035906001600160401b03908183116107d457366023840112156107d4578281013591610ae883610df1565b93610af586519586610d6c565b838552868501906024809560051b82010192368411610c2857858201925b848410610bfe575050505050825160ff8111610bec57505050805190606094905b828210610b8b57505090610b7c602161016d93835196879160ff60f81b9060f81b1687830152610b6c81518092898686019101610da9565b8101036001810187520185610d6c565b51928284938452830190610dcc565b9094610be690610be086610ba8610ba28a8761142e565b5161136c565b9287519381610bc08693518092868087019101610da9565b8201610bd482518093868085019101610da9565b01038084520182610d6c565b95611409565b90610b34565b845163a341969160e01b815291820152fd5b8335828111610c24578a91610c1983928a3691880101610e5e565b815201930192610b13565b8b80fd5b8980fd5b848460a036600319011261017457610c4383610ccf565b610c4b610d8d565b91828452602435908160208601526044359160ff83168303610174578284870152606435908160608801526084359260ff84168403610171575082608061016d98015284519563ffffffff60e01b166020870152602486015260ff60f81b809360f81b166044860152604585015260f81b1660658301526046825261015b82610d00565b60a081019081106001600160401b03821117610cea57604052565b634e487b7160e01b600052604160045260246000fd5b608081019081106001600160401b03821117610cea57604052565b606081019081106001600160401b03821117610cea57604052565b604081019081106001600160401b03821117610cea57604052565b602081019081106001600160401b03821117610cea57604052565b90601f801991011681019081106001600160401b03821117610cea57604052565b600435906001600160e01b031982168203610da457565b600080fd5b60005b838110610dbc5750506000910152565b8181015183820152602001610dac565b90602091610de581518092818552858086019101610da9565b601f01601f1916010190565b6001600160401b038111610cea5760051b60200190565b81601f82011215610da4578035906001600160401b038211610cea5760405192610e3c601f8401601f191660200185610d6c565b82845260208383010111610da457816000926020809301838601378301015290565b9190604083820312610da45760405190610e7782610d36565b8193803560ff81168103610da45783526020810135916001600160401b038311610da457602092610ea89201610e08565b910152565b610eeb9181518152602082015160208201526060610eda6040840151608060408501526080840190610dcc565b920151906060818403910152610dcc565b90565b9060606040610eeb9380518452602081015160208501520151918160408201520190610dcc565b6040600319820112610da457600435906001600160401b038211610da457610f3f91600401610e08565b9060243590565b9060406020610eeb9360ff81511684520151918160208201520190610dcc565b9190606083820312610da45760405190610f7f82610d1b565b819380358352602081013560208401526040810135916001600160401b038311610da457604092610ea89201610e08565b6040810180515161ffff811161101757506062610eeb91519283519360208251920151946040519586936020850152604084015261ffff60f01b9060f01b1660608301526110078151809260208686019101610da9565b8101036042810184520182610d6c565b6024906040519063a341969160e01b82526004820152fd5b6040519061103c82610d1b565b606060408360008152600060208201520152565b9061108c61105c61102f565b92602081015184526040810151602085015261108061ffff60428301511682611131565b9190604086015261108e565b565b519080820361109b575050565b60449250604051916355c5b3e360e11b835260048301526024820152fd5b9091821561111357826046019160405193601f811691821561110a575b6046838701938385019201015b8184106110fa5750508452601f01601f1916604052565b80518452602093840193016110e3565b602092506110d6565b91505060405161112281610d51565b60008152600036813790604690565b9091821561118b57826042019160405193601f8116918215611182575b6042838701938385019201015b8184106111725750508452601f01601f1916604052565b805184526020938401930161115b565b6020925061114e565b91505060405161119a81610d51565b60008152600036813790604290565b9091821561120357826002019160405193601f81169182156111fa575b6002838701938385019201015b8184106111ea5750508452601f01601f1916604052565b80518452602093840193016111d3565b602092506111c6565b91505060405161121281610d51565b60008152600036813790600290565b92908215611278578281019260405194601f821692831561126f575b838701938385019201015b81841061125f5750508452601f01601f1916604052565b8051845260209384019301611248565b6020935061123d565b9250905060405161128881610d51565b6000815260003681379190565b604082018051519061ffff918281116110175750805151916060850190815151908111611017575091610eeb939160689351918251916020885198015190519060405198899663ffffffff60e01b1660208801526024870152604486015261ffff60f01b809260f01b166064860152611318815180926020606689019101610da9565b84019160f01b1660668201526113378251809360208785019101610da9565b01036048810184520182610d6c565b6040519061135382610d00565b6060808360008152600060208201528160408201520152565b6020810180515160ff811161101757506022610eeb915192835190519360405194859260ff60f81b809260f81b16602085015260f81b16602183015261045f8151809260208686019101610da9565b604051906113c882610d36565b6060602083600081520152565b9190611400906113e36113bb565b93600260ff81848401826001820151168952015116920190611221565b91906020840152565b60001981146114185760010190565b634e487b7160e01b600052601160045260246000fd5b80518210156114425760209160051b010190565b634e487b7160e01b600052603260045260246000fdfea2646970667358221220c1ceb2695532b437f8fc3b1aa96d6a94c8dbb7fb87db89db2f12226a889a5d0664736f6c63430008130033

Deployed Bytecode

0x608060408181526004918236101561001657600080fd5b600092833560e01c918263054a7d8414610c2c57508163055cedbd14610aac57816308a700d6146109c0578163107383fb146109755781631185b23c146108cb57816322cebdee146108935781632b9f4796146107dc5781633906001d1461073457816340d2f75a14610703578163433e3f29146106525781635f396d4b146105d35781638b4979b81461058d578163a733bdaa14610479578163b3f07bbd146103ee578163b620e87214610262578163c9bc77bb14610178575063eeca1f60146100e057600080fd5b6060366003190112610174578051906100f882610d1b565b610100610d8d565b918281526024359361ffff851685036101715750838161016d95602085940152604435928391015282519363ffffffff60e01b16602085015261ffff60f01b9060f01b16602484015260268301526026825261015b82610d1b565b51918291602083526020830190610dcc565b0390f35b80fd5b5080fd5b9050602036600319011261025e5780356001600160401b03811161025a576101a39036908301610e08565b918051926101b084610ccf565b848452602084018581528285019186835260608601948786526080870197885263ffffffff60e01b91828282015160e01b1688526024810151845260ff60258201511685526045810151875260ff6046820151168952516046810361023d5760a08860ff8b8a8a838b8b8b8451985116885251602088015251169085015251606084015251166080820152f35b85516355c5b3e360e11b8152918201526046602482015260449150fd5b8380fd5b8280fd5b828461026d36610f15565b6001808301519093928492909160ff9081169061028983610df1565b9861029689519a8b610d6c565b838a52601f196102a585610df1565b01875b8181106103d15750508693875b84811061032857505050505050906102cc9161108e565b825192602080850191818652865180935281818701918460051b880101970193905b8382106102fb5786880387f35b90919293948380610317839a603f198b82030186528951610f46565b9997019594939190910191016102ee565b9091929394966103449061033d9c9a9c6113bb565b50876113d5565b97908581511691831515806103c7575b6103ab57508382101561038f5791610381828c989796959461037a82610387969b61142e565b528c61142e565b50611409565b9a989a6102b5565b60448585848f519263344fa80b60e11b84528301526024820152fd5b85836044928f5192630555a4b960e01b84528301526024820152fd5b5080831115610354565b6020906103df9c9a9c6113bb565b82828d010152019a989a6102a8565b8284816003193601126101715782359061ffff8216820361017157602435906001600160401b038211610171575061042e60209461043392369101610f66565b610fb0565b61046f6022845180938782019561ffff60f01b9060f01b16865261045f815180928a8686019101610da9565b8101036002810184520182610d6c565b5190209051908152f35b828460203660031901126101715782356001600160401b038111610174576104a49036908501610e08565b908251926104b184610d00565b8184526020840182815281850183815260608601938452848701519196909160e01b6001600160e01b0319166319ac6aeb60e21b81016105775750600585015168ffffffffffffffff0060ff600d88015192169160081b16178652602d8501518752604d850151825261ffff9485604f82015116855251604f810361055a57505060809568ffffffffffffffffff83519651168652516020860152519084015251166060820152f35b83516355c5b3e360e11b815291820152604f602482015260449150fd5b83516356d2569d60e01b81529182015260249150fd5b82846020366003190112610171578235906001600160401b038211610171575061042e61016d936105c092369101610f66565b9051918291602083526020830190610dcc565b82846020366003190112610171578235906001600160401b038211610171575061016d9261060391369101610e08565b9061060c6113bb565b506106406106186113bb565b9260ff600182015116845261063460ff600283015116826111a9565b9190602086015261108e565b51918291602083526020830190610f46565b838360203660031901126101745782356001600160401b03811161025e5761067d9036908501610e08565b9181519261068a84610d1b565b8184526020840182815283850192835263ffffffff60e01b808784015160e01b16865261ffff92836006820151168352602681015185525196602688036106e557506060965084519551168552511660208401525190820152f35b85516355c5b3e360e11b815290810188905260266024820152604490fd5b8261071661071036610f15565b906113d5565b825183815292839261072a91840190610f46565b9060208301520390f35b9050600319828136011261025a5761074a610d8d565b91602435916001600160401b03908184116107d85760809084360301126107d45784519561077787610d00565b838301358752602484013560208801526044840135828111610174576107a290843691870101610e08565b868801526064840135918211610171575061016d95926105c094926107ca9236920101610e08565b6060830152611295565b8580fd5b8680fd5b83836080366003190112610174578051926107f684610d00565b359168ffffffffffffffffff83168303610171578284526024358060208601526044359081848701526064359261ffff84168403610171575082606061016d970152835194632653951560e21b602087015260ff60f81b8160f81b1660248701526001600160401b0360c01b9060b81b166025860152602d850152604d84015261ffff60f01b9060f01b16606d830152604f825261015b82610d00565b82846020366003190112610171578235906001600160401b03821161017157506108c661016d936105c092369101610e5e565b61136c565b828460a0366003190112610171576108e1610d8d565b926001600160401b0360643581811161025a576109019036908401610e08565b926084359182116101715750916109216109549261016d94369101610e08565b9461092a611346565b50845195869261093984610d00565b60243584526044356020850152868401526060830152611295565b6109678351948486958652850190610ead565b908382036020850152610dcc565b82846020366003190112610171578235906001600160401b03821161017157506109a861016d936109ad92369101610e08565b611050565b9051918291602083526020830190610eee565b90508160031936011261025e576109d5610d8d565b92602435906001600160401b03821161017157506109f69036908301610e08565b906109ff611346565b50610a0861102f565b50610a11611346565b9363ffffffff60e01b808385015160e01b1691168103610577575050610a8b81602461016d930151855260448101516020860152610a8561ffff91610a796002610a6185604685015116846110b9565b919095898b0196875281838601015116910183611221565b9190606089015261108e565b51611050565b610a9e8351948486958652850190610ead565b908382036020850152610eee565b60209291503660031901831361025a578035906001600160401b03908183116107d457366023840112156107d4578281013591610ae883610df1565b93610af586519586610d6c565b838552868501906024809560051b82010192368411610c2857858201925b848410610bfe575050505050825160ff8111610bec57505050805190606094905b828210610b8b57505090610b7c602161016d93835196879160ff60f81b9060f81b1687830152610b6c81518092898686019101610da9565b8101036001810187520185610d6c565b51928284938452830190610dcc565b9094610be690610be086610ba8610ba28a8761142e565b5161136c565b9287519381610bc08693518092868087019101610da9565b8201610bd482518093868085019101610da9565b01038084520182610d6c565b95611409565b90610b34565b845163a341969160e01b815291820152fd5b8335828111610c24578a91610c1983928a3691880101610e5e565b815201930192610b13565b8b80fd5b8980fd5b848460a036600319011261017457610c4383610ccf565b610c4b610d8d565b91828452602435908160208601526044359160ff83168303610174578284870152606435908160608801526084359260ff84168403610171575082608061016d98015284519563ffffffff60e01b166020870152602486015260ff60f81b809360f81b166044860152604585015260f81b1660658301526046825261015b82610d00565b60a081019081106001600160401b03821117610cea57604052565b634e487b7160e01b600052604160045260246000fd5b608081019081106001600160401b03821117610cea57604052565b606081019081106001600160401b03821117610cea57604052565b604081019081106001600160401b03821117610cea57604052565b602081019081106001600160401b03821117610cea57604052565b90601f801991011681019081106001600160401b03821117610cea57604052565b600435906001600160e01b031982168203610da457565b600080fd5b60005b838110610dbc5750506000910152565b8181015183820152602001610dac565b90602091610de581518092818552858086019101610da9565b601f01601f1916010190565b6001600160401b038111610cea5760051b60200190565b81601f82011215610da4578035906001600160401b038211610cea5760405192610e3c601f8401601f191660200185610d6c565b82845260208383010111610da457816000926020809301838601378301015290565b9190604083820312610da45760405190610e7782610d36565b8193803560ff81168103610da45783526020810135916001600160401b038311610da457602092610ea89201610e08565b910152565b610eeb9181518152602082015160208201526060610eda6040840151608060408501526080840190610dcc565b920151906060818403910152610dcc565b90565b9060606040610eeb9380518452602081015160208501520151918160408201520190610dcc565b6040600319820112610da457600435906001600160401b038211610da457610f3f91600401610e08565b9060243590565b9060406020610eeb9360ff81511684520151918160208201520190610dcc565b9190606083820312610da45760405190610f7f82610d1b565b819380358352602081013560208401526040810135916001600160401b038311610da457604092610ea89201610e08565b6040810180515161ffff811161101757506062610eeb91519283519360208251920151946040519586936020850152604084015261ffff60f01b9060f01b1660608301526110078151809260208686019101610da9565b8101036042810184520182610d6c565b6024906040519063a341969160e01b82526004820152fd5b6040519061103c82610d1b565b606060408360008152600060208201520152565b9061108c61105c61102f565b92602081015184526040810151602085015261108061ffff60428301511682611131565b9190604086015261108e565b565b519080820361109b575050565b60449250604051916355c5b3e360e11b835260048301526024820152fd5b9091821561111357826046019160405193601f811691821561110a575b6046838701938385019201015b8184106110fa5750508452601f01601f1916604052565b80518452602093840193016110e3565b602092506110d6565b91505060405161112281610d51565b60008152600036813790604690565b9091821561118b57826042019160405193601f8116918215611182575b6042838701938385019201015b8184106111725750508452601f01601f1916604052565b805184526020938401930161115b565b6020925061114e565b91505060405161119a81610d51565b60008152600036813790604290565b9091821561120357826002019160405193601f81169182156111fa575b6002838701938385019201015b8184106111ea5750508452601f01601f1916604052565b80518452602093840193016111d3565b602092506111c6565b91505060405161121281610d51565b60008152600036813790600290565b92908215611278578281019260405194601f821692831561126f575b838701938385019201015b81841061125f5750508452601f01601f1916604052565b8051845260209384019301611248565b6020935061123d565b9250905060405161128881610d51565b6000815260003681379190565b604082018051519061ffff918281116110175750805151916060850190815151908111611017575091610eeb939160689351918251916020885198015190519060405198899663ffffffff60e01b1660208801526024870152604486015261ffff60f01b809260f01b166064860152611318815180926020606689019101610da9565b84019160f01b1660668201526113378251809360208785019101610da9565b01036048810184520182610d6c565b6040519061135382610d00565b6060808360008152600060208201528160408201520152565b6020810180515160ff811161101757506022610eeb915192835190519360405194859260ff60f81b809260f81b16602085015260f81b16602183015261045f8151809260208686019101610da9565b604051906113c882610d36565b6060602083600081520152565b9190611400906113e36113bb565b93600260ff81848401826001820151168952015116920190611221565b91906020840152565b60001981146114185760010190565b634e487b7160e01b600052601160045260246000fd5b80518210156114425760209160051b010190565b634e487b7160e01b600052603260045260246000fdfea2646970667358221220c1ceb2695532b437f8fc3b1aa96d6a94c8dbb7fb87db89db2f12226a889a5d0664736f6c63430008130033

Block Transaction Difficulty Gas Used Reward
View All Blocks Produced

Block Uncle Number Difficulty Gas Used Reward
View All Uncles
Loading...
Loading
Loading...
Loading

Validator Index Block Amount
View All Withdrawals

Transaction Hash Block Value Eth2 PubKey Valid
View All Deposits
Loading...
Loading
[ Download: CSV Export  ]

A contract address hosts a smart contract, which is a set of code stored on the blockchain that runs when predetermined conditions are met. Learn more about addresses in our Knowledge Base.