Contract 0x1242b6c5e0e349b8d4bcf0938f961c4b4f7ea3fa

Contract Overview

Balance:
0 ETH
Txn Hash Method
Block
From
To
Value
0xec4b5bb146031164f5f6f7de7c2465f79b7a2bc5bd26c5f45f0460cd59de2a10Transmit105335802024-05-27 18:44:0811 mins ago0xf694c80ab63d01591b3950dc3709dfbc4ba8fc93 IN  0x1242b6c5e0e349b8d4bcf0938f961c4b4f7ea3fa0 ETH0.0003351846261.000000603
0x644a9bfb6953b5d249e9249d57388b423a286cc4803f777a5d0d23e793bc2a36Transmit105335502024-05-27 18:43:0812 mins ago0x5edbe288c2484f99c5cd07b06a323e90b04b5424 IN  0x1242b6c5e0e349b8d4bcf0938f961c4b4f7ea3fa0 ETH0.0003519700431.000000579
0x2b6fa42a4654d42fdf81622453c4cbed44fa9d15fff6f19e93a653f4837891fbTransmit105334602024-05-27 18:40:0815 mins ago0x3ddedc24f2d78e4f8510315575213535fd7856d7 IN  0x1242b6c5e0e349b8d4bcf0938f961c4b4f7ea3fa0 ETH0.0001921798810.00150072
0x4cc62f0c569f9370b0df20fe87ca50997864349306cc15f6dff4ceb2aae96018Transmit105334302024-05-27 18:39:0816 mins ago0x87aed093904608e14361569c4a7e23a2d3ba376f IN  0x1242b6c5e0e349b8d4bcf0938f961c4b4f7ea3fa0 ETH0.0001851691880.001500692
0x857594624f757c6cee5800f0ad9f64a5eea4d222cf973f7e854fc8b2a558e3ebTransmit105311202024-05-27 17:22:081 hr 33 mins ago0x3a61ede2540886712b8ba54074debe94f31c2324 IN  0x1242b6c5e0e349b8d4bcf0938f961c4b4f7ea3fa0 ETH0.0007296138550.001300623
0x107ac099770717d1ec2a2d1b9b26bc3a13eac065475f8b542650c5eb8689c795Transmit105310902024-05-27 17:21:081 hr 34 mins ago0x28fa06a806269ecbef60ca4b06a33ff16c436b50 IN  0x1242b6c5e0e349b8d4bcf0938f961c4b4f7ea3fa0 ETH0.0006506136010.001300624
0xe636e7e1ebffb480145800309bf572e9ae74bd48f0f7290cc04a8440140ec3f1Transmit105308922024-05-27 17:14:321 hr 41 mins ago0x096f8a2fb7bf9a14a5c94fedcb425ad344e6700a IN  0x1242b6c5e0e349b8d4bcf0938f961c4b4f7ea3fa0 ETH0.00047471550.00113027
0x782350bf619b64d7d915278e86d1f1712a6f163e53d8e19596dc9caa1b5e4446Transmit105308502024-05-27 17:13:081 hr 42 mins ago0x3ddedc24f2d78e4f8510315575213535fd7856d7 IN  0x1242b6c5e0e349b8d4bcf0938f961c4b4f7ea3fa0 ETH0.0005774245910.00113027
0x13d42a47d29c11d440de5a4ea36e2b2105e69e1a7165a691fcb788791a5719caTransmit105306102024-05-27 17:05:081 hr 50 mins ago0x3ddedc24f2d78e4f8510315575213535fd7856d7 IN  0x1242b6c5e0e349b8d4bcf0938f961c4b4f7ea3fa0 ETH0.0004061918590.00120032
0xf05f4183aa4189129ff75f187ae298475cbc72d3317b1d9ec53ac95798f86f02Transmit105305802024-05-27 17:04:081 hr 51 mins ago0x74445d903dfd19ceffe7b1db2155be260be7df8b IN  0x1242b6c5e0e349b8d4bcf0938f961c4b4f7ea3fa0 ETH0.0004930158780.001200319
0xa96abd7a22d556cf6b27f497badaff368f2bcc5cbd207381769d2e21c69282a8Transmit105305502024-05-27 17:03:081 hr 52 mins ago0x87aed093904608e14361569c4a7e23a2d3ba376f IN  0x1242b6c5e0e349b8d4bcf0938f961c4b4f7ea3fa0 ETH0.000534885960.001200318
0xe67e9715054a8e61df69f714d3d68f7e3eaa303ac1554152d23965519756014eTransmit105304902024-05-27 17:01:081 hr 54 mins ago0x96526f37441f3e2917dc41aeebe9ac9d599fcbc3 IN  0x1242b6c5e0e349b8d4bcf0938f961c4b4f7ea3fa0 ETH0.000675786690.001100569
0x1116fbefbbeb267c9c5e0615c1d77ed91609c220c4a7c6597bc50783b5385478Transmit105304602024-05-27 17:00:081 hr 55 mins ago0x3a61ede2540886712b8ba54074debe94f31c2324 IN  0x1242b6c5e0e349b8d4bcf0938f961c4b4f7ea3fa0 ETH0.0006517959810.001200321
0xfcadb0c275c95b6cb66791801c80f5e34239062a199c73dc164d62ff6311ae2eTransmit105303702024-05-27 16:57:081 hr 58 mins ago0x3ddedc24f2d78e4f8510315575213535fd7856d7 IN  0x1242b6c5e0e349b8d4bcf0938f961c4b4f7ea3fa0 ETH0.0008240703920.003000809
0xc5c9329d55e1c79393ebad52572baed48b88eb52f6c4963e7f5382e185bd8d99Transmit105303402024-05-27 16:56:081 hr 59 mins ago0x87aed093904608e14361569c4a7e23a2d3ba376f IN  0x1242b6c5e0e349b8d4bcf0938f961c4b4f7ea3fa0 ETH0.0008567424980.00300081
0xee15de241d46455253e5df6718dfc78359b1e28285e2fdfc7f0aea2d6e8be93bTransmit105303102024-05-27 16:55:082 hrs ago0x74445d903dfd19ceffe7b1db2155be260be7df8b IN  0x1242b6c5e0e349b8d4bcf0938f961c4b4f7ea3fa0 ETH0.0008901453390.003000809
0xd18c13d4e746575241df8f6ae6a5e530578be9476f3ec1e05747fee87ea8baa7Transmit105302502024-05-27 16:53:082 hrs 2 mins ago0x3ddedc24f2d78e4f8510315575213535fd7856d7 IN  0x1242b6c5e0e349b8d4bcf0938f961c4b4f7ea3fa0 ETH0.0008229929030.003000806
0x5bdf2b9435e153292acf089894d562a92edcf293aa9f1f8f8bfb54e2aeb482ddTransmit105302332024-05-27 16:52:342 hrs 3 mins ago0x245f1cb268afd4d0171955f25c1a90a08622fcde IN  0x1242b6c5e0e349b8d4bcf0938f961c4b4f7ea3fa0 ETH0.0009257394120.003000799
0x9224d5c3d15c1a20feb861bc97bde3659698b5089f380f1be3aec19f4e19ae30Transmit105301002024-05-27 16:48:082 hrs 7 mins ago0x0e0451a5dba790500f5d9682c36b7bb1a44396b3 IN  0x1242b6c5e0e349b8d4bcf0938f961c4b4f7ea3fa0 ETH0.0007305551510.001300628
0xdc2e8f83dbdd3a0023012a8b590b833d79136ef186504142385c8b0b87622e77Transmit105300702024-05-27 16:47:082 hrs 8 mins ago0x5edbe288c2484f99c5cd07b06a323e90b04b5424 IN  0x1242b6c5e0e349b8d4bcf0938f961c4b4f7ea3fa0 ETH0.0007605220630.001300632
0x3091b03c0837a0e483e04ad39cf96f661921dc88515c26eb3ff9da6475d3cd3aTransmit105298602024-05-27 16:40:082 hrs 15 mins ago0x5edbe288c2484f99c5cd07b06a323e90b04b5424 IN  0x1242b6c5e0e349b8d4bcf0938f961c4b4f7ea3fa0 ETH0.0008579497090.001200322
0xbff7a79fe7043b5f15f445aa4a3e58a0dfc32cca30400f004d4a2248b4fd79a4Transmit105298002024-05-27 16:38:082 hrs 17 mins ago0x5edbe288c2484f99c5cd07b06a323e90b04b5424 IN  0x1242b6c5e0e349b8d4bcf0938f961c4b4f7ea3fa0 ETH0.0007612015170.00130062
0x6d942f2c6f7b5d9821a7f11b3d215a8e443dabef1fccc6bef13bcc97563b51b7Transmit105295602024-05-27 16:30:082 hrs 25 mins ago0xbc2533eca140802e2bfc166d5cbdd922512797f5 IN  0x1242b6c5e0e349b8d4bcf0938f961c4b4f7ea3fa0 ETH0.0011665606641.000000266
0x040fee4b5836e18d2cc2b507377dc6d262bd23955217c0bc7806ffb6142c3d7fTransmit105295002024-05-27 16:28:082 hrs 27 mins ago0x28fa06a806269ecbef60ca4b06a33ff16c436b50 IN  0x1242b6c5e0e349b8d4bcf0938f961c4b4f7ea3fa0 ETH0.0010378343150.003000821
0xf8260b54735d93fbb5575ffdce7649c8b802a24d05c46cf29fca98bcc5d5b3b4Transmit105292902024-05-27 16:21:082 hrs 34 mins ago0x0e0451a5dba790500f5d9682c36b7bb1a44396b3 IN  0x1242b6c5e0e349b8d4bcf0938f961c4b4f7ea3fa0 ETH0.0003760957110.001130278
[ Download CSV Export 
Parent Txn Hash Block From To Value
Loading

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

Contract Name:
CommitStore

Compiler Version
v0.8.19+commit.7dd6d404

Optimization Enabled:
Yes with 26000 runs

Other Settings:
paris EvmVersion
File 1 of 14 : CommitStore.sol
// SPDX-License-Identifier: BUSL-1.1
pragma solidity 0.8.19;

import {ITypeAndVersion} from "../shared/interfaces/ITypeAndVersion.sol";
import {ICommitStore} from "./interfaces/ICommitStore.sol";
import {IARM} from "./interfaces/IARM.sol";
import {IPriceRegistry} from "./interfaces/IPriceRegistry.sol";

import {OCR2Base} from "./ocr/OCR2Base.sol";
import {Internal} from "./libraries/Internal.sol";
import {MerkleMultiProof} from "./libraries/MerkleMultiProof.sol";

contract CommitStore is ICommitStore, ITypeAndVersion, OCR2Base {
  error StaleReport();
  error PausedError();
  error InvalidInterval(Interval interval);
  error InvalidRoot();
  error InvalidCommitStoreConfig();
  error BadARMSignal();
  error RootAlreadyCommitted();

  event Paused(address account);
  event Unpaused(address account);
  /// @dev RMN depends on this event, if changing, please notify the RMN maintainers.
  event ReportAccepted(CommitReport report);
  event ConfigSet(StaticConfig staticConfig, DynamicConfig dynamicConfig);
  event RootRemoved(bytes32 root);

  /// @notice Static commit store config
  /// @dev RMN depends on this struct, if changing, please notify the RMN maintainers.
  struct StaticConfig {
    uint64 chainSelector; // ───────╮  Destination chainSelector
    uint64 sourceChainSelector; // ─╯  Source chainSelector
    address onRamp; // OnRamp address on the source chain
    address armProxy; // ARM proxy address
  }

  /// @notice Dynamic commit store config
  struct DynamicConfig {
    address priceRegistry; // Price registry address on the destination chain
  }

  /// @notice a sequenceNumber interval
  /// @dev RMN depends on this struct, if changing, please notify the RMN maintainers.
  struct Interval {
    uint64 min; // ───╮ Minimum sequence number, inclusive
    uint64 max; // ───╯ Maximum sequence number, inclusive
  }

  /// @notice Report that is committed by the observing DON at the committing phase
  /// @dev RMN depends on this struct, if changing, please notify the RMN maintainers.
  struct CommitReport {
    Internal.PriceUpdates priceUpdates;
    Interval interval;
    bytes32 merkleRoot;
  }

  // STATIC CONFIG
  // solhint-disable-next-line chainlink-solidity/all-caps-constant-storage-variables
  string public constant override typeAndVersion = "CommitStore 1.2.0";
  // Chain ID of this chain
  uint64 internal immutable i_chainSelector;
  // Chain ID of the source chain
  uint64 internal immutable i_sourceChainSelector;
  // The onRamp address on the source chain
  address internal immutable i_onRamp;
  // The address of the arm proxy
  address internal immutable i_armProxy;

  // DYNAMIC CONFIG
  // The dynamic commitStore config
  DynamicConfig internal s_dynamicConfig;

  // STATE
  // The min sequence number expected for future messages
  uint64 private s_minSeqNr = 1;
  /// @dev The epoch and round of the last report
  uint40 private s_latestPriceEpochAndRound;
  /// @dev Whether this OnRamp is paused or not
  bool private s_paused = false;
  // merkleRoot => timestamp when received
  mapping(bytes32 merkleRoot => uint256 timestamp) private s_roots;

  /// @param staticConfig Containing the static part of the commitStore config
  /// @dev When instantiating OCR2Base we set UNIQUE_REPORTS to false, which means
  /// that we do not require 2f+1 signatures on a report, only f+1 to save gas. 2f+1 is required
  /// only if one must strictly ensure that for a given round there is only one valid report ever generated by
  /// the DON. In our case additional valid reports (i.e. approved by >= f+1 oracles) are not a problem, as they will
  /// will either be ignored (reverted as an invalid interval) or will be accepted as an additional valid price update.
  constructor(StaticConfig memory staticConfig) OCR2Base(false) {
    if (
      staticConfig.onRamp == address(0) ||
      staticConfig.chainSelector == 0 ||
      staticConfig.sourceChainSelector == 0 ||
      staticConfig.armProxy == address(0)
    ) revert InvalidCommitStoreConfig();

    i_chainSelector = staticConfig.chainSelector;
    i_sourceChainSelector = staticConfig.sourceChainSelector;
    i_onRamp = staticConfig.onRamp;
    i_armProxy = staticConfig.armProxy;
  }

  // ================================================================
  // │                        Verification                          │
  // ================================================================

  /// @notice Returns the next expected sequence number.
  /// @return the next expected sequenceNumber.
  function getExpectedNextSequenceNumber() external view returns (uint64) {
    return s_minSeqNr;
  }

  /// @notice Sets the minimum sequence number.
  /// @param minSeqNr The new minimum sequence number.
  function setMinSeqNr(uint64 minSeqNr) external onlyOwner {
    s_minSeqNr = minSeqNr;
  }

  /// @notice Returns the epoch and round of the last price update.
  /// @return the latest price epoch and round.
  function getLatestPriceEpochAndRound() public view returns (uint64) {
    return s_latestPriceEpochAndRound;
  }

  /// @notice Sets the latest epoch and round for price update.
  /// @param latestPriceEpochAndRound The new epoch and round for prices.
  function setLatestPriceEpochAndRound(uint40 latestPriceEpochAndRound) external onlyOwner {
    s_latestPriceEpochAndRound = latestPriceEpochAndRound;
  }

  /// @notice Returns the timestamp of a potentially previously committed merkle root.
  /// If the root was never committed 0 will be returned.
  /// @param root The merkle root to check the commit status for.
  /// @return the timestamp of the committed root or zero in the case that it was never
  /// committed.
  function getMerkleRoot(bytes32 root) external view returns (uint256) {
    return s_roots[root];
  }

  /// @notice Returns if a root is blessed or not.
  /// @param root The merkle root to check the blessing status for.
  /// @return whether the root is blessed or not.
  function isBlessed(bytes32 root) public view returns (bool) {
    return IARM(i_armProxy).isBlessed(IARM.TaggedRoot({commitStore: address(this), root: root}));
  }

  /// @notice Used by the owner in case an invalid sequence of roots has been
  /// posted and needs to be removed. The interval in the report is trusted.
  /// @param rootToReset The roots that will be reset. This function will only
  /// reset roots that are not blessed.
  function resetUnblessedRoots(bytes32[] calldata rootToReset) external onlyOwner {
    for (uint256 i = 0; i < rootToReset.length; ++i) {
      bytes32 root = rootToReset[i];
      if (!isBlessed(root)) {
        delete s_roots[root];
        emit RootRemoved(root);
      }
    }
  }

  /// @inheritdoc ICommitStore
  function verify(
    bytes32[] calldata hashedLeaves,
    bytes32[] calldata proofs,
    uint256 proofFlagBits
  ) external view override whenNotPaused returns (uint256 timestamp) {
    bytes32 root = MerkleMultiProof.merkleRoot(hashedLeaves, proofs, proofFlagBits);
    // Only return non-zero if present and blessed.
    if (!isBlessed(root)) {
      return 0;
    }
    return s_roots[root];
  }

  /// @inheritdoc OCR2Base
  /// @dev A commitReport can have two distinct parts (batched together to amortize the cost of checking sigs):
  /// 1. Price updates
  /// 2. A merkle root and sequence number interval
  /// Both have their own, separate, staleness checks, with price updates using the epoch and round
  /// number of the latest price update. The merkle root checks for staleness based on the seqNums.
  /// They need to be separate because a price report for round t+2 might be included before a report
  /// containing a merkle root for round t+1. This merkle root report for round t+1 is still valid
  /// and should not be rejected. When a report with a stale root but valid price updates is submitted,
  /// we are OK to revert to preserve the invariant that we always revert on invalid sequence number ranges.
  /// If that happens, prices will be updates in later rounds.
  function _report(bytes calldata encodedReport, uint40 epochAndRound) internal override whenNotPaused whenHealthy {
    CommitReport memory report = abi.decode(encodedReport, (CommitReport));

    // Check if the report contains price updates
    if (report.priceUpdates.tokenPriceUpdates.length > 0 || report.priceUpdates.gasPriceUpdates.length > 0) {
      // Check for price staleness based on the epoch and round
      if (s_latestPriceEpochAndRound < epochAndRound) {
        // If prices are not stale, update the latest epoch and round
        s_latestPriceEpochAndRound = epochAndRound;
        // And update the prices in the price registry
        IPriceRegistry(s_dynamicConfig.priceRegistry).updatePrices(report.priceUpdates);

        // If there is no root, the report only contained fee updated and
        // we return to not revert on the empty root check below.
        if (report.merkleRoot == bytes32(0)) return;
      } else {
        // If prices are stale and the report doesn't contain a root, this report
        // does not have any valid information and we revert.
        // If it does contain a merkle root, continue to the root checking section.
        if (report.merkleRoot == bytes32(0)) revert StaleReport();
      }
    }

    // If we reached this section, the report should contain a valid root
    if (s_minSeqNr != report.interval.min || report.interval.min > report.interval.max)
      revert InvalidInterval(report.interval);

    if (report.merkleRoot == bytes32(0)) revert InvalidRoot();
    // Disallow duplicate roots as that would reset the timestamp and
    // delay potential manual execution.
    if (s_roots[report.merkleRoot] != 0) revert RootAlreadyCommitted();

    s_minSeqNr = report.interval.max + 1;
    s_roots[report.merkleRoot] = block.timestamp;
    emit ReportAccepted(report);
  }

  // ================================================================
  // │                           Config                             │
  // ================================================================

  /// @notice Returns the static commit store config.
  /// @dev RMN depends on this function, if changing, please notify the RMN maintainers.
  /// @return the configuration.
  function getStaticConfig() external view returns (StaticConfig memory) {
    return
      StaticConfig({
        chainSelector: i_chainSelector,
        sourceChainSelector: i_sourceChainSelector,
        onRamp: i_onRamp,
        armProxy: i_armProxy
      });
  }

  /// @notice Returns the dynamic commit store config.
  /// @return the configuration.
  function getDynamicConfig() external view returns (DynamicConfig memory) {
    return s_dynamicConfig;
  }

  /// @notice Sets the dynamic config. This function is called during `setOCR2Config` flow
  function _beforeSetConfig(bytes memory onchainConfig) internal override {
    DynamicConfig memory dynamicConfig = abi.decode(onchainConfig, (DynamicConfig));

    if (dynamicConfig.priceRegistry == address(0)) revert InvalidCommitStoreConfig();

    s_dynamicConfig = dynamicConfig;
    // When the OCR config changes, we reset the price epoch and round
    // since epoch and rounds are scoped per config digest.
    // Note that s_minSeqNr/roots do not need to be reset as the roots persist
    // across reconfigurations and are de-duplicated separately.
    s_latestPriceEpochAndRound = 0;

    emit ConfigSet(
      StaticConfig({
        chainSelector: i_chainSelector,
        sourceChainSelector: i_sourceChainSelector,
        onRamp: i_onRamp,
        armProxy: i_armProxy
      }),
      dynamicConfig
    );
  }

  // ================================================================
  // │                        Access and ARM                        │
  // ================================================================

  /// @notice Single function to check the status of the commitStore.
  function isUnpausedAndARMHealthy() external view returns (bool) {
    return !IARM(i_armProxy).isCursed() && !s_paused;
  }

  /// @notice Support querying whether health checker is healthy.
  function isARMHealthy() external view returns (bool) {
    return !IARM(i_armProxy).isCursed();
  }

  /// @notice Ensure that the ARM has not emitted a bad signal, and that the latest heartbeat is not stale.
  modifier whenHealthy() {
    if (IARM(i_armProxy).isCursed()) revert BadARMSignal();
    _;
  }

  /// @notice Modifier to make a function callable only when the contract is not paused.
  modifier whenNotPaused() {
    if (paused()) revert PausedError();
    _;
  }

  /// @notice Returns true if the contract is paused, and false otherwise.
  function paused() public view returns (bool) {
    return s_paused;
  }

  /// @notice Pause the contract
  /// @dev only callable by the owner
  function pause() external onlyOwner {
    s_paused = true;
    emit Paused(msg.sender);
  }

  /// @notice Unpause the contract
  /// @dev only callable by the owner
  function unpause() external onlyOwner {
    s_paused = false;
    emit Unpaused(msg.sender);
  }
}

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

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

File 3 of 14 : ICommitStore.sol
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;

interface ICommitStore {
  /// @notice Returns timestamp of when root was accepted or 0 if verification fails.
  /// @dev This method uses a merkle tree within a merkle tree, with the hashedLeaves,
  /// proofs and proofFlagBits being used to get the root of the inner tree.
  /// This root is then used as the singular leaf of the outer tree.
  function verify(
    bytes32[] calldata hashedLeaves,
    bytes32[] calldata proofs,
    uint256 proofFlagBits
  ) external view returns (uint256 timestamp);

  /// @notice Returns the expected next sequence number
  function getExpectedNextSequenceNumber() external view returns (uint64 sequenceNumber);
}

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

/// @notice This interface contains the only ARM-related functions that might be used on-chain by other CCIP contracts.
interface IARM {
  /// @notice A Merkle root tagged with the address of the commit store contract it is destined for.
  struct TaggedRoot {
    address commitStore;
    bytes32 root;
  }

  /// @notice Callers MUST NOT cache the return value as a blessed tagged root could become unblessed.
  function isBlessed(TaggedRoot calldata taggedRoot) external view returns (bool);

  /// @notice When the ARM is "cursed", CCIP pauses until the curse is lifted.
  function isCursed() external view returns (bool);
}

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

import {Internal} from "../libraries/Internal.sol";

interface IPriceRegistry {
  /// @notice Update the price for given tokens and gas prices for given chains.
  /// @param priceUpdates The price updates to apply.
  function updatePrices(Internal.PriceUpdates memory priceUpdates) external;

  /// @notice Get the `tokenPrice` for a given token.
  /// @param token The token to get the price for.
  /// @return tokenPrice The tokenPrice for the given token.
  function getTokenPrice(address token) external view returns (Internal.TimestampedPackedUint224 memory);

  /// @notice Get the `tokenPrice` for a given token, checks if the price is valid.
  /// @param token The token to get the price for.
  /// @return tokenPrice The tokenPrice for the given token if it exists and is valid.
  function getValidatedTokenPrice(address token) external view returns (uint224);

  /// @notice Get the `tokenPrice` for an array of tokens.
  /// @param tokens The tokens to get prices for.
  /// @return tokenPrices The tokenPrices for the given tokens.
  function getTokenPrices(address[] calldata tokens) external view returns (Internal.TimestampedPackedUint224[] memory);

  /// @notice Get an encoded `gasPrice` for a given destination chain ID.
  /// The 224-bit result encodes necessary gas price components.
  /// On L1 chains like Ethereum or Avax, the only component is the gas price.
  /// On Optimistic Rollups, there are two components - the L2 gas price, and L1 base fee for data availability.
  /// On future chains, there could be more or differing price components.
  /// PriceRegistry does not contain chain-specific logic to parse destination chain price components.
  /// @param destChainSelector The destination chain to get the price for.
  /// @return gasPrice The encoded gasPrice for the given destination chain ID.
  function getDestinationChainGasPrice(
    uint64 destChainSelector
  ) external view returns (Internal.TimestampedPackedUint224 memory);

  /// @notice Gets the fee token price and the gas price, both denominated in dollars.
  /// @param token The source token to get the price for.
  /// @param destChainSelector The destination chain to get the gas price for.
  /// @return tokenPrice The price of the feeToken in 1e18 dollars per base unit.
  /// @return gasPrice The price of gas in 1e18 dollars per base unit.
  function getTokenAndGasPrices(
    address token,
    uint64 destChainSelector
  ) external view returns (uint224 tokenPrice, uint224 gasPrice);

  /// @notice Convert a given token amount to target token amount.
  /// @param fromToken The given token address.
  /// @param fromTokenAmount The given token amount.
  /// @param toToken The target token address.
  /// @return toTokenAmount The target token amount.
  function convertTokenAmount(
    address fromToken,
    uint256 fromTokenAmount,
    address toToken
  ) external view returns (uint256 toTokenAmount);
}

File 6 of 14 : OCR2Base.sol
// SPDX-License-Identifier: BUSL-1.1
pragma solidity ^0.8.0;

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

/// @notice Onchain verification of reports from the offchain reporting protocol
/// @dev For details on its operation, see the offchain reporting protocol design
/// doc, which refers to this contract as simply the "contract".
abstract contract OCR2Base is OwnerIsCreator, OCR2Abstract {
  error InvalidConfig(string message);
  error WrongMessageLength(uint256 expected, uint256 actual);
  error ConfigDigestMismatch(bytes32 expected, bytes32 actual);
  error ForkedChain(uint256 expected, uint256 actual);
  error WrongNumberOfSignatures();
  error SignaturesOutOfRegistration();
  error UnauthorizedTransmitter();
  error UnauthorizedSigner();
  error NonUniqueSignatures();
  error OracleCannotBeZeroAddress();

  // Packing these fields used on the hot path in a ConfigInfo variable reduces the
  // retrieval of all of them to a minimum number of SLOADs.
  struct ConfigInfo {
    bytes32 latestConfigDigest;
    uint8 f;
    uint8 n;
  }

  // Used for s_oracles[a].role, where a is an address, to track the purpose
  // of the address, or to indicate that the address is unset.
  enum Role {
    // No oracle role has been set for address a
    Unset,
    // Signing address for the s_oracles[a].index'th oracle. I.e., report
    // signatures from this oracle should ecrecover back to address a.
    Signer,
    // Transmission address for the s_oracles[a].index'th oracle. I.e., if a
    // report is received by OCR2Aggregator.transmit in which msg.sender is
    // a, it is attributed to the s_oracles[a].index'th oracle.
    Transmitter
  }

  struct Oracle {
    uint8 index; // Index of oracle in s_signers/s_transmitters
    Role role; // Role of the address which mapped to this struct
  }

  // The current config
  ConfigInfo internal s_configInfo;

  // incremented each time a new config is posted. This count is incorporated
  // into the config digest, to prevent replay attacks.
  uint32 internal s_configCount;
  // makes it easier for offchain systems to extract config from logs.
  uint32 internal s_latestConfigBlockNumber;

  // signer OR transmitter address
  mapping(address signerOrTransmitter => Oracle oracle) internal s_oracles;

  // s_signers contains the signing address of each oracle
  address[] internal s_signers;

  // s_transmitters contains the transmission address of each oracle,
  // i.e. the address the oracle actually sends transactions to the contract from
  address[] internal s_transmitters;

  // The constant-length components of the msg.data sent to transmit.
  // See the "If we wanted to call sam" example on for example reasoning
  // https://solidity.readthedocs.io/en/v0.7.2/abi-spec.html
  uint16 private constant TRANSMIT_MSGDATA_CONSTANT_LENGTH_COMPONENT =
    4 + // function selector
      32 *
      3 + // 3 words containing reportContext
      32 + // word containing start location of abiencoded report value
      32 + // word containing location start of abiencoded rs value
      32 + // word containing start location of abiencoded ss value
      32 + // rawVs value
      32 + // word containing length of report
      32 + // word containing length rs
      32; // word containing length of ss

  bool internal immutable i_uniqueReports;
  uint256 internal immutable i_chainID;

  constructor(bool uniqueReports) {
    i_uniqueReports = uniqueReports;
    i_chainID = block.chainid;
  }

  // Reverts transaction if config args are invalid
  modifier checkConfigValid(
    uint256 numSigners,
    uint256 numTransmitters,
    uint256 f
  ) {
    if (numSigners > MAX_NUM_ORACLES) revert InvalidConfig("too many signers");
    if (f == 0) revert InvalidConfig("f must be positive");
    if (numSigners != numTransmitters) revert InvalidConfig("oracle addresses out of registration");
    if (numSigners <= 3 * f) revert InvalidConfig("faulty-oracle f too high");
    _;
  }

  /// @notice sets offchain reporting protocol configuration incl. participating oracles
  /// @param signers addresses with which oracles sign the reports
  /// @param transmitters addresses oracles use to transmit the reports
  /// @param f number of faulty oracles the system can tolerate
  /// @param onchainConfig encoded on-chain contract configuration
  /// @param offchainConfigVersion version number for offchainEncoding schema
  /// @param offchainConfig encoded off-chain oracle configuration
  function setOCR2Config(
    address[] memory signers,
    address[] memory transmitters,
    uint8 f,
    bytes memory onchainConfig,
    uint64 offchainConfigVersion,
    bytes memory offchainConfig
  ) external override checkConfigValid(signers.length, transmitters.length, f) onlyOwner {
    _beforeSetConfig(onchainConfig);
    uint256 oldSignerLength = s_signers.length;
    for (uint256 i = 0; i < oldSignerLength; ++i) {
      delete s_oracles[s_signers[i]];
      delete s_oracles[s_transmitters[i]];
    }

    uint256 newSignersLength = signers.length;
    for (uint256 i = 0; i < newSignersLength; ++i) {
      // add new signer/transmitter addresses
      address signer = signers[i];
      if (s_oracles[signer].role != Role.Unset) revert InvalidConfig("repeated signer address");
      if (signer == address(0)) revert OracleCannotBeZeroAddress();
      s_oracles[signer] = Oracle(uint8(i), Role.Signer);

      address transmitter = transmitters[i];
      if (s_oracles[transmitter].role != Role.Unset) revert InvalidConfig("repeated transmitter address");
      if (transmitter == address(0)) revert OracleCannotBeZeroAddress();
      s_oracles[transmitter] = Oracle(uint8(i), Role.Transmitter);
    }

    s_signers = signers;
    s_transmitters = transmitters;

    s_configInfo.f = f;
    s_configInfo.n = uint8(newSignersLength);
    s_configInfo.latestConfigDigest = _configDigestFromConfigData(
      block.chainid,
      address(this),
      ++s_configCount,
      signers,
      transmitters,
      f,
      onchainConfig,
      offchainConfigVersion,
      offchainConfig
    );

    uint32 previousConfigBlockNumber = s_latestConfigBlockNumber;
    s_latestConfigBlockNumber = uint32(block.number);

    emit ConfigSet(
      previousConfigBlockNumber,
      s_configInfo.latestConfigDigest,
      s_configCount,
      signers,
      transmitters,
      f,
      onchainConfig,
      offchainConfigVersion,
      offchainConfig
    );
  }

  /// @dev Hook that is run from setOCR2Config() right after validating configuration.
  /// Empty by default, please provide an implementation in a child contract if you need additional configuration processing
  function _beforeSetConfig(bytes memory _onchainConfig) internal virtual {}

  /// @return list of addresses permitted to transmit reports to this contract
  /// @dev The list will match the order used to specify the transmitter during setConfig
  function getTransmitters() external view returns (address[] memory) {
    return s_transmitters;
  }

  /// @notice transmit is called to post a new report to the contract
  /// @param report serialized report, which the signatures are signing.
  /// @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
  function transmit(
    // NOTE: If these parameters are changed, expectedMsgDataLength and/or
    // TRANSMIT_MSGDATA_CONSTANT_LENGTH_COMPONENT need to be changed accordingly
    bytes32[3] calldata reportContext,
    bytes calldata report,
    bytes32[] calldata rs,
    bytes32[] calldata ss,
    bytes32 rawVs // signatures
  ) external override {
    // Scoping this reduces stack pressure and gas usage
    {
      // report and epochAndRound
      _report(report, uint40(uint256(reportContext[1])));
    }

    // 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];
    ConfigInfo memory configInfo = s_configInfo;

    if (configInfo.latestConfigDigest != configDigest)
      revert ConfigDigestMismatch(configInfo.latestConfigDigest, configDigest);
    // If the cached chainID at time of deployment doesn't match the current chainID, we reject all signed reports.
    // This avoids a (rare) scenario where chain A forks into chain A and A', A' still has configDigest
    // calculated from chain A and so OCR reports will be valid on both forks.
    if (i_chainID != block.chainid) revert ForkedChain(i_chainID, block.chainid);

    emit Transmitted(configDigest, uint32(uint256(reportContext[1]) >> 8));

    uint256 expectedNumSignatures;
    if (i_uniqueReports) {
      expectedNumSignatures = (configInfo.n + configInfo.f) / 2 + 1;
    } else {
      expectedNumSignatures = configInfo.f + 1;
    }
    if (rs.length != expectedNumSignatures) revert WrongNumberOfSignatures();
    if (rs.length != ss.length) revert SignaturesOutOfRegistration();

    // Scoping this reduces stack pressure and gas usage
    {
      Oracle memory transmitter = s_oracles[msg.sender];
      // Check that sender is authorized to report
      if (!(transmitter.role == Role.Transmitter && msg.sender == s_transmitters[transmitter.index]))
        revert UnauthorizedTransmitter();
    }
    // Scoping this reduces stack pressure and gas usage
    {
      uint256 expectedDataLength = uint256(TRANSMIT_MSGDATA_CONSTANT_LENGTH_COMPONENT) +
        report.length + // one byte pure entry in _report
        rs.length *
        32 + // 32 bytes per entry in _rs
        ss.length *
        32; // 32 bytes per entry in _ss)
      if (msg.data.length != expectedDataLength) revert WrongMessageLength(expectedDataLength, msg.data.length);
    }

    // Verify signatures attached to report
    bytes32 h = keccak256(abi.encodePacked(keccak256(report), reportContext));
    bool[MAX_NUM_ORACLES] memory signed;

    uint256 numberOfSignatures = rs.length;
    for (uint256 i = 0; i < numberOfSignatures; ++i) {
      // Safe from ECDSA malleability here since we check for duplicate signers.
      address signer = ecrecover(h, uint8(rawVs[i]) + 27, rs[i], ss[i]);
      // Since we disallow address(0) as a valid signer address, it can
      // never have a signer role.
      Oracle memory oracle = s_oracles[signer];
      if (oracle.role != Role.Signer) revert UnauthorizedSigner();
      if (signed[oracle.index]) revert NonUniqueSignatures();
      signed[oracle.index] = true;
    }
  }

  /// @notice information about current offchain reporting protocol configuration
  /// @return configCount ordinal number of current config, out of all configs applied to this contract so far
  /// @return blockNumber block at which this config was set
  /// @return configDigest domain-separation tag for current config (see _configDigestFromConfigData)
  function latestConfigDetails()
    external
    view
    override
    returns (uint32 configCount, uint32 blockNumber, bytes32 configDigest)
  {
    return (s_configCount, s_latestConfigBlockNumber, s_configInfo.latestConfigDigest);
  }

  /// @inheritdoc OCR2Abstract
  function latestConfigDigestAndEpoch()
    external
    view
    virtual
    override
    returns (bool scanLogs, bytes32 configDigest, uint32 epoch)
  {
    return (true, bytes32(0), uint32(0));
  }

  function _report(bytes calldata report, uint40 epochAndRound) internal virtual;
}

File 7 of 14 : Internal.sol
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;

import {Client} from "./Client.sol";
import {MerkleMultiProof} from "../libraries/MerkleMultiProof.sol";

// Library for CCIP internal definitions common to multiple contracts.
library Internal {
  /// @dev The minimum amount of gas to perform the call with exact gas.
  /// We include this in the offramp so that we can redeploy to adjust it
  /// should a hardfork change the gas costs of relevant opcodes in callWithExactGas.
  uint16 internal constant GAS_FOR_CALL_EXACT_CHECK = 5_000;
  // @dev We limit return data to a selector plus 4 words. This is to avoid
  // malicious contracts from returning large amounts of data and causing
  // repeated out-of-gas scenarios.
  uint16 internal constant MAX_RET_BYTES = 4 + 4 * 32;

  /// @notice A collection of token price and gas price updates.
  /// @dev RMN depends on this struct, if changing, please notify the RMN maintainers.
  struct PriceUpdates {
    TokenPriceUpdate[] tokenPriceUpdates;
    GasPriceUpdate[] gasPriceUpdates;
  }

  /// @notice Token price in USD.
  /// @dev RMN depends on this struct, if changing, please notify the RMN maintainers.
  struct TokenPriceUpdate {
    address sourceToken; // Source token
    uint224 usdPerToken; // 1e18 USD per smallest unit of token
  }

  /// @notice Gas price for a given chain in USD, its value may contain tightly packed fields.
  /// @dev RMN depends on this struct, if changing, please notify the RMN maintainers.
  struct GasPriceUpdate {
    uint64 destChainSelector; // Destination chain selector
    uint224 usdPerUnitGas; // 1e18 USD per smallest unit (e.g. wei) of destination chain gas
  }

  /// @notice A timestamped uint224 value that can contain several tightly packed fields.
  struct TimestampedPackedUint224 {
    uint224 value; // ───────╮ Value in uint224, packed.
    uint32 timestamp; // ────╯ Timestamp of the most recent price update.
  }

  /// @dev Gas price is stored in 112-bit unsigned int. uint224 can pack 2 prices.
  /// When packing L1 and L2 gas prices, L1 gas price is left-shifted to the higher-order bits.
  /// Using uint8 type, which cannot be higher than other bit shift operands, to avoid shift operand type warning.
  uint8 public constant GAS_PRICE_BITS = 112;

  struct PoolUpdate {
    address token; // The IERC20 token address
    address pool; // The token pool address
  }

  /// @notice Report that is submitted by the execution DON at the execution phase.
  /// @dev RMN depends on this struct, if changing, please notify the RMN maintainers.
  struct ExecutionReport {
    EVM2EVMMessage[] messages;
    // Contains a bytes array for each message, each inner bytes array contains bytes per transferred token
    bytes[][] offchainTokenData;
    bytes32[] proofs;
    uint256 proofFlagBits;
  }

  /// @notice The cross chain message that gets committed to EVM chains.
  /// @dev RMN depends on this struct, if changing, please notify the RMN maintainers.
  struct EVM2EVMMessage {
    uint64 sourceChainSelector; // ─────────╮ the chain selector of the source chain, note: not chainId
    address sender; // ─────────────────────╯ sender address on the source chain
    address receiver; // ───────────────────╮ receiver address on the destination chain
    uint64 sequenceNumber; // ──────────────╯ sequence number, not unique across lanes
    uint256 gasLimit; //                      user supplied maximum gas amount available for dest chain execution
    bool strict; // ────────────────────────╮ DEPRECATED
    uint64 nonce; //                        │ nonce for this lane for this sender, not unique across senders/lanes
    address feeToken; // ───────────────────╯ fee token
    uint256 feeTokenAmount; //                fee token amount
    bytes data; //                            arbitrary data payload supplied by the message sender
    Client.EVMTokenAmount[] tokenAmounts; //  array of tokens and amounts to transfer
    bytes[] sourceTokenData; //               array of token pool return values, one per token
    bytes32 messageId; //                     a hash of the message data
  }

  /// @dev EVM2EVMMessage struct has 13 fields, including 3 variable arrays.
  /// Each variable array takes 1 more slot to store its length.
  /// When abi encoded, excluding array contents,
  /// EVM2EVMMessage takes up a fixed number of 16 lots, 32 bytes each.
  /// For structs that contain arrays, 1 more slot is added to the front, reaching a total of 17.
  uint256 public constant MESSAGE_FIXED_BYTES = 32 * 17;

  /// @dev Each token transfer adds 1 EVMTokenAmount and 1 bytes.
  /// When abiEncoded, each EVMTokenAmount takes 2 slots, each bytes takes 2 slots, excl bytes contents
  uint256 public constant MESSAGE_FIXED_BYTES_PER_TOKEN = 32 * 4;

  function _toAny2EVMMessage(
    EVM2EVMMessage memory original,
    Client.EVMTokenAmount[] memory destTokenAmounts
  ) internal pure returns (Client.Any2EVMMessage memory message) {
    message = Client.Any2EVMMessage({
      messageId: original.messageId,
      sourceChainSelector: original.sourceChainSelector,
      sender: abi.encode(original.sender),
      data: original.data,
      destTokenAmounts: destTokenAmounts
    });
  }

  bytes32 internal constant EVM_2_EVM_MESSAGE_HASH = keccak256("EVM2EVMMessageHashV2");

  function _hash(EVM2EVMMessage memory original, bytes32 metadataHash) internal pure returns (bytes32) {
    // Fixed-size message fields are included in nested hash to reduce stack pressure.
    // This hashing scheme is also used by RMN. If changing it, please notify the RMN maintainers.
    return
      keccak256(
        abi.encode(
          MerkleMultiProof.LEAF_DOMAIN_SEPARATOR,
          metadataHash,
          keccak256(
            abi.encode(
              original.sender,
              original.receiver,
              original.sequenceNumber,
              original.gasLimit,
              original.strict,
              original.nonce,
              original.feeToken,
              original.feeTokenAmount
            )
          ),
          keccak256(original.data),
          keccak256(abi.encode(original.tokenAmounts)),
          keccak256(abi.encode(original.sourceTokenData))
        )
      );
  }

  /// @notice Enum listing the possible message execution states within
  /// the offRamp contract.
  /// UNTOUCHED never executed
  /// IN_PROGRESS currently being executed, used a replay protection
  /// SUCCESS successfully executed. End state
  /// FAILURE unsuccessfully executed, manual execution is now enabled.
  /// @dev RMN depends on this enum, if changing, please notify the RMN maintainers.
  enum MessageExecutionState {
    UNTOUCHED,
    IN_PROGRESS,
    SUCCESS,
    FAILURE
  }
}

File 8 of 14 : MerkleMultiProof.sol
// SPDX-License-Identifier: BUSL-1.1
pragma solidity ^0.8.0;

library MerkleMultiProof {
  /// @notice Leaf domain separator, should be used as the first 32 bytes of a leaf's preimage.
  bytes32 internal constant LEAF_DOMAIN_SEPARATOR = 0x0000000000000000000000000000000000000000000000000000000000000000;
  /// @notice Internal domain separator, should be used as the first 32 bytes of an internal node's preiimage.
  bytes32 internal constant INTERNAL_DOMAIN_SEPARATOR =
    0x0000000000000000000000000000000000000000000000000000000000000001;

  uint256 internal constant MAX_NUM_HASHES = 256;

  error InvalidProof();
  error LeavesCannotBeEmpty();

  /// @notice Computes the root based on provided pre-hashed leaf nodes in
  /// leaves, internal nodes in proofs, and using proofFlagBits' i-th bit to
  /// determine if an element of proofs or one of the previously computed leafs
  /// or internal nodes will be used for the i-th hash.
  /// @param leaves Should be pre-hashed and the first 32 bytes of a leaf's
  /// preimage should match LEAF_DOMAIN_SEPARATOR.
  /// @param proofs The hashes to be used instead of a leaf hash when the proofFlagBits
  ///  indicates a proof should be used.
  /// @param proofFlagBits A single uint256 of which each bit indicates whether a leaf or
  ///  a proof needs to be used in a hash operation.
  /// @dev the maximum number of hash operations it set to 256. Any input that would require
  ///  more than 256 hashes to get to a root will revert.
  /// @dev For given input `leaves` = [a,b,c] `proofs` = [D] and `proofFlagBits` = 5
  ///     totalHashes = 3 + 1 - 1 = 3
  ///  ** round 1 **
  ///    proofFlagBits = (5 >> 0) & 1 = true
  ///    hashes[0] = hashPair(a, b)
  ///    (leafPos, hashPos, proofPos) = (2, 0, 0);
  ///
  ///  ** round 2 **
  ///    proofFlagBits = (5 >> 1) & 1 = false
  ///    hashes[1] = hashPair(D, c)
  ///    (leafPos, hashPos, proofPos) = (3, 0, 1);
  ///
  ///  ** round 3 **
  ///    proofFlagBits = (5 >> 2) & 1 = true
  ///    hashes[2] = hashPair(hashes[0], hashes[1])
  ///    (leafPos, hashPos, proofPos) = (3, 2, 1);
  ///
  ///    i = 3 and no longer < totalHashes. The algorithm is done
  ///    return hashes[totalHashes - 1] = hashes[2]; the last hash we computed.
  // We mark this function as internal to force it to be inlined in contracts
  // that use it, but semantically it is public.
  // solhint-disable-next-line chainlink-solidity/prefix-internal-functions-with-underscore
  function merkleRoot(
    bytes32[] memory leaves,
    bytes32[] memory proofs,
    uint256 proofFlagBits
  ) internal pure returns (bytes32) {
    unchecked {
      uint256 leavesLen = leaves.length;
      uint256 proofsLen = proofs.length;
      if (leavesLen == 0) revert LeavesCannotBeEmpty();
      if (!(leavesLen <= MAX_NUM_HASHES + 1 && proofsLen <= MAX_NUM_HASHES + 1)) revert InvalidProof();
      uint256 totalHashes = leavesLen + proofsLen - 1;
      if (!(totalHashes <= MAX_NUM_HASHES)) revert InvalidProof();
      if (totalHashes == 0) {
        return leaves[0];
      }
      bytes32[] memory hashes = new bytes32[](totalHashes);
      (uint256 leafPos, uint256 hashPos, uint256 proofPos) = (0, 0, 0);

      for (uint256 i = 0; i < totalHashes; ++i) {
        // Checks if the bit flag signals the use of a supplied proof or a leaf/previous hash.
        bytes32 a;
        if (proofFlagBits & (1 << i) == (1 << i)) {
          // Use a leaf or a previously computed hash.
          if (leafPos < leavesLen) {
            a = leaves[leafPos++];
          } else {
            a = hashes[hashPos++];
          }
        } else {
          // Use a supplied proof.
          a = proofs[proofPos++];
        }

        // The second part of the hashed pair is never a proof as hashing two proofs would result in a
        // hash that can already be computed offchain.
        bytes32 b;
        if (leafPos < leavesLen) {
          b = leaves[leafPos++];
        } else {
          b = hashes[hashPos++];
        }

        if (!(hashPos <= i)) revert InvalidProof();

        hashes[i] = _hashPair(a, b);
      }
      if (!(hashPos == totalHashes - 1 && leafPos == leavesLen && proofPos == proofsLen)) revert InvalidProof();
      // Return the last hash.
      return hashes[totalHashes - 1];
    }
  }

  /// @notice Hashes two bytes32 objects in their given order, prepended by the
  /// INTERNAL_DOMAIN_SEPARATOR.
  function _hashInternalNode(bytes32 left, bytes32 right) private pure returns (bytes32 hash) {
    return keccak256(abi.encode(INTERNAL_DOMAIN_SEPARATOR, left, right));
  }

  /// @notice Hashes two bytes32 objects. The order is taken into account,
  /// using the lower value first.
  function _hashPair(bytes32 a, bytes32 b) private pure returns (bytes32) {
    return a < b ? _hashInternalNode(a, b) : _hashInternalNode(b, a);
  }
}

File 9 of 14 : 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 10 of 14 : OCR2Abstract.sol
// SPDX-License-Identifier: BUSL-1.1
pragma solidity ^0.8.0;

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

abstract contract OCR2Abstract is ITypeAndVersion {
  // Maximum number of oracles the offchain reporting protocol is designed for
  uint256 internal constant MAX_NUM_ORACLES = 31;

  /// @notice triggers a new run of the offchain reporting protocol
  /// @param previousConfigBlockNumber block in which the previous config was set, to simplify historic analysis
  /// @param configDigest configDigest of this configuration
  /// @param configCount ordinal number of this config setting among all config settings over the life of this contract
  /// @param signers ith element is address ith oracle uses to sign a report
  /// @param transmitters ith element is address ith oracle uses to transmit a report via the transmit method
  /// @param f maximum number of faulty/dishonest oracles the protocol can tolerate while still working correctly
  /// @param onchainConfig serialized configuration used by the contract (and possibly oracles)
  /// @param offchainConfigVersion version of the serialization format used for "offchainConfig" parameter
  /// @param offchainConfig serialized configuration used by the oracles exclusively and only passed through the contract
  event ConfigSet(
    uint32 previousConfigBlockNumber,
    bytes32 configDigest,
    uint64 configCount,
    address[] signers,
    address[] transmitters,
    uint8 f,
    bytes onchainConfig,
    uint64 offchainConfigVersion,
    bytes offchainConfig
  );

  /// @notice sets offchain reporting protocol configuration incl. participating oracles
  /// @param signers addresses with which oracles sign the reports
  /// @param transmitters addresses oracles use to transmit the reports
  /// @param f number of faulty oracles the system can tolerate
  /// @param onchainConfig serialized configuration used by the contract (and possibly oracles)
  /// @param offchainConfigVersion version number for offchainEncoding schema
  /// @param offchainConfig serialized configuration used by the oracles exclusively and only passed through the contract
  function setOCR2Config(
    address[] memory signers,
    address[] memory transmitters,
    uint8 f,
    bytes memory onchainConfig,
    uint64 offchainConfigVersion,
    bytes memory offchainConfig
  ) external virtual;

  /// @notice information about current offchain reporting protocol configuration
  /// @return configCount ordinal number of current config, out of all configs applied to this contract so far
  /// @return blockNumber block at which this config was set
  /// @return configDigest domain-separation tag for current config (see _configDigestFromConfigData)
  function latestConfigDetails()
    external
    view
    virtual
    returns (uint32 configCount, uint32 blockNumber, bytes32 configDigest);

  function _configDigestFromConfigData(
    uint256 chainId,
    address contractAddress,
    uint64 configCount,
    address[] memory signers,
    address[] memory transmitters,
    uint8 f,
    bytes memory onchainConfig,
    uint64 offchainConfigVersion,
    bytes memory offchainConfig
  ) internal pure returns (bytes32) {
    uint256 h = uint256(
      keccak256(
        abi.encode(
          chainId,
          contractAddress,
          configCount,
          signers,
          transmitters,
          f,
          onchainConfig,
          offchainConfigVersion,
          offchainConfig
        )
      )
    );
    uint256 prefixMask = type(uint256).max << (256 - 16); // 0xFFFF00..00
    uint256 prefix = 0x0001 << (256 - 16); // 0x000100..00
    return bytes32((prefix & prefixMask) | (h & ~prefixMask));
  }

  /// @notice optionally emitted to indicate the latest configDigest and epoch for
  /// which a report was successfully transmitted. Alternatively, the contract may
  /// use latestConfigDigestAndEpoch with scanLogs set to false.
  event Transmitted(bytes32 configDigest, uint32 epoch);

  /// @notice optionally returns the latest configDigest and epoch for which a
  /// report was successfully transmitted. Alternatively, the contract may return
  /// scanLogs set to true and use Transmitted events to provide this information
  /// to offchain watchers.
  /// @return scanLogs indicates whether to rely on the configDigest and epoch
  /// returned or whether to scan logs for the Transmitted event instead.
  /// @return configDigest
  /// @return epoch
  function latestConfigDigestAndEpoch()
    external
    view
    virtual
    returns (bool scanLogs, bytes32 configDigest, uint32 epoch);

  /// @notice transmit is called to post a new report to the contract
  /// @param report serialized report, which the signatures are signing.
  /// @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
  function transmit(
    // NOTE: If these parameters are changed, expectedMsgDataLength and/or
    // TRANSMIT_MSGDATA_CONSTANT_LENGTH_COMPONENT need to be changed accordingly
    bytes32[3] calldata reportContext,
    bytes calldata report,
    bytes32[] calldata rs,
    bytes32[] calldata ss,
    bytes32 rawVs // signatures
  ) external virtual;
}

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

// End consumer library.
library Client {
  /// @dev RMN depends on this struct, if changing, please notify the RMN maintainers.
  struct EVMTokenAmount {
    address token; // token address on the local chain.
    uint256 amount; // Amount of tokens.
  }

  struct Any2EVMMessage {
    bytes32 messageId; // MessageId corresponding to ccipSend on source.
    uint64 sourceChainSelector; // Source chain selector.
    bytes sender; // abi.decode(sender) if coming from an EVM chain.
    bytes data; // payload sent in original message.
    EVMTokenAmount[] destTokenAmounts; // Tokens and their amounts in their destination chain representation.
  }

  // If extraArgs is empty bytes, the default is 200k gas limit.
  struct EVM2AnyMessage {
    bytes receiver; // abi.encode(receiver address) for dest EVM chains
    bytes data; // Data payload
    EVMTokenAmount[] tokenAmounts; // Token transfers
    address feeToken; // Address of feeToken. address(0) means you will send msg.value.
    bytes extraArgs; // Populate this with _argsToBytes(EVMExtraArgsV1)
  }

  // bytes4(keccak256("CCIP EVMExtraArgsV1"));
  bytes4 public constant EVM_EXTRA_ARGS_V1_TAG = 0x97a657c9;
  struct EVMExtraArgsV1 {
    uint256 gasLimit;
  }

  function _argsToBytes(EVMExtraArgsV1 memory extraArgs) internal pure returns (bytes memory bts) {
    return abi.encodeWithSelector(EVM_EXTRA_ARGS_V1_TAG, extraArgs);
  }
}

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

import "./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 13 of 14 : ConfirmedOwnerWithProposal.sol
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;

import "../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) {
    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,
   * pending.
   */
  function transferOwnership(address to) public override onlyOwner {
    _transferOwnership(to);
  }

  /**
   * @notice Allows an ownership transfer to be completed by the recipient.
   */
  function acceptOwnership() external override {
    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 {
    require(to != msg.sender, "Cannot transfer to self");

    s_pendingOwner = to;

    emit OwnershipTransferRequested(s_owner, to);
  }

  /**
   * @notice validate access
   */
  function _validateOwnership() internal view {
    require(msg.sender == s_owner, "Only callable by owner");
  }

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

File 14 of 14 : 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": [
    "ds-test/=foundry-lib/forge-std/lib/ds-test/src/",
    "forge-std/=foundry-lib/forge-std/src/",
    "openzeppelin-contracts/=foundry-lib/openzeppelin-contracts/contracts/",
    "@openzeppelin/=node_modules/@openzeppelin/",
    "hardhat/=node_modules/hardhat/",
    "@eth-optimism/=node_modules/@eth-optimism/",
    "erc4626-tests/=foundry-lib/openzeppelin-contracts/lib/erc4626-tests/"
  ],
  "optimizer": {
    "enabled": true,
    "runs": 26000
  },
  "metadata": {
    "useLiteralContent": false,
    "bytecodeHash": "none",
    "appendCBOR": true
  },
  "outputSelection": {
    "*": {
      "*": [
        "evm.bytecode",
        "evm.deployedBytecode",
        "devdoc",
        "userdoc",
        "metadata",
        "abi"
      ]
    }
  },
  "evmVersion": "paris",
  "libraries": {}
}

