Sonic Blaze Testnet

Contract

0xcFC9A8Efad365B04253575326f6A9bcDD8131Eb7

Overview

S Balance

Sonic Blaze LogoSonic Blaze LogoSonic Blaze Logo0 S

Multichain Info

No addresses found
Transaction Hash
Method
Block
From
To
Transfer Ownersh...49082162024-12-17 22:24:2439 hrs ago1734474264IN
0xcFC9A8Ef...DD8131Eb7
0 S0.000047771

Latest 1 internal transaction

Parent Transaction Hash Block From To
47771832024-12-17 10:05:172 days ago1734429917
0xcFC9A8Ef...DD8131Eb7
0 S
Loading...
Loading

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

Contract Name:
Verifier

Compiler Version
v0.8.19+commit.7dd6d404

Optimization Enabled:
Yes with 1000000 runs

Other Settings:
paris EvmVersion

Contract Source Code (Solidity Standard Json-Input format)

File 1 of 12 : Verifier.sol
// SPDX-License-Identifier: MIT
pragma solidity 0.8.19;

import {ConfirmedOwner} from "../../shared/access/ConfirmedOwner.sol";
import {IVerifier} from "./interfaces/IVerifier.sol";
import {IVerifierProxy} from "./interfaces/IVerifierProxy.sol";
import {TypeAndVersionInterface} from "../../interfaces/TypeAndVersionInterface.sol";
import {IERC165} from "../../vendor/openzeppelin-solidity/v4.8.3/contracts/interfaces/IERC165.sol";
import {Common} from "../libraries/Common.sol";

// OCR2 standard
uint256 constant MAX_NUM_ORACLES = 31;

/*
 * The verifier contract is used to verify offchain reports signed
 * by DONs. A report consists of a price, block number and feed Id. It
 * represents the observed price of an asset at a specified block number for
 * a feed. The verifier contract is used to verify that such reports have
 * been signed by the correct signers.
 **/
