ETH Price: $2,121.65 (+8.18%)

Contract

0x04c816032A076dF65b411Bb3F31c8d569d411ee2
 

Overview

ETH Balance

0 ETH

Eth Value

$0.00

Token Holdings

More Info

Private Name Tags

Multichain Info

No addresses found
Transaction Hash
Method
Block
From
To

There are no matching entries

> 10 Internal Transactions and > 10 Token Transfers found.

Latest 25 internal transactions (View All)

Advanced mode:
Parent Transaction Hash Method Block
From
To
Prove243978732026-02-06 12:45:5926 days ago1770381959
0x04c81603...69d411ee2
0.00000247 ETH
Transfer243978732026-02-06 12:45:5926 days ago1770381959
0x04c81603...69d411ee2
0.004765 ETH
Fulfill And Prov...243978732026-02-06 12:45:5926 days ago1770381959
0x04c81603...69d411ee2
0.00476747 ETH
Prove243415582026-01-29 15:58:2334 days ago1769702303
0x04c81603...69d411ee2
0.00006839 ETH
Fulfill And Prov...243415582026-01-29 15:58:2334 days ago1769702303
0x04c81603...69d411ee2
0.00006839 ETH
Prove240782142025-12-23 22:11:4771 days ago1766527907
0x04c81603...69d411ee2
0.00006806 ETH
Fulfill And Prov...240782142025-12-23 22:11:4771 days ago1766527907
0x04c81603...69d411ee2
0.00006806 ETH
Prove240781592025-12-23 22:00:4771 days ago1766527247
0x04c81603...69d411ee2
0.00006806 ETH
Fulfill And Prov...240781592025-12-23 22:00:4771 days ago1766527247
0x04c81603...69d411ee2
0.00006806 ETH
Prove240561522025-12-20 20:18:4774 days ago1766261927
0x04c81603...69d411ee2
0.00006806 ETH
Fulfill And Prov...240561522025-12-20 20:18:4774 days ago1766261927
0x04c81603...69d411ee2
0.00006806 ETH
Prove240549652025-12-20 16:19:5974 days ago1766247599
0x04c81603...69d411ee2
0.00006806 ETH
Fulfill And Prov...240549652025-12-20 16:19:5974 days ago1766247599
0x04c81603...69d411ee2
0.00006806 ETH
Prove240544572025-12-20 14:37:5974 days ago1766241479
0x04c81603...69d411ee2
0.00006806 ETH
Fulfill And Prov...240544572025-12-20 14:37:5974 days ago1766241479
0x04c81603...69d411ee2
0.00006806 ETH
Prove240523922025-12-20 7:43:1174 days ago1766216591
0x04c81603...69d411ee2
0.00006806 ETH
Fulfill And Prov...240523922025-12-20 7:43:1174 days ago1766216591
0x04c81603...69d411ee2
0.00006806 ETH
Prove240522942025-12-20 7:23:3574 days ago1766215415
0x04c81603...69d411ee2
0.00006806 ETH
Fulfill And Prov...240522942025-12-20 7:23:3574 days ago1766215415
0x04c81603...69d411ee2
0.00006806 ETH
Prove240401982025-12-18 14:51:3576 days ago1766069495
0x04c81603...69d411ee2
0.00006806 ETH
Fulfill And Prov...240401982025-12-18 14:51:3576 days ago1766069495
0x04c81603...69d411ee2
0.00006806 ETH
Prove238787492025-11-25 22:24:2399 days ago1764109463
0x04c81603...69d411ee2
0.00000024 ETH
Transfer238787492025-11-25 22:24:2399 days ago1764109463
0x04c81603...69d411ee2
0.4963 ETH
Fulfill And Prov...238787492025-11-25 22:24:2399 days ago1764109463
0x04c81603...69d411ee2
0.49630024 ETH
Prove238787402025-11-25 22:22:3599 days ago1764109355
0x04c81603...69d411ee2
0.00000024 ETH
View All Internal Transactions
Loading...
Loading
Loading...
Loading
Cross-Chain Transactions

Block Transaction Difficulty Gas Used Reward
View All Blocks Produced

Validator Index Block Amount
View All Withdrawals

Transaction Hash Block Value Eth2 PubKey Valid
View All Deposits
Loading...
Loading

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

Contract Name:
Inbox

Compiler Version
v0.8.27+commit.40a35a09

Optimization Enabled:
Yes with 200 runs

Other Settings:
cancun EvmVersion

Contract Source Code (Solidity Standard Json-Input format)

// SPDX-License-Identifier: MIT
pragma solidity ^0.8.26;

import {TypeCasts} from "@hyperlane-xyz/core/contracts/libs/TypeCasts.sol";
import {IERC20} from "@openzeppelin/contracts/token/ERC20/IERC20.sol";
import {IProver} from "./interfaces/IProver.sol";
import {Eco7683DestinationSettler} from "./Eco7683DestinationSettler.sol";
import {SafeERC20} from "@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol";
import {IERC165} from "@openzeppelin/contracts/utils/introspection/IERC165.sol";
import {IInbox} from "./interfaces/IInbox.sol";

import {Route, Call, TokenAmount} from "./types/Intent.sol";
import {Semver} from "./libs/Semver.sol";

/**
 * @title Inbox
 * @notice Main entry point for fulfilling intents on the destination chain
 * @dev Validates intent hash authenticity, executes calldata, and enables provers
 * to claim rewards on the source chain by checking the fulfilled mapping
 */
