Sepolia Testnet

Contract

0x32586e7e90304b0643E706376D2B3D6A04875384

Overview

ETH Balance

0 ETH

Multichain Info

N/A
Transaction Hash
Method
Block
From
To
Value
Cache Mmr Root56614132024-04-09 13:15:3648 days ago1712668536IN
0x32586e7e...A04875384
0 ETH0.000056820.87045931
Cache Mmr Root56610932024-04-09 12:07:0048 days ago1712664420IN
0x32586e7e...A04875384
0 ETH0.000066341.01628522
Cache Mmr Root56609272024-04-09 11:32:2448 days ago1712662344IN
0x32586e7e...A04875384
0 ETH0.000069331.06203262
Cache Mmr Root56608412024-04-09 11:14:4848 days ago1712661288IN
0x32586e7e...A04875384
0 ETH0.000073191.12116048
Cache Mmr Root56607532024-04-09 10:56:0048 days ago1712660160IN
0x32586e7e...A04875384
0 ETH0.000072561.59912133
Cache Mmr Root56607292024-04-09 10:51:1248 days ago1712659872IN
0x32586e7e...A04875384
0 ETH0.000080841.7815421
Cache Mmr Root56607172024-04-09 10:48:3648 days ago1712659716IN
0x32586e7e...A04875384
0 ETH0.000077661.71136023
Cache Mmr Root56607082024-04-09 10:46:4848 days ago1712659608IN
0x32586e7e...A04875384
0 ETH0.000080911.78297269
Cache Mmr Root56607032024-04-09 10:45:4848 days ago1712659548IN
0x32586e7e...A04875384
0 ETH0.000080381.77131326
Cache Mmr Root56606992024-04-09 10:45:0048 days ago1712659500IN
0x32586e7e...A04875384
0 ETH0.00008331.83566347
Cache Mmr Root56606942024-04-09 10:44:0048 days ago1712659440IN
0x32586e7e...A04875384
0 ETH0.000124481.90696698
Cache Mmr Root56606902024-04-09 10:43:0048 days ago1712659380IN
0x32586e7e...A04875384
0 ETH0.000090321.99033916
Cache Mmr Root56606872024-04-09 10:42:2448 days ago1712659344IN
0x32586e7e...A04875384
0 ETH0.000094072.07291146
Cache Mmr Root56606852024-04-09 10:42:0048 days ago1712659320IN
0x32586e7e...A04875384
0 ETH0.000096092.11750723
Cache Mmr Root56606822024-04-09 10:41:2448 days ago1712659284IN
0x32586e7e...A04875384
0 ETH0.000141012.16014347
0x60c0346156601682024-04-09 8:53:4849 days ago1712652828IN
 Create: HdpExecutionStore
0 ETH0.00400883.00067831

Advanced mode:
Parent Transaction Hash Block From To Value
View All Internal Transactions
Loading...
Loading

Contract Source Code Verified (Exact Match)

Contract Name:
HdpExecutionStore

Compiler Version
v0.8.21+commit.d9974bed

Optimization Enabled:
Yes with 20000 runs

Other Settings:
paris EvmVersion

Contract Source Code (Solidity Standard Json-Input format)

File 1 of 14 : HdpExecutionStore.sol
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.4;

import {AccessControl} from "openzeppelin-contracts/contracts/access/AccessControl.sol";
import {MerkleProof} from "openzeppelin-contracts/contracts/utils/cryptography/MerkleProof.sol";

import {IFactsRegistry} from "./interfaces/IFactsRegistry.sol";
import {ISharpFactsAggregator} from "./interfaces/ISharpFactsAggregator.sol";
import {IAggregatorsFactory} from "./interfaces/IAggregatorsFactory.sol";

import {BlockSampledDatalake, BlockSampledDatalakeCodecs} from "./datatypes/BlockSampledDatalakeCodecs.sol";
import {IterativeDynamicLayoutDatalake} from "./datatypes/IterativeDynamicLayoutDatalakeCodecs.sol";
import {IterativeDynamicLayoutDatalakeCodecs} from "./datatypes/IterativeDynamicLayoutDatalakeCodecs.sol";
import {ComputationalTask, ComputationalTaskCodecs} from "./datatypes/ComputationalTaskCodecs.sol";

/// Caller is not authorized to perform the action
error Unauthorized();
/// Task is already registered
error DoubleRegistration();
/// Fact doesn't exist in the registry
error InvalidFact();
/// Element is not in the batch
error NotInBatch();
/// Task is not finalized
error NotFinalized();