contract Verifier is IVerifier, ConfirmedOwner, TypeAndVersionInterface {
  // The first byte of the mask can be 0, because we only ever have 31 oracles
  uint256 internal constant ORACLE_MASK = 0x0001010101010101010101010101010101010101010101010101010101010101;

  enum Role {
    // Default role for an oracle address.  This means that the oracle address
    // is not a signer
    Unset,
    // Role given to an oracle address that is allowed to sign a report
    Signer
  }

  struct Signer {
    // Index of oracle in a configuration
    uint8 index;
    // The oracle's role
    Role role;
  }

  struct VerifierState {
    // The block number of the block the last time the configuration was updated.
    uint32 latestConfigBlockNumber;
    // Whether the config is deactivated
    bool isActive;
    // Fault tolerance
    uint8 f;
    // Number of signers
    uint8 oracleCount;
    // Map of signer addresses to oracles
    mapping(address => Signer) oracles;
  }

  /// @notice This event is emitted when a new report is verified.
  /// It is used to keep a historical record of verified reports.
  event ReportVerified(bytes32 indexed feedId, address requester);

  /// @notice This event is emitted whenever a new DON configuration is set.
  event ConfigSet(
    bytes32 indexed configDigest,
    address[] signers,
    uint8 f
  );

  /// @notice This event is
  event ConfigUpdated(
    bytes32 indexed configDigest,
    address[] prevSigners,
    address[] newSigners
  );

  /// @notice This event is emitted whenever a configuration is deactivated
  event ConfigDeactivated(bytes32 indexed configDigest);

  /// @notice This event is emitted whenever a configuration is activated
  event ConfigActivated(bytes32 indexed configDigest);

  /// @notice This error is thrown whenever an address tries
  /// to exeecute a transaction that it is not authorized to do so
  error AccessForbidden();

  /// @notice This error is thrown whenever a zero address is passed
  error ZeroAddress();

  /// @notice This error is thrown whenever the config digest
  /// is empty
  error DigestEmpty();

  /// @notice This error is thrown whenever the config digest
  /// passed in has not been set in this verifier
  /// @param configDigest The config digest that has not been set
  error DigestNotSet(bytes32 configDigest);

  /// @notice This error is thrown whenever the config digest
  /// has been deactivated
  /// @param configDigest The config digest that is inactive
  error DigestInactive(bytes32 configDigest);

  /// @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 a report is signed
  /// with more than the max number of signers
  /// @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 report is signed
  /// with less than the minimum number of signers
  /// @param numSigners The number of signers who have signed the report
  /// @param minSigners The minimum number of signers that need to sign a report
  error InsufficientSigners(uint256 numSigners, uint256 minSigners);

  /// @notice This error is thrown whenever a report is signed
  /// with an incorrect number of signers
  /// @param numSigners The number of signers who have signed the report
  /// @param expectedNumSigners The expected number of signers that need to sign
  /// a report
  error IncorrectSignatureCount(uint256 numSigners, uint256 expectedNumSigners);

  /// @notice This error is thrown whenever the R and S signer components
  /// have different lengths
  /// @param rsLength The number of r signature components
  /// @param ssLength The number of s signature components
  error MismatchedSignatures(uint256 rsLength, uint256 ssLength);

  /// @notice This error is thrown whenever setting a config with duplicate signatures
  error NonUniqueSignatures();

  /// @notice This error is thrown whenever a report fails to verify due to bad or duplicate signatures
  error BadVerification();

  /// @notice This error is thrown whenever a config digest is already set when setting the configuration
  error ConfigDigestAlreadySet();

  /// @notice The address of the verifier proxy
  address private immutable i_verifierProxyAddr;

  /// @notice Verifier states keyed on config digest
  mapping(bytes32 => VerifierState) internal s_verifierStates;

  /// @param verifierProxyAddr The address of the VerifierProxy contract
  constructor(address verifierProxyAddr) ConfirmedOwner(msg.sender) {
    if (verifierProxyAddr == address(0)) revert ZeroAddress();
    i_verifierProxyAddr = verifierProxyAddr;
  }

  modifier checkConfigValid(uint256 numSigners, uint256 f) {
    if (f == 0) revert FaultToleranceMustBePositive();
    if (numSigners > MAX_NUM_ORACLES) revert ExcessSigners(numSigners, MAX_NUM_ORACLES);
    if (numSigners <= 3 * f) revert InsufficientSigners(numSigners, 3 * f + 1);
    _;
  }

  /// @inheritdoc IERC165
  function supportsInterface(bytes4 interfaceId) external pure override returns (bool isVerifier) {
    return interfaceId == this.verify.selector;
  }

  /// @inheritdoc TypeAndVersionInterface
  function typeAndVersion() external pure override returns (string memory) {
    return "Verifier 2.0.0";
  }

  /// @inheritdoc IVerifier
  function verify(
    bytes calldata signedReport,
    address sender
  ) external override returns (bytes memory verifierResponse) {
    if (msg.sender != i_verifierProxyAddr) revert AccessForbidden();
    (
      bytes32[3] memory reportContext,
      bytes memory reportData,
      bytes32[] memory rs,
      bytes32[] memory ss,
      bytes32 rawVs
    ) = abi.decode(signedReport, (bytes32[3], bytes, bytes32[], bytes32[], bytes32));

    // reportContext consists of:
    // reportContext[0]: ConfigDigest
    // reportContext[1]: 27 byte padding, 4-byte epoch and 1-byte round
    // reportContext[2]: ExtraHash
    bytes32 configDigest = reportContext[0];

    VerifierState storage verifierState = s_verifierStates[configDigest];

    _validateReport(configDigest, rs, ss, verifierState);

    bytes32 hashedReport = keccak256(reportData);

    _verifySignatures(hashedReport, reportContext, rs, ss, rawVs, verifierState);
    emit ReportVerified(bytes32(reportData), sender);

    return reportData;
  }

  /// @notice Validates parameters of the report
  /// @param configDigest Config digest from the report
  /// @param rs R components from the report
  /// @param ss S components from the report
  /// @param config Config for the given digest
  function _validateReport(
    bytes32 configDigest,
    bytes32[] memory rs,
    bytes32[] memory ss,
    VerifierState storage config
  ) private view {
    uint8 expectedNumSignatures = config.f + 1;

    if (!config.isActive) revert DigestInactive(configDigest);
    if (rs.length != expectedNumSignatures) revert IncorrectSignatureCount(rs.length, expectedNumSignatures);
    if (rs.length != ss.length) revert MismatchedSignatures(rs.length, ss.length);
  }


  /// @notice Verifies that a report has been signed by the correct
  /// signers and that enough signers have signed the reports.
  /// @param hashedReport The keccak256 hash of the raw report's bytes
  /// @param reportContext The context the report was signed in
  /// @param rs ith element is the R components of the ith signature on report. Must have at most MAX_NUM_ORACLES entries
  /// @param ss ith element is the S components of the ith signature on report. Must have at most MAX_NUM_ORACLES entries
  /// @param rawVs ith element is the the V component of the ith signature
  /// @param config The config digest the report was signed for
  function _verifySignatures(
    bytes32 hashedReport,
    bytes32[3] memory reportContext,
    bytes32[] memory rs,
    bytes32[] memory ss,
    bytes32 rawVs,
    VerifierState storage config
  ) private view {
    bytes32 h = keccak256(abi.encodePacked(hashedReport, reportContext));
    // i-th byte counts number of sigs made by i-th signer
    uint256 signedCount;

    Signer memory o;
    address signerAddress;
    uint256 numSigners = rs.length;
    for (uint256 i; i < numSigners; ++i) {
      signerAddress = ecrecover(h, uint8(rawVs[i]) + 27, rs[i], ss[i]);
      o = config.oracles[signerAddress];
      if (o.role != Role.Signer) revert BadVerification();
      unchecked {
        signedCount += 1 << (8 * o.index);
      }
    }

    if (signedCount & ORACLE_MASK != signedCount) revert BadVerification();
  }

  /// @inheritdoc IVerifier
  function updateConfig(
    bytes32 configDigest,
    address[] calldata prevSigners,
    address[] calldata newSigners,
    uint8 f
  ) external override checkConfigValid(newSigners.length, f) onlyOwner {
    VerifierState storage config = s_verifierStates[configDigest];

    if (config.f == 0) revert DigestNotSet(configDigest);

    // We must be removing the number of signers that were originally set
    if(config.oracleCount != prevSigners.length){
      revert NonUniqueSignatures();
    }

    for (uint256 i; i < prevSigners.length; ++i) {
      // Check the signers being removed are not zero address or duplicates
      if(config.oracles[prevSigners[i]].role == Role.Unset){
        revert NonUniqueSignatures();
      }

      delete config.oracles[prevSigners[i]];
    }

    // Once signers have been cleared we can set the new signers
    _setConfig(configDigest, newSigners, f, new Common.AddressAndWeight[](0), true);


    emit ConfigUpdated(configDigest, prevSigners, newSigners);
  }

  /// @inheritdoc IVerifier
  function setConfig(
    bytes32 configDigest,
    address[] calldata signers,
    uint8 f,
    Common.AddressAndWeight[] memory recipientAddressesAndWeights
  ) external override checkConfigValid(signers.length, f) onlyOwner {
    _setConfig(configDigest, signers, f, recipientAddressesAndWeights, false);
  }

  function _setConfig(
    bytes32 configDigest,
    address[] calldata signers,
    uint8 f,
    Common.AddressAndWeight[] memory recipientAddressesAndWeights,
    bool _updateConfig
  ) internal {
    VerifierState storage verifierState = s_verifierStates[configDigest];

    if(verifierState.f > 0 && !_updateConfig) {
      revert ConfigDigestAlreadySet();
    }

    verifierState.latestConfigBlockNumber = uint32(block.number);
    verifierState.f = f;
    verifierState.isActive = true;
    verifierState.oracleCount = uint8(signers.length);

    for (uint8 i; i < signers.length; ++i) {
      address signerAddr = signers[i];
      if (signerAddr == address(0)) revert ZeroAddress();

      // All signer roles are unset by default for a new config digest.
      // Here the contract checks to see if a signer's address has already
      // been set to ensure that the group of signer addresses that will
      // sign reports with the config digest are unique.
      bool isSignerAlreadySet = verifierState.oracles[signerAddr].role !=
        Role.Unset;
      if (isSignerAlreadySet) revert NonUniqueSignatures();
      verifierState.oracles[signerAddr] = Signer({
        role: Role.Signer,
        index: i
      });
    }

    if(!_updateConfig) {
      IVerifierProxy(i_verifierProxyAddr).setVerifier(
        bytes32(0),
        configDigest,
        recipientAddressesAndWeights
      );

      emit ConfigSet(
        configDigest,
        signers,
        f
      );
    }
  }

  /// @inheritdoc IVerifier
  function activateConfig(bytes32 configDigest) external onlyOwner {
    VerifierState storage verifierState = s_verifierStates[configDigest];

    if (configDigest == bytes32("")) revert DigestEmpty();
    if (verifierState.f == 0) revert DigestNotSet(configDigest);
    verifierState.isActive = true;
    emit ConfigActivated(configDigest);
  }

  /// @inheritdoc IVerifier
  function deactivateConfig(bytes32 configDigest) external onlyOwner {
    VerifierState storage verifierState = s_verifierStates[configDigest];

    if (configDigest == bytes32("")) revert DigestEmpty();
    if (verifierState.f == 0) revert DigestNotSet(configDigest);
    verifierState.isActive = false;
    emit ConfigDeactivated(configDigest);
  }

  /// @inheritdoc IVerifier
  function latestConfigDetails(
    bytes32 configDigest
  ) external view override returns (uint32 blockNumber) {
    VerifierState storage verifierState = s_verifierStates[configDigest];
    return (
      verifierState.latestConfigBlockNumber
    );
  }
}

