Sepolia Testnet

Contract

0xd0dbB2486e3Fbf371D1B2e35Fa330bef6529d2f4

Overview

ETH Balance

0 ETH

Multichain Info

N/A
Transaction Hash
Method
Block
From
To
Report79429722025-03-20 14:51:001 min ago1742482260IN
0xd0dbB248...f6529d2f4
0 ETH0.000012080.14730416
Report79429712025-03-20 14:50:481 min ago1742482248IN
0xd0dbB248...f6529d2f4
0 ETH0.000012050.14672757
Report79429702025-03-20 14:50:361 min ago1742482236IN
0xd0dbB248...f6529d2f4
0 ETH0.000085941.04721745
Report79429702025-03-20 14:50:361 min ago1742482236IN
0xd0dbB248...f6529d2f4
0 ETH0.000086011.04721745
Report79429692025-03-20 14:50:241 min ago1742482224IN
0xd0dbB248...f6529d2f4
0 ETH0.000126811.54527171
Report79429692025-03-20 14:50:241 min ago1742482224IN
0xd0dbB248...f6529d2f4
0 ETH0.000126921.54527171
Report79429682025-03-20 14:50:122 mins ago1742482212IN
0xd0dbB248...f6529d2f4
0 ETH0.000110471.04095828
Report79429682025-03-20 14:50:122 mins ago1742482212IN
0xd0dbB248...f6529d2f4
0 ETH0.000103221.04095828
Report79429682025-03-20 14:50:122 mins ago1742482212IN
0xd0dbB248...f6529d2f4
0 ETH0.000152921.54095828
Report79429632025-03-20 14:49:123 mins ago1742482152IN
0xd0dbB248...f6529d2f4
0 ETH0.000128321.04438908
Report79429632025-03-20 14:49:123 mins ago1742482152IN
0xd0dbB248...f6529d2f4
0 ETH0.000125341.04438908
Report79429482025-03-20 14:46:126 mins ago1742481972IN
0xd0dbB248...f6529d2f4
0 ETH0.000130821.03986719
Report79429462025-03-20 14:45:486 mins ago1742481948IN
0xd0dbB248...f6529d2f4
0 ETH0.000085231.03796183
Report79429462025-03-20 14:45:486 mins ago1742481948IN
0xd0dbB248...f6529d2f4
0 ETH0.000085211.03796183
Report79429452025-03-20 14:45:366 mins ago1742481936IN
0xd0dbB248...f6529d2f4
0 ETH0.000110011.34020365
Report79429452025-03-20 14:45:366 mins ago1742481936IN
0xd0dbB248...f6529d2f4
0 ETH0.000110041.34020365
Report79429442025-03-20 14:45:246 mins ago1742481924IN
0xd0dbB248...f6529d2f4
0 ETH0.000126361.53911193
Report79429442025-03-20 14:45:246 mins ago1742481924IN
0xd0dbB248...f6529d2f4
0 ETH0.000126381.53911193
Report79429432025-03-20 14:45:127 mins ago1742481912IN
0xd0dbB248...f6529d2f4
0 ETH0.000152781.53998573
Report79429432025-03-20 14:45:127 mins ago1742481912IN
0xd0dbB248...f6529d2f4
0 ETH0.000152751.53998573
Report79429332025-03-20 14:43:129 mins ago1742481792IN
0xd0dbB248...f6529d2f4
0 ETH0.000189661.54327116
Report79429332025-03-20 14:43:129 mins ago1742481792IN
0xd0dbB248...f6529d2f4
0 ETH0.000185271.54327116
Report79429232025-03-20 14:41:1211 mins ago1742481672IN
0xd0dbB248...f6529d2f4
0 ETH0.00011071.04333475
Report79429192025-03-20 14:40:2411 mins ago1742481624IN
0xd0dbB248...f6529d2f4
0 ETH0.000085831.04527746
Report79429192025-03-20 14:40:2411 mins ago1742481624IN
0xd0dbB248...f6529d2f4
0 ETH0.000085851.04527746
View all transactions

View more zero value Internal Transactions in Advanced View mode

Advanced mode:
Loading...
Loading

Similar Match Source Code
This contract matches the deployed Bytecode of the Source Code for Contract 0xd89eF599...4A3AA71d4
The constructor portion of the code might be different and could alter the actual behaviour of the contract

Contract Name:
KeystoneForwarder

Compiler Version
v0.8.24+commit.e11b9ed9

Optimization Enabled:
Yes with 1000000 runs

Other Settings:
paris EvmVersion

Contract Source Code (Solidity Standard Json-Input format)

File 1 of 11 : KeystoneForwarder.sol
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.19;

import {IReceiver} from "./interfaces/IReceiver.sol";
import {IRouter} from "./interfaces/IRouter.sol";
import {ITypeAndVersion} from "../shared/interfaces/ITypeAndVersion.sol";

import {OwnerIsCreator} from "../shared/access/OwnerIsCreator.sol";

import {ERC165Checker} from "../vendor/openzeppelin-solidity/v4.8.3/contracts/utils/introspection/ERC165Checker.sol";