contract Inbox is IInbox, Eco7683DestinationSettler, Semver {
    using TypeCasts for address;
    using SafeERC20 for IERC20;

    /**
     * @notice Interface ID for IProver used to detect prover contracts
     */
    bytes4 public constant IPROVER_INTERFACE_ID = type(IProver).interfaceId;

    /**
     * @notice Mapping of intent hashes to their claimant addresses
     * @dev Stores the address eligible to claim rewards for each fulfilled intent
     */
    mapping(bytes32 => address) public fulfilled;

    /**
     * @notice Initializes the Inbox contract
     */
    constructor() {}

    /**
     * @notice Fulfills an intent to be proven via storage proofs
     * @dev Validates intent hash, executes calls, and marks as fulfilled
     * @param _route The route of the intent
     * @param _rewardHash The hash of the reward details
     * @param _claimant The address that will receive the reward on the source chain
     * @param _expectedHash The hash of the intent as created on the source chain
     * @param _localProver The prover contract to use for verification
     * @return Array of execution results from each call
     */
    function fulfill(
        Route memory _route,
        bytes32 _rewardHash,
        address _claimant,
        bytes32 _expectedHash,
        address _localProver
    ) external payable override returns (bytes[] memory) {
        bytes[] memory result = _fulfill(
            _route,
            _rewardHash,
            _claimant,
            _expectedHash,
            _localProver
        );

        return result;
    }

    /**
     * @notice Fulfills an intent and initiates proving in one transaction
     * @dev Executes intent actions and sends proof message to source chain
     * @param _route The route of the intent
     * @param _rewardHash The hash of the reward details
     * @param _claimant The address that will receive the reward on the source chain
     * @param _expectedHash The hash of the intent as created on the source chain
     * @param _localProver Address of prover on the destination chain
     * @param _data Additional data for message formatting
     * @return Array of execution results
     */
    function fulfillAndProve(
        Route memory _route,
        bytes32 _rewardHash,
        address _claimant,
        bytes32 _expectedHash,
        address _localProver,
        bytes memory _data
    )
        public
        payable
        override(Eco7683DestinationSettler, IInbox)
        returns (bytes[] memory)
    {
        bytes[] memory result = _fulfill(
            _route,
            _rewardHash,
            _claimant,
            _expectedHash,
            _localProver
        );

        bytes32[] memory hashes = new bytes32[](1);
        hashes[0] = _expectedHash;

        initiateProving(_route.source, hashes, _localProver, _data);
        return result;
    }

    /**
     * @notice Initiates proving process for fulfilled intents
     * @dev Sends message to source chain to verify intent execution
     * @param _sourceChainId Chain ID of the source chain
     * @param _intentHashes Array of intent hashes to prove
     * @param _localProver Address of prover on the destination chain
     * @param _data Additional data for message formatting
     */
    function initiateProving(
        uint256 _sourceChainId,
        bytes32[] memory _intentHashes,
        address _localProver,
        bytes memory _data
    ) public payable {
        if (_localProver == address(0)) {
            // storage prover case, this method should do nothing
            return;
        }
        uint256 size = _intentHashes.length;
        address[] memory claimants = new address[](size);
        for (uint256 i = 0; i < size; ++i) {
            address claimant = fulfilled[_intentHashes[i]];

            if (claimant == address(0)) {
                revert IntentNotFulfilled(_intentHashes[i]);
            }
            claimants[i] = claimant;
        }
        IProver(_localProver).prove{value: address(this).balance}(
            msg.sender,
            _sourceChainId,
            _intentHashes,
            claimants,
            _data
        );
    }

    /**
     * @notice Internal function to fulfill intents
     * @dev Validates intent and executes calls
     * @param _route The route of the intent
     * @param _rewardHash The hash of the reward
     * @param _claimant The reward recipient address
     * @param _expectedHash The expected intent hash
     * @param _localProver The prover contract to use
     * @return Array of execution results
     */
    function _fulfill(
        Route memory _route,
        bytes32 _rewardHash,
        address _claimant,
        bytes32 _expectedHash,
        address _localProver
    ) internal returns (bytes[] memory) {
        if (_route.destination != block.chainid) {
            revert WrongChain(_route.destination);
        }

        bytes32 routeHash = keccak256(abi.encode(_route));
        bytes32 intentHash = keccak256(
            abi.encodePacked(routeHash, _rewardHash)
        );

        if (_route.inbox != address(this)) {
            revert InvalidInbox(_route.inbox);
        }
        if (intentHash != _expectedHash) {
            revert InvalidHash(_expectedHash);
        }
        if (fulfilled[intentHash] != address(0)) {
            revert IntentAlreadyFulfilled(intentHash);
        }
        if (_claimant == address(0)) {
            revert ZeroClaimant();
        }

        fulfilled[intentHash] = _claimant;

        emit Fulfillment(_expectedHash, _route.source, _localProver, _claimant);

        uint256 routeTokenCount = _route.tokens.length;
        // Transfer ERC20 tokens to the inbox
        for (uint256 i = 0; i < routeTokenCount; ++i) {
            TokenAmount memory approval = _route.tokens[i];
            IERC20(approval.token).safeTransferFrom(
                msg.sender,
                address(this),
                approval.amount
            );
        }

        // Store the results of the calls
        bytes[] memory results = new bytes[](_route.calls.length);

        for (uint256 i = 0; i < _route.calls.length; ++i) {
            Call memory call = _route.calls[i];
            if (call.target.code.length == 0) {
                if (call.data.length > 0) {
                    // no code at this address
                    revert CallToEOA(call.target);
                }
            } else {
                try
                    IERC165(call.target).supportsInterface(IPROVER_INTERFACE_ID)
                returns (bool isProverCall) {
                    if (isProverCall) {
                        // call to prover
                        revert CallToProver();
                    }
                } catch {
                    // If target doesn't support ERC-165, continue.
                }
            }

            (bool success, bytes memory result) = call.target.call{
                value: call.value
            }(call.data);
            if (!success) {
                revert IntentCallFailed(
                    call.target,
                    call.data,
                    call.value,
                    result
                );
            }
            results[i] = result;
        }
        return (results);
    }

    /**
     * @notice Allows the contract to receive ETH
     * @dev Required for handling ETH transfer for intent execution
     */
    receive() external payable {}
}

// SPDX-License-Identifier: MIT OR Apache-2.0
pragma solidity >=0.6.11;

library TypeCasts {
    // alignment preserving cast
    function addressToBytes32(address _addr) internal pure returns (bytes32) {
        return bytes32(uint256(uint160(_addr)));
    }

    // alignment preserving cast
    function bytes32ToAddress(bytes32 _buf) internal pure returns (address) {
        return address(uint160(uint256(_buf)));
    }
}

// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v5.0.0) (token/ERC20/IERC20.sol)

pragma solidity ^0.8.20;

/**
 * @dev Interface of the ERC20 standard as defined in the EIP.
 */
interface IERC20 {
    /**
     * @dev Emitted when `value` tokens are moved from one account (`from`) to
     * another (`to`).
     *
     * Note that `value` may be zero.
     */
    event Transfer(address indexed from, address indexed to, uint256 value);

    /**
     * @dev Emitted when the allowance of a `spender` for an `owner` is set by
     * a call to {approve}. `value` is the new allowance.
     */
    event Approval(address indexed owner, address indexed spender, uint256 value);

    /**
     * @dev Returns the value of tokens in existence.
     */
    function totalSupply() external view returns (uint256);

    /**
     * @dev Returns the value of tokens owned by `account`.
     */
    function balanceOf(address account) external view returns (uint256);

    /**
     * @dev Moves a `value` amount of tokens from the caller's account to `to`.
     *
     * Returns a boolean value indicating whether the operation succeeded.
     *
     * Emits a {Transfer} event.
     */
    function transfer(address to, uint256 value) external returns (bool);

    /**
     * @dev Returns the remaining number of tokens that `spender` will be
     * allowed to spend on behalf of `owner` through {transferFrom}. This is
     * zero by default.
     *
     * This value changes when {approve} or {transferFrom} are called.
     */
    function allowance(address owner, address spender) external view returns (uint256);

    /**
     * @dev Sets a `value` amount of tokens as the allowance of `spender` over the
     * caller's tokens.
     *
     * Returns a boolean value indicating whether the operation succeeded.
     *
     * IMPORTANT: Beware that changing an allowance with this method brings the risk
     * that someone may use both the old and the new allowance by unfortunate
     * transaction ordering. One possible solution to mitigate this race
     * condition is to first reduce the spender's allowance to 0 and set the
     * desired value afterwards:
     * https://github.com/ethereum/EIPs/issues/20#issuecomment-263524729
     *
     * Emits an {Approval} event.
     */
    function approve(address spender, uint256 value) external returns (bool);

    /**
     * @dev Moves a `value` amount of tokens from `from` to `to` using the
     * allowance mechanism. `value` is then deducted from the caller's
     * allowance.
     *
     * Returns a boolean value indicating whether the operation succeeded.
     *
     * Emits a {Transfer} event.
     */
    function transferFrom(address from, address to, uint256 value) external returns (bool);
}

// SPDX-License-Identifier: MIT
pragma solidity ^0.8.26;

import {ISemver} from "./ISemver.sol";
import {Intent} from "../types/Intent.sol";

/**
 * @title IProver
 * @notice Interface for proving intent fulfillment
 * @dev Defines required functionality for proving intent execution with different
 * proof mechanisms (storage or Hyperlane)
 */
interface IProver is ISemver {
    struct ProofData {
        uint96 destinationChainID;
        address claimant;
    }

    /**
     * @notice Arrays of intent hashes and claimants must have the same length
     */
    error ArrayLengthMismatch();

    /**
     * @notice Destination chain ID associated with intent does not match that in proof.
     * @param _hash Hash of the intent
     * @param _expectedDestinationChainID Expected destination chain ID for the intent
     * @param _actualDestinationChainID Actual destination chain ID for the intent
     */
    error BadDestinationChainID(
        bytes32 _hash,
        uint96 _expectedDestinationChainID,
        uint96 _actualDestinationChainID
    );

    /**
     * @notice Emitted when an intent is successfully proven
     * @param _hash Hash of the proven intent
     * @param _claimant Address eligible to claim the intent's rewards
     */
    event IntentProven(bytes32 indexed _hash, address indexed _claimant);

    /**
     * @notice Emitted when attempting to prove an already-proven intent
     * @dev Event instead of error to allow batch processing to continue
     * @param _intentHash Hash of the already proven intent
     */
    event IntentAlreadyProven(bytes32 _intentHash);

    /**
     * @notice Fetches a ProofData from the provenIntents mapping
     * @param _intentHash the hash of the intent whose proof data is being queried
     * @return ProofData struct containing the destination chain ID and claimant address
     */
    function provenIntents(
        bytes32 _intentHash
    ) external view returns (ProofData memory);

    /**
     * @notice Gets the proof mechanism type used by this prover
     * @return string indicating the prover's mechanism
     */
    function getProofType() external pure returns (string memory);