/// @title HdpExecutionStore
/// @author Herodotus Dev
/// @notice A contract to store the execution results of HDP tasks
contract HdpExecutionStore is AccessControl {
    using MerkleProof for bytes32[];
    using BlockSampledDatalakeCodecs for BlockSampledDatalake;
    using IterativeDynamicLayoutDatalakeCodecs for IterativeDynamicLayoutDatalake;
    using ComputationalTaskCodecs for ComputationalTask;

    /// @notice The status of a task
    enum TaskStatus {
        NONE,
        SCHEDULED,
        FINALIZED
    }

    /// @notice The struct representing a task result
    struct TaskResult {
        TaskStatus status;
        bytes32 result;
    }

    /// @notice emitted when a new MMR root is cached
    event MmrRootCached(uint256 mmrId, uint256 mmrSize, bytes32 mmrRoot);

    /// @notice emitted when a new task is scheduled
    event TaskWithBlockSampledDatalakeScheduled(BlockSampledDatalake datalake, ComputationalTask task);

    /// @notice constant representing role of operator
    bytes32 public constant OPERATOR_ROLE = keccak256("OPERATOR_ROLE");

    /// @notice constant representing the pedersen hash of the Cairo HDP program
    bytes32 public constant PROGRAM_HASH = 0x0099423699f60ef2e51458ec9890eb9ee3ea011067337b8009ab6adcbac6148e;
    /// @notice interface to the facts registry of SHARP
    IFactsRegistry public immutable SHARP_FACTS_REGISTRY;

    /// @notice interface to the aggregators factory
    IAggregatorsFactory public immutable AGGREGATORS_FACTORY;

    /// @notice mapping of task result hash => task
    mapping(bytes32 => TaskResult) public cachedTasksResult;

    /// @notice mapping of mmr id => mmr size => mmr root
    mapping(uint256 => mapping(uint256 => bytes32)) public cachedMMRsRoots;

    constructor(IFactsRegistry factsRegistry, IAggregatorsFactory aggregatorsFactory) {
        SHARP_FACTS_REGISTRY = factsRegistry;
        AGGREGATORS_FACTORY = aggregatorsFactory;

        _setRoleAdmin(OPERATOR_ROLE, OPERATOR_ROLE);
        _grantRole(OPERATOR_ROLE, _msgSender());
    }

    /// @notice Reverts if the caller is not an operator
    modifier onlyOperator() {
        if (!hasRole(OPERATOR_ROLE, _msgSender())) revert Unauthorized();
        _;
    }

    /// @notice Caches the MMR root for a given MMR id
    /// @notice Get MMR size and root from the aggregator and cache it
    function cacheMmrRoot(uint256 mmrId) public {
        ISharpFactsAggregator aggregator = AGGREGATORS_FACTORY.aggregatorsById(mmrId);
        ISharpFactsAggregator.AggregatorState memory aggregatorState = aggregator.aggregatorState();
        cachedMMRsRoots[mmrId][aggregatorState.mmrSize] = aggregatorState.poseidonMmrRoot;

        emit MmrRootCached(mmrId, aggregatorState.mmrSize, aggregatorState.poseidonMmrRoot);
    }

    /// @notice Requests the execution of a task with a block sampled datalake
    /// @param blockSampledDatalake The block sampled datalake
    /// @param computationalTask The computational task
    function requestExecutionOfTaskWithBlockSampledDatalake(
        BlockSampledDatalake calldata blockSampledDatalake,
        ComputationalTask calldata computationalTask
    ) external {
        bytes32 datalakeCommitment = blockSampledDatalake.commit();
        bytes32 taskCommitment = computationalTask.commit(datalakeCommitment);

        // Ensure task is not already scheduled
        if (cachedTasksResult[taskCommitment].status != TaskStatus.NONE) {
            revert DoubleRegistration();
        }

        // Store the task result
        cachedTasksResult[taskCommitment] = TaskResult({status: TaskStatus.SCHEDULED, result: ""});

        emit TaskWithBlockSampledDatalakeScheduled(blockSampledDatalake, computationalTask);
    }

    /// @notice Authenticates the execution of a task is finalized
    ///     by verifying the FactRegistry and Merkle proofs
    /// @param usedMmrId The id of the MMR used to compute task
    /// @param usedMmrSize The size of the MMR used to compute task
    /// @param batchResultsMerkleRootLow The low 128 bits of the results Merkle root
    /// @param batchResultsMerkleRootHigh The high 128 bits of the results Merkle root
    /// @param batchTasksMerkleRootLow The low 128 bits of the tasks Merkle root
    /// @param batchTasksMerkleRootHigh The high 128 bits of the tasks Merkle root
    /// @param batchInclusionProofsOfTasks The Merkle proof of the tasks
    /// @param batchInclusionProofsOfResults The Merkle proof of the results
    /// @param computationalTasksResult The result of the computational tasks
    /// @param taskCommitments The commitment of the tasks
    function authenticateTaskExecution(
        uint256 usedMmrId,
        uint256 usedMmrSize,
        uint128 batchResultsMerkleRootLow,
        uint128 batchResultsMerkleRootHigh,
        uint128 batchTasksMerkleRootLow,
        uint128 batchTasksMerkleRootHigh,
        bytes32[][] memory batchInclusionProofsOfTasks,
        bytes32[][] memory batchInclusionProofsOfResults,
        bytes32[] calldata computationalTasksResult,
        bytes32[] calldata taskCommitments
    ) external onlyOperator {
        // Load MMRs root
        bytes32 usedMmrRoot = loadMmrRoot(usedMmrId, usedMmrSize);

        // Initialize an array of uint256 to store the program output
        uint256[] memory programOutput = new uint256[](6);

        // Assign values to the program output array
        programOutput[0] = uint256(usedMmrRoot);
        programOutput[1] = uint256(usedMmrSize);
        programOutput[2] = uint256(batchResultsMerkleRootLow);
        programOutput[3] = uint256(batchResultsMerkleRootHigh);
        programOutput[4] = uint256(batchTasksMerkleRootLow);
        programOutput[5] = uint256(batchTasksMerkleRootHigh);

        // Compute program output hash
        bytes32 programOutputHash = keccak256(abi.encodePacked(programOutput));

        // Compute GPS fact hash
        bytes32 gpsFactHash = keccak256(abi.encode(PROGRAM_HASH, programOutputHash));

        // Ensure GPS fact is registered
        if (!SHARP_FACTS_REGISTRY.isValid(gpsFactHash)) {
            revert InvalidFact();
        }

        // Loop through all the tasks in the batch
        for (uint256 i = 0; i < computationalTasksResult.length; i++) {
            bytes32 computationalTaskResult = computationalTasksResult[i];
            bytes32[] memory batchInclusionProofsOfTask = batchInclusionProofsOfTasks[i];
            bytes32[] memory batchInclusionProofsOfResult = batchInclusionProofsOfResults[i];

            // Convert the low and high 128 bits to a single 256 bit value
            bytes32 batchResultsMerkleRoot =
                bytes32((uint256(batchResultsMerkleRootHigh) << 128) | uint256(batchResultsMerkleRootLow));
            bytes32 batchTasksMerkleRoot =
                bytes32((uint256(batchTasksMerkleRootHigh) << 128) | uint256(batchTasksMerkleRootLow));

            // Compute the Merkle leaf of the task
            bytes32 taskCommitment = taskCommitments[i];
            bytes32 taskMerkleLeaf = standardLeafHash(taskCommitment);
            // Ensure that the task is included in the batch, by verifying the Merkle proof
            bool isVerifiedTask = batchInclusionProofsOfTask.verify(batchTasksMerkleRoot, taskMerkleLeaf);

            if (!isVerifiedTask) {
                revert NotInBatch();
            }

            // Compute the Merkle leaf of the task result
            bytes32 taskResultCommitment = keccak256(abi.encode(taskCommitment, computationalTaskResult));
            bytes32 taskResultMerkleLeaf = standardLeafHash(taskResultCommitment);
            // Ensure that the task result is included in the batch, by verifying the Merkle proof
            bool isVerifiedResult = batchInclusionProofsOfResult.verify(batchResultsMerkleRoot, taskResultMerkleLeaf);

            if (!isVerifiedResult) {
                revert NotInBatch();
            }

            // Store the task result
            cachedTasksResult[taskCommitment] =
                TaskResult({status: TaskStatus.FINALIZED, result: computationalTaskResult});
        }
    }

    /// @notice Load MMR root from cache with given mmrId and mmrSize
    function loadMmrRoot(uint256 mmrId, uint256 mmrSize) public view returns (bytes32) {
        return cachedMMRsRoots[mmrId][mmrSize];
    }

    /// @notice Returns the result of a finalized task
    function getFinalizedTaskResult(bytes32 taskCommitment) external view returns (bytes32) {
        // Ensure task is finalized
        if (cachedTasksResult[taskCommitment].status != TaskStatus.FINALIZED) {
            revert NotFinalized();
        }
        return cachedTasksResult[taskCommitment].result;
    }

    /// @notice Returns the status of a task
    function getTaskStatus(bytes32 taskCommitment) external view returns (TaskStatus) {
        return cachedTasksResult[taskCommitment].status;
    }

    /// @notice Returns the leaf of standard merkle tree
    function standardLeafHash(bytes32 value) public pure returns (bytes32) {
        bytes32 firstHash = keccak256(abi.encode(value));
        bytes32 leaf = keccak256(abi.encode(firstHash));
        return leaf;
    }
}

File 3 of 14 : AccessControl.sol
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v4.9.0) (access/AccessControl.sol)

pragma solidity ^0.8.20;

import {IAccessControl} from "./IAccessControl.sol";
import {Context} from "../utils/Context.sol";
import {ERC165} from "../utils/introspection/ERC165.sol";

/**
 * @dev Contract module that allows children to implement role-based access
 * control mechanisms. This is a lightweight version that doesn't allow enumerating role
 * members except through off-chain means by accessing the contract event logs. Some
 * applications may benefit from on-chain enumerability, for those cases see
 * {AccessControlEnumerable}.
 *
 * Roles are referred to by their `bytes32` identifier. These should be exposed
 * in the external API and be unique. The best way to achieve this is by
 * using `public constant` hash digests:
 *
 * ```solidity
 * bytes32 public constant MY_ROLE = keccak256("MY_ROLE");
 * ```
 *
 * Roles can be used to represent a set of permissions. To restrict access to a
 * function call, use {hasRole}:
 *
 * ```solidity
 * function foo() public {
 *     require(hasRole(MY_ROLE, msg.sender));
 *     ...
 * }
 * ```
 *
 * Roles can be granted and revoked dynamically via the {grantRole} and
 * {revokeRole} functions. Each role has an associated admin role, and only
 * accounts that have a role's admin role can call {grantRole} and {revokeRole}.
 *
 * By default, the admin role for all roles is `DEFAULT_ADMIN_ROLE`, which means
 * that only accounts with this role will be able to grant or revoke other
 * roles. More complex role relationships can be created by using
 * {_setRoleAdmin}.
 *
 * WARNING: The `DEFAULT_ADMIN_ROLE` is also its own admin: it has permission to
 * grant and revoke this role. Extra precautions should be taken to secure
 * accounts that have been granted it. We recommend using {AccessControlDefaultAdminRules}
 * to enforce additional security measures for this role.
 */