Contract ABI

[{"inputs":[{"components":[{"internalType":"uint64","name":"chainSelector","type":"uint64"},{"internalType":"uint64","name":"sourceChainSelector","type":"uint64"},{"internalType":"address","name":"onRamp","type":"address"},{"internalType":"address","name":"armProxy","type":"address"}],"internalType":"struct CommitStore.StaticConfig","name":"staticConfig","type":"tuple"}],"stateMutability":"nonpayable","type":"constructor"},{"inputs":[],"name":"BadARMSignal","type":"error"},{"inputs":[{"internalType":"bytes32","name":"expected","type":"bytes32"},{"internalType":"bytes32","name":"actual","type":"bytes32"}],"name":"ConfigDigestMismatch","type":"error"},{"inputs":[{"internalType":"uint256","name":"expected","type":"uint256"},{"internalType":"uint256","name":"actual","type":"uint256"}],"name":"ForkedChain","type":"error"},{"inputs":[],"name":"InvalidCommitStoreConfig","type":"error"},{"inputs":[{"internalType":"string","name":"message","type":"string"}],"name":"InvalidConfig","type":"error"},{"inputs":[{"components":[{"internalType":"uint64","name":"min","type":"uint64"},{"internalType":"uint64","name":"max","type":"uint64"}],"internalType":"struct CommitStore.Interval","name":"interval","type":"tuple"}],"name":"InvalidInterval","type":"error"},{"inputs":[],"name":"InvalidProof","type":"error"},{"inputs":[],"name":"InvalidRoot","type":"error"},{"inputs":[],"name":"LeavesCannotBeEmpty","type":"error"},{"inputs":[],"name":"NonUniqueSignatures","type":"error"},{"inputs":[],"name":"OracleCannotBeZeroAddress","type":"error"},{"inputs":[],"name":"PausedError","type":"error"},{"inputs":[],"name":"RootAlreadyCommitted","type":"error"},{"inputs":[],"name":"SignaturesOutOfRegistration","type":"error"},{"inputs":[],"name":"StaleReport","type":"error"},{"inputs":[],"name":"UnauthorizedSigner","type":"error"},{"inputs":[],"name":"UnauthorizedTransmitter","type":"error"},{"inputs":[{"internalType":"uint256","name":"expected","type":"uint256"},{"internalType":"uint256","name":"actual","type":"uint256"}],"name":"WrongMessageLength","type":"error"},{"inputs":[],"name":"WrongNumberOfSignatures","type":"error"},{"anonymous":false,"inputs":[{"components":[{"internalType":"uint64","name":"chainSelector","type":"uint64"},{"internalType":"uint64","name":"sourceChainSelector","type":"uint64"},{"internalType":"address","name":"onRamp","type":"address"},{"internalType":"address","name":"armProxy","type":"address"}],"indexed":false,"internalType":"struct CommitStore.StaticConfig","name":"staticConfig","type":"tuple"},{"components":[{"internalType":"address","name":"priceRegistry","type":"address"}],"indexed":false,"internalType":"struct CommitStore.DynamicConfig","name":"dynamicConfig","type":"tuple"}],"name":"ConfigSet","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint32","name":"previousConfigBlockNumber","type":"uint32"},{"indexed":false,"internalType":"bytes32","name":"configDigest","type":"bytes32"},{"indexed":false,"internalType":"uint64","name":"configCount","type":"uint64"},{"indexed":false,"internalType":"address[]","name":"signers","type":"address[]"},{"indexed":false,"internalType":"address[]","name":"transmitters","type":"address[]"},{"indexed":false,"internalType":"uint8","name":"f","type":"uint8"},{"indexed":false,"internalType":"bytes","name":"onchainConfig","type":"bytes"},{"indexed":false,"internalType":"uint64","name":"offchainConfigVersion","type":"uint64"},{"indexed":false,"internalType":"bytes","name":"offchainConfig","type":"bytes"}],"name":"ConfigSet","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":false,"internalType":"address","name":"account","type":"address"}],"name":"Paused","type":"event"},{"anonymous":false,"inputs":[{"components":[{"components":[{"components":[{"internalType":"address","name":"sourceToken","type":"address"},{"internalType":"uint224","name":"usdPerToken","type":"uint224"}],"internalType":"struct Internal.TokenPriceUpdate[]","name":"tokenPriceUpdates","type":"tuple[]"},{"components":[{"internalType":"uint64","name":"destChainSelector","type":"uint64"},{"internalType":"uint224","name":"usdPerUnitGas","type":"uint224"}],"internalType":"struct Internal.GasPriceUpdate[]","name":"gasPriceUpdates","type":"tuple[]"}],"internalType":"struct Internal.PriceUpdates","name":"priceUpdates","type":"tuple"},{"components":[{"internalType":"uint64","name":"min","type":"uint64"},{"internalType":"uint64","name":"max","type":"uint64"}],"internalType":"struct CommitStore.Interval","name":"interval","type":"tuple"},{"internalType":"bytes32","name":"merkleRoot","type":"bytes32"}],"indexed":false,"internalType":"struct CommitStore.CommitReport","name":"report","type":"tuple"}],"name":"ReportAccepted","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"bytes32","name":"root","type":"bytes32"}],"name":"RootRemoved","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"bytes32","name":"configDigest","type":"bytes32"},{"indexed":false,"internalType":"uint32","name":"epoch","type":"uint32"}],"name":"Transmitted","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"account","type":"address"}],"name":"Unpaused","type":"event"},{"inputs":[],"name":"acceptOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"getDynamicConfig","outputs":[{"components":[{"internalType":"address","name":"priceRegistry","type":"address"}],"internalType":"struct CommitStore.DynamicConfig","name":"","type":"tuple"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getExpectedNextSequenceNumber","outputs":[{"internalType":"uint64","name":"","type":"uint64"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getLatestPriceEpochAndRound","outputs":[{"internalType":"uint64","name":"","type":"uint64"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes32","name":"root","type":"bytes32"}],"name":"getMerkleRoot","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getStaticConfig","outputs":[{"components":[{"internalType":"uint64","name":"chainSelector","type":"uint64"},{"internalType":"uint64","name":"sourceChainSelector","type":"uint64"},{"internalType":"address","name":"onRamp","type":"address"},{"internalType":"address","name":"armProxy","type":"address"}],"internalType":"struct CommitStore.StaticConfig","name":"","type":"tuple"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getTransmitters","outputs":[{"internalType":"address[]","name":"","type":"address[]"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"isARMHealthy","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes32","name":"root","type":"bytes32"}],"name":"isBlessed","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"isUnpausedAndARMHealthy","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"latestConfigDetails","outputs":[{"internalType":"uint32","name":"configCount","type":"uint32"},{"internalType":"uint32","name":"blockNumber","type":"uint32"},{"internalType":"bytes32","name":"configDigest","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"latestConfigDigestAndEpoch","outputs":[{"internalType":"bool","name":"scanLogs","type":"bool"},{"internalType":"bytes32","name":"configDigest","type":"bytes32"},{"internalType":"uint32","name":"epoch","type":"uint32"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"owner","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"pause","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"paused","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes32[]","name":"rootToReset","type":"bytes32[]"}],"name":"resetUnblessedRoots","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint40","name":"latestPriceEpochAndRound","type":"uint40"}],"name":"setLatestPriceEpochAndRound","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint64","name":"minSeqNr","type":"uint64"}],"name":"setMinSeqNr","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address[]","name":"signers","type":"address[]"},{"internalType":"address[]","name":"transmitters","type":"address[]"},{"internalType":"uint8","name":"f","type":"uint8"},{"internalType":"bytes","name":"onchainConfig","type":"bytes"},{"internalType":"uint64","name":"offchainConfigVersion","type":"uint64"},{"internalType":"bytes","name":"offchainConfig","type":"bytes"}],"name":"setOCR2Config","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"to","type":"address"}],"name":"transferOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes32[3]","name":"reportContext","type":"bytes32[3]"},{"internalType":"bytes","name":"report","type":"bytes"},{"internalType":"bytes32[]","name":"rs","type":"bytes32[]"},{"internalType":"bytes32[]","name":"ss","type":"bytes32[]"},{"internalType":"bytes32","name":"rawVs","type":"bytes32"}],"name":"transmit","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"typeAndVersion","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"unpause","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes32[]","name":"hashedLeaves","type":"bytes32[]"},{"internalType":"bytes32[]","name":"proofs","type":"bytes32[]"},{"internalType":"uint256","name":"proofFlagBits","type":"uint256"}],"name":"verify","outputs":[{"internalType":"uint256","name":"timestamp","type":"uint256"}],"stateMutability":"view","type":"function"}]