/// @notice This is an entry point for `write_${chain}` Target capability. It allows nodes to
/// determine if reports have been processed (successfully or not) in a decentralized and
/// product-agnostic way by recording processed reports.
contract KeystoneForwarder is OwnerIsCreator, ITypeAndVersion, IRouter {
  /// @notice This error is returned when the report is shorter than REPORT_METADATA_LENGTH,
  /// which is the minimum length of a report.
  error InvalidReport();

  /// @notice This error is thrown whenever trying to set a config with a fault tolerance of 0.
  error FaultToleranceMustBePositive();

  /// @notice This error is thrown whenever configuration provides more signers than the maximum allowed number.
  /// @param numSigners The number of signers who have signed the report
  /// @param maxSigners The maximum number of signers that can sign a report
  error ExcessSigners(uint256 numSigners, uint256 maxSigners);

  /// @notice This error is thrown whenever a configuration is provided with less than the minimum number of signers.
  /// @param numSigners The number of signers provided
  /// @param minSigners The minimum number of signers expected
  error InsufficientSigners(uint256 numSigners, uint256 minSigners);

  /// @notice This error is thrown whenever a duplicate signer address is provided in the configuration.
  /// @param signer The signer address that was duplicated.
  error DuplicateSigner(address signer);

  /// @notice This error is thrown whenever a report has an incorrect number of signatures.
  /// @param expected The number of signatures expected, F + 1
  /// @param received The number of signatures received
  error InvalidSignatureCount(uint256 expected, uint256 received);

  /// @notice This error is thrown whenever a report specifies a configuration that does not exist.
  /// @param configId (uint64(donId) << 32) | configVersion
  error InvalidConfig(uint64 configId);

  /// @notice This error is thrown whenever a signer address is not in the configuration or
  /// when trying to set a zero address as a signer.
  /// @param signer The signer address that was not in the configuration
  error InvalidSigner(address signer);

  /// @notice This error is thrown whenever a signature is invalid.
  /// @param signature The signature that was invalid
  error InvalidSignature(bytes signature);

  /// @notice Contains the signing address of each oracle
  struct OracleSet {
    uint8 f; // Number of faulty nodes allowed
    address[] signers;
    mapping(address signer => uint256 position) _positions; // 1-indexed to detect unset values
  }

  struct Transmission {
    address transmitter;
    // This is true if the receiver is not a contract or does not implement the `IReceiver` interface.
    bool invalidReceiver;
    // Whether the transmission attempt was successful. If `false`, the transmission can be retried
    // with an increased gas limit.
    bool success;
    // The amount of gas allocated for the `IReceiver.onReport` call. uint80 allows storing gas for known EVM block
    // gas limits. Ensures that the minimum gas requested by the user is available during the transmission attempt.
    // If the transmission fails (indicated by a `false` success state), it can be retried with an increased gas limit.
    uint80 gasLimit;
  }

  /// @notice Emitted when a report is processed
  /// @param result The result of the attempted delivery. True if successful.
  event ReportProcessed(
    address indexed receiver,
    bytes32 indexed workflowExecutionId,
    bytes2 indexed reportId,
    bool result
  );

  /// @notice Contains the configuration for each DON ID
  /// configId (uint64(donId) << 32) | configVersion
  mapping(uint64 configId => OracleSet oracleSet) internal s_configs;

  event ConfigSet(uint32 indexed donId, uint32 indexed configVersion, uint8 f, address[] signers);

  string public constant override typeAndVersion = "KeystoneForwarder 1.0.0";

  constructor() OwnerIsCreator() {
    s_forwarders[address(this)] = true;
  }

  uint256 internal constant MAX_ORACLES = 31;
  uint256 internal constant METADATA_LENGTH = 109;
  uint256 internal constant FORWARDER_METADATA_LENGTH = 45;
  uint256 internal constant SIGNATURE_LENGTH = 65;

  /// @dev This is the gas required to store `success` after the report is processed.
  /// It is a warm storage write because of the packed struct. In practice it will cost less.
  uint256 internal constant INTERNAL_GAS_REQUIREMENTS_AFTER_REPORT = 5_000;
  /// @dev This is the gas required to store the transmission struct and perform other checks.
  uint256 internal constant INTERNAL_GAS_REQUIREMENTS = 25_000 + INTERNAL_GAS_REQUIREMENTS_AFTER_REPORT;
  /// @dev This is the minimum gas required to route a report. This includes internal gas requirements
  /// as well as the minimum gas that the user contract will receive. 30k * 3 gas is to account for
  /// cases where consumers need close to the 30k limit provided in the supportsInterface check.
  uint256 internal constant MINIMUM_GAS_LIMIT = INTERNAL_GAS_REQUIREMENTS + 30_000 * 3 + 10_000;

  // ================================================================
  // │                          Router                              │
  // ================================================================

  mapping(address forwarder => bool isForwarder) internal s_forwarders;
  mapping(bytes32 transmissionId => Transmission transmission) internal s_transmissions;

  function addForwarder(address forwarder) external onlyOwner {
    s_forwarders[forwarder] = true;
    emit ForwarderAdded(forwarder);
  }

  function removeForwarder(address forwarder) external onlyOwner {
    s_forwarders[forwarder] = false;
    emit ForwarderRemoved(forwarder);
  }

  function route(
    bytes32 transmissionId,
    address transmitter,
    address receiver,
    bytes calldata metadata,
    bytes calldata validatedReport
  ) public returns (bool) {
    if (!s_forwarders[msg.sender]) revert UnauthorizedForwarder();

    uint256 gasLimit = gasleft() - INTERNAL_GAS_REQUIREMENTS;
    if (gasLimit < MINIMUM_GAS_LIMIT) revert InsufficientGasForRouting(transmissionId);

    Transmission memory transmission = s_transmissions[transmissionId];
    if (transmission.success || transmission.invalidReceiver) revert AlreadyAttempted(transmissionId);

    s_transmissions[transmissionId].transmitter = transmitter;
    s_transmissions[transmissionId].gasLimit = uint80(gasLimit);

    // This call can consume up to 90k gas.
    if (!ERC165Checker.supportsInterface(receiver, type(IReceiver).interfaceId)) {
      s_transmissions[transmissionId].invalidReceiver = true;
      return false;
    }

    bool success;
    bytes memory payload = abi.encodeCall(IReceiver.onReport, (metadata, validatedReport));

    uint256 remainingGas = gasleft() - INTERNAL_GAS_REQUIREMENTS_AFTER_REPORT;
    assembly {
      // call and return whether we succeeded. ignore return data
      // call(gas,addr,value,argsOffset,argsLength,retOffset,retLength)
      success := call(remainingGas, receiver, 0, add(payload, 0x20), mload(payload), 0x0, 0x0)
    }

    if (success) {
      s_transmissions[transmissionId].success = true;
    }
    return success;
  }

  function getTransmissionId(
    address receiver,
    bytes32 workflowExecutionId,
    bytes2 reportId
  ) public pure returns (bytes32) {
    // This is slightly cheaper compared to `keccak256(abi.encode(receiver, workflowExecutionId, reportId));`
    return keccak256(bytes.concat(bytes20(uint160(receiver)), workflowExecutionId, reportId));
  }

  function getTransmissionInfo(
    address receiver,
    bytes32 workflowExecutionId,
    bytes2 reportId
  ) external view returns (TransmissionInfo memory) {
    bytes32 transmissionId = getTransmissionId(receiver, workflowExecutionId, reportId);

    Transmission memory transmission = s_transmissions[transmissionId];

    TransmissionState state;

    if (transmission.transmitter == address(0)) {
      state = IRouter.TransmissionState.NOT_ATTEMPTED;
    } else if (transmission.invalidReceiver) {
      state = IRouter.TransmissionState.INVALID_RECEIVER;
    } else {
      state = transmission.success ? IRouter.TransmissionState.SUCCEEDED : IRouter.TransmissionState.FAILED;
    }

    return
      TransmissionInfo({
        gasLimit: transmission.gasLimit,
        invalidReceiver: transmission.invalidReceiver,
        state: state,
        success: transmission.success,
        transmissionId: transmissionId,
        transmitter: transmission.transmitter
      });
  }

  /// @notice Get transmitter of a given report or 0x0 if it wasn't transmitted yet
  function getTransmitter(
    address receiver,
    bytes32 workflowExecutionId,
    bytes2 reportId
  ) external view returns (address) {
    return s_transmissions[getTransmissionId(receiver, workflowExecutionId, reportId)].transmitter;
  }

  function isForwarder(address forwarder) external view returns (bool) {
    return s_forwarders[forwarder];
  }

  // ================================================================
  // │                          Forwarder                           │
  // ================================================================

  function setConfig(uint32 donId, uint32 configVersion, uint8 f, address[] calldata signers) external onlyOwner {
    if (f == 0) revert FaultToleranceMustBePositive();
    if (signers.length > MAX_ORACLES) revert ExcessSigners(signers.length, MAX_ORACLES);
    if (signers.length <= 3 * f) revert InsufficientSigners(signers.length, 3 * f + 1);

    uint64 configId = (uint64(donId) << 32) | configVersion;

    // remove any old signer addresses
    for (uint256 i = 0; i < s_configs[configId].signers.length; ++i) {
      delete s_configs[configId]._positions[s_configs[configId].signers[i]];
    }

    // add new signer addresses
    for (uint256 i = 0; i < signers.length; ++i) {
      // assign indices, detect duplicates
      address signer = signers[i];
      if (signer == address(0)) revert InvalidSigner(signer);
      if (s_configs[configId]._positions[signer] != 0) revert DuplicateSigner(signer);
      s_configs[configId]._positions[signer] = i + 1;
    }
    s_configs[configId].signers = signers;
    s_configs[configId].f = f;

    emit ConfigSet(donId, configVersion, f, signers);
  }

  function clearConfig(uint32 donId, uint32 configVersion) external onlyOwner {
    // We are not removing old signer positions, because it is sufficient to
    // clear the f value for `report` function. If we decide to restore
    // the configId in the future, the setConfig function clears the positions.
    s_configs[(uint64(donId) << 32) | configVersion].f = 0;

    emit ConfigSet(donId, configVersion, 0, new address[](0));
  }

  // send a report to receiver
  function report(
    address receiver,
    bytes calldata rawReport,
    bytes calldata reportContext,
    bytes[] calldata signatures
  ) external {
    if (rawReport.length < METADATA_LENGTH) {
      revert InvalidReport();
    }

    bytes32 workflowExecutionId;
    bytes2 reportId;
    {
      uint64 configId;
      (workflowExecutionId, configId, reportId) = _getMetadata(rawReport);
      OracleSet storage config = s_configs[configId];

      uint8 f = config.f;
      // f can never be 0, so this means the config doesn't actually exist
      if (f == 0) revert InvalidConfig(configId);
      if (f + 1 != signatures.length) revert InvalidSignatureCount(f + 1, signatures.length);

      // validate signatures
      bytes32 completeHash = keccak256(abi.encodePacked(keccak256(rawReport), reportContext));
      address[MAX_ORACLES + 1] memory signed;
      for (uint256 i = 0; i < signatures.length; ++i) {
        bytes calldata signature = signatures[i];
        if (signature.length != SIGNATURE_LENGTH) revert InvalidSignature(signature);
        address signer = ecrecover(
          completeHash,
          uint8(signature[64]) + 27,
          bytes32(signature[0:32]),
          bytes32(signature[32:64])
        );

        // validate signer is trusted and signature is unique
        uint256 index = config._positions[signer];
        if (index == 0) revert InvalidSigner(signer); // index is 1-indexed so we can detect unset signers
        if (signed[index] != address(0)) revert DuplicateSigner(signer);
        signed[index] = signer;
      }
    }

    bool success = this.route(
      getTransmissionId(receiver, workflowExecutionId, reportId),
      msg.sender,
      receiver,
      rawReport[FORWARDER_METADATA_LENGTH:METADATA_LENGTH],
      rawReport[METADATA_LENGTH:]
    );

    emit ReportProcessed(receiver, workflowExecutionId, reportId, success);
  }

  // solhint-disable-next-line chainlink-solidity/explicit-returns
  function _getMetadata(
    bytes memory rawReport
  ) internal pure returns (bytes32 workflowExecutionId, uint64 configId, bytes2 reportId) {
    // (first 32 bytes of memory contain length of the report)
    // version                offset  32, size  1
    // workflow_execution_id  offset  33, size 32
    // timestamp              offset  65, size  4
    // don_id                 offset  69, size  4
    // don_config_version,    offset  73, size  4
    // workflow_cid           offset  77, size 32
    // workflow_name          offset 109, size 10
    // workflow_owner         offset 119, size 20
    // report_id              offset 139, size  2
    assembly {
      workflowExecutionId := mload(add(rawReport, 33))
      // shift right by 24 bytes to get the combined don_id and don_config_version
      configId := shr(mul(24, 8), mload(add(rawReport, 69)))
      reportId := mload(add(rawReport, 139))
    }
  }
}