abstract contract AccessControl is Context, IAccessControl, ERC165 {
    struct RoleData {
        mapping(address => bool) members;
        bytes32 adminRole;
    }

    mapping(bytes32 => RoleData) private _roles;

    bytes32 public constant DEFAULT_ADMIN_ROLE = 0x00;

    /**
     * @dev Modifier that checks that an account has a specific role. Reverts
     * with an {AccessControlUnauthorizedAccount} error including the required role.
     */
    modifier onlyRole(bytes32 role) {
        _checkRole(role);
        _;
    }

    /**
     * @dev See {IERC165-supportsInterface}.
     */
    function supportsInterface(bytes4 interfaceId) public view virtual override returns (bool) {
        return interfaceId == type(IAccessControl).interfaceId || super.supportsInterface(interfaceId);
    }

    /**
     * @dev Returns `true` if `account` has been granted `role`.
     */
    function hasRole(bytes32 role, address account) public view virtual returns (bool) {
        return _roles[role].members[account];
    }

    /**
     * @dev Reverts with an {AccessControlUnauthorizedAccount} error if `_msgSender()`
     * is missing `role`. Overriding this function changes the behavior of the {onlyRole} modifier.
     */
    function _checkRole(bytes32 role) internal view virtual {
        _checkRole(role, _msgSender());
    }

    /**
     * @dev Reverts with an {AccessControlUnauthorizedAccount} error if `account`
     * is missing `role`.
     */
    function _checkRole(bytes32 role, address account) internal view virtual {
        if (!hasRole(role, account)) {
            revert AccessControlUnauthorizedAccount(account, role);
        }
    }

    /**
     * @dev Returns the admin role that controls `role`. See {grantRole} and
     * {revokeRole}.
     *
     * To change a role's admin, use {_setRoleAdmin}.
     */
    function getRoleAdmin(bytes32 role) public view virtual returns (bytes32) {
        return _roles[role].adminRole;
    }

    /**
     * @dev Grants `role` to `account`.
     *
     * If `account` had not been already granted `role`, emits a {RoleGranted}
     * event.
     *
     * Requirements:
     *
     * - the caller must have ``role``'s admin role.
     *
     * May emit a {RoleGranted} event.
     */
    function grantRole(bytes32 role, address account) public virtual onlyRole(getRoleAdmin(role)) {
        _grantRole(role, account);
    }

    /**
     * @dev Revokes `role` from `account`.
     *
     * If `account` had been granted `role`, emits a {RoleRevoked} event.
     *
     * Requirements:
     *
     * - the caller must have ``role``'s admin role.
     *
     * May emit a {RoleRevoked} event.
     */
    function revokeRole(bytes32 role, address account) public virtual onlyRole(getRoleAdmin(role)) {
        _revokeRole(role, account);
    }

    /**
     * @dev Revokes `role` from the calling account.
     *
     * Roles are often managed via {grantRole} and {revokeRole}: this function's
     * purpose is to provide a mechanism for accounts to lose their privileges
     * if they are compromised (such as when a trusted device is misplaced).
     *
     * If the calling account had been revoked `role`, emits a {RoleRevoked}
     * event.
     *
     * Requirements:
     *
     * - the caller must be `callerConfirmation`.
     *
     * May emit a {RoleRevoked} event.
     */
    function renounceRole(bytes32 role, address callerConfirmation) public virtual {
        if (callerConfirmation != _msgSender()) {
            revert AccessControlBadConfirmation();
        }

        _revokeRole(role, callerConfirmation);
    }

    /**
     * @dev Sets `adminRole` as ``role``'s admin role.
     *
     * Emits a {RoleAdminChanged} event.
     */
    function _setRoleAdmin(bytes32 role, bytes32 adminRole) internal virtual {
        bytes32 previousAdminRole = getRoleAdmin(role);
        _roles[role].adminRole = adminRole;
        emit RoleAdminChanged(role, previousAdminRole, adminRole);
    }

    /**
     * @dev Attempts to grant `role` to `account` and returns a boolean indicating if `role` was granted.
     *
     * Internal function without access restriction.
     *
     * May emit a {RoleGranted} event.
     */
    function _grantRole(bytes32 role, address account) internal virtual returns (bool) {
        if (!hasRole(role, account)) {
            _roles[role].members[account] = true;
            emit RoleGranted(role, account, _msgSender());
            return true;
        } else {
            return false;
        }
    }

    /**
     * @dev Attempts to revoke `role` to `account` and returns a boolean indicating if `role` was revoked.
     *
     * Internal function without access restriction.
     *
     * May emit a {RoleRevoked} event.
     */
    function _revokeRole(bytes32 role, address account) internal virtual returns (bool) {
        if (hasRole(role, account)) {
            _roles[role].members[account] = false;
            emit RoleRevoked(role, account, _msgSender());
            return true;
        } else {
            return false;
        }
    }
}

File 4 of 14 : MerkleProof.sol
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v4.9.2) (utils/cryptography/MerkleProof.sol)

pragma solidity ^0.8.20;

/**
 * @dev These functions deal with verification of Merkle Tree proofs.
 *
 * The tree and the proofs can be generated using our
 * https://github.com/OpenZeppelin/merkle-tree[JavaScript library].
 * You will find a quickstart guide in the readme.
 *
 * WARNING: You should avoid using leaf values that are 64 bytes long prior to
 * hashing, or use a hash function other than keccak256 for hashing leaves.
 * This is because the concatenation of a sorted pair of internal nodes in
 * the merkle tree could be reinterpreted as a leaf value.
 * OpenZeppelin's JavaScript library generates merkle trees that are safe
 * against this attack out of the box.
 */
library MerkleProof {
    /**
     *@dev The multiproof provided is not valid.
     */
    error MerkleProofInvalidMultiproof();

    /**
     * @dev Returns true if a `leaf` can be proved to be a part of a Merkle tree
     * defined by `root`. For this, a `proof` must be provided, containing
     * sibling hashes on the branch from the leaf to the root of the tree. Each
     * pair of leaves and each pair of pre-images are assumed to be sorted.
     */
    function verify(bytes32[] memory proof, bytes32 root, bytes32 leaf) internal pure returns (bool) {
        return processProof(proof, leaf) == root;
    }

    /**
     * @dev Calldata version of {verify}
     */
    function verifyCalldata(bytes32[] calldata proof, bytes32 root, bytes32 leaf) internal pure returns (bool) {
        return processProofCalldata(proof, leaf) == root;
    }

    /**
     * @dev Returns the rebuilt hash obtained by traversing a Merkle tree up
     * from `leaf` using `proof`. A `proof` is valid if and only if the rebuilt
     * hash matches the root of the tree. When processing the proof, the pairs
     * of leafs & pre-images are assumed to be sorted.
     */
    function processProof(bytes32[] memory proof, bytes32 leaf) internal pure returns (bytes32) {
        bytes32 computedHash = leaf;
        for (uint256 i = 0; i < proof.length; i++) {
            computedHash = _hashPair(computedHash, proof[i]);
        }
        return computedHash;
    }

    /**
     * @dev Calldata version of {processProof}
     */
    function processProofCalldata(bytes32[] calldata proof, bytes32 leaf) internal pure returns (bytes32) {
        bytes32 computedHash = leaf;
        for (uint256 i = 0; i < proof.length; i++) {
            computedHash = _hashPair(computedHash, proof[i]);
        }
        return computedHash;
    }

    /**
     * @dev Returns true if the `leaves` can be simultaneously proven to be a part of a merkle tree defined by
     * `root`, according to `proof` and `proofFlags` as described in {processMultiProof}.
     *
     * CAUTION: Not all merkle trees admit multiproofs. See {processMultiProof} for details.
     */
    function multiProofVerify(
        bytes32[] memory proof,
        bool[] memory proofFlags,
        bytes32 root,
        bytes32[] memory leaves
    ) internal pure returns (bool) {
        return processMultiProof(proof, proofFlags, leaves) == root;
    }

    /**
     * @dev Calldata version of {multiProofVerify}
     *
     * CAUTION: Not all merkle trees admit multiproofs. See {processMultiProof} for details.
     */
    function multiProofVerifyCalldata(
        bytes32[] calldata proof,
        bool[] calldata proofFlags,
        bytes32 root,
        bytes32[] memory leaves
    ) internal pure returns (bool) {
        return processMultiProofCalldata(proof, proofFlags, leaves) == root;
    }

    /**
     * @dev Returns the root of a tree reconstructed from `leaves` and sibling nodes in `proof`. The reconstruction
     * proceeds by incrementally reconstructing all inner nodes by combining a leaf/inner node with either another
     * leaf/inner node or a proof sibling node, depending on whether each `proofFlags` item is true or false
     * respectively.
     *
     * CAUTION: Not all merkle trees admit multiproofs. To use multiproofs, it is sufficient to ensure that: 1) the tree
     * is complete (but not necessarily perfect), 2) the leaves to be proven are in the opposite order they are in the
     * tree (i.e., as seen from right to left starting at the deepest layer and continuing at the next layer).
     */
    function processMultiProof(
        bytes32[] memory proof,
        bool[] memory proofFlags,
        bytes32[] memory leaves
    ) internal pure returns (bytes32 merkleRoot) {
        // This function rebuilds the root hash by traversing the tree up from the leaves. The root is rebuilt by
        // consuming and producing values on a queue. The queue starts with the `leaves` array, then goes onto the
        // `hashes` array. At the end of the process, the last hash in the `hashes` array should contain the root of
        // the merkle tree.
        uint256 leavesLen = leaves.length;
        uint256 proofLen = proof.length;
        uint256 totalHashes = proofFlags.length;

        // Check proof validity.
        if (leavesLen + proofLen - 1 != totalHashes) {
            revert MerkleProofInvalidMultiproof();
        }

        // The xxxPos values are "pointers" to the next value to consume in each array. All accesses are done using
        // `xxx[xxxPos++]`, which return the current value and increment the pointer, thus mimicking a queue's "pop".
        bytes32[] memory hashes = new bytes32[](totalHashes);
        uint256 leafPos = 0;
        uint256 hashPos = 0;
        uint256 proofPos = 0;
        // At each step, we compute the next hash using two values:
        // - a value from the "main queue". If not all leaves have been consumed, we get the next leaf, otherwise we
        //   get the next hash.
        // - depending on the flag, either another value from the "main queue" (merging branches) or an element from the
        //   `proof` array.
        for (uint256 i = 0; i < totalHashes; i++) {
            bytes32 a = leafPos < leavesLen ? leaves[leafPos++] : hashes[hashPos++];
            bytes32 b = proofFlags[i]
                ? (leafPos < leavesLen ? leaves[leafPos++] : hashes[hashPos++])
                : proof[proofPos++];
            hashes[i] = _hashPair(a, b);
        }

        if (totalHashes > 0) {
            if (proofPos != proofLen) {
                revert MerkleProofInvalidMultiproof();
            }
            unchecked {
                return hashes[totalHashes - 1];
            }
        } else if (leavesLen > 0) {
            return leaves[0];
        } else {
            return proof[0];
        }
    }

    /**
     * @dev Calldata version of {processMultiProof}.
     *
     * CAUTION: Not all merkle trees admit multiproofs. See {processMultiProof} for details.
     */
    function processMultiProofCalldata(
        bytes32[] calldata proof,
        bool[] calldata proofFlags,
        bytes32[] memory leaves
    ) internal pure returns (bytes32 merkleRoot) {
        // This function rebuilds the root hash by traversing the tree up from the leaves. The root is rebuilt by
        // consuming and producing values on a queue. The queue starts with the `leaves` array, then goes onto the
        // `hashes` array. At the end of the process, the last hash in the `hashes` array should contain the root of
        // the merkle tree.
        uint256 leavesLen = leaves.length;
        uint256 proofLen = proof.length;
        uint256 totalHashes = proofFlags.length;

        // Check proof validity.
        if (leavesLen + proofLen - 1 != totalHashes) {
            revert MerkleProofInvalidMultiproof();
        }

        // The xxxPos values are "pointers" to the next value to consume in each array. All accesses are done using
        // `xxx[xxxPos++]`, which return the current value and increment the pointer, thus mimicking a queue's "pop".
        bytes32[] memory hashes = new bytes32[](totalHashes);
        uint256 leafPos = 0;
        uint256 hashPos = 0;
        uint256 proofPos = 0;
        // At each step, we compute the next hash using two values:
        // - a value from the "main queue". If not all leaves have been consumed, we get the next leaf, otherwise we
        //   get the next hash.
        // - depending on the flag, either another value from the "main queue" (merging branches) or an element from the
        //   `proof` array.
        for (uint256 i = 0; i < totalHashes; i++) {
            bytes32 a = leafPos < leavesLen ? leaves[leafPos++] : hashes[hashPos++];
            bytes32 b = proofFlags[i]
                ? (leafPos < leavesLen ? leaves[leafPos++] : hashes[hashPos++])
                : proof[proofPos++];
            hashes[i] = _hashPair(a, b);
        }

        if (totalHashes > 0) {
            if (proofPos != proofLen) {
                revert MerkleProofInvalidMultiproof();
            }
            unchecked {
                return hashes[totalHashes - 1];
            }
        } else if (leavesLen > 0) {
            return leaves[0];
        } else {
            return proof[0];
        }
    }

    function _hashPair(bytes32 a, bytes32 b) private pure returns (bytes32) {
        return a < b ? _efficientHash(a, b) : _efficientHash(b, a);
    }

    function _efficientHash(bytes32 a, bytes32 b) private pure returns (bytes32 value) {
        /// @solidity memory-safe-assembly
        assembly {
            mstore(0x00, a)
            mstore(0x20, b)
            value := keccak256(0x00, 0x40)
        }
    }
}

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