File 2 of 12 : 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 3 of 12 : IVerifier.sol
// SPDX-License-Identifier: MIT
pragma solidity 0.8.19;

import {IERC165} from "../../../vendor/openzeppelin-solidity/v4.8.3/contracts/interfaces/IERC165.sol";
import {Common} from "../../libraries/Common.sol";

interface IVerifier is IERC165 {
  /**
   * @notice Verifies that the data encoded has been signed
   * correctly by routing to the correct verifier.
   * @param signedReport The encoded data to be verified.
   * @param sender The address that requested to verify the contract.
   * This is only used for logging purposes.
   * @dev Verification is typically only done through the proxy contract so
   * we can't just use msg.sender to log the requester as the msg.sender
   * contract will always be the proxy.
   * @return verifierResponse The encoded verified response.
   */
  function verify(bytes calldata signedReport, address sender) external returns (bytes memory verifierResponse);

  /**
   * @notice sets a configuration and its associated keys and f
   * @param configDigest The digest of the configuration we're setting
   * @param signers addresses with which oracles sign the reports
   * @param f number of faulty oracles the system can tolerate
   * @param recipientAddressesAndWeights the addresses and weights of all the recipients to receive rewards
   */
  function setConfig(
    bytes32 configDigest,
    address[] calldata signers,
    uint8 f,
    Common.AddressAndWeight[] memory recipientAddressesAndWeights
  ) external;