Deployed Bytecode

0x608060405234801561001057600080fd5b50600436106101985760003560e01c806379ba5097116100e3578063ad7a22f81161008c578063f2fde38b11610066578063f2fde38b146104fa578063f47a86901461050d578063ff888fb11461052057600080fd5b8063ad7a22f8146104b4578063afcb95d7146104c7578063b1dc65a4146104e757600080fd5b80638da5cb5b116100bd5780638da5cb5b146104645780638db94e441461048c578063a7206cd61461049457600080fd5b806379ba50971461042457806381ff70481461042c5780638456cb591461045c57600080fd5b806332048875116101455780635c975abb1161011f5780635c975abb146103b4578063666cab8d146103d05780637437ff9f146103e557600080fd5b806332048875146103795780633f4ba83a1461039a5780634120fccd146103a257600080fd5b8063181f5a7711610176578063181f5a77146103085780631ef381741461035157806329b980e41461036657600080fd5b806306285c691461019d5780630a6cd30d146102c057806310c374ed146102d8575b600080fd5b6102aa60408051608081018252600080825260208201819052918101829052606081019190915260405180608001604052807f0000000000000000000000000000000000000000000000008f90b8876dee653867ffffffffffffffff1681526020017f000000000000000000000000000000000000000000000000ccf0a31a221f3c9b67ffffffffffffffff1681526020017f0000000000000000000000001a674645f3eb4147543fca7d40c5719cbd99736273ffffffffffffffffffffffffffffffffffffffff1681526020017f00000000000000000000000099360767a4705f68cccb9533195b761648d6d80773ffffffffffffffffffffffffffffffffffffffff16815250905090565b6040516102b79190612656565b60405180910390f35b6102c8610533565b60405190151581526020016102b7565b60095468010000000000000000900464ffffffffff165b60405167ffffffffffffffff90911681526020016102b7565b6103446040518060400160405280601181526020017f436f6d6d697453746f726520312e322e3000000000000000000000000000000081525081565b6040516102b79190612713565b61036461035f366004612966565b6105ca565b005b610364610374366004612a33565b610deb565b61038c610387366004612aa6565b610e37565b6040519081526020016102b7565b610364610f2d565b60095467ffffffffffffffff166102ef565b6009546d0100000000000000000000000000900460ff166102c8565b6103d8610f93565b6040516102b79190612b6b565b604080516020808201835260009091528151808201835260085473ffffffffffffffffffffffffffffffffffffffff16908190529151918252016102b7565b610364611002565b6004546002546040805163ffffffff808516825264010000000090940490931660208401528201526060016102b7565b6103646110ff565b60005460405173ffffffffffffffffffffffffffffffffffffffff90911681526020016102b7565b6102c861116f565b61038c6104a2366004612b7e565b6000908152600a602052604090205490565b6103646104c2366004612b97565b611226565b6040805160018152600060208201819052918101919091526060016102b7565b6103646104f5366004612bb2565b611269565b610364610508366004612c97565b611889565b61036461051b366004612cb4565b61189d565b6102c861052e366004612b7e565b61193c565b60007f00000000000000000000000099360767a4705f68cccb9533195b761648d6d80773ffffffffffffffffffffffffffffffffffffffff1663397796f76040518163ffffffff1660e01b8152600401602060405180830381865afa1580156105a0573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906105c49190612cf6565b15905090565b855185518560ff16601f831115610642576040517f89a6198900000000000000000000000000000000000000000000000000000000815260206004820152601060248201527f746f6f206d616e79207369676e6572730000000000000000000000000000000060448201526064015b60405180910390fd5b806000036106ac576040517f89a6198900000000000000000000000000000000000000000000000000000000815260206004820152601260248201527f66206d75737420626520706f73697469766500000000000000000000000000006044820152606401610639565b81831461073a576040517f89a61989000000000000000000000000000000000000000000000000000000008152602060048201526024808201527f6f7261636c6520616464726573736573206f7574206f6620726567697374726160448201527f74696f6e000000000000000000000000000000000000000000000000000000006064820152608401610639565b610745816003612d47565b83116107ad576040517f89a6198900000000000000000000000000000000000000000000000000000000815260206004820152601860248201527f6661756c74792d6f7261636c65206620746f6f206869676800000000000000006044820152606401610639565b6107b5611a10565b6107be86611a93565b60065460005b818110156108ba5760056000600683815481106107e3576107e3612d5e565b600091825260208083209091015473ffffffffffffffffffffffffffffffffffffffff168352820192909252604001812080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00001690556007805460059291908490811061085357610853612d5e565b600091825260208083209091015473ffffffffffffffffffffffffffffffffffffffff168352820192909252604001902080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00001690556108b381612d8d565b90506107c4565b50895160005b81811015610c935760008c82815181106108dc576108dc612d5e565b60200260200101519050600060028111156108f9576108f9612dc5565b73ffffffffffffffffffffffffffffffffffffffff8216600090815260056020526040902054610100900460ff16600281111561093857610938612dc5565b1461099f576040517f89a6198900000000000000000000000000000000000000000000000000000000815260206004820152601760248201527f7265706561746564207369676e657220616464726573730000000000000000006044820152606401610639565b73ffffffffffffffffffffffffffffffffffffffff81166109ec576040517fd6c62c9b00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6040805180820190915260ff83168152602081016001905273ffffffffffffffffffffffffffffffffffffffff821660009081526005602090815260409091208251815460ff9091167fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0082168117835592840151919283917fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00001617610100836002811115610a9c57610a9c612dc5565b021790555090505060008c8381518110610ab857610ab8612d5e565b6020026020010151905060006002811115610ad557610ad5612dc5565b73ffffffffffffffffffffffffffffffffffffffff8216600090815260056020526040902054610100900460ff166002811115610b1457610b14612dc5565b14610b7b576040517f89a6198900000000000000000000000000000000000000000000000000000000815260206004820152601c60248201527f7265706561746564207472616e736d69747465722061646472657373000000006044820152606401610639565b73ffffffffffffffffffffffffffffffffffffffff8116610bc8576040517fd6c62c9b00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6040805180820190915260ff84168152602081016002905273ffffffffffffffffffffffffffffffffffffffff821660009081526005602090815260409091208251815460ff9091167fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0082168117835592840151919283917fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00001617610100836002811115610c7857610c78612dc5565b0217905550905050505080610c8c90612d8d565b90506108c0565b508a51610ca79060069060208e0190612598565b508951610cbb9060079060208d0190612598565b506003805460ff838116610100027fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0000909216908c161717905560048054610d41914691309190600090610d139063ffffffff16612df4565b91906101000a81548163ffffffff021916908363ffffffff160217905563ffffffff168e8e8e8e8e8e611c4f565b600260000181905550600060048054906101000a900463ffffffff169050436004806101000a81548163ffffffff021916908363ffffffff1602179055507f1591690b8638f5fb2dbec82ac741805ac5da8b45dc5263f4875b0496fdce4e0581600260000154600460009054906101000a900463ffffffff168f8f8f8f8f8f604051610dd599989796959493929190612e17565b60405180910390a1505050505050505050505050565b610df3611a10565b6009805464ffffffffff90921668010000000000000000027fffffffffffffffffffffffffffffffffffffff0000000000ffffffffffffffff909216919091179055565b6009546000906d0100000000000000000000000000900460ff1615610e88576040517feced32bc00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6000610ef987878080602002602001604051908101604052809392919081815260200183836020028082843760009201919091525050604080516020808b0282810182019093528a82529093508a925089918291850190849080828437600092019190915250889250611cfa915050565b9050610f048161193c565b610f12576000915050610f24565b6000908152600a602052604090205490505b95945050505050565b610f35611a10565b600980547fffffffffffffffffffffffffffffffffffff00ffffffffffffffffffffffffff1690556040513381527f5db9ee0a495bf2e6ff9c91a7834c1ba4fdd244a5e8aa4e537bd38aeae4b073aa906020015b60405180910390a1565b60606007805480602002602001604051908101604052809291908181526020018280548015610ff857602002820191906000526020600020905b815473ffffffffffffffffffffffffffffffffffffffff168152600190910190602001808311610fcd575b5050505050905090565b60015473ffffffffffffffffffffffffffffffffffffffff163314611083576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601660248201527f4d7573742062652070726f706f736564206f776e6572000000000000000000006044820152606401610639565b60008054337fffffffffffffffffffffffff00000000000000000000000000000000000000008083168217845560018054909116905560405173ffffffffffffffffffffffffffffffffffffffff90921692909183917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e091a350565b611107611a10565b600980547fffffffffffffffffffffffffffffffffffff00ffffffffffffffffffffffffff166d01000000000000000000000000001790556040513381527f62e78cea01bee320cd4e420270b5ea74000d11b0c9f74754ebdbfc544b05a25890602001610f89565b60007f00000000000000000000000099360767a4705f68cccb9533195b761648d6d80773ffffffffffffffffffffffffffffffffffffffff1663397796f76040518163ffffffff1660e01b8152600401602060405180830381865afa1580156111dc573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906112009190612cf6565b15801561122157506009546d0100000000000000000000000000900460ff16155b905090565b61122e611a10565b600980547fffffffffffffffffffffffffffffffffffffffffffffffff00000000000000001667ffffffffffffffff92909216919091179055565b611278878760208b013561201b565b6040805160608101825260025480825260035460ff8082166020850152610100909104169282019290925289359182146112eb5780516040517f93df584c000000000000000000000000000000000000000000000000000000008152600481019190915260248101839052604401610639565b467f0000000000000000000000000000000000000000000000000000000000014a341461136c576040517f0f01ce850000000000000000000000000000000000000000000000000000000081527f0000000000000000000000000000000000000000000000000000000000014a346004820152466024820152604401610639565b6040805183815260208c81013560081c63ffffffff16908201527fb04e63db38c49950639fa09d29872f21f5d49d614f3a969d8adf3d4b52e41a62910160405180910390a160007f00000000000000000000000000000000000000000000000000000000000000001561140e576002826020015183604001516113ef9190612ead565b6113f99190612ec6565b611404906001612ead565b60ff169050611424565b602082015161141e906001612ead565b60ff1690505b86811461145d576040517f71253a2500000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b868514611496576040517fa75d88af00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b3360009081526005602090815260408083208151808301909252805460ff808216845292939192918401916101009091041660028111156114d9576114d9612dc5565b60028111156114ea576114ea612dc5565b905250905060028160200151600281111561150757611507612dc5565b14801561154e57506007816000015160ff168154811061152957611529612d5e565b60009182526020909120015473ffffffffffffffffffffffffffffffffffffffff1633145b611584576040517fda0f08e800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b506000611592866020612d47565b61159d896020612d47565b6115a98c610144612f0f565b6115b39190612f0f565b6115bd9190612f0f565b9050368114611601576040517f8e1192e100000000000000000000000000000000000000000000000000000000815260048101829052366024820152604401610639565b5060008a8a604051611614929190612f22565b60405190819003812061162b918e90602001612f32565b60405160208183030381529060405280519060200120905061164b612622565b8860005b818110156118785760006001858a846020811061166e5761166e612d5e565b61167b91901a601b612ead565b8f8f8681811061168d5761168d612d5e565b905060200201358e8e878181106116a6576116a6612d5e565b90506020020135604051600081526020016040526040516116e3949392919093845260ff9290921660208401526040830152606082015260800190565b6020604051602081039080840390855afa158015611705573d6000803e3d6000fd5b5050604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe081015173ffffffffffffffffffffffffffffffffffffffff8116600090815260056020908152848220848601909552845460ff808216865293975091955092939284019161010090910416600281111561178857611788612dc5565b600281111561179957611799612dc5565b90525090506001816020015160028111156117b6576117b6612dc5565b146117ed576040517fca31867a00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b8051859060ff16601f811061180457611804612d5e565b602002015115611840576040517ff67bc7c400000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600185826000015160ff16601f811061185b5761185b612d5e565b9115156020909202015250611871905081612d8d565b905061164f565b505050505050505050505050505050565b611891611a10565b61189a81612428565b50565b6118a5611a10565b60005b818110156119375760008383838181106118c4576118c4612d5e565b9050602002013590506118d68161193c565b611926576000818152600a602052604080822091909155517f202f1139a3e334b6056064c0e9b19fd07e44a88d8f6e5ded571b24cf8c371f129061191d9083815260200190565b60405180910390a15b5061193081612d8d565b90506118a8565b505050565b6040805180820182523081526020810183815291517f4d616771000000000000000000000000000000000000000000000000000000008152905173ffffffffffffffffffffffffffffffffffffffff9081166004830152915160248201526000917f00000000000000000000000099360767a4705f68cccb9533195b761648d6d8071690634d61677190604401602060405180830381865afa1580156119e6573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611a0a9190612cf6565b92915050565b60005473ffffffffffffffffffffffffffffffffffffffff163314611a91576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601660248201527f4f6e6c792063616c6c61626c65206279206f776e6572000000000000000000006044820152606401610639565b565b600081806020019051810190611aa99190612f46565b805190915073ffffffffffffffffffffffffffffffffffffffff16611afa576040517f3f8be2be00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b8051600880547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff928316179055600980547fffffffffffffffffffffffffffffffffffffff0000000000ffffffffffffffff169055604080516080810182527f0000000000000000000000000000000000000000000000008f90b8876dee653867ffffffffffffffff90811682527f000000000000000000000000000000000000000000000000ccf0a31a221f3c9b1660208201527f0000000000000000000000001a674645f3eb4147543fca7d40c5719cbd9973628316818301527f00000000000000000000000099360767a4705f68cccb9533195b761648d6d8079092166060830152517fc9d7123efd4203e60b0f0a4b1dbc4800fc97ce63679f71c3a27279b24a7ddec391611c43918490612f92565b60405180910390a15050565b6000808a8a8a8a8a8a8a8a8a604051602001611c739998979695949392919061300f565b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe081840301815291905280516020909101207dffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff167e01000000000000000000000000000000000000000000000000000000000000179150509998505050505050505050565b8251825160009190818303611d3b576040517f11a6b26400000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6101018211801590611d4f57506101018111155b611d85576040517f09bde33900000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff82820101610100811115611de6576040517f09bde33900000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b80600003611e135786600081518110611e0157611e01612d5e565b60200260200101519350505050612014565b60008167ffffffffffffffff811115611e2e57611e2e612726565b604051908082528060200260200182016040528015611e57578160200160208202803683370190505b50905060008080805b85811015611f9a5760006001821b8b811603611ebb5788851015611ea4578c5160018601958e918110611e9557611e95612d5e565b60200260200101519050611edd565b8551600185019487918110611e9557611e95612d5e565b8b5160018401938d918110611ed257611ed2612d5e565b602002602001015190505b600089861015611f0d578d5160018701968f918110611efe57611efe612d5e565b60200260200101519050611f2f565b8651600186019588918110611f2457611f24612d5e565b602002602001015190505b82851115611f69576040517f09bde33900000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b611f73828261251d565b878481518110611f8557611f85612d5e565b60209081029190910101525050600101611e60565b506001850382148015611fac57508683145b8015611fb757508581145b611fed576040517f09bde33900000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b83600186038151811061200257612002612d5e565b60200260200101519750505050505050505b9392505050565b6009546d0100000000000000000000000000900460ff1615612069576040517feced32bc00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b7f00000000000000000000000099360767a4705f68cccb9533195b761648d6d80773ffffffffffffffffffffffffffffffffffffffff1663397796f76040518163ffffffff1660e01b8152600401602060405180830381865afa1580156120d4573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906120f89190612cf6565b1561212f576040517fc148371500000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600061213d8385018561319b565b8051515190915015158061215657508051602001515115155b1561228e5760095464ffffffffff8084166801000000000000000090920416101561225357600980547fffffffffffffffffffffffffffffffffffffff0000000000ffffffffffffffff166801000000000000000064ffffffffff85160217905560085481516040517f3937306f00000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff90921691633937306f9161220d916004016133ee565b600060405180830381600087803b15801561222757600080fd5b505af115801561223b573d6000803e3d6000fd5b50505050604081015161224e5750505050565b61228e565b604081015161228e576040517ff803a2ca00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60208101515160095467ffffffffffffffff90811691161415806122c9575060208082015190810151905167ffffffffffffffff9182169116115b156123065780602001516040517fbb1ae18d0000000000000000000000000000000000000000000000000000000081526004016106399190613401565b6040810151612341576040517f504570e300000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6040808201516000908152600a60205220541561238a576040517fa0bce24f00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b602080820151015161239d906001613426565b600980547fffffffffffffffffffffffffffffffffffffffffffffffff00000000000000001667ffffffffffffffff929092169190911790556040818101516000908152600a602052819020429055517f291698c01aa71f912280535d88a00d2c59fb63530a3f5d0098560468acb9ebf59061241a90839061344e565b60405180910390a150505050565b3373ffffffffffffffffffffffffffffffffffffffff8216036124a7576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601760248201527f43616e6e6f74207472616e7366657220746f2073656c660000000000000000006044820152606401610639565b600180547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff83811691821790925560008054604051929316917fed8889f560326eb138920d842192f0eb3dd22b4f139c87a2c57538e05bae12789190a350565b600081831061255f5760408051600160208083019190915281830185905260608083018790528351808403909101815260809092019092528051910120612014565b60408051600160208083019190915281830186905260608083018690528351808403909101815260809092019092528051910120612014565b828054828255906000526020600020908101928215612612579160200282015b8281111561261257825182547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff9091161782556020909201916001909101906125b8565b5061261e929150612641565b5090565b604051806103e00160405280601f906020820280368337509192915050565b5b8082111561261e5760008155600101612642565b60808101611a0a828467ffffffffffffffff80825116835280602083015116602084015250604081015173ffffffffffffffffffffffffffffffffffffffff808216604085015280606084015116606085015250505050565b6000815180845260005b818110156126d5576020818501810151868301820152016126b9565b5060006020828601015260207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f83011685010191505092915050565b60208152600061201460208301846126af565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b6040805190810167ffffffffffffffff8111828210171561277857612778612726565b60405290565b6040516060810167ffffffffffffffff8111828210171561277857612778612726565b604051601f82017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016810167ffffffffffffffff811182821017156127e8576127e8612726565b604052919050565b600067ffffffffffffffff82111561280a5761280a612726565b5060051b60200190565b73ffffffffffffffffffffffffffffffffffffffff8116811461189a57600080fd5b600082601f83011261284757600080fd5b8135602061285c612857836127f0565b6127a1565b82815260059290921b8401810191818101908684111561287b57600080fd5b8286015b8481101561289f57803561289281612814565b835291830191830161287f565b509695505050505050565b803560ff811681146128bb57600080fd5b919050565b600082601f8301126128d157600080fd5b813567ffffffffffffffff8111156128eb576128eb612726565b61291c60207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f840116016127a1565b81815284602083860101111561293157600080fd5b816020850160208301376000918101602001919091529392505050565b803567ffffffffffffffff811681146128bb57600080fd5b60008060008060008060c0878903121561297f57600080fd5b863567ffffffffffffffff8082111561299757600080fd5b6129a38a838b01612836565b975060208901359150808211156129b957600080fd5b6129c58a838b01612836565b96506129d360408a016128aa565b955060608901359150808211156129e957600080fd5b6129f58a838b016128c0565b9450612a0360808a0161294e565b935060a0890135915080821115612a1957600080fd5b50612a2689828a016128c0565b9150509295509295509295565b600060208284031215612a4557600080fd5b813564ffffffffff8116811461201457600080fd5b60008083601f840112612a6c57600080fd5b50813567ffffffffffffffff811115612a8457600080fd5b6020830191508360208260051b8501011115612a9f57600080fd5b9250929050565b600080600080600060608688031215612abe57600080fd5b853567ffffffffffffffff80821115612ad657600080fd5b612ae289838a01612a5a565b90975095506020880135915080821115612afb57600080fd5b50612b0888828901612a5a565b96999598509660400135949350505050565b600081518084526020808501945080840160005b83811015612b6057815173ffffffffffffffffffffffffffffffffffffffff1687529582019590820190600101612b2e565b509495945050505050565b6020815260006120146020830184612b1a565b600060208284031215612b9057600080fd5b5035919050565b600060208284031215612ba957600080fd5b6120148261294e565b60008060008060008060008060e0898b031215612bce57600080fd5b606089018a811115612bdf57600080fd5b8998503567ffffffffffffffff80821115612bf957600080fd5b818b0191508b601f830112612c0d57600080fd5b813581811115612c1c57600080fd5b8c6020828501011115612c2e57600080fd5b6020830199508098505060808b0135915080821115612c4c57600080fd5b612c588c838d01612a5a565b909750955060a08b0135915080821115612c7157600080fd5b50612c7e8b828c01612a5a565b999c989b50969995989497949560c00135949350505050565b600060208284031215612ca957600080fd5b813561201481612814565b60008060208385031215612cc757600080fd5b823567ffffffffffffffff811115612cde57600080fd5b612cea85828601612a5a565b90969095509350505050565b600060208284031215612d0857600080fd5b8151801515811461201457600080fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b8082028115828204841417611a0a57611a0a612d18565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b60007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8203612dbe57612dbe612d18565b5060010190565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602160045260246000fd5b600063ffffffff808316818103612e0d57612e0d612d18565b6001019392505050565b600061012063ffffffff808d1684528b6020850152808b16604085015250806060840152612e478184018a612b1a565b90508281036080840152612e5b8189612b1a565b905060ff871660a084015282810360c0840152612e7881876126af565b905067ffffffffffffffff851660e0840152828103610100840152612e9d81856126af565b9c9b505050505050505050505050565b60ff8181168382160190811115611a0a57611a0a612d18565b600060ff831680612f00577f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b8060ff84160491505092915050565b80820180821115611a0a57611a0a612d18565b8183823760009101908152919050565b828152606082602083013760800192915050565b600060208284031215612f5857600080fd5b6040516020810181811067ffffffffffffffff82111715612f7b57612f7b612726565b6040528251612f8981612814565b81529392505050565b60a08101612feb828567ffffffffffffffff80825116835280602083015116602084015250604081015173ffffffffffffffffffffffffffffffffffffffff808216604085015280606084015116606085015250505050565b73ffffffffffffffffffffffffffffffffffffffff83511660808301529392505050565b60006101208b835273ffffffffffffffffffffffffffffffffffffffff8b16602084015267ffffffffffffffff808b1660408501528160608501526130568285018b612b1a565b9150838203608085015261306a828a612b1a565b915060ff881660a085015283820360c085015261308782886126af565b90861660e08501528381036101008501529050612e9d81856126af565b80357bffffffffffffffffffffffffffffffffffffffffffffffffffffffff811681146128bb57600080fd5b600082601f8301126130e157600080fd5b813560206130f1612857836127f0565b82815260069290921b8401810191818101908684111561311057600080fd5b8286015b8481101561289f576040818903121561312d5760008081fd5b613135612755565b61313e8261294e565b815261314b8583016130a4565b81860152835291830191604001613114565b60006040828403121561316f57600080fd5b613177612755565b90506131828261294e565b81526131906020830161294e565b602082015292915050565b600060208083850312156131ae57600080fd5b823567ffffffffffffffff808211156131c657600080fd5b90840190608082870312156131da57600080fd5b6131e261277e565b8235828111156131f157600080fd5b8301604081890381131561320457600080fd5b61320c612755565b82358581111561321b57600080fd5b8301601f81018b1361322c57600080fd5b803561323a612857826127f0565b81815260069190911b8201890190898101908d83111561325957600080fd5b928a01925b828410156132a95785848f0312156132765760008081fd5b61327e612755565b843561328981612814565b8152613296858d016130a4565b818d0152825292850192908a019061325e565b845250505082870135858111156132bf57600080fd5b6132cb8b8286016130d0565b828901525083526132de8986880161315d565b8684015260608501358184015250508094505050505092915050565b805160408084528151848201819052600092602091908201906060870190855b81811015613373578351805173ffffffffffffffffffffffffffffffffffffffff1684528501517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1685840152928401929185019160010161331a565b50508583015187820388850152805180835290840192506000918401905b808310156133e2578351805167ffffffffffffffff1683528501517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1685830152928401926001929092019190850190613391565b50979650505050505050565b60208152600061201460208301846132fa565b60408101611a0a8284805167ffffffffffffffff908116835260209182015116910152565b67ffffffffffffffff81811683821601908082111561344757613447612d18565b5092915050565b60208152600082516080602084015261346a60a08401826132fa565b905060208401516134956040850182805167ffffffffffffffff908116835260209182015116910152565b5060408401516080840152809150509291505056fea164736f6c6343000813000a

Block Transaction Difficulty Gas Used Reward
Block Uncle Number Difficulty Gas Used Reward
Loading