    /**
     * @notice Initiates the proving process for intents from the destination chain
     * @dev Implemented by specific prover mechanisms (storage, Hyperlane, Metalayer)
     * @param _sender Address of the original transaction sender
     * @param _sourceChainId Chain ID of the source chain
     * @param _intentHashes Array of intent hashes to prove
     * @param _claimants Array of claimant addresses
     * @param _data Additional data specific to the proving implementation
     */
    function prove(
        address _sender,
        uint256 _sourceChainId,
        bytes32[] calldata _intentHashes,
        address[] calldata _claimants,
        bytes calldata _data
    ) external payable;

    /**
     * @notice Challenges a recorded proof
     * @param _intent Intent to challenge
     * @dev Clears the proof if the destination chain ID in the intent does not match the one in the proof
     * @dev even if not challenged, an incorrect proof cannot be used to claim rewards.
     * @dev does nothing if chainID is correct
     */
    function challengeIntentProof(Intent calldata _intent) external;
}

File 5 of 14 : Eco7683DestinationSettler.sol
/* -*- c-basic-offset: 4 -*- */
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.26;

import {IDestinationSettler} from "./interfaces/ERC7683/IDestinationSettler.sol";
import {Intent, Route} from "./types/Intent.sol";

abstract contract Eco7683DestinationSettler is IDestinationSettler {
    /**
     * @notice Fills a single leg of a particular order on the destination chain
     * @dev _originData is of type OnchainCrossChainOrder
     * @dev _fillerData is encoded bytes consisting of the claimant address and any additional data required for the chosen prover
     * @param _orderId Unique identifier for the order being filled
     * @param _originData Data emitted on the origin chain to parameterize the fill, equivalent to the originData field from the fillInstruction of the ResolvedCrossChainOrder. An encoded Intent struct.
     * @param _fillerData Data provided by the filler to inform the fill or express their preferences
     * @dev _fillerdata should contain the address of the claimant, the address of the prover on the destination chain, and any additional data required for the chosen prover, and any additional data required for the chosen prover
     */
    function fill(
        bytes32 _orderId,
        bytes calldata _originData,
        bytes calldata _fillerData
    ) external payable {
        Intent memory intent = abi.decode(_originData, (Intent));
        if (block.timestamp > intent.reward.deadline) {
            revert FillDeadlinePassed();
        }

        emit OrderFilled(_orderId, msg.sender);

        bytes32 rewardHash = keccak256(abi.encode(intent.reward));
        (address claimant, address localProver, bytes memory data) = abi.decode(
            _fillerData,
            (address, address, bytes)
        );
        fulfillAndProve(
            intent.route,
            rewardHash,
            claimant,
            _orderId,
            localProver,
            data
        );
    }

    function fulfillAndProve(
        Route memory _route,
        bytes32 _rewardHash,
        address _claimant,
        bytes32 _expectedHash,
        address _localProver,
        bytes memory _data
    ) public payable virtual returns (bytes[] memory);
}

// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v5.0.0) (token/ERC20/utils/SafeERC20.sol)

pragma solidity ^0.8.20;

import {IERC20} from "../IERC20.sol";
import {IERC20Permit} from "../extensions/IERC20Permit.sol";
import {Address} from "../../../utils/Address.sol";

/**
 * @title SafeERC20
 * @dev Wrappers around ERC20 operations that throw on failure (when the token
 * contract returns false). Tokens that return no value (and instead revert or
 * throw on failure) are also supported, non-reverting calls are assumed to be
 * successful.
 * To use this library you can add a `using SafeERC20 for IERC20;` statement to your contract,
 * which allows you to call the safe operations as `token.safeTransfer(...)`, etc.
 */
library SafeERC20 {
    using Address for address;

    /**
     * @dev An operation with an ERC20 token failed.
     */
    error SafeERC20FailedOperation(address token);

    /**
     * @dev Indicates a failed `decreaseAllowance` request.
     */
    error SafeERC20FailedDecreaseAllowance(address spender, uint256 currentAllowance, uint256 requestedDecrease);

    /**
     * @dev Transfer `value` amount of `token` from the calling contract to `to`. If `token` returns no value,
     * non-reverting calls are assumed to be successful.
     */
    function safeTransfer(IERC20 token, address to, uint256 value) internal {
        _callOptionalReturn(token, abi.encodeCall(token.transfer, (to, value)));
    }

    /**
     * @dev Transfer `value` amount of `token` from `from` to `to`, spending the approval given by `from` to the
     * calling contract. If `token` returns no value, non-reverting calls are assumed to be successful.
     */
    function safeTransferFrom(IERC20 token, address from, address to, uint256 value) internal {
        _callOptionalReturn(token, abi.encodeCall(token.transferFrom, (from, to, value)));
    }

    /**
     * @dev Increase the calling contract's allowance toward `spender` by `value`. If `token` returns no value,
     * non-reverting calls are assumed to be successful.
     */
    function safeIncreaseAllowance(IERC20 token, address spender, uint256 value) internal {
        uint256 oldAllowance = token.allowance(address(this), spender);
        forceApprove(token, spender, oldAllowance + value);
    }

    /**
     * @dev Decrease the calling contract's allowance toward `spender` by `requestedDecrease`. If `token` returns no
     * value, non-reverting calls are assumed to be successful.
     */
    function safeDecreaseAllowance(IERC20 token, address spender, uint256 requestedDecrease) internal {
        unchecked {
            uint256 currentAllowance = token.allowance(address(this), spender);
            if (currentAllowance < requestedDecrease) {
                revert SafeERC20FailedDecreaseAllowance(spender, currentAllowance, requestedDecrease);
            }
            forceApprove(token, spender, currentAllowance - requestedDecrease);
        }
    }

    /**
     * @dev Set the calling contract's allowance toward `spender` to `value`. If `token` returns no value,
     * non-reverting calls are assumed to be successful. Meant to be used with tokens that require the approval
     * to be set to zero before setting it to a non-zero value, such as USDT.
     */
    function forceApprove(IERC20 token, address spender, uint256 value) internal {
        bytes memory approvalCall = abi.encodeCall(token.approve, (spender, value));

        if (!_callOptionalReturnBool(token, approvalCall)) {
            _callOptionalReturn(token, abi.encodeCall(token.approve, (spender, 0)));
            _callOptionalReturn(token, approvalCall);
        }
    }

    /**
     * @dev Imitates a Solidity high-level call (i.e. a regular function call to a contract), relaxing the requirement
     * on the return value: the return value is optional (but if data is returned, it must not be false).
     * @param token The token targeted by the call.
     * @param data The call data (encoded using abi.encode or one of its variants).
     */
    function _callOptionalReturn(IERC20 token, bytes memory data) private {
        // We need to perform a low level call here, to bypass Solidity's return data size checking mechanism, since
        // we're implementing it ourselves. We use {Address-functionCall} to perform this call, which verifies that
        // the target address contains contract code and also asserts for success in the low-level call.

        bytes memory returndata = address(token).functionCall(data);
        if (returndata.length != 0 && !abi.decode(returndata, (bool))) {
            revert SafeERC20FailedOperation(address(token));
        }
    }

    /**
     * @dev Imitates a Solidity high-level call (i.e. a regular function call to a contract), relaxing the requirement
     * on the return value: the return value is optional (but if data is returned, it must not be false).
     * @param token The token targeted by the call.
     * @param data The call data (encoded using abi.encode or one of its variants).
     *
     * This is a variant of {_callOptionalReturn} that silents catches all reverts and returns a bool instead.
     */
    function _callOptionalReturnBool(IERC20 token, bytes memory data) private returns (bool) {
        // We need to perform a low level call here, to bypass Solidity's return data size checking mechanism, since
        // we're implementing it ourselves. We cannot use {Address-functionCall} here since this should return false
        // and not revert is the subcall reverts.

        (bool success, bytes memory returndata) = address(token).call(data);
        return success && (returndata.length == 0 || abi.decode(returndata, (bool))) && address(token).code.length > 0;
    }
}

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

pragma solidity ^0.8.20;

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

// SPDX-License-Identifier: MIT
pragma solidity ^0.8.26;

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

import {Route} from "../types/Intent.sol";

/**
 * @title IInbox
 * @notice Interface for the destination chain portion of the Eco Protocol's intent system
 * @dev Handles intent fulfillment and proving via different mechanisms (storage proofs,
 * Hyperlane instant/batched)
 */