  /**
   * @notice updates a configuration that has been set
   * @param configDigest The digest of the configuration we're updating
   * @param prevSigners the existing signers that need to be removed
   * @param newSigners the signers to be added
   * @param f the newnumber of faulty oracles the system can tolerate
   */
  function updateConfig(
    bytes32 configDigest,
    address[] calldata prevSigners,
    address[] calldata newSigners,
    uint8 f
  ) external;

  /**
   * @notice Activates the configuration for a config digest
   * @param configDigest The config digest to activate
   * @dev This function can be called by the contract admin to activate a configuration.
   */
  function activateConfig(bytes32 configDigest) external;

  /**
   * @notice Deactivates the configuration for a config digest
   * @param configDigest The config digest to deactivate
   * @dev This function can be called by the contract admin to deactivate an incorrect configuration.
   */
  function deactivateConfig(bytes32 configDigest) external;

  /**
   * @notice information about current offchain reporting protocol configuration
   * @param configDigest Config Digest to fetch data for
   * @return blockNumber block at which this config was set
   */
  function latestConfigDetails(
    bytes32 configDigest
  ) external view returns (uint32 blockNumber);
}

File 4 of 12 : IVerifierProxy.sol
// SPDX-License-Identifier: MIT
pragma solidity 0.8.19;

import {Common} from "../../libraries/Common.sol";
import {AccessControllerInterface} from "../../../shared/interfaces/AccessControllerInterface.sol";
import {IVerifierFeeManager} from "./IVerifierFeeManager.sol";

interface IVerifierProxy {
  /**
   * @notice Verifies that the data encoded has been signed
   * correctly by routing to the correct verifier, and bills the user if applicable.
   * @param payload The encoded data to be verified, including the signed
   * report.
   * @param parameterPayload fee metadata for billing
   * @return verifierResponse The encoded report from the verifier.
   */
  function verify(
    bytes calldata payload,
    bytes calldata parameterPayload
  ) external payable returns (bytes memory verifierResponse);

  /**
   * @notice Bulk verifies that the data encoded has been signed
   * correctly by routing to the correct verifier, and bills the user if applicable.
   * @param payloads The encoded payloads to be verified, including the signed
   * report.
   * @param parameterPayload fee metadata for billing
   * @return verifiedReports The encoded reports from the verifier.
   */
  function verifyBulk(
    bytes[] calldata payloads,
    bytes calldata parameterPayload
  ) external payable returns (bytes[] memory verifiedReports);

  /**
   * @notice Sets the verifier address initially, allowing `setVerifier` to be set by this Verifier in the future
   * @param verifierAddress The address of the verifier contract to initialize
   */
  function initializeVerifier(address verifierAddress) external;

  /**
   * @notice Sets a new verifier for a config digest
   * @param currentConfigDigest The current config digest
   * @param newConfigDigest The config digest to set
   * @param addressesAndWeights The addresses and weights of reward recipients
   * reports for a given config digest.
   */
  function setVerifier(
    bytes32 currentConfigDigest,
    bytes32 newConfigDigest,
    Common.AddressAndWeight[] memory addressesAndWeights
  ) external;

  /**
   * @notice Removes a verifier for a given config digest
   * @param configDigest The config digest of the verifier to remove
   */
  function unsetVerifier(bytes32 configDigest) external;

  /**
   * @notice Retrieves the verifier address that verifies reports
   * for a config digest.
   * @param configDigest The config digest to query for
   * @return verifierAddress The address of the verifier contract that verifies
   * reports for a given config digest.
   */
  function getVerifier(bytes32 configDigest) external view returns (address verifierAddress);

  /**
   * @notice Called by the admin to set an access controller contract
   * @param accessController The new access controller to set
   */
  function setAccessController(AccessControllerInterface accessController) external;

  /**
   * @notice Updates the fee manager
   * @param feeManager The new fee manager
   */
  function setFeeManager(IVerifierFeeManager feeManager) external;
}

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

abstract contract TypeAndVersionInterface {
  function typeAndVersion() external pure virtual returns (string memory);
}

File 6 of 12 : IERC165.sol
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts v4.4.1 (interfaces/IERC165.sol)

pragma solidity ^0.8.0;

import "../utils/introspection/IERC165.sol";

File 7 of 12 : Common.sol
// SPDX-License-Identifier: MIT
pragma solidity 0.8.19;

/*
 * @title Common
 * @author Michael Fletcher
 * @notice Common functions and structs
 */