File 2 of 11 : IReceiver.sol
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;

import {IERC165} from "../../vendor/openzeppelin-solidity/v5.0.2/contracts/utils/introspection/IERC165.sol";

/// @title IReceiver - receives keystone reports
/// @notice Implementations must support the IReceiver interface through ERC165.
interface IReceiver is IERC165 {
  /// @notice Handles incoming keystone reports.
  /// @dev If this function call reverts, it can be retried with a higher gas
  /// limit. The receiver is responsible for discarding stale reports.
  /// @param metadata Report's metadata.
  /// @param report Workflow report.
  function onReport(bytes calldata metadata, bytes calldata report) external;
}

File 3 of 11 : IRouter.sol
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.4;

/// @title IRouter - delivers keystone reports to receiver
interface IRouter {
  error UnauthorizedForwarder();
  /// @dev Thrown when the gas limit is insufficient for handling state after
  /// calling the receiver function.
  error InsufficientGasForRouting(bytes32 transmissionId);
  error AlreadyAttempted(bytes32 transmissionId);

  event ForwarderAdded(address indexed forwarder);
  event ForwarderRemoved(address indexed forwarder);

  enum TransmissionState {
    NOT_ATTEMPTED,
    SUCCEEDED,
    INVALID_RECEIVER,
    FAILED
  }