interface IInbox is ISemver {
    /**
     * @notice Emitted when an intent is successfully fulfilled
     * @param _hash Hash of the fulfilled intent
     * @param _sourceChainID ID of the source chain
     * @param _prover Address of the prover that fulfilled the intent
     * @param _claimant Address eligible to claim rewards
     */
    event Fulfillment(
        bytes32 indexed _hash,
        uint256 indexed _sourceChainID,
        address indexed _prover,
        address _claimant
    );

    /**
     * @notice Thrown when an attempt is made to fulfill an intent on the wrong destination chain
     * @param _chainID Chain ID of the destination chain on which this intent should be fulfilled
     */
    error WrongChain(uint256 _chainID);

    /**
     * @notice Intent has already been fulfilled
     * @param _hash Hash of the fulfilled intent
     */
    error IntentAlreadyFulfilled(bytes32 _hash);

    /**
     * @notice Invalid inbox address provided
     * @param _inbox Address that is not a valid inbox
     */
    error InvalidInbox(address _inbox);

    /**
     * @notice Generated hash doesn't match expected hash
     * @param _expectedHash Hash that was expected
     */
    error InvalidHash(bytes32 _expectedHash);

    /**
     * @notice Zero address provided as claimant
     */
    error ZeroClaimant();

    /**
     * @notice Call during intent execution failed
     * @param _addr Target contract address
     * @param _data Call data that failed
     * @param value Native token value sent
     * @param _returnData Error data returned
     */
    error IntentCallFailed(
        address _addr,
        bytes _data,
        uint256 value,
        bytes _returnData
    );

    /**
     * @notice Attempted call to a destination-chain prover
     */
    error CallToProver();

    /**
     * @notice Attempted call to an EOA
     * @param _EOA EOA address to which call was attempted
     */
    error CallToEOA(address _EOA);

    /**
     * @notice Attempted to batch an unfulfilled intent
     * @param _hash Hash of the unfulfilled intent
     */
    error IntentNotFulfilled(bytes32 _hash);

    /**
     * @notice Fulfills an intent using storage proofs
     * @dev Validates intent hash, executes calls, and marks as fulfilled
     * @param _route Route information for the intent
     * @param _rewardHash Hash of the reward details
     * @param _claimant Address eligible to claim rewards
     * @param _expectedHash Expected hash for validation
     * @return Array of execution results
     */
    function fulfill(
        Route calldata _route,
        bytes32 _rewardHash,
        address _claimant,
        bytes32 _expectedHash,
        address _localProver
    ) external payable returns (bytes[] memory);

    /**
     * @notice Fulfills an intent using storage proofs
     * @dev Validates intent hash, executes calls, and marks as fulfilled
     * @param _route Route information for the intent
     * @param _rewardHash Hash of the reward details
     * @param _claimant Address eligible to claim rewards
     * @param _expectedHash Expected hash for validation
     * @param _localProver Address of prover on the destination chain
     * @param _data Additional data for message formatting
     * @return Array of execution results
     */
    function fulfillAndProve(
        Route calldata _route,
        bytes32 _rewardHash,
        address _claimant,
        bytes32 _expectedHash,
        address _localProver,
        bytes calldata _data
    ) external payable returns (bytes[] memory);

    /**
     * @notice Initiates proving process for fulfilled intents
     * @dev Sends message to source chain to verify intent execution
     * @param _sourceChainId Chain ID of the source chain
     * @param _intentHashes Array of intent hashes to prove
     * @param _localProver Address of prover on the destination chain
     * @param _data Additional data for message formatting
     */
    function initiateProving(
        uint256 _sourceChainId,
        bytes32[] memory _intentHashes,
        address _localProver,
        bytes memory _data
    ) external payable;
}

File 9 of 14 : Intent.sol
/* -*- c-basic-offset: 4 -*- */
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.26;

/**
 * @notice Represents a single contract call with encoded function data
 * @dev Used to execute arbitrary function calls on the destination chain
 * @param target The contract address to call
 * @param data ABI-encoded function call data
 * @param value Amount of native tokens to send with the call
 */
struct Call {
    address target;
    bytes data;
    uint256 value;
}

/**
 * @notice Represents a token amount pair
 * @dev Used to specify token rewards and transfers
 * @param token Address of the ERC20 token contract
 * @param amount Amount of tokens in the token's smallest unit
 */
struct TokenAmount {
    address token;
    uint256 amount;
}

/**
 * @notice Defines the routing and execution instructions for cross-chain messages
 * @dev Contains all necessary information to route and execute a message on the destination chain
 * @param salt Unique identifier provided by the intent creator, used to prevent duplicates
 * @param source Chain ID where the intent originated
 * @param destination Target chain ID where the calls should be executed
 * @param inbox Address of the inbox contract on the destination chain that receives messages
 * @param tokens Array of tokens required for execution of calls on destination chain
 * @param calls Array of contract calls to execute on the destination chain in sequence
 */
struct Route {
    bytes32 salt;
    uint256 source;
    uint256 destination;
    address inbox;
    TokenAmount[] tokens;
    Call[] calls;
}

/**
 * @notice Defines the reward and validation parameters for cross-chain execution
 * @dev Specifies who can execute the intent and what rewards they receive
 * @param creator Address that created the intent and has authority to modify/cancel
 * @param prover Address of the prover contract that must approve execution
 * @param deadline Timestamp after which the intent can no longer be executed
 * @param nativeValue Amount of native tokens offered as reward
 * @param tokens Array of ERC20 tokens and amounts offered as additional rewards
 */
struct Reward {
    address creator;
    address prover;
    uint256 deadline;
    uint256 nativeValue;
    TokenAmount[] tokens;
}

/**
 * @notice Complete cross-chain intent combining routing and reward information
 * @dev Main structure used to process and execute cross-chain messages
 * @param route Routing and execution instructions
 * @param reward Reward and validation parameters
 */
struct Intent {
    Route route;
    Reward reward;
}

File 10 of 14 : Semver.sol
// SPDX-License-Identifier: UNLICENSED
pragma solidity ^0.8.26;

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

/**
 * @title Semver
 * @notice Implements semantic versioning for contracts
 * @dev Abstract contract that provides a standard way to access version information
 */
abstract contract Semver is ISemver {
    /**
     * @notice Returns the semantic version of the contract
     * @dev Implementation of ISemver interface
     * @return Current version string in semantic format
     */
    function version() external pure returns (string memory) {
        return "2.6";
    }
}

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

/**
 * @title Semver Interface
 * @dev An interface for a contract that has a version
 */
interface ISemver {
    function version() external pure returns (string memory);
}

File 12 of 14 : IDestinationSettler.sol
/* -*- c-basic-offset: 4 -*- */
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.26;

/**
 * @title IDestinationSettler
 * @notice Standard interface for settlement contracts on the destination chain
 */
interface IDestinationSettler {
    /**
     * @notice Emitted when an intent is fulfilled
     * @param _orderId Hash of the fulfilled intent
     * @param _solver Address that fulfilled the intent
     */
    event OrderFilled(bytes32 _orderId, address _solver);

    /// @notice Thrown when attempting to fill an order after the fill deadline has passed
    error FillDeadlinePassed();

    /**
     * @notice Fills a single leg of a particular order on the destination chain
     * @dev This method has been made payable, in contrast to original interface
     * @param orderId Unique order identifier for this order
     * @param originData Data emitted on the origin to parameterize the fill
     * @param fillerData Data provided by the filler to inform the fill or express their preferences
     */
    function fill(
        bytes32 orderId,
        bytes calldata originData,
        bytes calldata fillerData
    ) external payable;
}

// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v5.0.0) (token/ERC20/extensions/IERC20Permit.sol)

pragma solidity ^0.8.20;