/// @notice Interface for the facts registry (https://github.com/starkware-libs/starkex-contracts/blob/master/scalable-dex/contracts/src/components/FactRegistry.sol)
interface IFactsRegistry {
    function isValid(bytes32 fact) external view returns (bool);
    function markValid(bytes32 fact) external;
}

File 6 of 14 : ISharpFactsAggregator.sol
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.4;

/// @notice Interface for the SharpFactsAggregator.
interface ISharpFactsAggregator {
    struct AggregatorState {
        bytes32 poseidonMmrRoot;
        bytes32 keccakMmrRoot;
        uint256 mmrSize;
        bytes32 continuableParentHash;
    }

    function aggregatorState() external view returns (AggregatorState memory);
}

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

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

/// @notice Aggregators factory interface.
interface IAggregatorsFactory {
    function createAggregator(uint256 id, ISharpFactsAggregator aggregator) external;

    function aggregatorsById(uint256 id) external view returns (ISharpFactsAggregator);
}

File 8 of 14 : BlockSampledDatalakeCodecs.sol
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.4;

import {DatalakeCode} from "./Datalake.sol";

/// @dev A BlockSampledDatalake.
/// @param blockRangeStart The start block of the range.
/// @param blockRangeEnd The end block of the range.
/// @param increment The block increment.
/// @param sampledProperty The detail property to sample.
struct BlockSampledDatalake {
    uint256 blockRangeStart;
    uint256 blockRangeEnd;
    uint256 increment;
    bytes sampledProperty;
}

/// @notice Codecs for BlockSampledDatalake.
/// @dev Represent a datalake that samples a property at a fixed block interval.
library BlockSampledDatalakeCodecs {
    /// @dev Encodes a BlockSampledDatalake.
    /// @param datalake The BlockSampledDatalake to encode.
    function encode(BlockSampledDatalake memory datalake) internal pure returns (bytes memory) {
        return abi.encode(
            DatalakeCode.BlockSampled,
            datalake.blockRangeStart,
            datalake.blockRangeEnd,
            datalake.increment,
            datalake.sampledProperty
        );
    }

    /// @dev Get the commitment of a BlockSampledDatalake.
    /// @param datalake The BlockSampledDatalake to commit.
    function commit(BlockSampledDatalake memory datalake) internal pure returns (bytes32) {
        return keccak256(encode(datalake));
    }

    /// @dev Encodes a sampled property for a header property.
    /// @param headerPropId The header field from rlp decoded block header.
    function encodeSampledPropertyForHeaderProp(uint8 headerPropId) internal pure returns (bytes memory) {
        return abi.encodePacked(uint8(1), headerPropId);
    }

    /// @dev Encodes a sampled property for an account property.
    /// @param account The account address.
    /// @param propertyId The account field from rlp decoded account.
    function encodeSampledPropertyForAccount(address account, uint8 propertyId) internal pure returns (bytes memory) {
        return abi.encodePacked(uint8(2), account, propertyId);
    }

    /// @dev Encodes a sampled property for a storage.
    /// @param account The account address.
    /// @param slot The storage key.
    function encodeSampledPropertyForStorage(address account, bytes32 slot) internal pure returns (bytes memory) {
        return abi.encodePacked(uint8(3), account, slot);
    }

    /// @dev Decodes a BlockSampledDatalake.
    /// @param data The encoded BlockSampledDatalake.
    function decode(bytes memory data) internal pure returns (BlockSampledDatalake memory) {
        (, uint256 blockRangeStart, uint256 blockRangeEnd, uint256 increment, bytes memory sampledProperty) =
            abi.decode(data, (DatalakeCode, uint256, uint256, uint256, bytes));
        return BlockSampledDatalake({
            blockRangeStart: blockRangeStart,
            blockRangeEnd: blockRangeEnd,
            increment: increment,
            sampledProperty: sampledProperty
        });
    }
}

File 9 of 14 : IterativeDynamicLayoutDatalakeCodecs.sol
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.4;

import {DatalakeCode} from "./Datalake.sol";

struct IterativeDynamicLayoutDatalake {
    uint256 blockNumber;
    address account;
    uint256 slotIndex;
    uint256 initialKey;
    uint256 keyBoundry;
    uint256 increment;
}

library IterativeDynamicLayoutDatalakeCodecs {
    function encode(IterativeDynamicLayoutDatalake memory datalake) internal pure returns (bytes memory) {
        return abi.encode(
            DatalakeCode.IterativeDynamicLayout,
            datalake.blockNumber,
            datalake.account,
            datalake.slotIndex,
            datalake.initialKey,
            datalake.keyBoundry,
            datalake.increment
        );
    }

    function commit(IterativeDynamicLayoutDatalake memory datalake) internal pure returns (bytes32) {
        return keccak256(encode(datalake));
    }

    function decode(bytes memory data) internal pure returns (IterativeDynamicLayoutDatalake memory) {
        (
            ,
            uint256 blockNumber,
            address account,
            uint256 slotIndex,
            uint256 initialKey,
            uint256 keyBoundry,
            uint256 increment
        ) = abi.decode(data, (DatalakeCode, uint256, address, uint256, uint256, uint256, uint256));
        return IterativeDynamicLayoutDatalake({
            blockNumber: blockNumber,
            account: account,
            slotIndex: slotIndex,
            initialKey: initialKey,
            keyBoundry: keyBoundry,
            increment: increment
        });
    }
}

File 10 of 14 : ComputationalTaskCodecs.sol
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.4;

/// @dev A ComputationalTask.
/// @param AggregateFnId The aggregate function id.
/// @param operator The operator to use (only COUNT).
/// @param valueToCompare The value to compare (only COUNT).
/// The context is used to pass additional parameters to the aggregate function.
struct ComputationalTask {
    AggregateFn aggregateFnId;
    Operator operatorId;
    uint256 valueToCompare;
}

///@notice Aggregates functions.
enum AggregateFn {
    AVG,
    SUM,
    MIN,
    MAX,
    COUNT,
    MERKLE
}

///@notice Operators for COUNT.
enum Operator {
    NONE,
    EQ,
    NEQ,
    GT,
    GTE,
    LT,
    LTE
}