  struct TransmissionInfo {
    bytes32 transmissionId;
    TransmissionState state;
    address transmitter;
    // This is true if the receiver is not a contract or does not implement the
    // `IReceiver` interface.
    bool invalidReceiver;
    // Whether the transmission attempt was successful. If `false`, the
    // transmission can be retried with an increased gas limit.
    bool success;
    // The amount of gas allocated for the `IReceiver.onReport` call. uint80
    // allows storing gas for known EVM block gas limits.
    // Ensures that the minimum gas requested by the user is available during
    // the transmission attempt. If the transmission fails (indicated by a
    // `false` success state), it can be retried with an increased gas limit.
    uint80 gasLimit;
  }

  function addForwarder(address forwarder) external;
  function removeForwarder(address forwarder) external;

  function route(
    bytes32 transmissionId,
    address transmitter,
    address receiver,
    bytes calldata metadata,
    bytes calldata report
  ) external returns (bool);

  function getTransmissionId(
    address receiver,
    bytes32 workflowExecutionId,
    bytes2 reportId
  ) external pure returns (bytes32);
  function getTransmissionInfo(
    address receiver,
    bytes32 workflowExecutionId,
    bytes2 reportId
  ) external view returns (TransmissionInfo memory);
  function getTransmitter(
    address receiver,
    bytes32 workflowExecutionId,
    bytes2 reportId
  ) external view returns (address);
}

File 4 of 11 : ITypeAndVersion.sol
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;

interface ITypeAndVersion {
  function typeAndVersion() external pure returns (string memory);
}

File 5 of 11 : OwnerIsCreator.sol
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;

import {ConfirmedOwner} from "./ConfirmedOwner.sol";

/// @title The OwnerIsCreator contract
/// @notice A contract with helpers for basic contract ownership.
contract OwnerIsCreator is ConfirmedOwner {
  constructor() ConfirmedOwner(msg.sender) {}
}

File 6 of 11 : ERC165Checker.sol
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v4.8.2) (utils/introspection/ERC165Checker.sol)

pragma solidity ^0.8.0;

import "./IERC165.sol";

/**
 * @dev Library used to query support of an interface declared via {IERC165}.
 *
 * Note that these functions return the actual result of the query: they do not
 * `revert` if an interface is not supported. It is up to the caller to decide
 * what to do in these cases.
 */
library ERC165Checker {
    // As per the EIP-165 spec, no interface should ever match 0xffffffff
    bytes4 private constant _INTERFACE_ID_INVALID = 0xffffffff;

    /**
     * @dev Returns true if `account` supports the {IERC165} interface.
     */
    function supportsERC165(address account) internal view returns (bool) {
        // Any contract that implements ERC165 must explicitly indicate support of
        // InterfaceId_ERC165 and explicitly indicate non-support of InterfaceId_Invalid
        return
            supportsERC165InterfaceUnchecked(account, type(IERC165).interfaceId) &&
            !supportsERC165InterfaceUnchecked(account, _INTERFACE_ID_INVALID);
    }

    /**
     * @dev Returns true if `account` supports the interface defined by
     * `interfaceId`. Support for {IERC165} itself is queried automatically.
     *
     * See {IERC165-supportsInterface}.
     */
    function supportsInterface(address account, bytes4 interfaceId) internal view returns (bool) {
        // query support of both ERC165 as per the spec and support of _interfaceId
        return supportsERC165(account) && supportsERC165InterfaceUnchecked(account, interfaceId);
    }

    /**
     * @dev Returns a boolean array where each value corresponds to the
     * interfaces passed in and whether they're supported or not. This allows
     * you to batch check interfaces for a contract where your expectation
     * is that some interfaces may not be supported.
     *
     * See {IERC165-supportsInterface}.
     *
     * _Available since v3.4._
     */
    function getSupportedInterfaces(address account, bytes4[] memory interfaceIds)
        internal
        view
        returns (bool[] memory)
    {
        // an array of booleans corresponding to interfaceIds and whether they're supported or not
        bool[] memory interfaceIdsSupported = new bool[](interfaceIds.length);

        // query support of ERC165 itself
        if (supportsERC165(account)) {
            // query support of each interface in interfaceIds
            for (uint256 i = 0; i < interfaceIds.length; i++) {
                interfaceIdsSupported[i] = supportsERC165InterfaceUnchecked(account, interfaceIds[i]);
            }
        }

        return interfaceIdsSupported;
    }

    /**
     * @dev Returns true if `account` supports all the interfaces defined in
     * `interfaceIds`. Support for {IERC165} itself is queried automatically.
     *
     * Batch-querying can lead to gas savings by skipping repeated checks for
     * {IERC165} support.
     *
     * See {IERC165-supportsInterface}.
     */
    function supportsAllInterfaces(address account, bytes4[] memory interfaceIds) internal view returns (bool) {
        // query support of ERC165 itself
        if (!supportsERC165(account)) {
            return false;
        }

        // query support of each interface in interfaceIds
        for (uint256 i = 0; i < interfaceIds.length; i++) {
            if (!supportsERC165InterfaceUnchecked(account, interfaceIds[i])) {
                return false;
            }
        }

        // all interfaces supported
        return true;
    }

    /**
     * @notice Query if a contract implements an interface, does not check ERC165 support
     * @param account The address of the contract to query for support of an interface
     * @param interfaceId The interface identifier, as specified in ERC-165
     * @return true if the contract at account indicates support of the interface with
     * identifier interfaceId, false otherwise
     * @dev Assumes that account contains a contract that supports ERC165, otherwise
     * the behavior of this method is undefined. This precondition can be checked
     * with {supportsERC165}.
     *
     * Some precompiled contracts will falsely indicate support for a given interface, so caution
     * should be exercised when using this function.
     *
     * Interface identification is specified in ERC-165.
     */
    function supportsERC165InterfaceUnchecked(address account, bytes4 interfaceId) internal view returns (bool) {
        // prepare call
        bytes memory encodedParams = abi.encodeWithSelector(IERC165.supportsInterface.selector, interfaceId);

        // perform static call
        bool success;
        uint256 returnSize;
        uint256 returnValue;
        assembly {
            success := staticcall(30000, account, add(encodedParams, 0x20), mload(encodedParams), 0x00, 0x20)
            returnSize := returndatasize()
            returnValue := mload(0x00)
        }

        return success && returnSize >= 0x20 && returnValue > 0;
    }
}

File 7 of 11 : IERC165.sol
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v5.0.0) (utils/introspection/IERC165.sol)

pragma solidity ^0.8.20;

/**
 * @dev Interface of the ERC165 standard, as defined in the
 * https://eips.ethereum.org/EIPS/eip-165[EIP].
 *
 * Implementers can declare support of contract interfaces, which can then be
 * queried by others ({ERC165Checker}).
 *
 * For an implementation, see {ERC165}.
 */