/**
 * @dev Interface of the ERC20 Permit extension allowing approvals to be made via signatures, as defined in
 * https://eips.ethereum.org/EIPS/eip-2612[EIP-2612].
 *
 * Adds the {permit} method, which can be used to change an account's ERC20 allowance (see {IERC20-allowance}) by
 * presenting a message signed by the account. By not relying on {IERC20-approve}, the token holder account doesn't
 * need to send a transaction, and thus is not required to hold Ether at all.
 *
 * ==== Security Considerations
 *
 * There are two important considerations concerning the use of `permit`. The first is that a valid permit signature
 * expresses an allowance, and it should not be assumed to convey additional meaning. In particular, it should not be
 * considered as an intention to spend the allowance in any specific way. The second is that because permits have
 * built-in replay protection and can be submitted by anyone, they can be frontrun. A protocol that uses permits should
 * take this into consideration and allow a `permit` call to fail. Combining these two aspects, a pattern that may be
 * generally recommended is:
 *
 * ```solidity
 * function doThingWithPermit(..., uint256 value, uint256 deadline, uint8 v, bytes32 r, bytes32 s) public {
 *     try token.permit(msg.sender, address(this), value, deadline, v, r, s) {} catch {}
 *     doThing(..., value);
 * }
 *
 * function doThing(..., uint256 value) public {
 *     token.safeTransferFrom(msg.sender, address(this), value);
 *     ...
 * }
 * ```
 *
 * Observe that: 1) `msg.sender` is used as the owner, leaving no ambiguity as to the signer intent, and 2) the use of
 * `try/catch` allows the permit to fail and makes the code tolerant to frontrunning. (See also
 * {SafeERC20-safeTransferFrom}).
 *
 * Additionally, note that smart contract wallets (such as Argent or Safe) are not able to produce permit signatures, so
 * contracts should have entry points that don't rely on permit.
 */
interface IERC20Permit {
    /**
     * @dev Sets `value` as the allowance of `spender` over ``owner``'s tokens,
     * given ``owner``'s signed approval.
     *
     * IMPORTANT: The same issues {IERC20-approve} has related to transaction
     * ordering also apply here.
     *
     * Emits an {Approval} event.
     *
     * Requirements:
     *
     * - `spender` cannot be the zero address.
     * - `deadline` must be a timestamp in the future.
     * - `v`, `r` and `s` must be a valid `secp256k1` signature from `owner`
     * over the EIP712-formatted function arguments.
     * - the signature must use ``owner``'s current nonce (see {nonces}).
     *
     * For more information on the signature format, see the
     * https://eips.ethereum.org/EIPS/eip-2612#specification[relevant EIP
     * section].
     *
     * CAUTION: See Security Considerations above.
     */
    function permit(
        address owner,
        address spender,
        uint256 value,
        uint256 deadline,
        uint8 v,
        bytes32 r,
        bytes32 s
    ) external;

    /**
     * @dev Returns the current nonce for `owner`. This value must be
     * included whenever a signature is generated for {permit}.
     *
     * Every successful call to {permit} increases ``owner``'s nonce by one. This
     * prevents a signature from being used multiple times.
     */
    function nonces(address owner) external view returns (uint256);

    /**
     * @dev Returns the domain separator used in the encoding of the signature for {permit}, as defined by {EIP712}.
     */
    // solhint-disable-next-line func-name-mixedcase
    function DOMAIN_SEPARATOR() external view returns (bytes32);
}

// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v5.0.0) (utils/Address.sol)

pragma solidity ^0.8.20;

/**
 * @dev Collection of functions related to the address type
 */
library Address {
    /**
     * @dev The ETH balance of the account is not enough to perform the operation.
     */
    error AddressInsufficientBalance(address account);

    /**
     * @dev There's no code at `target` (it is not a contract).
     */
    error AddressEmptyCode(address target);

    /**
     * @dev A call to an address target failed. The target may have reverted.
     */
    error FailedInnerCall();

    /**
     * @dev Replacement for Solidity's `transfer`: sends `amount` wei to
     * `recipient`, forwarding all available gas and reverting on errors.
     *
     * https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost
     * of certain opcodes, possibly making contracts go over the 2300 gas limit
     * imposed by `transfer`, making them unable to receive funds via
     * `transfer`. {sendValue} removes this limitation.
     *
     * https://consensys.net/diligence/blog/2019/09/stop-using-soliditys-transfer-now/[Learn more].
     *
     * IMPORTANT: because control is transferred to `recipient`, care must be
     * taken to not create reentrancy vulnerabilities. Consider using
     * {ReentrancyGuard} or the
     * https://solidity.readthedocs.io/en/v0.8.20/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern].
     */
    function sendValue(address payable recipient, uint256 amount) internal {
        if (address(this).balance < amount) {
            revert AddressInsufficientBalance(address(this));
        }

        (bool success, ) = recipient.call{value: amount}("");
        if (!success) {
            revert FailedInnerCall();
        }
    }

    /**
     * @dev Performs a Solidity function call using a low level `call`. A
     * plain `call` is an unsafe replacement for a function call: use this
     * function instead.
     *
     * If `target` reverts with a revert reason or custom error, it is bubbled
     * up by this function (like regular Solidity function calls). However, if
     * the call reverted with no returned reason, this function reverts with a
     * {FailedInnerCall} error.
     *
     * Returns the raw returned data. To convert to the expected return value,
     * use https://solidity.readthedocs.io/en/latest/units-and-global-variables.html?highlight=abi.decode#abi-encoding-and-decoding-functions[`abi.decode`].
     *
     * Requirements:
     *
     * - `target` must be a contract.
     * - calling `target` with `data` must not revert.
     */
    function functionCall(address target, bytes memory data) internal returns (bytes memory) {
        return functionCallWithValue(target, data, 0);
    }

    /**
     * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],
     * but also transferring `value` wei to `target`.
     *
     * Requirements:
     *
     * - the calling contract must have an ETH balance of at least `value`.
     * - the called Solidity function must be `payable`.
     */
    function functionCallWithValue(address target, bytes memory data, uint256 value) internal returns (bytes memory) {
        if (address(this).balance < value) {
            revert AddressInsufficientBalance(address(this));
        }
        (bool success, bytes memory returndata) = target.call{value: value}(data);
        return verifyCallResultFromTarget(target, success, returndata);
    }

    /**
     * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],
     * but performing a static call.
     */
    function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) {
        (bool success, bytes memory returndata) = target.staticcall(data);
        return verifyCallResultFromTarget(target, success, returndata);
    }

    /**
     * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],
     * but performing a delegate call.
     */
    function functionDelegateCall(address target, bytes memory data) internal returns (bytes memory) {
        (bool success, bytes memory returndata) = target.delegatecall(data);
        return verifyCallResultFromTarget(target, success, returndata);
    }

    /**
     * @dev Tool to verify that a low level call to smart-contract was successful, and reverts if the target
     * was not a contract or bubbling up the revert reason (falling back to {FailedInnerCall}) in case of an
     * unsuccessful call.
     */
    function verifyCallResultFromTarget(
        address target,
        bool success,
        bytes memory returndata
    ) internal view returns (bytes memory) {
        if (!success) {
            _revert(returndata);
        } else {
            // only check if target is a contract if the call was successful and the return data is empty
            // otherwise we already know that it was a contract
            if (returndata.length == 0 && target.code.length == 0) {
                revert AddressEmptyCode(target);
            }
            return returndata;
        }
    }

    /**
     * @dev Tool to verify that a low level call was successful, and reverts if it wasn't, either by bubbling the
     * revert reason or with a default {FailedInnerCall} error.
     */
    function verifyCallResult(bool success, bytes memory returndata) internal pure returns (bytes memory) {
        if (!success) {
            _revert(returndata);
        } else {
            return returndata;
        }
    }

    /**
     * @dev Reverts with returndata if present. Otherwise reverts with {FailedInnerCall}.
     */
    function _revert(bytes memory returndata) private pure {
        // Look for revert reason and bubble it up if present
        if (returndata.length > 0) {
            // The easiest way to bubble the revert reason is using memory via assembly
            /// @solidity memory-safe-assembly
            assembly {
                let returndata_size := mload(returndata)
                revert(add(32, returndata), returndata_size)
            }
        } else {
            revert FailedInnerCall();
        }
    }
}