library Common {
  // @notice The asset struct to hold the address of an asset and amount
  struct Asset {
    address assetAddress;
    uint256 amount;
  }

  // @notice Struct to hold the address and its associated weight
  struct AddressAndWeight {
    address addr;
    uint64 weight;
  }

  /**
   * @notice Checks if an array of AddressAndWeight has duplicate addresses
   * @param recipients The array of AddressAndWeight to check
   * @return bool True if there are duplicates, false otherwise
   */
  function _hasDuplicateAddresses(address[] memory recipients) internal pure returns (bool) {
    for (uint256 i = 0; i < recipients.length; ) {
      for (uint256 j = i + 1; j < recipients.length; ) {
        if (recipients[i] == recipients[j]) {
          return true;
        }
        unchecked {
          ++j;
        }
      }
      unchecked {
        ++i;
      }
    }
    return false;
  }

  /**
   * @notice Checks if an array of AddressAndWeight has duplicate addresses
   * @param recipients The array of AddressAndWeight to check
   * @return bool True if there are duplicates, false otherwise
   */
  function _hasDuplicateAddresses(Common.AddressAndWeight[] memory recipients) internal pure returns (bool) {
    for (uint256 i = 0; i < recipients.length; ) {
      for (uint256 j = i + 1; j < recipients.length; ) {
        if (recipients[i].addr == recipients[j].addr) {
          return true;
        }
        unchecked {
          ++j;
        }
      }
      unchecked {
        ++i;
      }
    }
    return false;
  }

  /**
   * @notice sorts a list of addresses numerically
   * @param arr The array of addresses to sort
   * @param left the start index
   * @param right the end index
   */
  function _quickSort(address[] memory arr, int256 left, int256 right) internal pure {
    int256 i = left;
    int256 j = right;
    if (i == j) return;
    address pivot = arr[uint256(left + (right - left) / 2)];
    while (i <= j) {
      while (uint160(arr[uint256(i)]) < uint160(pivot)) i++;
      while (uint160(pivot) < uint160(arr[uint256(j)])) j--;
      if (i <= j) {
        (arr[uint256(i)], arr[uint256(j)]) = (arr[uint256(j)], arr[uint256(i)]);
        i++;
        j--;
      }
    }
    if (left < j) _quickSort(arr, left, j);
    if (i < right) _quickSort(arr, i, right);
  }
}

File 8 of 12 : 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 9 of 12 : AccessControllerInterface.sol
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;

// solhint-disable-next-line interface-starts-with-i
interface AccessControllerInterface {
  function hasAccess(address user, bytes calldata data) external view returns (bool);
}

File 10 of 12 : IVerifierFeeManager.sol
// SPDX-License-Identifier: MIT
pragma solidity 0.8.19;

import {IERC165} from "../../../vendor/openzeppelin-solidity/v4.8.3/contracts/interfaces/IERC165.sol";
import {Common} from "../../libraries/Common.sol";

interface IVerifierFeeManager is IERC165 {
  /**
   * @notice Handles fees for a report from the subscriber and manages rewards
   * @param payload report to process the fee for
   * @param parameterPayload fee payload
   * @param subscriber address of the fee will be applied
   */
  function processFee(bytes calldata payload, bytes calldata parameterPayload, address subscriber) external payable;

  /**
   * @notice Processes the fees for each report in the payload, billing the subscriber and paying the reward manager
   * @param payloads reports to process
   * @param parameterPayload fee payload
   * @param subscriber address of the user to process fee for
   */
  function processFeeBulk(
    bytes[] calldata payloads,
    bytes calldata parameterPayload,
    address subscriber
  ) external payable;

  /**
   * @notice Sets the fee recipients according to the fee manager
   * @param configDigest digest of the configuration
   * @param rewardRecipientAndWeights the address and weights of all the recipients to receive rewards
   */
  function setFeeRecipients(
    bytes32 configDigest,
    Common.AddressAndWeight[] calldata rewardRecipientAndWeights
  ) external;
}

File 11 of 12 : 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 12 of 12 : 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