interface IERC165 {
    /**
     * @dev Returns true if this contract implements the interface defined by
     * `interfaceId`. See the corresponding
     * https://eips.ethereum.org/EIPS/eip-165#how-interfaces-are-identified[EIP section]
     * to learn more about how these ids are created.
     *
     * This function call must use less than 30 000 gas.
     */
    function supportsInterface(bytes4 interfaceId) external view returns (bool);
}

File 8 of 11 : ConfirmedOwner.sol
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;

import {ConfirmedOwnerWithProposal} from "./ConfirmedOwnerWithProposal.sol";

/// @title The ConfirmedOwner contract
/// @notice A contract with helpers for basic contract ownership.
contract ConfirmedOwner is ConfirmedOwnerWithProposal {
  constructor(address newOwner) ConfirmedOwnerWithProposal(newOwner, address(0)) {}
}

File 9 of 11 : IERC165.sol
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts v4.4.1 (utils/introspection/IERC165.sol)

pragma solidity ^0.8.0;

/**
 * @dev Interface of the ERC165 standard, as defined in the
 * https://eips.ethereum.org/EIPS/eip-165[EIP].
 *
 * Implementers can declare support of contract interfaces, which can then be
 * queried by others ({ERC165Checker}).
 *
 * For an implementation, see {ERC165}.
 */
interface IERC165 {
    /**
     * @dev Returns true if this contract implements the interface defined by
     * `interfaceId`. See the corresponding
     * https://eips.ethereum.org/EIPS/eip-165#how-interfaces-are-identified[EIP section]
     * to learn more about how these ids are created.
     *
     * This function call must use less than 30 000 gas.
     */
    function supportsInterface(bytes4 interfaceId) external view returns (bool);
}

File 10 of 11 : ConfirmedOwnerWithProposal.sol
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;

import {IOwnable} from "../interfaces/IOwnable.sol";

/// @title The ConfirmedOwner contract
/// @notice A contract with helpers for basic contract ownership.
contract ConfirmedOwnerWithProposal is IOwnable {
  address private s_owner;
  address private s_pendingOwner;

  event OwnershipTransferRequested(address indexed from, address indexed to);
  event OwnershipTransferred(address indexed from, address indexed to);

  constructor(address newOwner, address pendingOwner) {
    // solhint-disable-next-line gas-custom-errors
    require(newOwner != address(0), "Cannot set owner to zero");

    s_owner = newOwner;
    if (pendingOwner != address(0)) {
      _transferOwnership(pendingOwner);
    }
  }

  /// @notice Allows an owner to begin transferring ownership to a new address.
  function transferOwnership(address to) public override onlyOwner {
    _transferOwnership(to);
  }

  /// @notice Allows an ownership transfer to be completed by the recipient.
  function acceptOwnership() external override {
    // solhint-disable-next-line gas-custom-errors
    require(msg.sender == s_pendingOwner, "Must be proposed owner");

    address oldOwner = s_owner;
    s_owner = msg.sender;
    s_pendingOwner = address(0);

    emit OwnershipTransferred(oldOwner, msg.sender);
  }

  /// @notice Get the current owner
  function owner() public view override returns (address) {
    return s_owner;
  }

  /// @notice validate, transfer ownership, and emit relevant events
  function _transferOwnership(address to) private {
    // solhint-disable-next-line gas-custom-errors
    require(to != msg.sender, "Cannot transfer to self");

    s_pendingOwner = to;

    emit OwnershipTransferRequested(s_owner, to);
  }

  /// @notice validate access
  function _validateOwnership() internal view {
    // solhint-disable-next-line gas-custom-errors
    require(msg.sender == s_owner, "Only callable by owner");
  }

  /// @notice Reverts if called by anyone other than the contract owner.
  modifier onlyOwner() {
    _validateOwnership();
    _;
  }
}

File 11 of 11 : IOwnable.sol
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;

interface IOwnable {
  function owner() external returns (address);

  function transferOwnership(address recipient) external;

  function acceptOwnership() external;
}

Settings
{
  "remappings": [
    "forge-std/=src/v0.8/vendor/forge-std/src/",
    "@openzeppelin/=node_modules/@openzeppelin/",
    "@arbitrum/=node_modules/@arbitrum/",
    "hardhat/=node_modules/hardhat/",
    "@eth-optimism/=node_modules/@eth-optimism/",
    "@scroll-tech/=node_modules/@scroll-tech/",
    "@zksync/=node_modules/@zksync/"
  ],
  "optimizer": {
    "enabled": true,
    "runs": 1000000
  },
  "metadata": {
    "useLiteralContent": false,
    "bytecodeHash": "none",
    "appendCBOR": true
  },
  "outputSelection": {
    "*": {
      "*": [
        "evm.bytecode",
        "evm.deployedBytecode",
        "devdoc",
        "userdoc",
        "metadata",
        "abi"
      ]
    }
  },
  "evmVersion": "paris",
  "viaIR": false,
  "libraries": {}
}

Contract ABI

