ETH Price: $2,906.16 (-1.09%)
 

Overview

ETH Balance

0 ETH

ETH Value

$0.00

More Info

Private Name Tags

Multichain Info

No addresses found
Transaction Hash
Block
From
To

There are no matching entries

Please try again later

View more zero value Internal Transactions in Advanced View mode

Advanced mode:

Cross-Chain Transactions
Loading...
Loading

Contract Source Code Verified (Exact Match)

Contract Name:
Fusion

Compiler Version
v0.8.24+commit.e11b9ed9

Optimization Enabled:
Yes with 800 runs

Other Settings:
paris EvmVersion
// SPDX-License-Identifier: LGPL-3.0-only
pragma solidity >=0.7.0 <0.9.0;

import "./common/Singleton.sol";
import "./common/StorageAccessible.sol";
import "./base/Executor.sol";
import "./base/ProofManager.sol";
import "./handler/TokenCallbackHandler.sol";
import "./external/Fusion2771Context.sol";
import "@openzeppelin/contracts/token/ERC20/IERC20.sol";
import "@openzeppelin/contracts/interfaces/IERC20Metadata.sol";
import "./base/LogManager.sol";

contract Fusion is
    Singleton,
    StorageAccessible,
    Executor,
    ProofManager,
    TokenCallbackHandler,
    Fusion2771Context
{
    string public constant VERSION = "1.0.0";

    bytes32 public DOMAIN;

    address public TxVerifier;
    address public RecoveryVerifier;

    bytes32 public TxHash;
    bytes32 public RecoveryHash;

    address public GasTank;

    bytes public PublicStorage;

    uint256 private nonce;

    event SetupFusion(
        bytes32 domain,
        address txVerifier,
        address recoveryVerifier,
        address forwarder,
        address gasTank,
        bytes32 txHash,
        bytes32 recoveryHash,
        bytes publicStorage
    );

    event ExecutionResult(bytes4 magicValue);

    function setupFusion(
        bytes32 _domain,
        address _txVerifier,
        address _recoveryVerifier,
        address _forwarder,
        address _gasTank,
        bytes32 _txHash,
        bytes32 _recoveryHash,
        bytes memory _publicStorage
    ) external {
        require(DOMAIN == bytes32(0), "Fusion: already initialized");
        require(TxVerifier == address(0), "Fusion: already initialized");
        require(RecoveryVerifier == address(0), "Fusion: already initialized");
        require(GasTank == address(0), "Fusion: already initialized");

        setupTrustedForwarder(_forwarder);
        DOMAIN = _domain;
        TxVerifier = _txVerifier;
        RecoveryVerifier = _recoveryVerifier;
        GasTank = _gasTank;
        TxHash = _txHash;
        RecoveryHash = _recoveryHash;
        PublicStorage = _publicStorage;

        emit SetupFusion(
            _domain,
            _txVerifier,
            _recoveryVerifier,
            _forwarder,
            _gasTank,
            _txHash,
            _recoveryHash,
            _publicStorage
        );
    }

    function executeTx(
        bytes calldata _proof,
        address to,
        uint256 value,
        bytes calldata data
    ) public payable notTrustedForwarder returns (bytes4) {
        if (!verify(_proof, _useNonce(), TxHash, TxVerifier, msg.sender)) {
            emit ExecutionResult(INVALID_PROOF);
            return INVALID_PROOF;
        }
        if (!execute(to, value, data, gasleft())) {
            emit ExecutionResult(UNEXPECTED_ERROR);
            return UNEXPECTED_ERROR;
        }
        emit ExecutionResult(EXECUTION_SUCCESSFUL);
        return EXECUTION_SUCCESSFUL;
    }

    function executeBatchTx(
        bytes calldata _proof,
        address[] calldata to,
        uint256[] calldata value,
        bytes[] calldata data
    ) public payable notTrustedForwarder returns (bytes4) {
        if (!verify(_proof, _useNonce(), TxHash, TxVerifier, msg.sender)) {
            emit ExecutionResult(INVALID_PROOF);
            return INVALID_PROOF;
        }
        if (!batchExecute(to, value, data)) {
            emit ExecutionResult(UNEXPECTED_ERROR);
            return UNEXPECTED_ERROR;
        }
        emit ExecutionResult(EXECUTION_SUCCESSFUL);
        return EXECUTION_SUCCESSFUL;
    }

    function executeRecovery(
        bytes calldata _proof,
        bytes32 _newTxHash,
        address _newTxVerifier,
        bytes calldata _publicStorage
    ) public payable notTrustedForwarder returns (bytes4) {
        if (
            !verify(
                _proof,
                _useNonce(),
                RecoveryHash,
                RecoveryVerifier,
                msg.sender
            )
        ) {
            emit ExecutionResult(INVALID_PROOF);
            return INVALID_PROOF;
        }
        TxHash = _newTxHash;
        TxVerifier = _newTxVerifier;
        PublicStorage = _publicStorage;

        emit ExecutionResult(RECOVERY_SUCCESSFUL);
        return RECOVERY_SUCCESSFUL;
    }

    function changeRecovery(
        bytes calldata _proof,
        bytes32 _newRecoveryHash,
        address _newRecoveryVerifier,
        bytes calldata _publicStorage
    ) public payable notTrustedForwarder returns (bytes4) {
        if (
            !verify(
                _proof,
                _useNonce(),
                RecoveryHash,
                RecoveryVerifier,
                msg.sender
            )
        ) {
            emit ExecutionResult(INVALID_PROOF);
            return INVALID_PROOF;
        }
        RecoveryHash = _newRecoveryHash;
        RecoveryVerifier = _newRecoveryVerifier;
        PublicStorage = _publicStorage;

        emit ExecutionResult(CHANGE_SUCCESSFUL);
        return CHANGE_SUCCESSFUL;
    }

    function executeTxWithForwarder(
        bytes calldata _proof,
        address from,
        address to,
        uint256 value,
        bytes calldata data,
        address token,
        uint256 gasPrice,
        uint256 baseGas,
        uint256 estimatedFees
    ) public payable onlyTrustedForwarder returns (bytes4 magicValue) {
        if (!verify(_proof, _useNonce(), TxHash, TxVerifier, from)) {
            emit ExecutionResult(INVALID_PROOF);
            return INVALID_PROOF;
        }

        if (!checkBalance(token, estimatedFees)) {
            emit ExecutionResult(INSUFFICIENT_BALANCE);
            return INSUFFICIENT_BALANCE;
        }

        uint256 startGas = gasleft();

        magicValue = EXECUTION_SUCCESSFUL;

        if (!execute(to, value, data, gasleft())) {
            magicValue = UNEXPECTED_ERROR;
        }

        magicValue = chargeFees(
            startGas,
            gasPrice,
            baseGas,
            GasTank,
            token,
            magicValue
        );
        emit ExecutionResult(magicValue);
    }

    function executeBatchTxWithForwarder(
        bytes calldata _proof,
        address from,
        address[] calldata to,
        uint256[] calldata value,
        bytes[] calldata data,
        address token,
        uint256 gasPrice,
        uint256 baseGas,
        uint256 estimatedFees
    ) public payable onlyTrustedForwarder returns (bytes4 magicValue) {
        if (!verify(_proof, _useNonce(), TxHash, TxVerifier, from)) {
            emit ExecutionResult(INVALID_PROOF);
            return INVALID_PROOF;
        }

        if (checkBalance(token, estimatedFees) == false) {
            emit ExecutionResult(INSUFFICIENT_BALANCE);
            return INSUFFICIENT_BALANCE;
        }

        uint256 startGas = gasleft();

        magicValue = EXECUTION_SUCCESSFUL;

        if (batchExecute(to, value, data)) {
            magicValue = UNEXPECTED_ERROR;
        }

        magicValue = chargeFees(
            startGas,
            gasPrice,
            baseGas,
            GasTank,
            token,
            magicValue
        );
        emit ExecutionResult(magicValue);
    }

    function executeRecoveryWithForwarder(
        bytes calldata _proof,
        address from,
        bytes32 _newTxHash,
        address _newTxVerifier,
        bytes calldata _publicStorage,
        address token,
        uint256 gasPrice,
        uint256 baseGas,
        uint256 estimatedFees
    ) public payable onlyTrustedForwarder returns (bytes4 magicValue) {
        if (
            !verify(_proof, _useNonce(), RecoveryHash, RecoveryVerifier, from)
        ) {
            emit ExecutionResult(INVALID_PROOF);
            return INVALID_PROOF;
        }

        if (!checkBalance(token, estimatedFees)) {
            emit ExecutionResult(INSUFFICIENT_BALANCE);
            return INSUFFICIENT_BALANCE;
        }

        uint256 startGas = gasleft();

        TxHash = _newTxHash;
        TxVerifier = _newTxVerifier;
        PublicStorage = _publicStorage;

        magicValue = chargeFees(
            startGas,
            gasPrice,
            baseGas,
            GasTank,
            token,
            RECOVERY_SUCCESSFUL
        );
        emit ExecutionResult(magicValue);
    }

    function changeRecoveryWithForwarder(
        bytes calldata _proof,
        address from,
        bytes32 _newRecoveryHash,
        address _newRecoveryVerifier,
        bytes calldata _publicStorage,
        address token,
        uint256 gasPrice,
        uint256 baseGas,
        uint256 estimatedFees
    ) public payable onlyTrustedForwarder returns (bytes4 magicValue) {
        if (
            !verify(_proof, _useNonce(), RecoveryHash, RecoveryVerifier, from)
        ) {
            emit ExecutionResult(INVALID_PROOF);
            return INVALID_PROOF;
        }

        if (!checkBalance(token, estimatedFees)) {
            emit ExecutionResult(INSUFFICIENT_BALANCE);
            return INSUFFICIENT_BALANCE;
        }

        uint256 startGas = gasleft();

        RecoveryHash = _newRecoveryHash;
        RecoveryVerifier = _newRecoveryVerifier;
        PublicStorage = _publicStorage;

        magicValue = chargeFees(
            startGas,
            gasPrice,
            baseGas,
            GasTank,
            token,
            CHANGE_SUCCESSFUL
        );
        emit ExecutionResult(magicValue);
    }

    function checkBalance(
        address token,
        uint256 estimatedFees
    ) internal view returns (bool) {
        if (token != address(0)) {
            uint8 decimals = IERC20Metadata(token).decimals();
            if (
                IERC20(token).balanceOf(address(this)) <
                estimatedFees / 10 ** (18 - decimals)
            ) {
                return false;
            }
        } else {
            if (address(this).balance < estimatedFees) {
                return false;
            }
        }

        return true;
    }

    function isValidSignature(
        bytes32 _hash,
        bytes calldata _signature
    ) public view returns (bytes4 magicValue) {
        if (verify(_signature, _hash, TxHash, TxVerifier, address(this))) {
            return 0x1626ba7e;
        } else {
            return 0xffffffff;
        }
    }

    function getNonce() public view returns (uint256) {
        return nonce;
    }

    function _useNonce() internal returns (uint256) {
        unchecked {
            return nonce++;
        }
    }

    receive() external payable {}

    fallback() external payable {}
}