Settings
{
  "remappings": [
    "forge-std/=lib/forge-std/src/",
    "@openzeppelin/contracts/=node_modules/@openzeppelin/contracts/",
    "@openzeppelin/contracts-upgradeable/=node_modules/@openzeppelin/contracts-upgradeable/",
    "@hyperlane-xyz/core/=node_modules/@hyperlane-xyz/core/",
    "@eth-optimism/contracts-bedrock/=node_modules/@eth-optimism/contracts-bedrock/",
    "@metalayer/contracts/=node_modules/@metalayer/contracts/",
    "erc4626-tests/=lib/openzeppelin-contracts-upgradeable/lib/erc4626-tests/",
    "halmos-cheatcodes/=lib/openzeppelin-contracts-upgradeable/lib/halmos-cheatcodes/src/",
    "openzeppelin-contracts-upgradeable/=lib/openzeppelin-contracts-upgradeable/",
    "openzeppelin-contracts/=lib/openzeppelin-contracts-upgradeable/lib/openzeppelin-contracts/"
  ],
  "optimizer": {
    "enabled": true,
    "runs": 200
  },
  "metadata": {
    "useLiteralContent": false,
    "bytecodeHash": "none",
    "appendCBOR": false
  },
  "outputSelection": {
    "*": {
      "*": [
        "evm.bytecode",
        "evm.deployedBytecode",
        "devdoc",
        "userdoc",
        "metadata",
        "abi"
      ]
    }
  },
  "evmVersion": "cancun",
  "viaIR": true,
  "libraries": {}
}

Contract Security Audit

Contract ABI

API
[{"inputs":[],"stateMutability":"nonpayable","type":"constructor"},{"inputs":[{"internalType":"address","name":"target","type":"address"}],"name":"AddressEmptyCode","type":"error"},{"inputs":[{"internalType":"address","name":"account","type":"address"}],"name":"AddressInsufficientBalance","type":"error"},{"inputs":[{"internalType":"address","name":"_EOA","type":"address"}],"name":"CallToEOA","type":"error"},{"inputs":[],"name":"CallToProver","type":"error"},{"inputs":[],"name":"FailedInnerCall","type":"error"},{"inputs":[],"name":"FillDeadlinePassed","type":"error"},{"inputs":[{"internalType":"bytes32","name":"_hash","type":"bytes32"}],"name":"IntentAlreadyFulfilled","type":"error"},{"inputs":[{"internalType":"address","name":"_addr","type":"address"},{"internalType":"bytes","name":"_data","type":"bytes"},{"internalType":"uint256","name":"value","type":"uint256"},{"internalType":"bytes","name":"_returnData","type":"bytes"}],"name":"IntentCallFailed","type":"error"},{"inputs":[{"internalType":"bytes32","name":"_hash","type":"bytes32"}],"name":"IntentNotFulfilled","type":"error"},{"inputs":[{"internalType":"bytes32","name":"_expectedHash","type":"bytes32"}],"name":"InvalidHash","type":"error"},{"inputs":[{"internalType":"address","name":"_inbox","type":"address"}],"name":"InvalidInbox","type":"error"},{"inputs":[{"internalType":"address","name":"token","type":"address"}],"name":"SafeERC20FailedOperation","type":"error"},{"inputs":[{"internalType":"uint256","name":"_chainID","type":"uint256"}],"name":"WrongChain","type":"error"},{"inputs":[],"name":"ZeroClaimant","type":"error"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"bytes32","name":"_hash","type":"bytes32"},{"indexed":true,"internalType":"uint256","name":"_sourceChainID","type":"uint256"},{"indexed":true,"internalType":"address","name":"_prover","type":"address"},{"indexed":false,"internalType":"address","name":"_claimant","type":"address"}],"name":"Fulfillment","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"bytes32","name":"_orderId","type":"bytes32"},{"indexed":false,"internalType":"address","name":"_solver","type":"address"}],"name":"OrderFilled","type":"event"},{"inputs":[],"name":"IPROVER_INTERFACE_ID","outputs":[{"internalType":"bytes4","name":"","type":"bytes4"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes32","name":"_orderId","type":"bytes32"},{"internalType":"bytes","name":"_originData","type":"bytes"},{"internalType":"bytes","name":"_fillerData","type":"bytes"}],"name":"fill","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[{"components":[{"internalType":"bytes32","name":"salt","type":"bytes32"},{"internalType":"uint256","name":"source","type":"uint256"},{"internalType":"uint256","name":"destination","type":"uint256"},{"internalType":"address","name":"inbox","type":"address"},{"components":[{"internalType":"address","name":"token","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"}],"internalType":"struct TokenAmount[]","name":"tokens","type":"tuple[]"},{"components":[{"internalType":"address","name":"target","type":"address"},{"internalType":"bytes","name":"data","type":"bytes"},{"internalType":"uint256","name":"value","type":"uint256"}],"internalType":"struct Call[]","name":"calls","type":"tuple[]"}],"internalType":"struct Route","name":"_route","type":"tuple"},{"internalType":"bytes32","name":"_rewardHash","type":"bytes32"},{"internalType":"address","name":"_claimant","type":"address"},{"internalType":"bytes32","name":"_expectedHash","type":"bytes32"},{"internalType":"address","name":"_localProver","type":"address"}],"name":"fulfill","outputs":[{"internalType":"bytes[]","name":"","type":"bytes[]"}],"stateMutability":"payable","type":"function"},{"inputs":[{"components":[{"internalType":"bytes32","name":"salt","type":"bytes32"},{"internalType":"uint256","name":"source","type":"uint256"},{"internalType":"uint256","name":"destination","type":"uint256"},{"internalType":"address","name":"inbox","type":"address"},{"components":[{"internalType":"address","name":"token","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"}],"internalType":"struct TokenAmount[]","name":"tokens","type":"tuple[]"},{"components":[{"internalType":"address","name":"target","type":"address"},{"internalType":"bytes","name":"data","type":"bytes"},{"internalType":"uint256","name":"value","type":"uint256"}],"internalType":"struct Call[]","name":"calls","type":"tuple[]"}],"internalType":"struct Route","name":"_route","type":"tuple"},{"internalType":"bytes32","name":"_rewardHash","type":"bytes32"},{"internalType":"address","name":"_claimant","type":"address"},{"internalType":"bytes32","name":"_expectedHash","type":"bytes32"},{"internalType":"address","name":"_localProver","type":"address"},{"internalType":"bytes","name":"_data","type":"bytes"}],"name":"fulfillAndProve","outputs":[{"internalType":"bytes[]","name":"","type":"bytes[]"}],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"name":"fulfilled","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"_sourceChainId","type":"uint256"},{"internalType":"bytes32[]","name":"_intentHashes","type":"bytes32[]"},{"internalType":"address","name":"_localProver","type":"address"},{"internalType":"bytes","name":"_data","type":"bytes"}],"name":"initiateProving","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[],"name":"version","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"pure","type":"function"},{"stateMutability":"payable","type":"receive"}]