API
[{"inputs":[],"stateMutability":"nonpayable","type":"constructor"},{"inputs":[{"internalType":"bytes32","name":"transmissionId","type":"bytes32"}],"name":"AlreadyAttempted","type":"error"},{"inputs":[{"internalType":"address","name":"signer","type":"address"}],"name":"DuplicateSigner","type":"error"},{"inputs":[{"internalType":"uint256","name":"numSigners","type":"uint256"},{"internalType":"uint256","name":"maxSigners","type":"uint256"}],"name":"ExcessSigners","type":"error"},{"inputs":[],"name":"FaultToleranceMustBePositive","type":"error"},{"inputs":[{"internalType":"bytes32","name":"transmissionId","type":"bytes32"}],"name":"InsufficientGasForRouting","type":"error"},{"inputs":[{"internalType":"uint256","name":"numSigners","type":"uint256"},{"internalType":"uint256","name":"minSigners","type":"uint256"}],"name":"InsufficientSigners","type":"error"},{"inputs":[{"internalType":"uint64","name":"configId","type":"uint64"}],"name":"InvalidConfig","type":"error"},{"inputs":[],"name":"InvalidReport","type":"error"},{"inputs":[{"internalType":"bytes","name":"signature","type":"bytes"}],"name":"InvalidSignature","type":"error"},{"inputs":[{"internalType":"uint256","name":"expected","type":"uint256"},{"internalType":"uint256","name":"received","type":"uint256"}],"name":"InvalidSignatureCount","type":"error"},{"inputs":[{"internalType":"address","name":"signer","type":"address"}],"name":"InvalidSigner","type":"error"},{"inputs":[],"name":"UnauthorizedForwarder","type":"error"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"uint32","name":"donId","type":"uint32"},{"indexed":true,"internalType":"uint32","name":"configVersion","type":"uint32"},{"indexed":false,"internalType":"uint8","name":"f","type":"uint8"},{"indexed":false,"internalType":"address[]","name":"signers","type":"address[]"}],"name":"ConfigSet","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"forwarder","type":"address"}],"name":"ForwarderAdded","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"forwarder","type":"address"}],"name":"ForwarderRemoved","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"from","type":"address"},{"indexed":true,"internalType":"address","name":"to","type":"address"}],"name":"OwnershipTransferRequested","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"from","type":"address"},{"indexed":true,"internalType":"address","name":"to","type":"address"}],"name":"OwnershipTransferred","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"receiver","type":"address"},{"indexed":true,"internalType":"bytes32","name":"workflowExecutionId","type":"bytes32"},{"indexed":true,"internalType":"bytes2","name":"reportId","type":"bytes2"},{"indexed":false,"internalType":"bool","name":"result","type":"bool"}],"name":"ReportProcessed","type":"event"},{"inputs":[],"name":"acceptOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"forwarder","type":"address"}],"name":"addForwarder","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint32","name":"donId","type":"uint32"},{"internalType":"uint32","name":"configVersion","type":"uint32"}],"name":"clearConfig","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"receiver","type":"address"},{"internalType":"bytes32","name":"workflowExecutionId","type":"bytes32"},{"internalType":"bytes2","name":"reportId","type":"bytes2"}],"name":"getTransmissionId","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"pure","type":"function"},{"inputs":[{"internalType":"address","name":"receiver","type":"address"},{"internalType":"bytes32","name":"workflowExecutionId","type":"bytes32"},{"internalType":"bytes2","name":"reportId","type":"bytes2"}],"name":"getTransmissionInfo","outputs":[{"components":[{"internalType":"bytes32","name":"transmissionId","type":"bytes32"},{"internalType":"enum IRouter.TransmissionState","name":"state","type":"uint8"},{"internalType":"address","name":"transmitter","type":"address"},{"internalType":"bool","name":"invalidReceiver","type":"bool"},{"internalType":"bool","name":"success","type":"bool"},{"internalType":"uint80","name":"gasLimit","type":"uint80"}],"internalType":"struct IRouter.TransmissionInfo","name":"","type":"tuple"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"receiver","type":"address"},{"internalType":"bytes32","name":"workflowExecutionId","type":"bytes32"},{"internalType":"bytes2","name":"reportId","type":"bytes2"}],"name":"getTransmitter","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"forwarder","type":"address"}],"name":"isForwarder","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"owner","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"forwarder","type":"address"}],"name":"removeForwarder","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"receiver","type":"address"},{"internalType":"bytes","name":"rawReport","type":"bytes"},{"internalType":"bytes","name":"reportContext","type":"bytes"},{"internalType":"bytes[]","name":"signatures","type":"bytes[]"}],"name":"report","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes32","name":"transmissionId","type":"bytes32"},{"internalType":"address","name":"transmitter","type":"address"},{"internalType":"address","name":"receiver","type":"address"},{"internalType":"bytes","name":"metadata","type":"bytes"},{"internalType":"bytes","name":"validatedReport","type":"bytes"}],"name":"route","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint32","name":"donId","type":"uint32"},{"internalType":"uint32","name":"configVersion","type":"uint32"},{"internalType":"uint8","name":"f","type":"uint8"},{"internalType":"address[]","name":"signers","type":"address[]"}],"name":"setConfig","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"to","type":"address"}],"name":"transferOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"typeAndVersion","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"}]

Deployed Bytecode