/// @notice Codecs for ComputationalTask.
/// @dev Represent a computational task with an aggregate function and context.
library ComputationalTaskCodecs {
    /// @dev Encodes a ComputationalTask.
    /// @param task The ComputationalTask to encode.
    function encode(ComputationalTask memory task) internal pure returns (bytes memory) {
        return abi.encode(task.aggregateFnId, task.operatorId, task.valueToCompare);
    }

    /// @dev Get the commitment of a ComputationalTask.
    /// @notice The commitment embeds the datalake commitment.
    /// @param task The ComputationalTask to commit.
    /// @param datalakeCommitment The commitment of the datalake.
    function commit(ComputationalTask memory task, bytes32 datalakeCommitment) internal pure returns (bytes32) {
        return keccak256(abi.encode(datalakeCommitment, task.aggregateFnId, task.operatorId, task.valueToCompare));
    }

    /// @dev Decodes a ComputationalTask.
    /// @param data The encoded ComputationalTask.
    function decode(bytes memory data) internal pure returns (ComputationalTask memory) {
        (uint8 aggregateFnId, uint8 operator, uint256 valueToCompare) = abi.decode(data, (uint8, uint8, uint256));
        return ComputationalTask({
            aggregateFnId: AggregateFn(aggregateFnId),
            operatorId: Operator(operator),
            valueToCompare: valueToCompare
        });
    }
}

File 11 of 14 : IAccessControl.sol
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts v4.4.1 (access/IAccessControl.sol)

pragma solidity ^0.8.20;

/**
 * @dev External interface of AccessControl declared to support ERC165 detection.
 */
interface IAccessControl {
    /**
     * @dev The `account` is missing a role.
     */
    error AccessControlUnauthorizedAccount(address account, bytes32 neededRole);

    /**
     * @dev The caller of a function is not the expected one.
     *
     * NOTE: Don't confuse with {AccessControlUnauthorizedAccount}.
     */
    error AccessControlBadConfirmation();

    /**
     * @dev Emitted when `newAdminRole` is set as ``role``'s admin role, replacing `previousAdminRole`
     *
     * `DEFAULT_ADMIN_ROLE` is the starting admin for all roles, despite
     * {RoleAdminChanged} not being emitted signaling this.
     */
    event RoleAdminChanged(bytes32 indexed role, bytes32 indexed previousAdminRole, bytes32 indexed newAdminRole);

    /**
     * @dev Emitted when `account` is granted `role`.
     *
     * `sender` is the account that originated the contract call, an admin role
     * bearer except when using {AccessControl-_setupRole}.
     */
    event RoleGranted(bytes32 indexed role, address indexed account, address indexed sender);

    /**
     * @dev Emitted when `account` is revoked `role`.
     *
     * `sender` is the account that originated the contract call:
     *   - if using `revokeRole`, it is the admin role bearer
     *   - if using `renounceRole`, it is the role bearer (i.e. `account`)
     */
    event RoleRevoked(bytes32 indexed role, address indexed account, address indexed sender);

    /**
     * @dev Returns `true` if `account` has been granted `role`.
     */
    function hasRole(bytes32 role, address account) external view returns (bool);

    /**
     * @dev Returns the admin role that controls `role`. See {grantRole} and
     * {revokeRole}.
     *
     * To change a role's admin, use {AccessControl-_setRoleAdmin}.
     */
    function getRoleAdmin(bytes32 role) external view returns (bytes32);

    /**
     * @dev Grants `role` to `account`.
     *
     * If `account` had not been already granted `role`, emits a {RoleGranted}
     * event.
     *
     * Requirements:
     *
     * - the caller must have ``role``'s admin role.
     */
    function grantRole(bytes32 role, address account) external;

    /**
     * @dev Revokes `role` from `account`.
     *
     * If `account` had been granted `role`, emits a {RoleRevoked} event.
     *
     * Requirements:
     *
     * - the caller must have ``role``'s admin role.
     */
    function revokeRole(bytes32 role, address account) external;

    /**
     * @dev Revokes `role` from the calling account.
     *
     * Roles are often managed via {grantRole} and {revokeRole}: this function's
     * purpose is to provide a mechanism for accounts to lose their privileges
     * if they are compromised (such as when a trusted device is misplaced).
     *
     * If the calling account had been granted `role`, emits a {RoleRevoked}
     * event.
     *
     * Requirements:
     *
     * - the caller must be `callerConfirmation`.
     */
    function renounceRole(bytes32 role, address callerConfirmation) external;
}

File 12 of 14 : Context.sol
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts v4.4.1 (utils/Context.sol)

pragma solidity ^0.8.20;

/**
 * @dev Provides information about the current execution context, including the
 * sender of the transaction and its data. While these are generally available
 * via msg.sender and msg.data, they should not be accessed in such a direct
 * manner, since when dealing with meta-transactions the account sending and
 * paying for execution may not be the actual sender (as far as an application
 * is concerned).
 *
 * This contract is only required for intermediate, library-like contracts.
 */
abstract contract Context {
    function _msgSender() internal view virtual returns (address) {
        return msg.sender;
    }

    function _msgData() internal view virtual returns (bytes calldata) {
        return msg.data;
    }
}

File 13 of 14 : ERC165.sol
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts v4.4.1 (utils/introspection/ERC165.sol)

pragma solidity ^0.8.20;

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

/**
 * @dev Implementation of the {IERC165} interface.
 *
 * Contracts that want to implement ERC165 should inherit from this contract and override {supportsInterface} to check
 * for the additional interface id that will be supported. For example:
 *
 * ```solidity
 * function supportsInterface(bytes4 interfaceId) public view virtual override returns (bool) {
 *     return interfaceId == type(MyInterface).interfaceId || super.supportsInterface(interfaceId);
 * }
 * ```
 */
abstract contract ERC165 is IERC165 {
    /**
     * @dev See {IERC165-supportsInterface}.
     */
    function supportsInterface(bytes4 interfaceId) public view virtual returns (bool) {
        return interfaceId == type(IERC165).interfaceId;
    }
}

File 14 of 14 : Datalake.sol
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.4;

/// @notice Datalake type.
enum DatalakeCode {
    BlockSampled,
    IterativeDynamicLayout
}

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

pragma solidity ^0.8.20;

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

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

Contract ABI