File 2 of 18 : IERC20Metadata.sol
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v5.0.0) (interfaces/IERC20Metadata.sol)

pragma solidity ^0.8.20;

import {IERC20Metadata} from "../token/ERC20/extensions/IERC20Metadata.sol";

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

pragma solidity ^0.8.20;

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

/**
 * @dev Interface for the optional metadata functions from the ERC20 standard.
 */
interface IERC20Metadata is IERC20 {
    /**
     * @dev Returns the name of the token.
     */
    function name() external view returns (string memory);

    /**
     * @dev Returns the symbol of the token.
     */
    function symbol() external view returns (string memory);

    /**
     * @dev Returns the decimals places of the token.
     */
    function decimals() external view returns (uint8);
}

// 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: LGPL-3.0-only
pragma solidity >=0.7.0 <0.9.0;

abstract contract Executor {
    function execute(
        address to,
        uint256 value,
        bytes memory data,
        uint256 txGas
    ) internal returns (bool success) {
        // solhint-disable-next-line no-inline-assembly
        assembly {
            success := call(
                txGas,
                to,
                value,
                add(data, 0x20),
                mload(data),
                0,
                0
            )
        }
    }

    function batchExecute(
        address[] memory tos,
        uint256[] memory values,
        bytes[] memory datas
    ) internal returns (bool success) {
        require(
            tos.length == values.length && tos.length == datas.length,
            "Array lengths must match"
        );

        for (uint i = 0; i < tos.length; i++) {
            success = execute(tos[i], values[i], datas[i], gasleft());

            if (!success) {
                break;
            }
        }
    }
}

File 6 of 18 : LogManager.sol
// SPDX-License-Identifier: LGPL-3.0-only
pragma solidity >=0.7.0 <0.9.0;

abstract contract LogManager {
    // Invalid Proof Error
    bytes4 internal constant INVALID_PROOF = bytes4(keccak256("Invalid proof"));

    // Invalid Balance Error
    bytes4 internal constant INSUFFICIENT_BALANCE =
        bytes4(keccak256("Insufficient balance"));

    // Unexpected Error
    bytes4 internal constant UNEXPECTED_ERROR =
        bytes4(keccak256("Unexpected error"));

    // Error Transfering
    bytes4 internal constant TRANSFER_FAILED =
        bytes4(keccak256("Gas Transfer failed"));

    // Execution Successful
    bytes4 internal constant EXECUTION_SUCCESSFUL =
        bytes4(keccak256("Execution successful"));

    // Recovery Successful
    bytes4 internal constant RECOVERY_SUCCESSFUL =
        bytes4(keccak256("Recovery successful"));

    // Change Successful
    bytes4 internal constant CHANGE_SUCCESSFUL =
        bytes4(keccak256("Change successful"));
}

File 7 of 18 : ProofManager.sol
// SPDX-License-Identifier: LGPL-3.0-only
pragma solidity >=0.7.0 <0.9.0;
import "./Verifier.sol";
import "../libraries/Conversion.sol";

abstract contract ProofManager is Verifier {
    function verify(
        bytes calldata _proof,
        uint256 _nonce,
        bytes32 _hash,
        address _verifier,
        address _addr
    ) internal view returns (bool) {
        bytes32[] memory publicInputs;
        {
            bytes32 message = Conversion.hashMessage(
                Conversion.uintToString(_nonce)
            );
            publicInputs = Conversion.convertToInputs(message, _hash, _addr);
        }
        return verifyProof(_proof, publicInputs, _verifier);
    }

    function verify(
        bytes calldata _proof,
        bytes32 _message,
        bytes32 _hash,
        address _verifier,
        address _addr
    ) internal view returns (bool) {
        bytes32[] memory publicInputs = Conversion.convertToInputs(
            _message,
            _hash,
            _addr
        );
        return verifyProof(_proof, publicInputs, _verifier);
    }
}

// SPDX-License-Identifier: LGPL-3.0-only
pragma solidity >=0.7.0 <0.9.0;

interface UltraVerifierInterface {
    function verify(
        bytes calldata _proof,
        bytes32[] calldata _publicInputs
    ) external view returns (bool);
}

abstract contract Verifier {
    function verifyProof(
        bytes calldata _proof,
        bytes32[] memory _publicInputs,
        address _verifier
    ) internal view returns (bool) {
        return UltraVerifierInterface(_verifier).verify(_proof, _publicInputs);
    }
}

File 9 of 18 : Singleton.sol
// SPDX-License-Identifier: LGPL-3.0-only
pragma solidity >=0.7.0 <0.9.0;

abstract contract Singleton {
    address private singleton;
}

// SPDX-License-Identifier: LGPL-3.0-only
pragma solidity >=0.7.0 <0.9.0;

abstract contract StorageAccessible {
    function getStorageAt(
        uint256 offset,
        uint256 length
    ) public view returns (bytes memory) {
        bytes memory result = new bytes(length * 32);
        for (uint256 index = 0; index < length; index++) {
            // solhint-disable-next-line no-inline-assembly
            assembly {
                let word := sload(add(offset, index))
                mstore(add(add(result, 0x20), mul(index, 0x20)), word)
            }
        }
        return result;
    }

    function simulateAndRevert(
        address targetContract,
        bytes memory calldataPayload
    ) external {
        // solhint-disable-next-line no-inline-assembly
        assembly {
            let success := delegatecall(
                gas(),
                targetContract,
                add(calldataPayload, 0x20),
                mload(calldataPayload),
                0,
                0
            )

            mstore(0x00, success)
            mstore(0x20, returndatasize())
            returndatacopy(0x40, 0, returndatasize())
            revert(0, add(returndatasize(), 0x40))
        }
    }
}

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

pragma solidity >=0.7.0 <0.9.0;

/**
 * @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;
    }

    function _contextSuffixLength() internal view virtual returns (uint256) {
        return 0;
    }
}

// SPDX-License-Identifier: MIT

pragma solidity >=0.7.0 <0.9.0;

import {Context} from "./Context.sol";
import {IERC20} from "@openzeppelin/contracts/token/ERC20/IERC20.sol";
import {IERC20Metadata} from "@openzeppelin/contracts/token/ERC20/extensions/IERC20Metadata.sol";
import "../base/LogManager.sol";

abstract contract Fusion2771Context is Context, LogManager {
    /// @custom:oz-upgrades-unsafe-allow state-variable-immutable
    address private _trustedForwarder;

    function setupTrustedForwarder(address forwarder) internal {
        require(
            _trustedForwarder == address(0),
            "ERC2771Context: forwarder already set"
        );
        require(
            forwarder != address(0),
            "ERC2771Context: invalid trusted forwarder"
        );
        _trustedForwarder = forwarder;
    }

    function chargeFees(
        uint256 startGas,
        uint256 gasPrice,
        uint256 baseGas,
        address GasTank,
        address token,
        bytes4 defaultReturn
    ) internal returns (bytes4) {
        uint256 gasUsed = startGas - gasleft();
        uint256 gasFee = (gasUsed + baseGas) * gasPrice;

        if (token != address(0)) {
            uint8 decimals = IERC20Metadata(token).decimals();
            try
                IERC20(token).transfer(GasTank, gasFee / 10 ** (18 - decimals))
            {} catch {
                return TRANSFER_FAILED;
            }
        } else {
            (bool success, ) = GasTank.call{value: gasFee}("");
            if (!success) {
                return TRANSFER_FAILED;
            }
        }

        return defaultReturn;
    }

    function trustedForwarder() public view virtual returns (address) {
        return _trustedForwarder;
    }

    function isTrustedForwarder(
        address forwarder
    ) public view virtual returns (bool) {
        return forwarder == trustedForwarder();
    }

    modifier onlyTrustedForwarder() {
        require(
            isTrustedForwarder(msg.sender),
            "ERC2771Context: caller is not the trusted forwarder"
        );
        _;
    }

    modifier notTrustedForwarder() {
        require(
            !isTrustedForwarder(msg.sender),
            "ERC2771Context: caller is the trusted forwarder"
        );
        _;
    }

    function _msgSender() internal view virtual override returns (address) {
        uint256 calldataLength = msg.data.length;
        uint256 contextSuffixLength = _contextSuffixLength();
        if (
            isTrustedForwarder(msg.sender) &&
            calldataLength >= contextSuffixLength
        ) {
            return
                address(
                    bytes20(msg.data[calldataLength - contextSuffixLength:])
                );
        } else {
            return super._msgSender();
        }
    }

    function _msgData()
        internal
        view
        virtual
        override
        returns (bytes calldata)
    {
        uint256 calldataLength = msg.data.length;
        uint256 contextSuffixLength = _contextSuffixLength();
        if (
            isTrustedForwarder(msg.sender) &&
            calldataLength >= contextSuffixLength
        ) {
            return msg.data[:calldataLength - contextSuffixLength];
        } else {
            return super._msgData();
        }
    }

    function _contextSuffixLength()
        internal
        view
        virtual
        override
        returns (uint256)
    {
        return 20;
    }
}

// SPDX-License-Identifier: LGPL-3.0-only
pragma solidity >=0.7.0 <0.9.0;

import "../interfaces/ERC1155TokenReceiver.sol";
import "../interfaces/ERC721TokenReceiver.sol";
import "../interfaces/ERC777TokensRecipient.sol";
import "../interfaces/IERC165.sol";

contract TokenCallbackHandler is
    ERC1155TokenReceiver,
    ERC777TokensRecipient,
    ERC721TokenReceiver,
    IERC165
{
    function onERC1155Received(
        address,
        address,
        uint256,
        uint256,
        bytes calldata
    ) external pure override returns (bytes4) {
        return 0xf23a6e61;
    }

    function onERC1155BatchReceived(
        address,
        address,
        uint256[] calldata,
        uint256[] calldata,
        bytes calldata
    ) external pure override returns (bytes4) {
        return 0xbc197c81;
    }

    function onERC721Received(
        address,
        address,
        uint256,
        bytes calldata
    ) external pure override returns (bytes4) {
        return 0x150b7a02;
    }

    function tokensReceived(
        address,
        address,
        address,
        uint256,
        bytes calldata,
        bytes calldata
    ) external pure override {
        // We implement this for completeness, doesn't really have any value
    }

    function supportsInterface(
        bytes4 interfaceId
    ) external view virtual override returns (bool) {
        return
            interfaceId == type(ERC1155TokenReceiver).interfaceId ||
            interfaceId == type(ERC721TokenReceiver).interfaceId ||
            interfaceId == type(IERC165).interfaceId;
    }
}

// SPDX-License-Identifier: LGPL-3.0-only
pragma solidity >=0.7.0 <0.9.0;

// Note: The ERC-165 identifier for this interface is 0x4e2312e0.
interface ERC1155TokenReceiver {
    /**
     * @notice Handle the receipt of a single ERC1155 token type.
     * @dev An ERC1155-compliant smart contract MUST call this function on the token recipient contract, at the end of a `safeTransferFrom` after the balance has been updated.
     *      This function MUST return `bytes4(keccak256("onERC1155Received(address,address,uint256,uint256,bytes)"))` (i.e. 0xf23a6e61) if it accepts the transfer.
     *      This function MUST revert if it rejects the transfer.
     *      Return of any other value than the prescribed keccak256 generated value MUST result in the transaction being reverted by the caller.
     * @param _operator  The address which initiated the transfer (i.e. msg.sender).
     * @param _from      The address which previously owned the token.
     * @param _id        The ID of the token being transferred.
     * @param _value     The amount of tokens being transferred.
     * @param _data      Additional data with no specified format.
     * @return           `bytes4(keccak256("onERC1155Received(address,address,uint256,uint256,bytes)"))`.
     */
    function onERC1155Received(
        address _operator,
        address _from,
        uint256 _id,
        uint256 _value,
        bytes calldata _data
    ) external returns (bytes4);

    /**
     * @notice Handle the receipt of multiple ERC1155 token types.
     * @dev An ERC1155-compliant smart contract MUST call this function on the token recipient contract, at the end of a `safeBatchTransferFrom` after the balances have been updated.
     *      This function MUST return `bytes4(keccak256("onERC1155BatchReceived(address,address,uint256[],uint256[],bytes)"))` (i.e. 0xbc197c81) if it accepts the transfer(s).
     *      This function MUST revert if it rejects the transfer(s).
     *      Return of any other value than the prescribed keccak256 generated value MUST result in the transaction being reverted by the caller.
     * @param _operator  The address which initiated the batch transfer (i.e. msg.sender).
     * @param _from      The address which previously owned the token.
     * @param _ids       An array containing ids of each token being transferred (order and length must match _values array).
     * @param _values    An array containing amounts of each token being transferred (order and length must match _ids array).
     * @param _data      Additional data with no specified format.
     * @return           `bytes4(keccak256("onERC1155BatchReceived(address,address,uint256[],uint256[],bytes)"))`.
     */
    function onERC1155BatchReceived(
        address _operator,
        address _from,
        uint256[] calldata _ids,
        uint256[] calldata _values,
        bytes calldata _data
    ) external returns (bytes4);
}