0x608060405234801561001057600080fd5b50600436106100ea5760003560e01c806379ba50971161008c578063abcef55411610066578063abcef5541461035d578063ee59d26c14610396578063ef6e17a0146103a9578063f2fde38b146103bc57600080fd5b806379ba50971461025e5780638864b864146102665780638da5cb5b1461033f57600080fd5b8063272cbd93116100c8578063272cbd9314610179578063354bdd66146101995780634d93172d146102385780635c41d2fe1461024b57600080fd5b806311289565146100ef578063181f5a7714610104578063233fd52d14610156575b600080fd5b6101026100fd366004611a33565b6103cf565b005b6101406040518060400160405280601781526020017f4b657973746f6e65466f7277617264657220312e302e3000000000000000000081525081565b60405161014d9190611ade565b60405180910390f35b610169610164366004611b4b565b610989565b604051901515815260200161014d565b61018c610187366004611bd3565b610d4a565b60405161014d9190611c67565b61022a6101a7366004611bd3565b6040517fffffffffffffffffffffffffffffffffffffffff000000000000000000000000606085901b166020820152603481018390527fffff000000000000000000000000000000000000000000000000000000000000821660548201526000906056016040516020818303038152906040528051906020012090509392505050565b60405190815260200161014d565b610102610246366004611d0f565b610f50565b610102610259366004611d0f565b610fcc565b61010261104b565b61031a610274366004611bd3565b6040805160609490941b7fffffffffffffffffffffffffffffffffffffffff0000000000000000000000001660208086019190915260348501939093527fffff000000000000000000000000000000000000000000000000000000000000919091166054840152805160368185030181526056909301815282519282019290922060009081526004909152205473ffffffffffffffffffffffffffffffffffffffff1690565b60405173ffffffffffffffffffffffffffffffffffffffff909116815260200161014d565b60005473ffffffffffffffffffffffffffffffffffffffff1661031a565b61016961036b366004611d0f565b73ffffffffffffffffffffffffffffffffffffffff1660009081526003602052604090205460ff1690565b6101026103a4366004611d3e565b611148565b6101026103b7366004611dbc565b611525565b6101026103ca366004611d0f565b6115c5565b606d85101561040a576040517fb55ac75400000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600080600061044e89898080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152506115d992505050565b67ffffffffffffffff8216600090815260026020526040812080549497509195509193509160ff16908190036104c1576040517fdf3b81ea00000000000000000000000000000000000000000000000000000000815267ffffffffffffffff841660048201526024015b60405180910390fd5b856104cd826001611e1e565b60ff161461051f576104e0816001611e1e565b6040517fd6022e8e00000000000000000000000000000000000000000000000000000000815260ff9091166004820152602481018790526044016104b8565b60008b8b604051610531929190611e37565b60405190819003812061054a918c908c90602001611e47565b60405160208183030381529060405280519060200120905061056a6118c0565b60005b888110156107ec573660008b8b8481811061058a5761058a611e61565b905060200281019061059c9190611e90565b9092509050604181146105df5781816040517f2adfdc300000000000000000000000000000000000000000000000000000000081526004016104b8929190611f3e565b6000600186848460408181106105f7576105f7611e61565b61060992013560f81c9050601b611e1e565b610617602060008789611f5a565b61062091611f84565b61062e60406020888a611f5a565b61063791611f84565b6040805160008152602081018083529590955260ff909316928401929092526060830152608082015260a0016020604051602081039080840390855afa158015610685573d6000803e3d6000fd5b5050604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0015173ffffffffffffffffffffffffffffffffffffffff8116600090815260028c0160205291822054909350915081900361072b576040517fbf18af4300000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff831660048201526024016104b8565b600086826020811061073f5761073f611e61565b602002015173ffffffffffffffffffffffffffffffffffffffff16146107a9576040517fe021c4f200000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff831660048201526024016104b8565b818682602081106107bc576107bc611e61565b73ffffffffffffffffffffffffffffffffffffffff909216602092909202015250506001909201915061056d9050565b50506040805160608f901b7fffffffffffffffffffffffffffffffffffffffff00000000000000000000000016602080830191909152603482018990527fffff0000000000000000000000000000000000000000000000000000000000008816605483015282516036818403018152605690920190925280519101206000945030935063233fd52d92509050338d8d8d602d90606d9261088e93929190611f5a565b8f8f606d9080926108a193929190611f5a565b6040518863ffffffff1660e01b81526004016108c39796959493929190611fc0565b6020604051808303816000875af11580156108e2573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906109069190612021565b9050817dffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916838b73ffffffffffffffffffffffffffffffffffffffff167f3617b009e9785c42daebadb6d3fb553243a4bf586d07ea72d65d80013ce116b584604051610975911515815260200190565b60405180910390a450505050505050505050565b3360009081526003602052604081205460ff166109d2576040517fd79e123d00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60006109e26113886161a861204a565b5a6109ed919061205d565b90506109fd6113886161a861204a565b610a0a9062015f9061204a565b610a169061271061204a565b811015610a52576040517f0bfecd63000000000000000000000000000000000000000000000000000000008152600481018a90526024016104b8565b6000898152600460209081526040918290208251608081018452905473ffffffffffffffffffffffffffffffffffffffff8116825274010000000000000000000000000000000000000000810460ff90811615159383019390935275010000000000000000000000000000000000000000008104909216151592810183905276010000000000000000000000000000000000000000000090910469ffffffffffffffffffff1660608201529080610b0a575080602001515b15610b44576040517fa53dc8ca000000000000000000000000000000000000000000000000000000008152600481018b90526024016104b8565b60008a8152600460205260409020805469ffffffffffffffffffff84167601000000000000000000000000000000000000000000000275ffff000000000000000000000000000000000000000090911673ffffffffffffffffffffffffffffffffffffffff8c1617179055610bd9887f805f2132000000000000000000000000000000000000000000000000000000006115f4565b610c3057505050600087815260046020526040812080547fffffffffffffffffffffff00ffffffffffffffffffffffffffffffffffffffff1674010000000000000000000000000000000000000000179055610d3f565b60008088888888604051602401610c4a9493929190612070565b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08184030181529190526020810180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167f805f213200000000000000000000000000000000000000000000000000000000179052905060006113885a610cd2919061205d565b905060008083516020850160008f86f192508215610d375760008d815260046020526040902080547fffffffffffffffffffff00ffffffffffffffffffffffffffffffffffffffffff1675010000000000000000000000000000000000000000001790555b509093505050505b979650505050505050565b6040805160c0810182526000808252602080830182905282840182905260608084018390526080840183905260a0840183905284519088901b7fffffffffffffffffffffffffffffffffffffffff0000000000000000000000001681830152603481018790527fffff000000000000000000000000000000000000000000000000000000000000861660548201528451603681830301815260568201808752815191840191909120808552600490935285842060d68301909652945473ffffffffffffffffffffffffffffffffffffffff811680875274010000000000000000000000000000000000000000820460ff9081161515607685015275010000000000000000000000000000000000000000008304161515609684015276010000000000000000000000000000000000000000000090910469ffffffffffffffffffff1660b69092019190915292939092909190610ea857506000610ed0565b816020015115610eba57506002610ed0565b8160400151610eca576003610ecd565b60015b90505b6040518060c00160405280848152602001826003811115610ef357610ef3611c38565b8152602001836000015173ffffffffffffffffffffffffffffffffffffffff168152602001836020015115158152602001836040015115158152602001836060015169ffffffffffffffffffff1681525093505050509392505050565b610f58611619565b73ffffffffffffffffffffffffffffffffffffffff811660008181526003602052604080822080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00169055517fb96d15bf9258c7b8df062753a6a262864611fc7b060a5ee2e57e79b85f898d389190a250565b610fd4611619565b73ffffffffffffffffffffffffffffffffffffffff811660008181526003602052604080822080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00166001179055517f0ea0ce2c048ff45a4a95f2947879de3fb94abec2f152190400cab2d1272a68e79190a250565b60015473ffffffffffffffffffffffffffffffffffffffff1633146110cc576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601660248201527f4d7573742062652070726f706f736564206f776e65720000000000000000000060448201526064016104b8565b60008054337fffffffffffffffffffffffff00000000000000000000000000000000000000008083168217845560018054909116905560405173ffffffffffffffffffffffffffffffffffffffff90921692909183917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e091a350565b611150611619565b8260ff1660000361118d576040517f0743bae600000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b601f8111156111d2576040517f61750f4000000000000000000000000000000000000000000000000000000000815260048101829052601f60248201526044016104b8565b6111dd836003612097565b60ff16811161123b57806111f2846003612097565b6111fd906001611e1e565b6040517f9dd9e6d8000000000000000000000000000000000000000000000000000000008152600481019290925260ff1660248201526044016104b8565b67ffffffff00000000602086901b1663ffffffff85161760005b67ffffffffffffffff82166000908152600260205260409020600101548110156112eb5767ffffffffffffffff82166000908152600260208190526040822060018101805491909201929190849081106112b1576112b1611e61565b600091825260208083209091015473ffffffffffffffffffffffffffffffffffffffff168352820192909252604001812055600101611255565b5060005b8281101561146757600084848381811061130b5761130b611e61565b90506020020160208101906113209190611d0f565b905073ffffffffffffffffffffffffffffffffffffffff8116611387576040517fbf18af4300000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff821660048201526024016104b8565b67ffffffffffffffff8316600090815260026020818152604080842073ffffffffffffffffffffffffffffffffffffffff86168552909201905290205415611413576040517fe021c4f200000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff821660048201526024016104b8565b61141e82600161204a565b67ffffffffffffffff8416600090815260026020818152604080842073ffffffffffffffffffffffffffffffffffffffff909616845294909101905291909120556001016112ef565b5067ffffffffffffffff8116600090815260026020526040902061148f9060010184846118df565b5067ffffffffffffffff81166000908152600260205260409081902080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff001660ff87161790555163ffffffff86811691908816907f4120bd3b23957dd423555817d55654d4481b438aa15485c21b4180c784f1a45590611515908890889088906120b3565b60405180910390a3505050505050565b61152d611619565b63ffffffff818116602084811b67ffffffff00000000168217600090815260028252604080822080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff001690558051828152928301905291928516917f4120bd3b23957dd423555817d55654d4481b438aa15485c21b4180c784f1a455916040516115b9929190612119565b60405180910390a35050565b6115cd611619565b6115d68161169c565b50565b60218101516045820151608b90920151909260c09290921c91565b60006115ff83611791565b8015611610575061161083836117f5565b90505b92915050565b60005473ffffffffffffffffffffffffffffffffffffffff16331461169a576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601660248201527f4f6e6c792063616c6c61626c65206279206f776e65720000000000000000000060448201526064016104b8565b565b3373ffffffffffffffffffffffffffffffffffffffff82160361171b576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601760248201527f43616e6e6f74207472616e7366657220746f2073656c6600000000000000000060448201526064016104b8565b600180547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff83811691821790925560008054604051929316917fed8889f560326eb138920d842192f0eb3dd22b4f139c87a2c57538e05bae12789190a350565b60006117bd827f01ffc9a7000000000000000000000000000000000000000000000000000000006117f5565b801561161357506117ee827fffffffff000000000000000000000000000000000000000000000000000000006117f5565b1592915050565b604080517fffffffff000000000000000000000000000000000000000000000000000000008316602480830191909152825180830390910181526044909101909152602080820180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167f01ffc9a700000000000000000000000000000000000000000000000000000000178152825160009392849283928392918391908a617530fa92503d915060005190508280156118ad575060208210155b8015610d3f575015159695505050505050565b6040518061040001604052806020906020820280368337509192915050565b828054828255906000526020600020908101928215611957579160200282015b828111156119575781547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff8435161782556020909201916001909101906118ff565b50611963929150611967565b5090565b5b808211156119635760008155600101611968565b803573ffffffffffffffffffffffffffffffffffffffff811681146119a057600080fd5b919050565b60008083601f8401126119b757600080fd5b50813567ffffffffffffffff8111156119cf57600080fd5b6020830191508360208285010111156119e757600080fd5b9250929050565b60008083601f840112611a0057600080fd5b50813567ffffffffffffffff811115611a1857600080fd5b6020830191508360208260051b85010111156119e757600080fd5b60008060008060008060006080888a031215611a4e57600080fd5b611a578861197c565b9650602088013567ffffffffffffffff80821115611a7457600080fd5b611a808b838c016119a5565b909850965060408a0135915080821115611a9957600080fd5b611aa58b838c016119a5565b909650945060608a0135915080821115611abe57600080fd5b50611acb8a828b016119ee565b989b979a50959850939692959293505050565b60006020808352835180602085015260005b81811015611b0c57858101830151858201604001528201611af0565b5060006040828601015260407fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f8301168501019250505092915050565b600080600080600080600060a0888a031215611b6657600080fd5b87359650611b766020890161197c565b9550611b846040890161197c565b9450606088013567ffffffffffffffff80821115611ba157600080fd5b611bad8b838c016119a5565b909650945060808a0135915080821115611bc657600080fd5b50611acb8a828b016119a5565b600080600060608486031215611be857600080fd5b611bf18461197c565b92506020840135915060408401357fffff00000000000000000000000000000000000000000000000000000000000081168114611c2d57600080fd5b809150509250925092565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602160045260246000fd5b81518152602082015160c082019060048110611cac577f4e487b7100000000000000000000000000000000000000000000000000000000600052602160045260246000fd5b8060208401525073ffffffffffffffffffffffffffffffffffffffff604084015116604083015260608301511515606083015260808301511515608083015260a0830151611d0860a084018269ffffffffffffffffffff169052565b5092915050565b600060208284031215611d2157600080fd5b6116108261197c565b803563ffffffff811681146119a057600080fd5b600080600080600060808688031215611d5657600080fd5b611d5f86611d2a565b9450611d6d60208701611d2a565b9350604086013560ff81168114611d8357600080fd5b9250606086013567ffffffffffffffff811115611d9f57600080fd5b611dab888289016119ee565b969995985093965092949392505050565b60008060408385031215611dcf57600080fd5b611dd883611d2a565b9150611de660208401611d2a565b90509250929050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b60ff818116838216019081111561161357611613611def565b8183823760009101908152919050565b838152818360208301376000910160200190815292915050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b60008083357fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe1843603018112611ec557600080fd5b83018035915067ffffffffffffffff821115611ee057600080fd5b6020019150368190038213156119e757600080fd5b8183528181602085013750600060208284010152600060207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f840116840101905092915050565b602081526000611f52602083018486611ef5565b949350505050565b60008085851115611f6a57600080fd5b83861115611f7757600080fd5b5050820193919092039150565b80356020831015611613577fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff602084900360031b1b1692915050565b878152600073ffffffffffffffffffffffffffffffffffffffff808916602084015280881660408401525060a0606083015261200060a083018688611ef5565b8281036080840152612013818587611ef5565b9a9950505050505050505050565b60006020828403121561203357600080fd5b8151801515811461204357600080fd5b9392505050565b8082018082111561161357611613611def565b8181038181111561161357611613611def565b604081526000612084604083018688611ef5565b8281036020840152610d3f818587611ef5565b60ff8181168382160290811690818114611d0857611d08611def565b60ff8416815260406020808301829052908201839052600090849060608401835b8681101561210d5773ffffffffffffffffffffffffffffffffffffffff6120fa8561197c565b16825292820192908201906001016120d4565b50979650505050505050565b60006040820160ff8516835260206040602085015281855180845260608601915060208701935060005b8181101561217557845173ffffffffffffffffffffffffffffffffffffffff1683529383019391830191600101612143565b509097965050505050505056fea164736f6c6343000818000a

Block Transaction Difficulty Gas Used Reward
View All Blocks Produced

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

Validator Index Block Amount
View All Withdrawals

Transaction Hash Block Value Eth2 PubKey Valid
View All Deposits
Loading...
Loading
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.