[{"inputs":[{"internalType":"address","name":"verifierProxyAddr","type":"address"}],"stateMutability":"nonpayable","type":"constructor"},{"inputs":[],"name":"AccessForbidden","type":"error"},{"inputs":[],"name":"BadVerification","type":"error"},{"inputs":[],"name":"ConfigDigestAlreadySet","type":"error"},{"inputs":[],"name":"DigestEmpty","type":"error"},{"inputs":[{"internalType":"bytes32","name":"configDigest","type":"bytes32"}],"name":"DigestInactive","type":"error"},{"inputs":[{"internalType":"bytes32","name":"configDigest","type":"bytes32"}],"name":"DigestNotSet","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":"uint256","name":"numSigners","type":"uint256"},{"internalType":"uint256","name":"expectedNumSigners","type":"uint256"}],"name":"IncorrectSignatureCount","type":"error"},{"inputs":[{"internalType":"uint256","name":"numSigners","type":"uint256"},{"internalType":"uint256","name":"minSigners","type":"uint256"}],"name":"InsufficientSigners","type":"error"},{"inputs":[{"internalType":"uint256","name":"rsLength","type":"uint256"},{"internalType":"uint256","name":"ssLength","type":"uint256"}],"name":"MismatchedSignatures","type":"error"},{"inputs":[],"name":"NonUniqueSignatures","type":"error"},{"inputs":[],"name":"ZeroAddress","type":"error"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"bytes32","name":"configDigest","type":"bytes32"}],"name":"ConfigActivated","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"bytes32","name":"configDigest","type":"bytes32"}],"name":"ConfigDeactivated","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"bytes32","name":"configDigest","type":"bytes32"},{"indexed":false,"internalType":"address[]","name":"signers","type":"address[]"},{"indexed":false,"internalType":"uint8","name":"f","type":"uint8"}],"name":"ConfigSet","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"bytes32","name":"configDigest","type":"bytes32"},{"indexed":false,"internalType":"address[]","name":"prevSigners","type":"address[]"},{"indexed":false,"internalType":"address[]","name":"newSigners","type":"address[]"}],"name":"ConfigUpdated","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":"bytes32","name":"feedId","type":"bytes32"},{"indexed":false,"internalType":"address","name":"requester","type":"address"}],"name":"ReportVerified","type":"event"},{"inputs":[],"name":"acceptOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes32","name":"configDigest","type":"bytes32"}],"name":"activateConfig","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes32","name":"configDigest","type":"bytes32"}],"name":"deactivateConfig","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes32","name":"configDigest","type":"bytes32"}],"name":"latestConfigDetails","outputs":[{"internalType":"uint32","name":"blockNumber","type":"uint32"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"owner","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes32","name":"configDigest","type":"bytes32"},{"internalType":"address[]","name":"signers","type":"address[]"},{"internalType":"uint8","name":"f","type":"uint8"},{"components":[{"internalType":"address","name":"addr","type":"address"},{"internalType":"uint64","name":"weight","type":"uint64"}],"internalType":"struct Common.AddressAndWeight[]","name":"recipientAddressesAndWeights","type":"tuple[]"}],"name":"setConfig","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes4","name":"interfaceId","type":"bytes4"}],"name":"supportsInterface","outputs":[{"internalType":"bool","name":"isVerifier","type":"bool"}],"stateMutability":"pure","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":"pure","type":"function"},{"inputs":[{"internalType":"bytes32","name":"configDigest","type":"bytes32"},{"internalType":"address[]","name":"prevSigners","type":"address[]"},{"internalType":"address[]","name":"newSigners","type":"address[]"},{"internalType":"uint8","name":"f","type":"uint8"}],"name":"updateConfig","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes","name":"signedReport","type":"bytes"},{"internalType":"address","name":"sender","type":"address"}],"name":"verify","outputs":[{"internalType":"bytes","name":"verifierResponse","type":"bytes"}],"stateMutability":"nonpayable","type":"function"}]

Deployed Bytecode