[{"inputs":[{"internalType":"contract IFactsRegistry","name":"factsRegistry","type":"address"},{"internalType":"contract IAggregatorsFactory","name":"aggregatorsFactory","type":"address"}],"stateMutability":"nonpayable","type":"constructor"},{"inputs":[],"name":"AccessControlBadConfirmation","type":"error"},{"inputs":[{"internalType":"address","name":"account","type":"address"},{"internalType":"bytes32","name":"neededRole","type":"bytes32"}],"name":"AccessControlUnauthorizedAccount","type":"error"},{"inputs":[],"name":"DoubleRegistration","type":"error"},{"inputs":[],"name":"InvalidFact","type":"error"},{"inputs":[],"name":"NotFinalized","type":"error"},{"inputs":[],"name":"NotInBatch","type":"error"},{"inputs":[],"name":"Unauthorized","type":"error"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"mmrId","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"mmrSize","type":"uint256"},{"indexed":false,"internalType":"bytes32","name":"mmrRoot","type":"bytes32"}],"name":"MmrRootCached","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"bytes32","name":"role","type":"bytes32"},{"indexed":true,"internalType":"bytes32","name":"previousAdminRole","type":"bytes32"},{"indexed":true,"internalType":"bytes32","name":"newAdminRole","type":"bytes32"}],"name":"RoleAdminChanged","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"bytes32","name":"role","type":"bytes32"},{"indexed":true,"internalType":"address","name":"account","type":"address"},{"indexed":true,"internalType":"address","name":"sender","type":"address"}],"name":"RoleGranted","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"bytes32","name":"role","type":"bytes32"},{"indexed":true,"internalType":"address","name":"account","type":"address"},{"indexed":true,"internalType":"address","name":"sender","type":"address"}],"name":"RoleRevoked","type":"event"},{"anonymous":false,"inputs":[{"components":[{"internalType":"uint256","name":"blockRangeStart","type":"uint256"},{"internalType":"uint256","name":"blockRangeEnd","type":"uint256"},{"internalType":"uint256","name":"increment","type":"uint256"},{"internalType":"bytes","name":"sampledProperty","type":"bytes"}],"indexed":false,"internalType":"struct BlockSampledDatalake","name":"datalake","type":"tuple"},{"components":[{"internalType":"enum AggregateFn","name":"aggregateFnId","type":"uint8"},{"internalType":"enum Operator","name":"operatorId","type":"uint8"},{"internalType":"uint256","name":"valueToCompare","type":"uint256"}],"indexed":false,"internalType":"struct ComputationalTask","name":"task","type":"tuple"}],"name":"TaskWithBlockSampledDatalakeScheduled","type":"event"},{"inputs":[],"name":"AGGREGATORS_FACTORY","outputs":[{"internalType":"contract IAggregatorsFactory","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"DEFAULT_ADMIN_ROLE","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"OPERATOR_ROLE","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"PROGRAM_HASH","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"SHARP_FACTS_REGISTRY","outputs":[{"internalType":"contract IFactsRegistry","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"usedMmrId","type":"uint256"},{"internalType":"uint256","name":"usedMmrSize","type":"uint256"},{"internalType":"uint128","name":"batchResultsMerkleRootLow","type":"uint128"},{"internalType":"uint128","name":"batchResultsMerkleRootHigh","type":"uint128"},{"internalType":"uint128","name":"batchTasksMerkleRootLow","type":"uint128"},{"internalType":"uint128","name":"batchTasksMerkleRootHigh","type":"uint128"},{"internalType":"bytes32[][]","name":"batchInclusionProofsOfTasks","type":"bytes32[][]"},{"internalType":"bytes32[][]","name":"batchInclusionProofsOfResults","type":"bytes32[][]"},{"internalType":"bytes32[]","name":"computationalTasksResult","type":"bytes32[]"},{"internalType":"bytes32[]","name":"taskCommitments","type":"bytes32[]"}],"name":"authenticateTaskExecution","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"mmrId","type":"uint256"}],"name":"cacheMmrRoot","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"","type":"uint256"},{"internalType":"uint256","name":"","type":"uint256"}],"name":"cachedMMRsRoots","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"name":"cachedTasksResult","outputs":[{"internalType":"enum HdpExecutionStore.TaskStatus","name":"status","type":"uint8"},{"internalType":"bytes32","name":"result","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes32","name":"taskCommitment","type":"bytes32"}],"name":"getFinalizedTaskResult","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes32","name":"role","type":"bytes32"}],"name":"getRoleAdmin","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes32","name":"taskCommitment","type":"bytes32"}],"name":"getTaskStatus","outputs":[{"internalType":"enum HdpExecutionStore.TaskStatus","name":"","type":"uint8"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes32","name":"role","type":"bytes32"},{"internalType":"address","name":"account","type":"address"}],"name":"grantRole","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes32","name":"role","type":"bytes32"},{"internalType":"address","name":"account","type":"address"}],"name":"hasRole","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"mmrId","type":"uint256"},{"internalType":"uint256","name":"mmrSize","type":"uint256"}],"name":"loadMmrRoot","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes32","name":"role","type":"bytes32"},{"internalType":"address","name":"callerConfirmation","type":"address"}],"name":"renounceRole","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"components":[{"internalType":"uint256","name":"blockRangeStart","type":"uint256"},{"internalType":"uint256","name":"blockRangeEnd","type":"uint256"},{"internalType":"uint256","name":"increment","type":"uint256"},{"internalType":"bytes","name":"sampledProperty","type":"bytes"}],"internalType":"struct BlockSampledDatalake","name":"blockSampledDatalake","type":"tuple"},{"components":[{"internalType":"enum AggregateFn","name":"aggregateFnId","type":"uint8"},{"internalType":"enum Operator","name":"operatorId","type":"uint8"},{"internalType":"uint256","name":"valueToCompare","type":"uint256"}],"internalType":"struct ComputationalTask","name":"computationalTask","type":"tuple"}],"name":"requestExecutionOfTaskWithBlockSampledDatalake","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes32","name":"role","type":"bytes32"},{"internalType":"address","name":"account","type":"address"}],"name":"revokeRole","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes32","name":"value","type":"bytes32"}],"name":"standardLeafHash","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"pure","type":"function"},{"inputs":[{"internalType":"bytes4","name":"interfaceId","type":"bytes4"}],"name":"supportsInterface","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"}]