File 15 of 18 : ERC721TokenReceiver.sol
// SPDX-License-Identifier: LGPL-3.0-only
pragma solidity >=0.7.0 <0.9.0;

/// @dev Note: the ERC-165 identifier for this interface is 0x150b7a02.
interface ERC721TokenReceiver {
    /**
     * @notice Handle the receipt of an NFT
     * @dev The ERC721 smart contract calls this function on the recipient
     *  after a `transfer`. This function MAY throw to revert and reject the
     *  transfer. Return of other than the magic value MUST result in the
     *  transaction being reverted.
     *  Note: the contract address is always the message sender.
     * @param _operator The address which called `safeTransferFrom` function.
     * @param _from The address which previously owned the token.
     * @param _tokenId The NFT identifier which is being transferred.
     * @param _data Additional data with no specified format.
     * @return `bytes4(keccak256("onERC721Received(address,address,uint256,bytes)"))`.
     *  unless throwing
     */
    function onERC721Received(
        address _operator,
        address _from,
        uint256 _tokenId,
        bytes calldata _data
    ) external returns (bytes4);
}

File 16 of 18 : ERC777TokensRecipient.sol
// SPDX-License-Identifier: LGPL-3.0-only
pragma solidity >=0.7.0 <0.9.0;

/**
 * @title ERC777TokensRecipient
 * @dev Interface for contracts that will be called with the ERC777 token's `tokensReceived` method.
 * The contract receiving the tokens must implement this interface in order to receive the tokens.
 */
interface ERC777TokensRecipient {
    /**
     * @dev Called by the ERC777 token contract after a successful transfer or a minting operation.
     * @param operator The address of the operator performing the transfer or minting operation.
     * @param from The address of the sender.
     * @param to The address of the recipient.
     * @param amount The amount of tokens that were transferred or minted.
     * @param data Additional data that was passed during the transfer or minting operation.
     * @param operatorData Additional data that was passed by the operator during the transfer or minting operation.
     */
    function tokensReceived(
        address operator,
        address from,
        address to,
        uint256 amount,
        bytes calldata data,
        bytes calldata operatorData
    ) external;
}

// SPDX-License-Identifier: LGPL-3.0-only
pragma solidity >=0.7.0 <0.9.0;