0x608060405234801561001057600080fd5b50600436106100c95760003560e01c80633d3ac1b5116100815780638da5cb5b1161005b5780638da5cb5b146101e3578063e84f128e1461020b578063f2fde38b1461024657600080fd5b80633d3ac1b5146101b557806341e3df58146101c857806379ba5097146101db57600080fd5b80630e112e54116100b25780630e112e541461014d5780630f672ef414610160578063181f5a771461017357600080fd5b806301ffc9a7146100ce5780630d1d79af14610138575b600080fd5b6101236100dc366004611333565b7fffffffff00000000000000000000000000000000000000000000000000000000167f3d3ac1b5000000000000000000000000000000000000000000000000000000001490565b60405190151581526020015b60405180910390f35b61014b61014636600461137c565b610259565b005b61014b61015b3660046113f7565b610351565b61014b61016e36600461137c565b6106bc565b60408051808201909152600e81527f566572696669657220322e302e3000000000000000000000000000000000000060208201525b60405161012f91906114e4565b6101a86101c336600461151b565b6107a8565b61014b6101d636600461168a565b6108cc565b61014b61098e565b60005460405173ffffffffffffffffffffffffffffffffffffffff909116815260200161012f565b61023161021936600461137c565b60009081526002602052604090205463ffffffff1690565b60405163ffffffff909116815260200161012f565b61014b6102543660046117a3565b610a8b565b610261610a9f565b6000818152600260205260409020816102a6576040517fe332262700000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b805465010000000000900460ff166000036102f5576040517f74eb4b93000000000000000000000000000000000000000000000000000000008152600481018390526024015b60405180910390fd5b80547fffffffffffffffffffffffffffffffffffffffffffffffffffffff00ffffffff1664010000000017815560405182907fa543797a0501218bba8a3daf75a71c8df8d1a7f791f4e44d40e43b6450183cea90600090a25050565b8160ff82166000819003610391576040517f0743bae600000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b601f8211156103d6576040517f61750f4000000000000000000000000000000000000000000000000000000000815260048101839052601f60248201526044016102ec565b6103e18160036117ed565b821161043957816103f38260036117ed565b6103fe90600161180a565b6040517f9dd9e6d8000000000000000000000000000000000000000000000000000000008152600481019290925260248201526044016102ec565b610441610a9f565b6000888152600260205260408120805490916501000000000090910460ff16900361049b576040517f74eb4b93000000000000000000000000000000000000000000000000000000008152600481018a90526024016102ec565b80546601000000000000900460ff1687146104e2576040517ff67bc7c400000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60005b8781101561061c5760008260010160008b8b858181106105075761050761184c565b905060200201602081019061051c91906117a3565b73ffffffffffffffffffffffffffffffffffffffff168152602081019190915260400160002054610100900460ff16600181111561055c5761055c61181d565b03610593576040517ff67bc7c400000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b8160010160008a8a848181106105ab576105ab61184c565b90506020020160208101906105c091906117a3565b73ffffffffffffffffffffffffffffffffffffffff168152602081019190915260400160002080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00001690556106158161187b565b90506104e5565b5061067389878787600060405190808252806020026020018201604052801561066b57816020015b60408051808201909152600080825260208201528152602001906001900390816106445790505b506001610b22565b887fb0b75a854fab801413da6202fc07e875c54eaf371a1e3909fb2645364ba58616898989896040516106a99493929190611907565b60405180910390a2505050505050505050565b6106c4610a9f565b600081815260026020526040902081610709576040517fe332262700000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b805465010000000000900460ff16600003610753576040517f74eb4b93000000000000000000000000000000000000000000000000000000008152600481018390526024016102ec565b80547fffffffffffffffffffffffffffffffffffffffffffffffffffffff00ffffffff16815560405182907f5bfaab86edc1b932e3c334327a591c9ded067cb521abae19b95ca927d607657990600090a25050565b60603373ffffffffffffffffffffffffffffffffffffffff7f000000000000000000000000c539169910de08d237df0d73bcda9074c787a4a11614610819576040517fef67f5d800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60008080808061082b888a018a611a2d565b84516000818152600260205260409020959a50939850919650945092509061085582868684610ec2565b8551602087012061086a818988888887610fc2565b61087387611b08565b60405173ffffffffffffffffffffffffffffffffffffffff8c1681527f58ca9502e98a536e06e72d680fcc251e5d10b72291a281665a2c2dc0ac30fcc59060200160405180910390a250949a9950505050505050505050565b8260ff8316600081900361090c576040517f0743bae600000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b601f821115610951576040517f61750f4000000000000000000000000000000000000000000000000000000000815260048101839052601f60248201526044016102ec565b61095c8160036117ed565b821161096e57816103f38260036117ed565b610976610a9f565b61098587878787876000610b22565b50505050505050565b60015473ffffffffffffffffffffffffffffffffffffffff163314610a0f576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601660248201527f4d7573742062652070726f706f736564206f776e65720000000000000000000060448201526064016102ec565b60008054337fffffffffffffffffffffffff00000000000000000000000000000000000000008083168217845560018054909116905560405173ffffffffffffffffffffffffffffffffffffffff90921692909183917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e091a350565b610a93610a9f565b610a9c8161123e565b50565b60005473ffffffffffffffffffffffffffffffffffffffff163314610b20576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601660248201527f4f6e6c792063616c6c61626c65206279206f776e65720000000000000000000060448201526064016102ec565b565b6000868152600260205260409020805465010000000000900460ff1615801590610b4a575081155b15610b81576040517f961dba8800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b805460ff8681166601000000000000027fffffffffffffffffffffffffffffffffffffffffffffffffff00ff00ffffffff91871665010000000000027fffffffffffffffffffffffffffffffffffffffffffffffffffff00ff0000000090931663ffffffff43161792909217161764010000000017815560005b60ff8116861115610dce57600087878360ff16818110610c1d57610c1d61184c565b9050602002016020810190610c3291906117a3565b905073ffffffffffffffffffffffffffffffffffffffff8116610c81576040517fd92e233d00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60008073ffffffffffffffffffffffffffffffffffffffff831660009081526001868101602052604090912054610100900460ff1690811115610cc657610cc661181d565b1480159150610d01576040517ff67bc7c400000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60408051808201825260ff85811682526001602080840182815273ffffffffffffffffffffffffffffffffffffffff881660009081528a84019092529490208351815493167fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff008416811782559451939490939284927fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff000090911690911790610100908490811115610db357610db361181d565b0217905550905050505080610dc790611b4d565b9050610bfb565b5081610985576040517fb011b24700000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff7f000000000000000000000000c539169910de08d237df0d73bcda9074c787a4a1169063b011b24790610e4b906000908b908890600401611b6c565b600060405180830381600087803b158015610e6557600080fd5b505af1158015610e79573d6000803e3d6000fd5b50505050867f5b1f376eb2bda670fa39339616d0a73f45b61bec8faeba8ca834f2ebb49676e0878787604051610eb193929190611bec565b60405180910390a250505050505050565b8054600090610ede9065010000000000900460ff166001611c13565b8254909150640100000000900460ff16610f27576040517fd990d621000000000000000000000000000000000000000000000000000000008152600481018690526024016102ec565b8060ff16845114610f735783516040517f5348a282000000000000000000000000000000000000000000000000000000008152600481019190915260ff821660248201526044016102ec565b8251845114610fbb57835183516040517ff0d31408000000000000000000000000000000000000000000000000000000008152600481019290925260248201526044016102ec565b5050505050565b60008686604051602001610fd7929190611c2c565b604051602081830303815290604052805190602001209050600061100b604080518082019091526000808252602082015290565b8651600090815b818110156111d65760018689836020811061102f5761102f61184c565b61103c91901a601b611c13565b8c848151811061104e5761104e61184c565b60200260200101518c85815181106110685761106861184c565b6020026020010151604051600081526020016040526040516110a6949392919093845260ff9290921660208401526040830152606082015260800190565b6020604051602081039080840390855afa1580156110c8573d6000803e3d6000fd5b5050604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe081015173ffffffffffffffffffffffffffffffffffffffff811660009081526001808d01602090815291859020848601909552845460ff80821686529399509395509085019261010090049091169081111561114d5761114d61181d565b600181111561115e5761115e61181d565b905250935060018460200151600181111561117b5761117b61181d565b146111b2576040517f4df18f0700000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b836000015160080260ff166001901b85019450806111cf9061187b565b9050611012565b50837e01010101010101010101010101010101010101010101010101010101010101851614611231576040517f4df18f0700000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b5050505050505050505050565b3373ffffffffffffffffffffffffffffffffffffffff8216036112bd576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601760248201527f43616e6e6f74207472616e7366657220746f2073656c6600000000000000000060448201526064016102ec565b600180547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff83811691821790925560008054604051929316917fed8889f560326eb138920d842192f0eb3dd22b4f139c87a2c57538e05bae12789190a350565b60006020828403121561134557600080fd5b81357fffffffff000000000000000000000000000000000000000000000000000000008116811461137557600080fd5b9392505050565b60006020828403121561138e57600080fd5b5035919050565b60008083601f8401126113a757600080fd5b50813567ffffffffffffffff8111156113bf57600080fd5b6020830191508360208260051b85010111156113da57600080fd5b9250929050565b803560ff811681146113f257600080fd5b919050565b6000806000806000806080878903121561141057600080fd5b86359550602087013567ffffffffffffffff8082111561142f57600080fd5b61143b8a838b01611395565b9097509550604089013591508082111561145457600080fd5b5061146189828a01611395565b90945092506114749050606088016113e1565b90509295509295509295565b6000815180845260005b818110156114a65760208185018101518683018201520161148a565b5060006020828601015260207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f83011685010191505092915050565b6020815260006113756020830184611480565b803573ffffffffffffffffffffffffffffffffffffffff811681146113f257600080fd5b60008060006040848603121561153057600080fd5b833567ffffffffffffffff8082111561154857600080fd5b818601915086601f83011261155c57600080fd5b81358181111561156b57600080fd5b87602082850101111561157d57600080fd5b60209283019550935061159391860190506114f7565b90509250925092565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b6040805190810167ffffffffffffffff811182821017156115ee576115ee61159c565b60405290565b6040516060810167ffffffffffffffff811182821017156115ee576115ee61159c565b604051601f82017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016810167ffffffffffffffff8111828210171561165e5761165e61159c565b604052919050565b600067ffffffffffffffff8211156116805761168061159c565b5060051b60200190565b6000806000806000608086880312156116a257600080fd5b8535945060208087013567ffffffffffffffff808211156116c257600080fd5b6116ce8a838b01611395565b9097509550604091506116e28983016113e1565b94506060890135818111156116f657600080fd5b8901601f81018b1361170757600080fd5b803561171a61171582611666565b611617565b81815260069190911b8201850190858101908d83111561173957600080fd5b928601925b8284101561178f5785848f0312156117565760008081fd5b61175e6115cb565b611767856114f7565b815287850135868116811461177c5760008081fd5b818901528252928501929086019061173e565b809750505050505050509295509295909350565b6000602082840312156117b557600080fd5b611375826114f7565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b8082028115828204841417611804576118046117be565b92915050565b80820180821115611804576118046117be565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602160045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b60007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff82036118ac576118ac6117be565b5060010190565b8183526000602080850194508260005b858110156118fc5773ffffffffffffffffffffffffffffffffffffffff6118e9836114f7565b16875295820195908201906001016118c3565b509495945050505050565b60408152600061191b6040830186886118b3565b828103602084015261192e8185876118b3565b979650505050505050565b600082601f83011261194a57600080fd5b813567ffffffffffffffff8111156119645761196461159c565b61199560207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f84011601611617565b8181528460208386010111156119aa57600080fd5b816020850160208301376000918101602001919091529392505050565b600082601f8301126119d857600080fd5b813560206119e861171583611666565b82815260059290921b84018101918181019086841115611a0757600080fd5b8286015b84811015611a225780358352918301918301611a0b565b509695505050505050565b600080600080600060e08688031215611a4557600080fd5b86601f870112611a5457600080fd5b611a5c6115f4565b806060880189811115611a6e57600080fd5b885b81811015611a88578035845260209384019301611a70565b5090965035905067ffffffffffffffff80821115611aa557600080fd5b611ab189838a01611939565b95506080880135915080821115611ac757600080fd5b611ad389838a016119c7565b945060a0880135915080821115611ae957600080fd5b50611af6888289016119c7565b9598949750929560c001359392505050565b80516020808301519190811015611b47577fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8160200360031b1b821691505b50919050565b600060ff821660ff8103611b6357611b636117be565b60010192915050565b600060608201858352602085818501526040606081860152828651808552608087019150838801945060005b81811015611bdd578551805173ffffffffffffffffffffffffffffffffffffffff16845285015167ffffffffffffffff16858401529484019491830191600101611b98565b50909998505050505050505050565b604081526000611c006040830185876118b3565b905060ff83166020830152949350505050565b60ff8181168382160190811115611804576118046117be565b828152600060208083018460005b6003811015611c5757815183529183019190830190600101611c3a565b50505050608082019050939250505056fea164736f6c6343000813000a

Block Transaction 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
[ Download: CSV Export  ]
[ 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.