60c0346100eb57601f6200181638819003918201601f19168301916001600160401b038311848410176100f05780849260409485528339810103126100eb5780516001600160a01b039182821682036100eb576020015191821682036100eb5760805260a052600080516020620017f683398151915280600052600060205260016040600020018181549155817fbd79b86ffe0ab8e8776151514217cd7cacd52c909f66475c3af44e129f0b00ff600080a46100ba33610106565b5060405161164e9081620001a882396080518181816101a20152610c8f015260a05181818161072b01526108170152f35b600080fd5b634e487b7160e01b600052604160045260246000fd5b6001600160a01b031660008181527fee57cd81e84075558e8fcc182a1f4393f91fc97f963a136e66b7f949a62f319f6020526040812054909190600080516020620017f68339815191529060ff166101a257808352826020526040832082845260205260408320600160ff198254161790557f2f8788117e7eff1d82e926ec794901d17c78024a50270940304540a733656f0d339380a4600190565b50509056fe608080604052600436101561001357600080fd5b60003560e01c908163019d8386146110be5750806301ffc9a71461101d578063248a9ca314610fee5780632bf6cc7914610fb85780632d3b431414610f925780632f2ff15d14610f6157806336568abe14610f0357806376b330ea146109eb5780637ba8414c146109ac5780638ecc5fdc146107b957806391d148541461076b578063a217fddf1461074f578063b436df92146106fe578063c3cd0938146106cb578063cee4e7d6146106cb578063d547741f14610698578063d9c91ddf146101c6578063e80c360c14610175578063eaa916111461013b5763f5b541a6146100fb57600080fd5b346101365760006003193601126101365760206040517f97667070c54ef182b0f5858b034beac1b6f3089aa2d3188bb1e8929f4fa9b9298152f35b600080fd5b346101365760006003193601126101365760206040517e99423699f60ef2e51458ec9890eb9ee3ea011067337b8009ab6adcbac6148e8152f35b3461013657600060031936011261013657602060405173ffffffffffffffffffffffffffffffffffffffff7f0000000000000000000000000000000000000000000000000000000000000000168152f35b34610136576003196080813601126101365767ffffffffffffffff6004351161013657608090600435360301126101365760607fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffdc3601126101365760405161022d81611195565b60043560040135815260246004350135602082015260446004350135604082015267ffffffffffffffff6064600435013511610136573660043560648101350160230112156101365767ffffffffffffffff60048035606481013501013511610651576040516102d0600480356064810135010135601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016602001826111cd565b6004803560648101350190810135808352369101602401116101365760048035606481013501908101359060240160208301376000602060046064813501358135010135830101528060608301528151916040602082015191015190604051936000602086015260408501526060840152608083015260a080830152818151918260c083015260005b83811061068057826103a560e0827fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f896000858286010152011681010360c08101845201826111cd565b602081519101206040516060810181811067ffffffffffffffff821117610651576040526006602435101561013657602435815260076044351015610136576044356020820152604060643591015260405190602082015261040c604082016024356114ea565b61041b606082016044356114f7565b6064356080820152608081528060a081011067ffffffffffffffff60a0830111176106515760a08101604052805160208201209081600052600160205260ff6040600020541660038110156105f55761062457506040519061047c82611179565b600182526020820190600082526000526001602052604060002091519060038210156105f55760019160ff7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00855416911617835551910155604051608081526004356004013560808201526024600435013560a08201526044600435013560c08201527fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffdd6004353603016064600435013512156101365760043560646004350135019060246004830135920167ffffffffffffffff831161013657823603811361013657817fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f7fc421ce05a3ca95a5c451baf76b9e248a8b2eec2fbac75ed393da9dbd817f3b0495608060e08501528061010085015280610120958686013760008582860101526105d4602085016024356114ea565b6105e3604085016044356114f7565b606435606085015201168101030190a1005b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602160045260246000fd5b60a0817fb1c4a1390000000000000000000000000000000000000000000000000000000082600494015201fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b602082820181015160e0878401015285935001610359565b34610136576106c96106a936611146565b908060005260006020526106c4600160406000200154611342565b611449565b005b34610136576106d93661132c565b9060005260026020526040600020906000526020526020604060002054604051908152f35b3461013657600060031936011261013657602060405173ffffffffffffffffffffffffffffffffffffffff7f0000000000000000000000000000000000000000000000000000000000000000168152f35b3461013657600060031936011261013657602060405160008152f35b346101365761077936611146565b90600052600060205273ffffffffffffffffffffffffffffffffffffffff60406000209116600052602052602060ff604060002054166040519015158152f35b34610136576020806003193601126101365760043573ffffffffffffffffffffffffffffffffffffffff6040517f7b8269220000000000000000000000000000000000000000000000000000000081528260048201528381602481857f0000000000000000000000000000000000000000000000000000000000000000165afa801561096957600090610975575b608091506004604051809481937fcf90c31e000000000000000000000000000000000000000000000000000000008352165afa908115610969576000916108e6575b7f3d9010878007c7ac4a8ab2b61591cdb85c4343ad26e526d8b9ac90053efa69b9606084868580518360005260028352604060002090604083019182516000528452604060002055519051916040519384528301526040820152a1005b9190506080823d8211610961575b81610901608093836111cd565b81010312610136577f3d9010878007c7ac4a8ab2b61591cdb85c4343ad26e526d8b9ac90053efa69b992606092836040519161093c83611195565b8051835283810151848401526040810151604084015201518482015291925092610889565b3d91506108f4565b6040513d6000823e3d90fd5b508381813d83116109a5575b61098b81836111cd565b810103126101365751818116810361013657608090610847565b503d610981565b34610136576020600319360112610136576004356000526001602052604080600020600160ff8254169101546109e483518093611139565b6020820152f35b3461013657610140600319360112610136576fffffffffffffffffffffffffffffffff60443581811681036101365781606435166064350361013657608435908282168203610136578260a4351660a435036101365760c43567ffffffffffffffff811161013657610a61903690600401611226565b9260e43567ffffffffffffffff811161013657610a82903690600401611226565b916101043567ffffffffffffffff811161013657610aa49036906004016112fb565b94906101243567ffffffffffffffff811161013657610ac79036906004016112fb565b3360009081527fee57cd81e84075558e8fcc182a1f4393f91fc97f963a136e66b7f949a62f319f60205260409020549193909160ff1615610ed957600435600052600260205260406000206024356000526020526040600020546040519060e0820182811067ffffffffffffffff821117610651576040526006825260c0366020840137815115610eaa576020820152805160011015610eaa576024356040820152805160021015610eaa578686166060820152805160031015610eaa5786606435166080820152805160041015610eaa5786821660a0820152805160051015610eaa578660a4351660c082015260405160208101818193602081519391019260005b818110610e91575050610c049250037fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe081018352826111cd565b51902060405160208101917e99423699f60ef2e51458ec9890eb9ee3ea011067337b8009ab6adcbac6148e8352604082015260408152610c43816111b1565b519020604051907f6a938567000000000000000000000000000000000000000000000000000000008252600482015260208160248173ffffffffffffffffffffffffffffffffffffffff7f0000000000000000000000000000000000000000000000000000000000000000165afa90811561096957600091610e56575b5015610e2c5791967fffffffffffffffffffffffffffffffff00000000000000000000000000000000929060005b818110610cf757005b610d0281838c611574565b3590610d0e818d611504565b51610d19828c611504565b51610d46610d2884898c611574565b3592610d33846115e1565b908d89168b60a43560801b161790611584565b15610e0257610d8b90610d78604051602081019085825287604082015260408152610d70816111b1565b5190206115e1565b908c8c168a60643560801b161790611584565b15610e025760405192610d9d84611179565b6002845260208401526000526001602052604060002082519260038410156105f5576020600191610dfd9560ff7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0086541691161784550151910155611518565b610cee565b60046040517f6a737b09000000000000000000000000000000000000000000000000000000008152fd5b60046040517f4801faa3000000000000000000000000000000000000000000000000000000008152fd5b90506020813d602011610e89575b81610e71602093836111cd565b8101031261013657518015158103610136578a610cc0565b3d9150610e64565b8451835260209485019486945090920191600101610bca565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b60046040517f82b42900000000000000000000000000000000000000000000000000000000008152fd5b3461013657610f1136611146565b3373ffffffffffffffffffffffffffffffffffffffff821603610f37576106c991611449565b60046040517f6697b232000000000000000000000000000000000000000000000000000000008152fd5b34610136576106c9610f7236611146565b90806000526000602052610f8d600160406000200154611342565b61139f565b34610136576020600319360112610136576020610fb06004356115e1565b604051908152f35b34610136576020600319360112610136576004356000526001602052602060ff60406000205416610fec6040518092611139565bf35b346101365760206003193601126101365760043560005260006020526020600160406000200154604051908152f35b34610136576020600319360112610136576004357fffffffff00000000000000000000000000000000000000000000000000000000811680910361013657807f7965db0b0000000000000000000000000000000000000000000000000000000060209214908115611094575b506040519015158152f35b7f01ffc9a70000000000000000000000000000000000000000000000000000000091501482611089565b34610136576020600319360112610136576004359081600052600160205260ff6040600020541660038110156105f557600203611111575060005260016020526020600160406000200154604051908152f35b807f1bee0d5a0000000000000000000000000000000000000000000000000000000060049252fd5b9060038210156105f55752565b6003196040910112610136576004359060243573ffffffffffffffffffffffffffffffffffffffff811681036101365790565b6040810190811067ffffffffffffffff82111761065157604052565b6080810190811067ffffffffffffffff82111761065157604052565b6060810190811067ffffffffffffffff82111761065157604052565b90601f7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0910116810190811067ffffffffffffffff82111761065157604052565b67ffffffffffffffff81116106515760051b60200190565b81601f8201121561013657602090803561123f8161120e565b93604061124e815196876111cd565b8286528486019185600594851b8601019481861161013657868101935b86851061127d57505050505050505090565b843567ffffffffffffffff811161013657820183603f820112156101365788810135906112a98261120e565b916112b6875193846111cd565b808352868b8401918a1b830101918683116101365791878c94929593015b8181106112eb57505082935081520194019361126b565b80358652948401948c94016112d4565b9181601f840112156101365782359167ffffffffffffffff8311610136576020808501948460051b01011161013657565b6003196040910112610136576004359060243590565b80600052600060205260406000203360005260205260ff60406000205416156113685750565b604490604051907fe2517d3f0000000000000000000000000000000000000000000000000000000082523360048301526024820152fd5b906000918083528260205273ffffffffffffffffffffffffffffffffffffffff6040842092169182845260205260ff604084205416156000146114445780835282602052604083208284526020526040832060017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff008254161790557f2f8788117e7eff1d82e926ec794901d17c78024a50270940304540a733656f0d339380a4600190565b505090565b906000918083528260205273ffffffffffffffffffffffffffffffffffffffff6040842092169182845260205260ff604084205416600014611444578083528260205260408320828452602052604083207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0081541690557ff6391f5c32d9c69d2a47ea670b442974b53935d1edc7fd64eb21e047a839171b339380a4600190565b9060068210156105f55752565b9060078210156105f55752565b8051821015610eaa5760209160051b010190565b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff81146115455760010190565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b9190811015610eaa5760051b0190565b929091906000915b84518310156115d95761159f8386611504565b51906000828210156115c757506000526020526115c160406000205b92611518565b9161158c565b6040916115c1938252602052206115bb565b915092501490565b60405160208101918252602081526115f881611179565b519020604051602081019182526020815261161281611179565b5190209056fea264697066735822122061e46f346e9c3b1707af4d413b956320d8893a559e1d12a52ca5412751f99fbd64736f6c6343000815003397667070c54ef182b0f5858b034beac1b6f3089aa2d3188bb1e8929f4fa9b9290000000000000000000000000ed8c44415e882f3033b4f3aff916bbb4997f91500000000000000000000000070c61dd17b7207b450cb7dedc92c1707a07a1213

Deployed Bytecode