/// @notice More details at https://github.com/OpenZeppelin/openzeppelin-contracts/blob/master/contracts/utils/introspection/IERC165.sol
interface IERC165 {
    /**
     * @dev Returns true if this contract implements the interface defined by `interfaceId`.
     * See the corresponding EIP section
     * https://eips.ethereum.org/EIPS/eip-165#how-interfaces-are-identified
     * 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: LGPL-3.0-only
pragma solidity >=0.7.0 <0.9.0;

library Conversion {
    function convertToPaddedByte32(
        bytes32 value
    ) internal pure returns (bytes32) {
        bytes32 paddedValue;
        paddedValue = bytes32(uint256(value) >> (31 * 8));
        return paddedValue;
    }

    function convertToInputs(
        bytes32 _message,
        bytes32 _hash,
        address _addr
    ) internal pure returns (bytes32[] memory) {
        bytes32[] memory byte32Inputs = new bytes32[](34);
        for (uint256 i = 0; i < 32; i++) {
            byte32Inputs[i] = convertToPaddedByte32(_message[i]);
        }
        byte32Inputs[32] = _hash;
        byte32Inputs[33] = bytes32(uint256(uint160(_addr)));

        return byte32Inputs;
    }

    function uintToString(uint256 v) internal pure returns (string memory) {
        if (v == 0) {
            return "0";
        }

        uint256 maxlength = 100;
        bytes memory reversed = new bytes(maxlength);
        uint256 i = 0;
        while (v != 0) {
            uint256 remainder = v % 10;
            v = v / 10;
            reversed[i++] = bytes1(uint8(48 + remainder));
        }
        bytes memory s = new bytes(i);
        for (uint256 j = 0; j < i; j++) {
            s[j] = reversed[i - 1 - j];
        }
        return string(s);
    }

    function bytesToString(
        bytes memory data
    ) internal pure returns (string memory) {
        bytes memory alphabet = "0123456789abcdef";
        bytes memory str = new bytes(2 * data.length);
        for (uint256 i = 0; i < data.length; i++) {
            str[2 * i] = alphabet[uint8(data[i] >> 4)];
            str[2 * i + 1] = alphabet[uint8(data[i] & 0x0f)];
        }
        return string(str);
    }

    function hashMessage(
        string memory message
    ) internal pure returns (bytes32) {
        string memory messagePrefix = "\x19Ethereum Signed Message:\n";
        string memory lengthString = uintToString(bytes(message).length);
        string memory concatenatedMessage = string(
            abi.encodePacked(messagePrefix, lengthString, message)
        );
        return keccak256(bytes(concatenatedMessage));
    }
}

Settings
{
  "optimizer": {
    "enabled": true,
    "runs": 800,
    "details": {
      "yulDetails": {
        "optimizerSteps": "u"
      }
    }
  },
  "evmVersion": "paris",
  "viaIR": true,
  "outputSelection": {
    "*": {
      "*": [
        "evm.bytecode",
        "evm.deployedBytecode",
        "devdoc",
        "userdoc",
        "metadata",
        "abi"
      ]
    }
  },
  "libraries": {}
}

Contract Security Audit

Contract ABI

API
[{"anonymous":false,"inputs":[{"indexed":false,"internalType":"bytes4","name":"magicValue","type":"bytes4"}],"name":"ExecutionResult","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"bytes32","name":"domain","type":"bytes32"},{"indexed":false,"internalType":"address","name":"txVerifier","type":"address"},{"indexed":false,"internalType":"address","name":"recoveryVerifier","type":"address"},{"indexed":false,"internalType":"address","name":"forwarder","type":"address"},{"indexed":false,"internalType":"address","name":"gasTank","type":"address"},{"indexed":false,"internalType":"bytes32","name":"txHash","type":"bytes32"},{"indexed":false,"internalType":"bytes32","name":"recoveryHash","type":"bytes32"},{"indexed":false,"internalType":"bytes","name":"publicStorage","type":"bytes"}],"name":"SetupFusion","type":"event"},{"stateMutability":"payable","type":"fallback"},{"inputs":[],"name":"DOMAIN","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"GasTank","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"PublicStorage","outputs":[{"internalType":"bytes","name":"","type":"bytes"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"RecoveryHash","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"RecoveryVerifier","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"TxHash","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"TxVerifier","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"VERSION","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes","name":"_proof","type":"bytes"},{"internalType":"bytes32","name":"_newRecoveryHash","type":"bytes32"},{"internalType":"address","name":"_newRecoveryVerifier","type":"address"},{"internalType":"bytes","name":"_publicStorage","type":"bytes"}],"name":"changeRecovery","outputs":[{"internalType":"bytes4","name":"","type":"bytes4"}],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"bytes","name":"_proof","type":"bytes"},{"internalType":"address","name":"from","type":"address"},{"internalType":"bytes32","name":"_newRecoveryHash","type":"bytes32"},{"internalType":"address","name":"_newRecoveryVerifier","type":"address"},{"internalType":"bytes","name":"_publicStorage","type":"bytes"},{"internalType":"address","name":"token","type":"address"},{"internalType":"uint256","name":"gasPrice","type":"uint256"},{"internalType":"uint256","name":"baseGas","type":"uint256"},{"internalType":"uint256","name":"estimatedFees","type":"uint256"}],"name":"changeRecoveryWithForwarder","outputs":[{"internalType":"bytes4","name":"magicValue","type":"bytes4"}],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"bytes","name":"_proof","type":"bytes"},{"internalType":"address[]","name":"to","type":"address[]"},{"internalType":"uint256[]","name":"value","type":"uint256[]"},{"internalType":"bytes[]","name":"data","type":"bytes[]"}],"name":"executeBatchTx","outputs":[{"internalType":"bytes4","name":"","type":"bytes4"}],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"bytes","name":"_proof","type":"bytes"},{"internalType":"address","name":"from","type":"address"},{"internalType":"address[]","name":"to","type":"address[]"},{"internalType":"uint256[]","name":"value","type":"uint256[]"},{"internalType":"bytes[]","name":"data","type":"bytes[]"},{"internalType":"address","name":"token","type":"address"},{"internalType":"uint256","name":"gasPrice","type":"uint256"},{"internalType":"uint256","name":"baseGas","type":"uint256"},{"internalType":"uint256","name":"estimatedFees","type":"uint256"}],"name":"executeBatchTxWithForwarder","outputs":[{"internalType":"bytes4","name":"magicValue","type":"bytes4"}],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"bytes","name":"_proof","type":"bytes"},{"internalType":"bytes32","name":"_newTxHash","type":"bytes32"},{"internalType":"address","name":"_newTxVerifier","type":"address"},{"internalType":"bytes","name":"_publicStorage","type":"bytes"}],"name":"executeRecovery","outputs":[{"internalType":"bytes4","name":"","type":"bytes4"}],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"bytes","name":"_proof","type":"bytes"},{"internalType":"address","name":"from","type":"address"},{"internalType":"bytes32","name":"_newTxHash","type":"bytes32"},{"internalType":"address","name":"_newTxVerifier","type":"address"},{"internalType":"bytes","name":"_publicStorage","type":"bytes"},{"internalType":"address","name":"token","type":"address"},{"internalType":"uint256","name":"gasPrice","type":"uint256"},{"internalType":"uint256","name":"baseGas","type":"uint256"},{"internalType":"uint256","name":"estimatedFees","type":"uint256"}],"name":"executeRecoveryWithForwarder","outputs":[{"internalType":"bytes4","name":"magicValue","type":"bytes4"}],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"bytes","name":"_proof","type":"bytes"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"value","type":"uint256"},{"internalType":"bytes","name":"data","type":"bytes"}],"name":"executeTx","outputs":[{"internalType":"bytes4","name":"","type":"bytes4"}],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"bytes","name":"_proof","type":"bytes"},{"internalType":"address","name":"from","type":"address"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"value","type":"uint256"},{"internalType":"bytes","name":"data","type":"bytes"},{"internalType":"address","name":"token","type":"address"},{"internalType":"uint256","name":"gasPrice","type":"uint256"},{"internalType":"uint256","name":"baseGas","type":"uint256"},{"internalType":"uint256","name":"estimatedFees","type":"uint256"}],"name":"executeTxWithForwarder","outputs":[{"internalType":"bytes4","name":"magicValue","type":"bytes4"}],"stateMutability":"payable","type":"function"},{"inputs":[],"name":"getNonce","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"offset","type":"uint256"},{"internalType":"uint256","name":"length","type":"uint256"}],"name":"getStorageAt","outputs":[{"internalType":"bytes","name":"","type":"bytes"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"forwarder","type":"address"}],"name":"isTrustedForwarder","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes32","name":"_hash","type":"bytes32"},{"internalType":"bytes","name":"_signature","type":"bytes"}],"name":"isValidSignature","outputs":[{"internalType":"bytes4","name":"magicValue","type":"bytes4"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"},{"internalType":"address","name":"","type":"address"},{"internalType":"uint256[]","name":"","type":"uint256[]"},{"internalType":"uint256[]","name":"","type":"uint256[]"},{"internalType":"bytes","name":"","type":"bytes"}],"name":"onERC1155BatchReceived","outputs":[{"internalType":"bytes4","name":"","type":"bytes4"}],"stateMutability":"pure","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"},{"internalType":"address","name":"","type":"address"},{"internalType":"uint256","name":"","type":"uint256"},{"internalType":"uint256","name":"","type":"uint256"},{"internalType":"bytes","name":"","type":"bytes"}],"name":"onERC1155Received","outputs":[{"internalType":"bytes4","name":"","type":"bytes4"}],"stateMutability":"pure","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"},{"internalType":"address","name":"","type":"address"},{"internalType":"uint256","name":"","type":"uint256"},{"internalType":"bytes","name":"","type":"bytes"}],"name":"onERC721Received","outputs":[{"internalType":"bytes4","name":"","type":"bytes4"}],"stateMutability":"pure","type":"function"},{"inputs":[{"internalType":"bytes32","name":"_domain","type":"bytes32"},{"internalType":"address","name":"_txVerifier","type":"address"},{"internalType":"address","name":"_recoveryVerifier","type":"address"},{"internalType":"address","name":"_forwarder","type":"address"},{"internalType":"address","name":"_gasTank","type":"address"},{"internalType":"bytes32","name":"_txHash","type":"bytes32"},{"internalType":"bytes32","name":"_recoveryHash","type":"bytes32"},{"internalType":"bytes","name":"_publicStorage","type":"bytes"}],"name":"setupFusion","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"targetContract","type":"address"},{"internalType":"bytes","name":"calldataPayload","type":"bytes"}],"name":"simulateAndRevert","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes4","name":"interfaceId","type":"bytes4"}],"name":"supportsInterface","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"},{"internalType":"address","name":"","type":"address"},{"internalType":"address","name":"","type":"address"},{"internalType":"uint256","name":"","type":"uint256"},{"internalType":"bytes","name":"","type":"bytes"},{"internalType":"bytes","name":"","type":"bytes"}],"name":"tokensReceived","outputs":[],"stateMutability":"pure","type":"function"},{"inputs":[],"name":"trustedForwarder","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"stateMutability":"payable","type":"receive"}]

60806040523461001a57604051612a136100208239612a1390f35b600080fdfe60806040526004361015610018575b361561001657005b005b60003560e01c806223de29146101d757806301ffc9a7146101d257806303d43e9f146101cd578063150b7a02146101c85780631626ba7e146101c35780631692d4ef146101be57806337ce1908146101b957806352a9674b146101b45780635624b25b146101af578063572b6c05146101aa5780636319c4bc146101a55780636efc71e4146101a05780637c15ba261461019b5780637da0a877146101965780637f51ca5114610191578063aef8c46e1461018c578063b44a22f714610187578063b4faba0914610182578063bc197c811461017d578063be0a05ee14610178578063c00eb6b214610173578063c1e67bec1461016e578063cbe4c34414610169578063d087d28814610164578063da3279251461015f578063f23a6e611461015a578063ffa1ad74146101555763ffb7aad80361000e57610f16565b610dd4565b610d55565b610cd2565b610cb7565b610c9a565b610c7d565b610c2b565b610c02565b610b98565b610afa565b610aa4565b6109f9565b6109d2565b6109ab565b610988565b61090d565b6107a3565b61077c565b610740565b61068d565b610645565b61053f565b6104ed565b610498565b610409565b61032e565b6102d8565b6001600160a01b031690565b90565b6001600160a01b0381165b036101fd57565b600080fd5b9050359061020f826101eb565b565b806101f6565b9050359061020f82610211565b909182601f830112156101fd5781359167ffffffffffffffff83116101fd5760200192600183028401116101fd57565b60c0818303126101fd576102688282610202565b926102768360208401610202565b926102848160408501610202565b926102928260608301610217565b92608082013567ffffffffffffffff81116101fd57836102b3918401610224565b92909360a082013567ffffffffffffffff81116101fd576102d49201610224565b9091565b346101fd576102e8366004610254565b505050505050505061001660405190565b0390f35b6001600160e01b031981166101f6565b9050359061020f826102fd565b906020828203126101fd576101e89161030d565b346101fd576102f961034961034436600461031a565b610f31565b60405191829182901515815260200190565b610120818303126101fd57803567ffffffffffffffff81116101fd5782610383918301610224565b9290936103938260208501610202565b926103a18360408301610217565b926103af8160608401610202565b92608083013567ffffffffffffffff81116101fd57826103d0918501610224565b9290936103e08260a08301610202565b926101e86103f18460c08501610217565b936101006104028260e08701610217565b9401610217565b6102f961042c61041a36600461035b565b99989098979197969296959395611383565b6040515b918291826001600160e01b0319909116815260200190565b906080828203126101fd5761045d8183610202565b9261046b8260208501610202565b926104798360408301610217565b92606082013567ffffffffffffffff81116101fd576102d49201610224565b346101fd576102f961042c6104ae366004610448565b939290926113ab565b9190916040818403126101fd576104ce8382610217565b92602082013567ffffffffffffffff81116101fd576102d49201610224565b346101fd576102f961042c6105033660046104b7565b916113c6565b60009103126101fd57565b6101e8916008021c6001600160a01b031690565b906101e89154610514565b6101e860006003610528565b346101fd5761054f366004610509565b6102f961055a610533565b604051918291826001600160a01b03909116815260200190565b909182601f830112156101fd5781359167ffffffffffffffff83116101fd5760200192602083028401116101fd57565b9091610120828403126101fd57813567ffffffffffffffff81116101fd57836105ce918401610224565b9290936105de8160208401610202565b92604083013567ffffffffffffffff81116101fd57826105ff918501610574565b929093606081013567ffffffffffffffff81116101fd5782610622918301610574565b929093608083013567ffffffffffffffff81116101fd57826103d0918501610574565b6102f961042c6106563660046105a4565b9b9a909a999199989298979397969496611631565b6101e8916008021c81565b906101e8915461066b565b6101e860006002610676565b346101fd5761069d366004610509565b6102f96106a8610681565b6040519182918290815260200190565b91906040838203126101fd576101e89060206104028286610217565b60005b8381106106e75750506000910152565b81810151838201526020016106d7565b61071861072160209361072b9361070c815190565b80835293849260200190565b958691016106d4565b601f01601f191690565b0190565b60208082526101e8929101906106f7565b346101fd576102f961075c6107563660046106b8565b9061169e565b6040519182918261072f565b906020828203126101fd576101e891610202565b346101fd576102f9610349610792366004610768565b6116ed565b6101e860006007610528565b346101fd576107b3366004610509565b6102f961055a610797565b634e487b7160e01b600052604160045260246000fd5b90601f01601f1916810190811067ffffffffffffffff8211176107f657604052565b6107be565b9061020f61080860405190565b92836107d4565b67ffffffffffffffff81116107f657602090601f01601f19160190565b90826000939282370152565b9092919261084d6108488261080f565b6107fb565b93818552818301116101fd5761020f91602085019061082c565b9080601f830112156101fd578160206101e893359101610838565b919091610100818403126101fd5761089a8382610217565b926108a88160208401610202565b926108b68260408501610202565b926108c48360608301610202565b926108d28160808401610202565b926108e08260a08501610217565b926108ee8360c08301610217565b9260e082013567ffffffffffffffff81116101fd576101e89201610867565b346101fd5761092f610920366004610882565b9695909594919493929361188a565b604051005b610120818303126101fd57803567ffffffffffffffff81116101fd578261095c918301610224565b92909361096c8260208501610202565b9261097a8360408301610202565b926103af8160608401610217565b6102f961042c610999366004610934565b99989098979197969296959395611a2c565b346101fd576109bb366004610509565b6102f961055a611a41565b6101e860006006610676565b346101fd576109e2366004610509565b6102f96106a86109c6565b6101e860006005610676565b346101fd57610a09366004610509565b6102f96106a86109ed565b90916080828403126101fd57813567ffffffffffffffff81116101fd5783610a3d918401610224565b929093602082013567ffffffffffffffff81116101fd5781610a60918401610574565b929093604082013567ffffffffffffffff81116101fd5783610a83918401610574565b929093606082013567ffffffffffffffff81116101fd576102d49201610574565b6102f961042c610ab5366004610a14565b96959095949194939293611b61565b9190916040818403126101fd57610adb8382610202565b92602082013567ffffffffffffffff81116101fd576101e89201610867565b346101fd57610b0a366004610ac4565b90611b73565b9160a0838303126101fd57610b258284610202565b92610b338360208301610202565b92604082013567ffffffffffffffff81116101fd5781610b54918401610574565b929093606082013567ffffffffffffffff81116101fd5783610b77918401610574565b929093608082013567ffffffffffffffff81116101fd576102d49201610224565b346101fd576102f961042c610bae366004610b10565b96959095949194939293611b96565b6080818303126101fd57803567ffffffffffffffff81116101fd5782610be4918301610224565b929093610bf48260208501610217565b926104798360408301610202565b6102f961042c610c13366004610bbd565b94939093929192611c2d565b6101e860006004610528565b346101fd57610c3b366004610509565b6102f961055a610c1f565b6080818303126101fd57803567ffffffffffffffff81116101fd5782610c6d918301610224565b92909361046b8260208501610202565b6102f961042c610c8e366004610c46565b94939093929192611c82565b6102f961042c610cab366004610bbd565b94939093929192611cea565b346101fd57610cc7366004610509565b6102f96106a8611cfa565b6102f961042c610ce336600461035b565b99989098979197969296959395611d7f565b91909160a0818403126101fd57610d0c8382610202565b92610d1a8160208401610202565b92610d288260408501610217565b92610d368360608301610217565b92608082013567ffffffffffffffff81116101fd576102d49201610224565b346101fd576102f961042c610d6b366004610cf5565b94939093929192611d94565b90610d846108488361080f565b918252565b610d936005610d77565b7f312e302e30000000000000000000000000000000000000000000000000000000602082015290565b6101e8610d89565b6101e8610dbc565b6101e8610dc4565b346101fd57610de4366004610509565b6102f961075c610dcc565b634e487b7160e01b600052600060045260246000fd5b634e487b7160e01b600052602260045260246000fd5b9060016002830492168015610e3b575b6020831014610e3657565b610e05565b91607f1691610e2b565b80546000939291610e62610e5883610e1b565b8085529360200190565b9160018116908115610eb45750600114610e7b57505050565b610e8e9192939450600052602060002090565b916000925b818410610ea05750500190565b805484840152602090930192600101610e93565b92949550505060ff1916825215156020020190565b906101e891610e45565b9061020f610eed92610ee460405190565b93848092610ec9565b03836107d4565b90600010610f05576101e890610ed3565b610def565b6101e860006008610ef4565b346101fd57610f26366004610509565b6102f961075c610f0a565b630271189760e51b6001600160e01b0319821614908115610f73575b8115610f57575090565b6301ffc9a760e01b91506001600160e01b0319161490565b1490565b6001600160e01b03198116630a85bd0160e11b149150610f4d565b15610f9557565b60405162461bcd60e51b815260206004820152603360248201527f45524332373731436f6e746578743a2063616c6c6572206973206e6f7420746860448201527f65207472757374656420666f72776172646572000000000000000000000000006064820152608490fd5b906101e89b9a99989796959493929161102061101b336116ed565b610f8e565b611256565b6101e89081565b6101e89054611025565b6101e8906101dc565b6101e89054611036565b6001600160e01b03191690565b90600019905b9181191691161790565b906110746101e861107b9290565b8254611056565b9055565b906001600160a01b039061105c565b6101dc6101e86101e8926001600160a01b031690565b6101e89061108e565b6101e8906110a4565b906110c66101e861107b926110ad565b825461107f565b9160001960089290920291821b911b61105c565b6101e86101e86101e89290565b91906110ff6101e861107b936110e1565b9083546110cd565b61020f916000916110ee565b81811061111e575050565b8061112c6000600193611107565b01611113565b9190601f811161114157505050565b61115361020f93600052602060002090565b906020601f840181900483019310611175575b6020601f909101040190611113565b9091508190611166565b919067ffffffffffffffff82116107f6576111a48261119e8554610e1b565b85611132565b600090601f83116001146111df5761107b9291600091836111d4575b5050600019600883021c1916906002021790565b0135905038806111c0565b90601f198316916111f585600052602060002090565b92825b81811061123357509160029391856001969410611219575b50505002019055565b0135600019601f84166008021c19165b9055388080611210565b929360206001819287860135815501950193016111f8565b9061020f929161117f565b9061128e9261129294929c959b9896979c9a999a50611273611dc0565b61127d600661102c565b91611288600461103f565b93611dd8565b1590565b61136d5761128e6112a39187611ebb565b61131a576112e6966112c56112cc936112be5a996005611066565b60036110b6565b600861124b565b6112d6600761103f565b91637b7f3a6560e11b5b946120cf565b907f8922ac534e6e864e81cd941b33848b246d4b01fb868c7536ee54f17a0c6c31f06113158361043060405190565b0390a1565b5050505050505061132f6323a99e1b60e11b90565b7f8922ac534e6e864e81cd941b33848b246d4b01fb868c7536ee54f17a0c6c31f061135960405190565b6001600160e01b031983168152602090a190565b505050505050505061132f63dbb8b2d360e01b90565b6101e89a999897969594939291906000611000565b6110496113a56101e89290565b60e01b90565b50505050506113b8600090565b506101e863150b7a02611398565b6113f092906113d5600561102c565b906113e0600361103f565b926113ea306110ad565b9461224b565b15611402576101e8631626ba7e611398565b6101e863ffffffff611398565b906101e89d9c9b9a99989796959493929161142c61101b336116ed565b611565565b67ffffffffffffffff81116107f65760208091020190565b9092919261145961084882611431565b93818552602080860192028301928184116101fd57915b83831061147d5750505050565b6020809161148b8486610202565b815201920191611470565b6101e8913691611449565b909291926114b161084882611431565b93818552602080860192028301928184116101fd57915b8383106114d55750505050565b602080916114e38486610217565b8152019201916114c8565b6101e89136916114a1565b92919061150861084882611431565b93818552602080860192028101918383116101fd5781905b83821061152e575050505050565b813567ffffffffffffffff81116101fd5760209161154f8784938701610867565b815201910190611520565b6101e89136916114f9565b9061128e9261159894929e959d9a989e9c99969b9c50611583611dc0565b61158d600561102c565b91611288600361103f565b611619576115a69088611ebb565b15611602576115d86115de936115d26112e69b6115cc5a9a632e9de83560e21b9d611496565b956114ee565b9261155a565b916122e5565b6115f3575b6115ed600761103f565b926120cf565b639b951eb360e01b94506115e3565b50505050505050505061132f6323a99e1b60e11b90565b5050505050505050505061132f63dbb8b2d360e01b90565b6101e89c9b9a99989796959493929190600061140f565b634e487b7160e01b600052601160045260246000fd5b8181029291811591840414171561167157565b611648565b369037565b9061020f61169161168b84610d77565b9361080f565b601f190160208401611676565b916020906116bd6116b86116b260206110e1565b8561165e565b61167b565b906116c860006110e1565b848110156116e4578086015484820285850101526001016116c8565b50935091505090565b610f6f6116fb6101dc611a41565b916001600160a01b031690565b1561170f57565b60405162461bcd60e51b815260206004820152601b60248201527f467573696f6e3a20616c726561647920696e697469616c697a656400000000006044820152606490fd5b6101dc6101e86101e89290565b6101e890611754565b90611773815190565b9067ffffffffffffffff82116107f6576117918261119e8554610e1b565b602090601f83116001146117cb5761107b9291600091836117c0575050600019600883021c1916906002021790565b0151905038806111c0565b601f198316916117e085600052602060002090565b9260005b818110611818575091600293918560019694106118045750505002019055565b01516000196008601f8516021c1916611229565b919360206001819287870151815501950192016117e4565b9061020f9161176a565b9081526001600160a01b039182166020820152918116604083015291821660608201529116608082015260a081019190915260c081019190915261010060e082018190526101e8929101906106f7565b94909591937f314b36f555c877d28c7b478c1b405da361e6dab513b63ed9aca48c65cdb6717b9793611315956118dd6118c3600261102c565b6118d76118d36101e860006110e1565b9190565b14611708565b6119466118ea600361103f565b61190a6118f76000611761565b916118d76001600160a01b0384166116fb565b611929611917600461103f565b6118d76001600160a01b0384166116fb565b6118d76116fb611939600761103f565b926001600160a01b031690565b61194f82612495565b61195a886002611066565b6119658960036110b6565b6119708160046110b6565b61197b8360076110b6565b611986846005611066565b611991856006611066565b61199c866008611830565b6040519889988961183a565b906101e89b9a9998979695949392916119c361101b336116ed565b6119d3565b6101e8913691610838565b9061128e926119f194929c959c9b989b9a9796999a50611583611dc0565b61136d5761128e611a029187611ebb565b61131a5761128e6115de916112e6985a96611a26632e9de83560e21b9a5a946119c8565b916124e7565b6101e89a9998979695949392919060006119a8565b6101e8600161103f565b15611a5257565b60405162461bcd60e51b815260206004820152602f60248201527f45524332373731436f6e746578743a2063616c6c65722069732074686520747260448201527f757374656420666f7277617264657200000000000000000000000000000000006064820152608490fd5b906101e89897969594939291611add611ad861128e336116ed565b611a4b565b90611b149261128e92999495999896979850611af7611dc0565b611b01600561102c565b90611b0c600361103f565b923394611dd8565b611b4d576115d261128e956115cc611b2f986115d895611496565b611b4057632e9de83560e21b61132f565b639b951eb360e01b61132f565b50505050505061132f63dbb8b2d360e01b90565b6101e897969594939291906000611abd565b6000918291602082519201905af46000523d6020523d600060403e60403d016000fd5b5050505050505050611ba6600090565b506101e863bc197c81611398565b906101e8969594939291611bcd611ad861128e336116ed565b90611bf89261128e929796959750611be3611dc0565b611bed600661102c565b90611b0c600461103f565b611c1b57611c0e936112be6112c5926005611066565b637b7f3a6560e11b61132f565b5050505061132f63dbb8b2d360e01b90565b6101e89594939291906000611bb4565b906101e8969594939291611c56611ad861128e336116ed565b90611c6c9261128e929796959750611af7611dc0565b611c1b57611b2f93611a2661128e945a946119c8565b6101e89594939291906000611c3d565b906101e8969594939291611cab611ad861128e336116ed565b90611cc19261128e929796959750611be3611dc0565b611c1b57611cde93611cd76112c5926006611066565b60046110b6565b620e1ca760e21b61132f565b6101e89594939291906000611c92565b6101e8600961102c565b906101e89b9a999897969594939291611d1f61101b336116ed565b9061128e92611d3c94929c959b9896979c9a999a50611273611dc0565b61136d5761128e611d4d9187611ebb565b61131a576112e6966112c5611d6893611cd75a996006611066565b611d72600761103f565b91620e1ca760e21b6112e0565b6101e89a999897969594939291906000611d04565b505050505050611da2600090565b506101e863f23a6e61611398565b906110746101e861107b926110e1565b611dca600961102c565b6101e8600182016009611db0565b92946101e895611dfc611df7611e019495611df1600090565b50612584565b61272d565b6127ce565b91612924565b60ff81166101f6565b9050519061020f82611e07565b906020828203126101fd576101e891611e10565b6040513d6000823e3d90fd5b9050519061020f82610211565b906020828203126101fd576101e891611e3d565b611e6b6101e86101e89290565b60ff1690565b60ff908116911690039060ff821161167157565b60ff16604d811161167157600a0a90565b634e487b7160e01b600052601260045260246000fd5b8115611eb6570490565b611e96565b90611ec96101dc6000611761565b6001600160a01b0383161461203a57611ee9611ee4836110ad565b6110ad565b916020611ef560405190565b63313ce56760e01b815293849060049082905afa908115611ffb57611f6693600092612000575b50611f2b611ee46020926110ad565b611f34306110ad565b90611f3e60405190565b958692839182916370a0823160e01b8352600483016001600160a01b03909116815260200190565b03915afa928315611ffb57600093611fb4575b506101e8611fa592611f9f611f9a6118d394611f956012611e5e565b611e71565b611e85565b90611eac565b10611faf57600190565b600090565b6118d3919350611fa592611f9f611f9a611fe86101e89460203d602011611ff4575b611fe081836107d4565b810190611e4a565b96945050509250611f79565b503d611fd6565b611e31565b6020919250611ee461202a611f2b92843d8611612033575b61202281836107d4565b810190611e1d565b93925050611f1c565b503d612018565b9050611fa56118d361204b306110ad565b319290565b9190820391821161167157565b9190820180921161167157565b3d15612084576120793d610d77565b903d6000602084013e565b606090565b8015156101f6565b9050519061020f82612089565b906020828203126101fd576101e891612091565b6001600160a01b03909116815260408101929161020f9160200152565b6120f7926120ed6120f2929695966120e5600090565b505a90612050565b61205d565b61165e565b916121056101dc6000611761565b6001600160a01b0383161461221d57612120611ee4836110ad565b91602061212c60405190565b63313ce56760e01b815293849060049082905afa8015611ffb576121a2946020946000926121ec575b50611f9f611f9a61216c611ee461217795966110ad565b94611f956012611e5e565b91600061218360405190565b80968195829461219763a9059cbb60e01b90565b8452600484016120b2565b03925af190816121bf575b506101e8575b50635f953edb60e01b90565b6121e09060203d6020116121e5575b6121d881836107d4565b81019061209e565b6121ad565b503d6121ce565b6121779250611f9a61216c611ee4612213611f9f948a3d8c116120335761202281836107d4565b9550505050612155565b6000915081906122449361223060405190565b90818003925af161223f61206a565b501590565b6121b35790565b92946101e895611e01929361225e600090565b506127ce565b1561226b57565b60405162461bcd60e51b815260206004820152601860248201527f4172726179206c656e67746873206d757374206d6174636800000000000000006044820152606490fd5b634e487b7160e01b600052603260045260246000fd5b906122cf825190565b8110156122e0576020809102010190565b6122b0565b9291906000916122f3855190565b6123016118d36101e8855190565b148061238f575b61231190612264565b61231b60006110e1565b925b6123286101e8875190565b841015612388575061237161234d61234085886122c6565b516001600160a01b031690565b61235e61235a86866122c6565b5190565b61236886856122c6565b51905a926124e7565b928315612381576001019261231d565b5050509150565b9450505050565b5061231161239b865190565b6123a96118d36101e8855190565b149050612308565b156123b857565b60405162461bcd60e51b815260206004820152602560248201527f45524332373731436f6e746578743a20666f7277617264657220616c7265616460448201527f79207365740000000000000000000000000000000000000000000000000000006064820152608490fd5b1561242a57565b60405162461bcd60e51b815260206004820152602960248201527f45524332373731436f6e746578743a20696e76616c696420747275737465642060448201527f666f7277617264657200000000000000000000000000000000000000000000006064820152608490fd5b61020f906124e06124cf6124a9600161103f565b6101dc6124b66000611761565b916124c96001600160a01b0384166116fb565b146123b1565b6001600160a01b0383161415612423565b60016110b6565b600093849392909160208451940192f190565b6125046001610d77565b600360fc1b602082015290565b6101e86124fa565b8115611eb6570690565b6125396125336101e89260ff1690565b60f81b90565b7fff000000000000000000000000000000000000000000000000000000000000001690565b60001981146116715760010190565b90612576825190565b8110156122e0570160200190565b600091612590836110e1565b82146126ae576125a36116b860646110e1565b916125ad846110e1565b915b6125b8856110e1565b821461261a576125fd6125f86125f36125e8600a95611f9f6125e26125dc896110e1565b83612519565b976110e1565b946120ed60306110e1565b611e5e565b612523565b9261261461260a8261255e565b94871a918661256d565b536125af565b9290506126268261167b565b91612630856110e1565b818110156126a2578061268a61266461265e61269d9461265961265360016110e1565b88612050565b612050565b8661256d565b517fff000000000000000000000000000000000000000000000000000000000000001690565b871a612696828761256d565b5360010190565b612630565b5050506101e891925090565b9150506101e8612511565b6126c3601a610d77565b7f19457468657265756d205369676e6564204d6573736167653a0a000000000000602082015290565b6101e86126b9565b61072b61270c92602092612706815190565b94859290565b938491016106d4565b916127276101e89493612727936126f4565b906126f4565b6101e861277f9161273c600090565b506101e86127486126ec565b612758612753845190565b612584565b9061277361276560405190565b948593602085019384612715565b908103825203826107d4565b61279161278a825190565b9160200190565b2090565b90610d8461084883611431565b9061020f6116916127b284612795565b93611431565b6101e86101e86101e8926001600160a01b031690565b906127e16127dc60226110e1565b6127a2565b936127ec60006110e1565b60206127f7816110e1565b82101561283a578110156122e0576128359061282f61282261281d87841a60f81b612539565b6129b5565b61282c838a6122c6565b52565b60010190565b6127ec565b505093926101e8925061286961286e916128646128739461282c61285e60206110e1565b896122c6565b6110a4565b6127b8565b6110e1565b61282c61288060216110e1565b846122c6565b91906107218161289d8161072b9560209181520190565b809561082c565b906128c46128bd6128b3845190565b8084529260200190565b9260200190565b9060005b8181106128d55750505090565b9091926128f26128eb6001928651815260200190565b9460200190565b9291016128c8565b916101e893916129169160408501918583036000870152612886565b9160208184039101526128a4565b60209291612940611ee46129649661293a600090565b506110ad565b9161294a60405190565b95869485938493633a94343960e21b8552600485016128fa565b03915afa908115611ffb5760009161297a575090565b6101e8915060203d6020116121e5576121d881836107d4565b6101e8906110e1565b6101e8906129b06118d36101e89460ff1690565b901c90565b61286e6129cd6101e8926129c7600090565b50612993565b6129d760f8611e5e565b9061299c56fea26469706673582212202ca903edd4fa68f554fc44ebc0f395515ee50eee8d68db6e1d7a6113d380468a64736f6c63430008180033

Deployed Bytecode

0x60806040526004361015610018575b361561001657005b005b60003560e01c806223de29146101d757806301ffc9a7146101d257806303d43e9f146101cd578063150b7a02146101c85780631626ba7e146101c35780631692d4ef146101be57806337ce1908146101b957806352a9674b146101b45780635624b25b146101af578063572b6c05146101aa5780636319c4bc146101a55780636efc71e4146101a05780637c15ba261461019b5780637da0a877146101965780637f51ca5114610191578063aef8c46e1461018c578063b44a22f714610187578063b4faba0914610182578063bc197c811461017d578063be0a05ee14610178578063c00eb6b214610173578063c1e67bec1461016e578063cbe4c34414610169578063d087d28814610164578063da3279251461015f578063f23a6e611461015a578063ffa1ad74146101555763ffb7aad80361000e57610f16565b610dd4565b610d55565b610cd2565b610cb7565b610c9a565b610c7d565b610c2b565b610c02565b610b98565b610afa565b610aa4565b6109f9565b6109d2565b6109ab565b610988565b61090d565b6107a3565b61077c565b610740565b61068d565b610645565b61053f565b6104ed565b610498565b610409565b61032e565b6102d8565b6001600160a01b031690565b90565b6001600160a01b0381165b036101fd57565b600080fd5b9050359061020f826101eb565b565b806101f6565b9050359061020f82610211565b909182601f830112156101fd5781359167ffffffffffffffff83116101fd5760200192600183028401116101fd57565b60c0818303126101fd576102688282610202565b926102768360208401610202565b926102848160408501610202565b926102928260608301610217565b92608082013567ffffffffffffffff81116101fd57836102b3918401610224565b92909360a082013567ffffffffffffffff81116101fd576102d49201610224565b9091565b346101fd576102e8366004610254565b505050505050505061001660405190565b0390f35b6001600160e01b031981166101f6565b9050359061020f826102fd565b906020828203126101fd576101e89161030d565b346101fd576102f961034961034436600461031a565b610f31565b60405191829182901515815260200190565b610120818303126101fd57803567ffffffffffffffff81116101fd5782610383918301610224565b9290936103938260208501610202565b926103a18360408301610217565b926103af8160608401610202565b92608083013567ffffffffffffffff81116101fd57826103d0918501610224565b9290936103e08260a08301610202565b926101e86103f18460c08501610217565b936101006104028260e08701610217565b9401610217565b6102f961042c61041a36600461035b565b99989098979197969296959395611383565b6040515b918291826001600160e01b0319909116815260200190565b906080828203126101fd5761045d8183610202565b9261046b8260208501610202565b926104798360408301610217565b92606082013567ffffffffffffffff81116101fd576102d49201610224565b346101fd576102f961042c6104ae366004610448565b939290926113ab565b9190916040818403126101fd576104ce8382610217565b92602082013567ffffffffffffffff81116101fd576102d49201610224565b346101fd576102f961042c6105033660046104b7565b916113c6565b60009103126101fd57565b6101e8916008021c6001600160a01b031690565b906101e89154610514565b6101e860006003610528565b346101fd5761054f366004610509565b6102f961055a610533565b604051918291826001600160a01b03909116815260200190565b909182601f830112156101fd5781359167ffffffffffffffff83116101fd5760200192602083028401116101fd57565b9091610120828403126101fd57813567ffffffffffffffff81116101fd57836105ce918401610224565b9290936105de8160208401610202565b92604083013567ffffffffffffffff81116101fd57826105ff918501610574565b929093606081013567ffffffffffffffff81116101fd5782610622918301610574565b929093608083013567ffffffffffffffff81116101fd57826103d0918501610574565b6102f961042c6106563660046105a4565b9b9a909a999199989298979397969496611631565b6101e8916008021c81565b906101e8915461066b565b6101e860006002610676565b346101fd5761069d366004610509565b6102f96106a8610681565b6040519182918290815260200190565b91906040838203126101fd576101e89060206104028286610217565b60005b8381106106e75750506000910152565b81810151838201526020016106d7565b61071861072160209361072b9361070c815190565b80835293849260200190565b958691016106d4565b601f01601f191690565b0190565b60208082526101e8929101906106f7565b346101fd576102f961075c6107563660046106b8565b9061169e565b6040519182918261072f565b906020828203126101fd576101e891610202565b346101fd576102f9610349610792366004610768565b6116ed565b6101e860006007610528565b346101fd576107b3366004610509565b6102f961055a610797565b634e487b7160e01b600052604160045260246000fd5b90601f01601f1916810190811067ffffffffffffffff8211176107f657604052565b6107be565b9061020f61080860405190565b92836107d4565b67ffffffffffffffff81116107f657602090601f01601f19160190565b90826000939282370152565b9092919261084d6108488261080f565b6107fb565b93818552818301116101fd5761020f91602085019061082c565b9080601f830112156101fd578160206101e893359101610838565b919091610100818403126101fd5761089a8382610217565b926108a88160208401610202565b926108b68260408501610202565b926108c48360608301610202565b926108d28160808401610202565b926108e08260a08501610217565b926108ee8360c08301610217565b9260e082013567ffffffffffffffff81116101fd576101e89201610867565b346101fd5761092f610920366004610882565b9695909594919493929361188a565b604051005b610120818303126101fd57803567ffffffffffffffff81116101fd578261095c918301610224565b92909361096c8260208501610202565b9261097a8360408301610202565b926103af8160608401610217565b6102f961042c610999366004610934565b99989098979197969296959395611a2c565b346101fd576109bb366004610509565b6102f961055a611a41565b6101e860006006610676565b346101fd576109e2366004610509565b6102f96106a86109c6565b6101e860006005610676565b346101fd57610a09366004610509565b6102f96106a86109ed565b90916080828403126101fd57813567ffffffffffffffff81116101fd5783610a3d918401610224565b929093602082013567ffffffffffffffff81116101fd5781610a60918401610574565b929093604082013567ffffffffffffffff81116101fd5783610a83918401610574565b929093606082013567ffffffffffffffff81116101fd576102d49201610574565b6102f961042c610ab5366004610a14565b96959095949194939293611b61565b9190916040818403126101fd57610adb8382610202565b92602082013567ffffffffffffffff81116101fd576101e89201610867565b346101fd57610b0a366004610ac4565b90611b73565b9160a0838303126101fd57610b258284610202565b92610b338360208301610202565b92604082013567ffffffffffffffff81116101fd5781610b54918401610574565b929093606082013567ffffffffffffffff81116101fd5783610b77918401610574565b929093608082013567ffffffffffffffff81116101fd576102d49201610224565b346101fd576102f961042c610bae366004610b10565b96959095949194939293611b96565b6080818303126101fd57803567ffffffffffffffff81116101fd5782610be4918301610224565b929093610bf48260208501610217565b926104798360408301610202565b6102f961042c610c13366004610bbd565b94939093929192611c2d565b6101e860006004610528565b346101fd57610c3b366004610509565b6102f961055a610c1f565b6080818303126101fd57803567ffffffffffffffff81116101fd5782610c6d918301610224565b92909361046b8260208501610202565b6102f961042c610c8e366004610c46565b94939093929192611c82565b6102f961042c610cab366004610bbd565b94939093929192611cea565b346101fd57610cc7366004610509565b6102f96106a8611cfa565b6102f961042c610ce336600461035b565b99989098979197969296959395611d7f565b91909160a0818403126101fd57610d0c8382610202565b92610d1a8160208401610202565b92610d288260408501610217565b92610d368360608301610217565b92608082013567ffffffffffffffff81116101fd576102d49201610224565b346101fd576102f961042c610d6b366004610cf5565b94939093929192611d94565b90610d846108488361080f565b918252565b610d936005610d77565b7f312e302e30000000000000000000000000000000000000000000000000000000602082015290565b6101e8610d89565b6101e8610dbc565b6101e8610dc4565b346101fd57610de4366004610509565b6102f961075c610dcc565b634e487b7160e01b600052600060045260246000fd5b634e487b7160e01b600052602260045260246000fd5b9060016002830492168015610e3b575b6020831014610e3657565b610e05565b91607f1691610e2b565b80546000939291610e62610e5883610e1b565b8085529360200190565b9160018116908115610eb45750600114610e7b57505050565b610e8e9192939450600052602060002090565b916000925b818410610ea05750500190565b805484840152602090930192600101610e93565b92949550505060ff1916825215156020020190565b906101e891610e45565b9061020f610eed92610ee460405190565b93848092610ec9565b03836107d4565b90600010610f05576101e890610ed3565b610def565b6101e860006008610ef4565b346101fd57610f26366004610509565b6102f961075c610f0a565b630271189760e51b6001600160e01b0319821614908115610f73575b8115610f57575090565b6301ffc9a760e01b91506001600160e01b0319161490565b1490565b6001600160e01b03198116630a85bd0160e11b149150610f4d565b15610f9557565b60405162461bcd60e51b815260206004820152603360248201527f45524332373731436f6e746578743a2063616c6c6572206973206e6f7420746860448201527f65207472757374656420666f72776172646572000000000000000000000000006064820152608490fd5b906101e89b9a99989796959493929161102061101b336116ed565b610f8e565b611256565b6101e89081565b6101e89054611025565b6101e8906101dc565b6101e89054611036565b6001600160e01b03191690565b90600019905b9181191691161790565b906110746101e861107b9290565b8254611056565b9055565b906001600160a01b039061105c565b6101dc6101e86101e8926001600160a01b031690565b6101e89061108e565b6101e8906110a4565b906110c66101e861107b926110ad565b825461107f565b9160001960089290920291821b911b61105c565b6101e86101e86101e89290565b91906110ff6101e861107b936110e1565b9083546110cd565b61020f916000916110ee565b81811061111e575050565b8061112c6000600193611107565b01611113565b9190601f811161114157505050565b61115361020f93600052602060002090565b906020601f840181900483019310611175575b6020601f909101040190611113565b9091508190611166565b919067ffffffffffffffff82116107f6576111a48261119e8554610e1b565b85611132565b600090601f83116001146111df5761107b9291600091836111d4575b5050600019600883021c1916906002021790565b0135905038806111c0565b90601f198316916111f585600052602060002090565b92825b81811061123357509160029391856001969410611219575b50505002019055565b0135600019601f84166008021c19165b9055388080611210565b929360206001819287860135815501950193016111f8565b9061020f929161117f565b9061128e9261129294929c959b9896979c9a999a50611273611dc0565b61127d600661102c565b91611288600461103f565b93611dd8565b1590565b61136d5761128e6112a39187611ebb565b61131a576112e6966112c56112cc936112be5a996005611066565b60036110b6565b600861124b565b6112d6600761103f565b91637b7f3a6560e11b5b946120cf565b907f8922ac534e6e864e81cd941b33848b246d4b01fb868c7536ee54f17a0c6c31f06113158361043060405190565b0390a1565b5050505050505061132f6323a99e1b60e11b90565b7f8922ac534e6e864e81cd941b33848b246d4b01fb868c7536ee54f17a0c6c31f061135960405190565b6001600160e01b031983168152602090a190565b505050505050505061132f63dbb8b2d360e01b90565b6101e89a999897969594939291906000611000565b6110496113a56101e89290565b60e01b90565b50505050506113b8600090565b506101e863150b7a02611398565b6113f092906113d5600561102c565b906113e0600361103f565b926113ea306110ad565b9461224b565b15611402576101e8631626ba7e611398565b6101e863ffffffff611398565b906101e89d9c9b9a99989796959493929161142c61101b336116ed565b611565565b67ffffffffffffffff81116107f65760208091020190565b9092919261145961084882611431565b93818552602080860192028301928184116101fd57915b83831061147d5750505050565b6020809161148b8486610202565b815201920191611470565b6101e8913691611449565b909291926114b161084882611431565b93818552602080860192028301928184116101fd57915b8383106114d55750505050565b602080916114e38486610217565b8152019201916114c8565b6101e89136916114a1565b92919061150861084882611431565b93818552602080860192028101918383116101fd5781905b83821061152e575050505050565b813567ffffffffffffffff81116101fd5760209161154f8784938701610867565b815201910190611520565b6101e89136916114f9565b9061128e9261159894929e959d9a989e9c99969b9c50611583611dc0565b61158d600561102c565b91611288600361103f565b611619576115a69088611ebb565b15611602576115d86115de936115d26112e69b6115cc5a9a632e9de83560e21b9d611496565b956114ee565b9261155a565b916122e5565b6115f3575b6115ed600761103f565b926120cf565b639b951eb360e01b94506115e3565b50505050505050505061132f6323a99e1b60e11b90565b5050505050505050505061132f63dbb8b2d360e01b90565b6101e89c9b9a99989796959493929190600061140f565b634e487b7160e01b600052601160045260246000fd5b8181029291811591840414171561167157565b611648565b369037565b9061020f61169161168b84610d77565b9361080f565b601f190160208401611676565b916020906116bd6116b86116b260206110e1565b8561165e565b61167b565b906116c860006110e1565b848110156116e4578086015484820285850101526001016116c8565b50935091505090565b610f6f6116fb6101dc611a41565b916001600160a01b031690565b1561170f57565b60405162461bcd60e51b815260206004820152601b60248201527f467573696f6e3a20616c726561647920696e697469616c697a656400000000006044820152606490fd5b6101dc6101e86101e89290565b6101e890611754565b90611773815190565b9067ffffffffffffffff82116107f6576117918261119e8554610e1b565b602090601f83116001146117cb5761107b9291600091836117c0575050600019600883021c1916906002021790565b0151905038806111c0565b601f198316916117e085600052602060002090565b9260005b818110611818575091600293918560019694106118045750505002019055565b01516000196008601f8516021c1916611229565b919360206001819287870151815501950192016117e4565b9061020f9161176a565b9081526001600160a01b039182166020820152918116604083015291821660608201529116608082015260a081019190915260c081019190915261010060e082018190526101e8929101906106f7565b94909591937f314b36f555c877d28c7b478c1b405da361e6dab513b63ed9aca48c65cdb6717b9793611315956118dd6118c3600261102c565b6118d76118d36101e860006110e1565b9190565b14611708565b6119466118ea600361103f565b61190a6118f76000611761565b916118d76001600160a01b0384166116fb565b611929611917600461103f565b6118d76001600160a01b0384166116fb565b6118d76116fb611939600761103f565b926001600160a01b031690565b61194f82612495565b61195a886002611066565b6119658960036110b6565b6119708160046110b6565b61197b8360076110b6565b611986846005611066565b611991856006611066565b61199c866008611830565b6040519889988961183a565b906101e89b9a9998979695949392916119c361101b336116ed565b6119d3565b6101e8913691610838565b9061128e926119f194929c959c9b989b9a9796999a50611583611dc0565b61136d5761128e611a029187611ebb565b61131a5761128e6115de916112e6985a96611a26632e9de83560e21b9a5a946119c8565b916124e7565b6101e89a9998979695949392919060006119a8565b6101e8600161103f565b15611a5257565b60405162461bcd60e51b815260206004820152602f60248201527f45524332373731436f6e746578743a2063616c6c65722069732074686520747260448201527f757374656420666f7277617264657200000000000000000000000000000000006064820152608490fd5b906101e89897969594939291611add611ad861128e336116ed565b611a4b565b90611b149261128e92999495999896979850611af7611dc0565b611b01600561102c565b90611b0c600361103f565b923394611dd8565b611b4d576115d261128e956115cc611b2f986115d895611496565b611b4057632e9de83560e21b61132f565b639b951eb360e01b61132f565b50505050505061132f63dbb8b2d360e01b90565b6101e897969594939291906000611abd565b6000918291602082519201905af46000523d6020523d600060403e60403d016000fd5b5050505050505050611ba6600090565b506101e863bc197c81611398565b906101e8969594939291611bcd611ad861128e336116ed565b90611bf89261128e929796959750611be3611dc0565b611bed600661102c565b90611b0c600461103f565b611c1b57611c0e936112be6112c5926005611066565b637b7f3a6560e11b61132f565b5050505061132f63dbb8b2d360e01b90565b6101e89594939291906000611bb4565b906101e8969594939291611c56611ad861128e336116ed565b90611c6c9261128e929796959750611af7611dc0565b611c1b57611b2f93611a2661128e945a946119c8565b6101e89594939291906000611c3d565b906101e8969594939291611cab611ad861128e336116ed565b90611cc19261128e929796959750611be3611dc0565b611c1b57611cde93611cd76112c5926006611066565b60046110b6565b620e1ca760e21b61132f565b6101e89594939291906000611c92565b6101e8600961102c565b906101e89b9a999897969594939291611d1f61101b336116ed565b9061128e92611d3c94929c959b9896979c9a999a50611273611dc0565b61136d5761128e611d4d9187611ebb565b61131a576112e6966112c5611d6893611cd75a996006611066565b611d72600761103f565b91620e1ca760e21b6112e0565b6101e89a999897969594939291906000611d04565b505050505050611da2600090565b506101e863f23a6e61611398565b906110746101e861107b926110e1565b611dca600961102c565b6101e8600182016009611db0565b92946101e895611dfc611df7611e019495611df1600090565b50612584565b61272d565b6127ce565b91612924565b60ff81166101f6565b9050519061020f82611e07565b906020828203126101fd576101e891611e10565b6040513d6000823e3d90fd5b9050519061020f82610211565b906020828203126101fd576101e891611e3d565b611e6b6101e86101e89290565b60ff1690565b60ff908116911690039060ff821161167157565b60ff16604d811161167157600a0a90565b634e487b7160e01b600052601260045260246000fd5b8115611eb6570490565b611e96565b90611ec96101dc6000611761565b6001600160a01b0383161461203a57611ee9611ee4836110ad565b6110ad565b916020611ef560405190565b63313ce56760e01b815293849060049082905afa908115611ffb57611f6693600092612000575b50611f2b611ee46020926110ad565b611f34306110ad565b90611f3e60405190565b958692839182916370a0823160e01b8352600483016001600160a01b03909116815260200190565b03915afa928315611ffb57600093611fb4575b506101e8611fa592611f9f611f9a6118d394611f956012611e5e565b611e71565b611e85565b90611eac565b10611faf57600190565b600090565b6118d3919350611fa592611f9f611f9a611fe86101e89460203d602011611ff4575b611fe081836107d4565b810190611e4a565b96945050509250611f79565b503d611fd6565b611e31565b6020919250611ee461202a611f2b92843d8611612033575b61202281836107d4565b810190611e1d565b93925050611f1c565b503d612018565b9050611fa56118d361204b306110ad565b319290565b9190820391821161167157565b9190820180921161167157565b3d15612084576120793d610d77565b903d6000602084013e565b606090565b8015156101f6565b9050519061020f82612089565b906020828203126101fd576101e891612091565b6001600160a01b03909116815260408101929161020f9160200152565b6120f7926120ed6120f2929695966120e5600090565b505a90612050565b61205d565b61165e565b916121056101dc6000611761565b6001600160a01b0383161461221d57612120611ee4836110ad565b91602061212c60405190565b63313ce56760e01b815293849060049082905afa8015611ffb576121a2946020946000926121ec575b50611f9f611f9a61216c611ee461217795966110ad565b94611f956012611e5e565b91600061218360405190565b80968195829461219763a9059cbb60e01b90565b8452600484016120b2565b03925af190816121bf575b506101e8575b50635f953edb60e01b90565b6121e09060203d6020116121e5575b6121d881836107d4565b81019061209e565b6121ad565b503d6121ce565b6121779250611f9a61216c611ee4612213611f9f948a3d8c116120335761202281836107d4565b9550505050612155565b6000915081906122449361223060405190565b90818003925af161223f61206a565b501590565b6121b35790565b92946101e895611e01929361225e600090565b506127ce565b1561226b57565b60405162461bcd60e51b815260206004820152601860248201527f4172726179206c656e67746873206d757374206d6174636800000000000000006044820152606490fd5b634e487b7160e01b600052603260045260246000fd5b906122cf825190565b8110156122e0576020809102010190565b6122b0565b9291906000916122f3855190565b6123016118d36101e8855190565b148061238f575b61231190612264565b61231b60006110e1565b925b6123286101e8875190565b841015612388575061237161234d61234085886122c6565b516001600160a01b031690565b61235e61235a86866122c6565b5190565b61236886856122c6565b51905a926124e7565b928315612381576001019261231d565b5050509150565b9450505050565b5061231161239b865190565b6123a96118d36101e8855190565b149050612308565b156123b857565b60405162461bcd60e51b815260206004820152602560248201527f45524332373731436f6e746578743a20666f7277617264657220616c7265616460448201527f79207365740000000000000000000000000000000000000000000000000000006064820152608490fd5b1561242a57565b60405162461bcd60e51b815260206004820152602960248201527f45524332373731436f6e746578743a20696e76616c696420747275737465642060448201527f666f7277617264657200000000000000000000000000000000000000000000006064820152608490fd5b61020f906124e06124cf6124a9600161103f565b6101dc6124b66000611761565b916124c96001600160a01b0384166116fb565b146123b1565b6001600160a01b0383161415612423565b60016110b6565b600093849392909160208451940192f190565b6125046001610d77565b600360fc1b602082015290565b6101e86124fa565b8115611eb6570690565b6125396125336101e89260ff1690565b60f81b90565b7fff000000000000000000000000000000000000000000000000000000000000001690565b60001981146116715760010190565b90612576825190565b8110156122e0570160200190565b600091612590836110e1565b82146126ae576125a36116b860646110e1565b916125ad846110e1565b915b6125b8856110e1565b821461261a576125fd6125f86125f36125e8600a95611f9f6125e26125dc896110e1565b83612519565b976110e1565b946120ed60306110e1565b611e5e565b612523565b9261261461260a8261255e565b94871a918661256d565b536125af565b9290506126268261167b565b91612630856110e1565b818110156126a2578061268a61266461265e61269d9461265961265360016110e1565b88612050565b612050565b8661256d565b517fff000000000000000000000000000000000000000000000000000000000000001690565b871a612696828761256d565b5360010190565b612630565b5050506101e891925090565b9150506101e8612511565b6126c3601a610d77565b7f19457468657265756d205369676e6564204d6573736167653a0a000000000000602082015290565b6101e86126b9565b61072b61270c92602092612706815190565b94859290565b938491016106d4565b916127276101e89493612727936126f4565b906126f4565b6101e861277f9161273c600090565b506101e86127486126ec565b612758612753845190565b612584565b9061277361276560405190565b948593602085019384612715565b908103825203826107d4565b61279161278a825190565b9160200190565b2090565b90610d8461084883611431565b9061020f6116916127b284612795565b93611431565b6101e86101e86101e8926001600160a01b031690565b906127e16127dc60226110e1565b6127a2565b936127ec60006110e1565b60206127f7816110e1565b82101561283a578110156122e0576128359061282f61282261281d87841a60f81b612539565b6129b5565b61282c838a6122c6565b52565b60010190565b6127ec565b505093926101e8925061286961286e916128646128739461282c61285e60206110e1565b896122c6565b6110a4565b6127b8565b6110e1565b61282c61288060216110e1565b846122c6565b91906107218161289d8161072b9560209181520190565b809561082c565b906128c46128bd6128b3845190565b8084529260200190565b9260200190565b9060005b8181106128d55750505090565b9091926128f26128eb6001928651815260200190565b9460200190565b9291016128c8565b916101e893916129169160408501918583036000870152612886565b9160208184039101526128a4565b60209291612940611ee46129649661293a600090565b506110ad565b9161294a60405190565b95869485938493633a94343960e21b8552600485016128fa565b03915afa908115611ffb5760009161297a575090565b6101e8915060203d6020116121e5576121d881836107d4565b6101e8906110e1565b6101e8906129b06118d36101e89460ff1690565b901c90565b61286e6129cd6101e8926129c7600090565b50612993565b6129d760f8611e5e565b9061299c56fea26469706673582212202ca903edd4fa68f554fc44ebc0f395515ee50eee8d68db6e1d7a6113d380468a64736f6c63430008180033

Block Transaction Difficulty Gas Used Reward
View All Blocks Produced

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

Validator Index Block Amount
View All Withdrawals

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

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.