0x6080806040523460155761103a908161001a8239f35b5f80fdfe6080604052600436101561001a575b3615610018575f80fd5b005b5f3560e01c8063115f9a971461043c5780632aa91bfd1461040b57806337e312dc1461039a57806354fd4d50146103555780637b93f2181461033357806382e2c43f146100cf5763af9d22cf0361000e5760a03660031901126100cb576004356001600160401b0381116100cb576100bb61009c6100c7923690600401610666565b6100a461053e565b906100ad610554565b916064359160243590610b20565b604051918291826107f3565b0390f35b5f80fd5b60603660031901126100cb576004356024356001600160401b0381116100cb576100fd903690600401610852565b90916044356001600160401b0381116100cb5761011e903690600401610852565b9190928401936020818603126100cb578035906001600160401b0382116100cb5701936040858203126100cb5760405194610158866104eb565b80356001600160401b0381116100cb5782610174918301610666565b86526020810135906001600160401b0382116100cb57019060a0828203126100cb576040519160a083018381106001600160401b0382111761031f576040526101bc8161056a565b83526101ca6020820161056a565b60208401526040830191604082013583526060820135606085015260808201356001600160401b0381116100cb5761020292016105df565b608083015260208601918252514211610310577f0555709e59fb225fcf12cc582a9e5f7fd8eea54c91f3dc500ab9d8c37c50777060408051848152336020820152a1516040516102af816102a1608060208301956020875260018060a01b03815116604085015260018060a01b036020820151166060850152604081015182850152606081015160a0850152015160a060c084015260e0830190610a91565b03601f198101835282610506565b519020918301936060848603126100cb576102c98461056a565b926102d66020860161056a565b946040810135966001600160401b0388116100cb57610018976102f99201610599565b915191946001600160a01b03908116941691610a48565b6302857b7560e01b5f5260045ffd5b634e487b7160e01b5f52604160045260245ffd5b346100cb575f3660031901126100cb576040516308eacdfb60e21b8152602090f35b346100cb575f3660031901126100cb576100c7604051610376604082610506565b600381526219171b60e91b60208201526040519182916020835260208301906107cf565b60c03660031901126100cb576004356001600160401b0381116100cb576103c5903690600401610666565b6103cd61053e565b6103d5610554565b9060a435916001600160401b0383116100cb576100c7936103fd6100bb943690600401610599565b926064359160243590610a48565b346100cb5760203660031901126100cb576004355f525f602052602060018060a01b0360405f205416604051908152f35b60803660031901126100cb576024356001600160401b0381116100cb57366023820112156100cb5780600401359061047382610527565b916104816040519384610506565b8083526024602084019160051b830101913683116100cb57602401905b8282106104db57836104ae61053e565b90606435916001600160401b0383116100cb576104d2610018933690600401610599565b916004356108a7565b813581526020918201910161049e565b604081019081106001600160401b0382111761031f57604052565b90601f801991011681019081106001600160401b0382111761031f57604052565b6001600160401b03811161031f5760051b60200190565b604435906001600160a01b03821682036100cb57565b608435906001600160a01b03821682036100cb57565b35906001600160a01b03821682036100cb57565b6001600160401b03811161031f57601f01601f191660200190565b81601f820112156100cb578035906105b08261057e565b926105be6040519485610506565b828452602083830101116100cb57815f926020809301838601378301015290565b81601f820112156100cb578035906105f682610527565b926106046040519485610506565b82845260208085019360061b830101918183116100cb57602001925b82841061062e575050505090565b6040848303126100cb5760206040918251610648816104eb565b6106518761056a565b81528287013583820152815201930192610620565b919060c0838203126100cb5760405160c081018181106001600160401b0382111761031f5760405280938035825260208101356020830152604081013560408301526106b46060820161056a565b606083015260808101356001600160401b0381116100cb57836106d89183016105df565b608083015260a0810135906001600160401b0382116100cb570182601f820112156100cb5780359061070982610527565b936107176040519586610506565b82855260208086019360051b830101918183116100cb5760208101935b83851061074657505050505060a00152565b84356001600160401b0381116100cb5782016060818503601f1901126100cb5760405191606083018381106001600160401b0382111761031f5760405261078f6020830161056a565b83526040820135926001600160401b0384116100cb576060836107b9886020809881980101610599565b8584015201356040820152815201940193610734565b805180835260209291819084018484015e5f828201840152601f01601f1916010190565b602081016020825282518091526040820191602060408360051b8301019401925f915b83831061082557505050505090565b9091929394602080610843600193603f1986820301875289516107cf565b97019301930191939290610816565b9181601f840112156100cb578235916001600160401b0383116100cb57602083818601950101116100cb57565b80518210156108935760209160051b010190565b634e487b7160e01b5f52603260045260245ffd5b926001600160a01b03909216918215610a42578151906108c682610527565b926108d46040519485610506565b8284526108e083610527565b602085019390601f19013685375f5b8181106109e85750504793853b156100cb57959392919060405196879563321eb72360e21b875260a4870190336004890152602488015260a060448801528251809152602060c488019301905f5b8181106109cf5750505060209060031987840301606488015251918281520192905f5b8181106109ad57505050918361098581935f97956003198483030160848501526107cf565b03925af180156109a2576109965750565b5f6109a091610506565b565b6040513d5f823e3d90fd5b82516001600160a01b0316855288965060209485019490920191600101610960565b825185528a98506020948501949092019160010161093d565b6109f2818461087f565b515f908152602081905260409020546001600160a01b03168015610a255790600191610a1e828961087f565b52016108ef565b610a2f828561087f565b51636d5ba68f60e11b5f5260045260245ffd5b50505050565b949293848193610a589388610b20565b9360405190610a68604083610506565b600182526020808301919036833782511561089357610a8e9582602093505201516108a7565b90565b90602080835192838152019201905f5b818110610aae5750505090565b825180516001600160a01b031685526020908101518186015260409094019390920191600101610aa1565b908160209103126100cb575180151581036100cb5790565b3d15610b1b573d90610b028261057e565b91610b106040519384610506565b82523d5f602084013e565b606090565b93909192604085018051468103610fca57506040519460208601946020865287516040880152602088019283516060890152516080880152606088019560018060a01b0387511660a0890152608089019760a0610b898a5160c080850152610100840190610a91565b9a0199818b51603f198284030160e0830152805180845260208401936020808360051b8301019301945f915b838310610f755750505050610bd3925003601f198101835282610506565b519020906040519060208201928352604082015260408152610bf6606082610506565b51902094516001600160a01b0316308103610f635750828503610f50575f858152602081905260409020546001600160a01b0316610f3d576001600160a01b0316938415610f2e577f4a817ec64beb8020b3e400f30f3b458110d5765d7a9d1ace4e68754ed2d082de916020915f525f825260405f20866bffffffffffffffffffffffff60a01b825416179055519360405195865260018060a01b031694a4805151905f5b828110610e7e5750505080515191610cb283610527565b92610cc06040519485610506565b808452610ccf601f1991610527565b015f5b818110610e6d5750505f5b82518051821015610e665781610cf29161087f565b5180516001600160a01b0316803b610de25750602081015151610dc2575b60018060a01b0381511660408201905f8083516020860193845191602083519301915af192610d3d610af1565b9315610d665750505090600191610d54828761087f565b52610d5f818661087f565b5001610cdd565b5190519151604051630978ad9160e11b81526001600160a01b0390921660048301526080602483015290918291610dbe918590610da79060848601906107cf565b9160448501526003198483030160648501526107cf565b0390fd5b51632db5928960e01b5f9081526001600160a01b03909116600452602490fd5b6040516301ffc9a760e01b81526308eacdfb60e21b600482015290602090829060249082905afa5f9181610e36575b50610e1d575b50610d10565b610e27575f610e17565b639cc814c560e01b5f5260045ffd5b610e5891925060203d8111610e5f575b610e508183610506565b810190610ad9565b905f610e11565b503d610e46565b5090915050565b806060602080938801015201610cd2565b610e8981835161087f565b51610ee55f80602060018060a01b0385511694015160405160208101916323b872dd60e01b8352336024830152306044830152606482015260648152610ed0608482610506565b519082865af1610ede610af1565b9083610fdc565b8051908115159182610f13575b5050610f015750600101610c9b565b635274afe760e01b5f5260045260245ffd5b610f269250602080918301019101610ad9565b155f80610ef2565b6334d9914d60e11b5f5260045ffd5b8463373d207960e01b5f5260045260245ffd5b826344d659bf60e01b5f5260045260245ffd5b631c26f26d60e01b5f5260045260245ffd5b919360019193955060208091601f19858203018652885190848060a01b038251168152604080610fb28585015160608786015260608501906107cf565b93015191015297019301930190928694929593610bb5565b635ea03eed60e11b5f5260045260245ffd5b906110005750805115610ff157805190602001fd5b630a12f52160e11b5f5260045ffd5b81511580611031575b611011575090565b639996b31560e01b5f9081526001600160a01b0391909116600452602490fd5b50803b1561100956

Deployed Bytecode