0x608080604052600436101561001357600080fd5b60003560e01c908163019d8386146110be5750806301ffc9a71461101d578063248a9ca314610fee5780632bf6cc7914610fb85780632d3b431414610f925780632f2ff15d14610f6157806336568abe14610f0357806376b330ea146109eb5780637ba8414c146109ac5780638ecc5fdc146107b957806391d148541461076b578063a217fddf1461074f578063b436df92146106fe578063c3cd0938146106cb578063cee4e7d6146106cb578063d547741f14610698578063d9c91ddf146101c6578063e80c360c14610175578063eaa916111461013b5763f5b541a6146100fb57600080fd5b346101365760006003193601126101365760206040517f97667070c54ef182b0f5858b034beac1b6f3089aa2d3188bb1e8929f4fa9b9298152f35b600080fd5b346101365760006003193601126101365760206040517e99423699f60ef2e51458ec9890eb9ee3ea011067337b8009ab6adcbac6148e8152f35b3461013657600060031936011261013657602060405173ffffffffffffffffffffffffffffffffffffffff7f0000000000000000000000000ed8c44415e882f3033b4f3aff916bbb4997f915168152f35b34610136576003196080813601126101365767ffffffffffffffff6004351161013657608090600435360301126101365760607fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffdc3601126101365760405161022d81611195565b60043560040135815260246004350135602082015260446004350135604082015267ffffffffffffffff6064600435013511610136573660043560648101350160230112156101365767ffffffffffffffff60048035606481013501013511610651576040516102d0600480356064810135010135601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016602001826111cd565b6004803560648101350190810135808352369101602401116101365760048035606481013501908101359060240160208301376000602060046064813501358135010135830101528060608301528151916040602082015191015190604051936000602086015260408501526060840152608083015260a080830152818151918260c083015260005b83811061068057826103a560e0827fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f896000858286010152011681010360c08101845201826111cd565b602081519101206040516060810181811067ffffffffffffffff821117610651576040526006602435101561013657602435815260076044351015610136576044356020820152604060643591015260405190602082015261040c604082016024356114ea565b61041b606082016044356114f7565b6064356080820152608081528060a081011067ffffffffffffffff60a0830111176106515760a08101604052805160208201209081600052600160205260ff6040600020541660038110156105f55761062457506040519061047c82611179565b600182526020820190600082526000526001602052604060002091519060038210156105f55760019160ff7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00855416911617835551910155604051608081526004356004013560808201526024600435013560a08201526044600435013560c08201527fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffdd6004353603016064600435013512156101365760043560646004350135019060246004830135920167ffffffffffffffff831161013657823603811361013657817fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f7fc421ce05a3ca95a5c451baf76b9e248a8b2eec2fbac75ed393da9dbd817f3b0495608060e08501528061010085015280610120958686013760008582860101526105d4602085016024356114ea565b6105e3604085016044356114f7565b606435606085015201168101030190a1005b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602160045260246000fd5b60a0817fb1c4a1390000000000000000000000000000000000000000000000000000000082600494015201fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b602082820181015160e0878401015285935001610359565b34610136576106c96106a936611146565b908060005260006020526106c4600160406000200154611342565b611449565b005b34610136576106d93661132c565b9060005260026020526040600020906000526020526020604060002054604051908152f35b3461013657600060031936011261013657602060405173ffffffffffffffffffffffffffffffffffffffff7f00000000000000000000000070c61dd17b7207b450cb7dedc92c1707a07a1213168152f35b3461013657600060031936011261013657602060405160008152f35b346101365761077936611146565b90600052600060205273ffffffffffffffffffffffffffffffffffffffff60406000209116600052602052602060ff604060002054166040519015158152f35b34610136576020806003193601126101365760043573ffffffffffffffffffffffffffffffffffffffff6040517f7b8269220000000000000000000000000000000000000000000000000000000081528260048201528381602481857f00000000000000000000000070c61dd17b7207b450cb7dedc92c1707a07a1213165afa801561096957600090610975575b608091506004604051809481937fcf90c31e000000000000000000000000000000000000000000000000000000008352165afa908115610969576000916108e6575b7f3d9010878007c7ac4a8ab2b61591cdb85c4343ad26e526d8b9ac90053efa69b9606084868580518360005260028352604060002090604083019182516000528452604060002055519051916040519384528301526040820152a1005b9190506080823d8211610961575b81610901608093836111cd565b81010312610136577f3d9010878007c7ac4a8ab2b61591cdb85c4343ad26e526d8b9ac90053efa69b992606092836040519161093c83611195565b8051835283810151848401526040810151604084015201518482015291925092610889565b3d91506108f4565b6040513d6000823e3d90fd5b508381813d83116109a5575b61098b81836111cd565b810103126101365751818116810361013657608090610847565b503d610981565b34610136576020600319360112610136576004356000526001602052604080600020600160ff8254169101546109e483518093611139565b6020820152f35b3461013657610140600319360112610136576fffffffffffffffffffffffffffffffff60443581811681036101365781606435166064350361013657608435908282168203610136578260a4351660a435036101365760c43567ffffffffffffffff811161013657610a61903690600401611226565b9260e43567ffffffffffffffff811161013657610a82903690600401611226565b916101043567ffffffffffffffff811161013657610aa49036906004016112fb565b94906101243567ffffffffffffffff811161013657610ac79036906004016112fb565b3360009081527fee57cd81e84075558e8fcc182a1f4393f91fc97f963a136e66b7f949a62f319f60205260409020549193909160ff1615610ed957600435600052600260205260406000206024356000526020526040600020546040519060e0820182811067ffffffffffffffff821117610651576040526006825260c0366020840137815115610eaa576020820152805160011015610eaa576024356040820152805160021015610eaa578686166060820152805160031015610eaa5786606435166080820152805160041015610eaa5786821660a0820152805160051015610eaa578660a4351660c082015260405160208101818193602081519391019260005b818110610e91575050610c049250037fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe081018352826111cd565b51902060405160208101917e99423699f60ef2e51458ec9890eb9ee3ea011067337b8009ab6adcbac6148e8352604082015260408152610c43816111b1565b519020604051907f6a938567000000000000000000000000000000000000000000000000000000008252600482015260208160248173ffffffffffffffffffffffffffffffffffffffff7f0000000000000000000000000ed8c44415e882f3033b4f3aff916bbb4997f915165afa90811561096957600091610e56575b5015610e2c5791967fffffffffffffffffffffffffffffffff00000000000000000000000000000000929060005b818110610cf757005b610d0281838c611574565b3590610d0e818d611504565b51610d19828c611504565b51610d46610d2884898c611574565b3592610d33846115e1565b908d89168b60a43560801b161790611584565b15610e0257610d8b90610d78604051602081019085825287604082015260408152610d70816111b1565b5190206115e1565b908c8c168a60643560801b161790611584565b15610e025760405192610d9d84611179565b6002845260208401526000526001602052604060002082519260038410156105f5576020600191610dfd9560ff7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0086541691161784550151910155611518565b610cee565b60046040517f6a737b09000000000000000000000000000000000000000000000000000000008152fd5b60046040517f4801faa3000000000000000000000000000000000000000000000000000000008152fd5b90506020813d602011610e89575b81610e71602093836111cd565b8101031261013657518015158103610136578a610cc0565b3d9150610e64565b8451835260209485019486945090920191600101610bca565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b60046040517f82b42900000000000000000000000000000000000000000000000000000000008152fd5b3461013657610f1136611146565b3373ffffffffffffffffffffffffffffffffffffffff821603610f37576106c991611449565b60046040517f6697b232000000000000000000000000000000000000000000000000000000008152fd5b34610136576106c9610f7236611146565b90806000526000602052610f8d600160406000200154611342565b61139f565b34610136576020600319360112610136576020610fb06004356115e1565b604051908152f35b34610136576020600319360112610136576004356000526001602052602060ff60406000205416610fec6040518092611139565bf35b346101365760206003193601126101365760043560005260006020526020600160406000200154604051908152f35b34610136576020600319360112610136576004357fffffffff00000000000000000000000000000000000000000000000000000000811680910361013657807f7965db0b0000000000000000000000000000000000000000000000000000000060209214908115611094575b506040519015158152f35b7f01ffc9a70000000000000000000000000000000000000000000000000000000091501482611089565b34610136576020600319360112610136576004359081600052600160205260ff6040600020541660038110156105f557600203611111575060005260016020526020600160406000200154604051908152f35b807f1bee0d5a0000000000000000000000000000000000000000000000000000000060049252fd5b9060038210156105f55752565b6003196040910112610136576004359060243573ffffffffffffffffffffffffffffffffffffffff811681036101365790565b6040810190811067ffffffffffffffff82111761065157604052565b6080810190811067ffffffffffffffff82111761065157604052565b6060810190811067ffffffffffffffff82111761065157604052565b90601f7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0910116810190811067ffffffffffffffff82111761065157604052565b67ffffffffffffffff81116106515760051b60200190565b81601f8201121561013657602090803561123f8161120e565b93604061124e815196876111cd565b8286528486019185600594851b8601019481861161013657868101935b86851061127d57505050505050505090565b843567ffffffffffffffff811161013657820183603f820112156101365788810135906112a98261120e565b916112b6875193846111cd565b808352868b8401918a1b830101918683116101365791878c94929593015b8181106112eb57505082935081520194019361126b565b80358652948401948c94016112d4565b9181601f840112156101365782359167ffffffffffffffff8311610136576020808501948460051b01011161013657565b6003196040910112610136576004359060243590565b80600052600060205260406000203360005260205260ff60406000205416156113685750565b604490604051907fe2517d3f0000000000000000000000000000000000000000000000000000000082523360048301526024820152fd5b906000918083528260205273ffffffffffffffffffffffffffffffffffffffff6040842092169182845260205260ff604084205416156000146114445780835282602052604083208284526020526040832060017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff008254161790557f2f8788117e7eff1d82e926ec794901d17c78024a50270940304540a733656f0d339380a4600190565b505090565b906000918083528260205273ffffffffffffffffffffffffffffffffffffffff6040842092169182845260205260ff604084205416600014611444578083528260205260408320828452602052604083207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0081541690557ff6391f5c32d9c69d2a47ea670b442974b53935d1edc7fd64eb21e047a839171b339380a4600190565b9060068210156105f55752565b9060078210156105f55752565b8051821015610eaa5760209160051b010190565b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff81146115455760010190565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b9190811015610eaa5760051b0190565b929091906000915b84518310156115d95761159f8386611504565b51906000828210156115c757506000526020526115c160406000205b92611518565b9161158c565b6040916115c1938252602052206115bb565b915092501490565b60405160208101918252602081526115f881611179565b519020604051602081019182526020815261161281611179565b5190209056fea264697066735822122061e46f346e9c3b1707af4d413b956320d8893a559e1d12a52ca5412751f99fbd64736f6c63430008150033

Constructor Arguments (ABI-Encoded and is the last bytes of the Contract Creation Code above)

0000000000000000000000000ed8c44415e882f3033b4f3aff916bbb4997f91500000000000000000000000070c61dd17b7207b450cb7dedc92c1707a07a1213

-----Decoded View---------------
Arg [0] : factsRegistry (address): 0x0ed8c44415e882F3033B4F3AFF916BbB4997f915
Arg [1] : aggregatorsFactory (address): 0x70C61dd17b7207B450Cb7DeDC92C1707A07a1213

-----Encoded View---------------
2 Constructor Arguments found :
Arg [0] : 0000000000000000000000000ed8c44415e882f3033b4f3aff916bbb4997f915
Arg [1] : 00000000000000000000000070c61dd17b7207b450cb7dedc92c1707a07a1213


Block Transaction Difficulty Gas Used Reward
View All Blocks Produced

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

Validator Index Block Amount
View All Withdrawals

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

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