0x6080604052600436101561001a575b3615610018575f80fd5b005b5f3560e01c8063115f9a971461043c5780632aa91bfd1461040b57806337e312dc1461039a57806354fd4d50146103555780637b93f2181461033357806382e2c43f146100cf5763af9d22cf0361000e5760a03660031901126100cb576004356001600160401b0381116100cb576100bb61009c6100c7923690600401610666565b6100a461053e565b906100ad610554565b916064359160243590610b20565b604051918291826107f3565b0390f35b5f80fd5b60603660031901126100cb576004356024356001600160401b0381116100cb576100fd903690600401610852565b90916044356001600160401b0381116100cb5761011e903690600401610852565b9190928401936020818603126100cb578035906001600160401b0382116100cb5701936040858203126100cb5760405194610158866104eb565b80356001600160401b0381116100cb5782610174918301610666565b86526020810135906001600160401b0382116100cb57019060a0828203126100cb576040519160a083018381106001600160401b0382111761031f576040526101bc8161056a565b83526101ca6020820161056a565b60208401526040830191604082013583526060820135606085015260808201356001600160401b0381116100cb5761020292016105df565b608083015260208601918252514211610310577f0555709e59fb225fcf12cc582a9e5f7fd8eea54c91f3dc500ab9d8c37c50777060408051848152336020820152a1516040516102af816102a1608060208301956020875260018060a01b03815116604085015260018060a01b036020820151166060850152604081015182850152606081015160a0850152015160a060c084015260e0830190610a91565b03601f198101835282610506565b519020918301936060848603126100cb576102c98461056a565b926102d66020860161056a565b946040810135966001600160401b0388116100cb57610018976102f99201610599565b915191946001600160a01b03908116941691610a48565b6302857b7560e01b5f5260045ffd5b634e487b7160e01b5f52604160045260245ffd5b346100cb575f3660031901126100cb576040516308eacdfb60e21b8152602090f35b346100cb575f3660031901126100cb576100c7604051610376604082610506565b600381526219171b60e91b60208201526040519182916020835260208301906107cf565b60c03660031901126100cb576004356001600160401b0381116100cb576103c5903690600401610666565b6103cd61053e565b6103d5610554565b9060a435916001600160401b0383116100cb576100c7936103fd6100bb943690600401610599565b926064359160243590610a48565b346100cb5760203660031901126100cb576004355f525f602052602060018060a01b0360405f205416604051908152f35b60803660031901126100cb576024356001600160401b0381116100cb57366023820112156100cb5780600401359061047382610527565b916104816040519384610506565b8083526024602084019160051b830101913683116100cb57602401905b8282106104db57836104ae61053e565b90606435916001600160401b0383116100cb576104d2610018933690600401610599565b916004356108a7565b813581526020918201910161049e565b604081019081106001600160401b0382111761031f57604052565b90601f801991011681019081106001600160401b0382111761031f57604052565b6001600160401b03811161031f5760051b60200190565b604435906001600160a01b03821682036100cb57565b608435906001600160a01b03821682036100cb57565b35906001600160a01b03821682036100cb57565b6001600160401b03811161031f57601f01601f191660200190565b81601f820112156100cb578035906105b08261057e565b926105be6040519485610506565b828452602083830101116100cb57815f926020809301838601378301015290565b81601f820112156100cb578035906105f682610527565b926106046040519485610506565b82845260208085019360061b830101918183116100cb57602001925b82841061062e575050505090565b6040848303126100cb5760206040918251610648816104eb565b6106518761056a565b81528287013583820152815201930192610620565b919060c0838203126100cb5760405160c081018181106001600160401b0382111761031f5760405280938035825260208101356020830152604081013560408301526106b46060820161056a565b606083015260808101356001600160401b0381116100cb57836106d89183016105df565b608083015260a0810135906001600160401b0382116100cb570182601f820112156100cb5780359061070982610527565b936107176040519586610506565b82855260208086019360051b830101918183116100cb5760208101935b83851061074657505050505060a00152565b84356001600160401b0381116100cb5782016060818503601f1901126100cb5760405191606083018381106001600160401b0382111761031f5760405261078f6020830161056a565b83526040820135926001600160401b0384116100cb576060836107b9886020809881980101610599565b8584015201356040820152815201940193610734565b805180835260209291819084018484015e5f828201840152601f01601f1916010190565b602081016020825282518091526040820191602060408360051b8301019401925f915b83831061082557505050505090565b9091929394602080610843600193603f1986820301875289516107cf565b97019301930191939290610816565b9181601f840112156100cb578235916001600160401b0383116100cb57602083818601950101116100cb57565b80518210156108935760209160051b010190565b634e487b7160e01b5f52603260045260245ffd5b926001600160a01b03909216918215610a42578151906108c682610527565b926108d46040519485610506565b8284526108e083610527565b602085019390601f19013685375f5b8181106109e85750504793853b156100cb57959392919060405196879563321eb72360e21b875260a4870190336004890152602488015260a060448801528251809152602060c488019301905f5b8181106109cf5750505060209060031987840301606488015251918281520192905f5b8181106109ad57505050918361098581935f97956003198483030160848501526107cf565b03925af180156109a2576109965750565b5f6109a091610506565b565b6040513d5f823e3d90fd5b82516001600160a01b0316855288965060209485019490920191600101610960565b825185528a98506020948501949092019160010161093d565b6109f2818461087f565b515f908152602081905260409020546001600160a01b03168015610a255790600191610a1e828961087f565b52016108ef565b610a2f828561087f565b51636d5ba68f60e11b5f5260045260245ffd5b50505050565b949293848193610a589388610b20565b9360405190610a68604083610506565b600182526020808301919036833782511561089357610a8e9582602093505201516108a7565b90565b90602080835192838152019201905f5b818110610aae5750505090565b825180516001600160a01b031685526020908101518186015260409094019390920191600101610aa1565b908160209103126100cb575180151581036100cb5790565b3d15610b1b573d90610b028261057e565b91610b106040519384610506565b82523d5f602084013e565b606090565b93909192604085018051468103610fca57506040519460208601946020865287516040880152602088019283516060890152516080880152606088019560018060a01b0387511660a0890152608089019760a0610b898a5160c080850152610100840190610a91565b9a0199818b51603f198284030160e0830152805180845260208401936020808360051b8301019301945f915b838310610f755750505050610bd3925003601f198101835282610506565b519020906040519060208201928352604082015260408152610bf6606082610506565b51902094516001600160a01b0316308103610f635750828503610f50575f858152602081905260409020546001600160a01b0316610f3d576001600160a01b0316938415610f2e577f4a817ec64beb8020b3e400f30f3b458110d5765d7a9d1ace4e68754ed2d082de916020915f525f825260405f20866bffffffffffffffffffffffff60a01b825416179055519360405195865260018060a01b031694a4805151905f5b828110610e7e5750505080515191610cb283610527565b92610cc06040519485610506565b808452610ccf601f1991610527565b015f5b818110610e6d5750505f5b82518051821015610e665781610cf29161087f565b5180516001600160a01b0316803b610de25750602081015151610dc2575b60018060a01b0381511660408201905f8083516020860193845191602083519301915af192610d3d610af1565b9315610d665750505090600191610d54828761087f565b52610d5f818661087f565b5001610cdd565b5190519151604051630978ad9160e11b81526001600160a01b0390921660048301526080602483015290918291610dbe918590610da79060848601906107cf565b9160448501526003198483030160648501526107cf565b0390fd5b51632db5928960e01b5f9081526001600160a01b03909116600452602490fd5b6040516301ffc9a760e01b81526308eacdfb60e21b600482015290602090829060249082905afa5f9181610e36575b50610e1d575b50610d10565b610e27575f610e17565b639cc814c560e01b5f5260045ffd5b610e5891925060203d8111610e5f575b610e508183610506565b810190610ad9565b905f610e11565b503d610e46565b5090915050565b806060602080938801015201610cd2565b610e8981835161087f565b51610ee55f80602060018060a01b0385511694015160405160208101916323b872dd60e01b8352336024830152306044830152606482015260648152610ed0608482610506565b519082865af1610ede610af1565b9083610fdc565b8051908115159182610f13575b5050610f015750600101610c9b565b635274afe760e01b5f5260045260245ffd5b610f269250602080918301019101610ad9565b155f80610ef2565b6334d9914d60e11b5f5260045ffd5b8463373d207960e01b5f5260045260245ffd5b826344d659bf60e01b5f5260045260245ffd5b631c26f26d60e01b5f5260045260245ffd5b919360019193955060208091601f19858203018652885190848060a01b038251168152604080610fb28585015160608786015260608501906107cf565b93015191015297019301930190928694929593610bb5565b635ea03eed60e11b5f5260045260245ffd5b906110005750805115610ff157805190602001fd5b630a12f52160e11b5f5260045ffd5b81511580611031575b611011575090565b639996b31560e01b5f9081526001600160a01b0391909116600452602490fd5b50803b1561100956

Block Uncle Number Difficulty Gas Used Reward
View All Uncles
Loading...
Loading
Loading...
Loading
Loading...
Loading
[ Download: CSV Export  ]

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