ETH Price: $1,984.82 (+1.51%)

Contract

0x77fEF66b77d6a44AeCcCCf911f9864c7b7ca392C
 

Overview

ETH Balance

0 ETH

Eth Value

$0.00

More Info

Private Name Tags

Multichain Info

No addresses found
Transaction Hash
Method
Block
From
To
Set Gateways244202512026-02-09 15:57:4727 days ago1770652667IN
0x77fEF66b...7b7ca392C
0 ETH0.000017980.27668893

Advanced mode:
Parent Transaction Hash Method Block
From
To
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

Contract Source Code Verified (Exact Match)

Contract Name:
OffchainResolver

Compiler Version
v0.8.30+commit.73712a01

Optimization Enabled:
No with 200 runs

Other Settings:
prague EvmVersion
// SPDX-License-Identifier: MIT
pragma solidity >=0.8.13;

import {Ownable} from "@oz/access/Ownable.sol";
import {ERC165} from "@oz/utils/introspection/ERC165.sol";
import {ECDSA} from "@oz/utils/cryptography/ECDSA.sol";
import {IERC7996} from "@ens/utils/IERC7996.sol";
import {ResolverFeatures} from "@ens/resolvers/ResolverFeatures.sol";
import {IExtendedResolver} from "@ens/resolvers/profiles/IExtendedResolver.sol";
import {OffchainLookup} from "@ens/ccipRead/EIP3668.sol";
import {IGatewayProvider} from "@ens/ccipRead/IGatewayProvider.sol";
import {EfficientHashLib} from "solady/utils/EfficientHashLib.sol";

contract OffchainResolver is Ownable, ERC165, IExtendedResolver, IGatewayProvider, IERC7996 {
    error CCIPReadExpired(uint64 expiry);
    error CCIPReadUntrusted(address signed, address expected);

    string[] _gateways;

    /// @notice The current offchain signer.
    address public signer;

    constructor(address signer_, string[] memory gateways_) Ownable(msg.sender) {
        signer = signer_;
        _gateways = gateways_;
    }

    /// @inheritdoc ERC165
    function supportsInterface(bytes4 interfaceId) public view override returns (bool) {
        return interfaceId == type(IExtendedResolver).interfaceId || interfaceId == type(IERC7996).interfaceId
            || interfaceId == type(IGatewayProvider).interfaceId || super.supportsInterface(interfaceId);
    }

    /// @inheritdoc IERC7996
    function supportsFeature(bytes4 featureId) external pure returns (bool) {
        return featureId == ResolverFeatures.RESOLVE_MULTICALL;
    }

    /// @notice Set the offchain signer.
    function setSigner(address signer_) external onlyOwner {
        signer = signer_;
    }

    /// @notice Set the gateways.
    function setGateways(string[] memory gateways_) external onlyOwner {
        _gateways = gateways_;
    }

    /// @inheritdoc IGatewayProvider
    function gateways() external view returns (string[] memory) {
        return _gateways;
    }

    /// @inheritdoc IExtendedResolver
    function resolve(
        bytes calldata,
        /*name*/
        bytes calldata /*data*/
    )
        external
        view
        returns (bytes memory)
    {
        revert OffchainLookup(address(this), _gateways, msg.data, this.resolveCallback.selector, msg.data);
    }

    /// @dev CCIP-Read callback for `resolve()`.
    function resolveCallback(bytes calldata response, bytes calldata request) external view returns (bytes memory) {
        return _verifyResponse(request, response);
    }

    /// @dev Verify the offchain response was signed by `signer`.
    /// @param request The original request data.
    /// @param response The ABI-encoded response: (bytes answer, uint64 expiry, bytes sig).
    /// @return answer The decoded answer from the response.
    /// The signature is verified over: keccak256(0x1900 || address(this) || expiry || keccak256(request) || keccak256(answer))
    function _verifyResponse(bytes memory request, bytes calldata response) internal view returns (bytes memory) {
        (bytes memory answer, uint64 expiry, bytes memory sig) = abi.decode(response, (bytes, uint64, bytes));
        if (expiry < block.timestamp) {
            revert CCIPReadExpired(expiry);
        }
        bytes32 hash = EfficientHashLib.hash(
            abi.encodePacked(
                hex"1900", address(this), expiry, EfficientHashLib.hash(request), EfficientHashLib.hash(answer)
            )
        );
        address signed = ECDSA.recover(hash, sig);
        if (signed != signer) {
            revert CCIPReadUntrusted(signed, signer);
        }
        return answer;
    }
}

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

pragma solidity ^0.8.20;

import {Context} from "../utils/Context.sol";

/**
 * @dev Contract module which provides a basic access control mechanism, where
 * there is an account (an owner) that can be granted exclusive access to
 * specific functions.
 *
 * The initial owner is set to the address provided by the deployer. This can
 * later be changed with {transferOwnership}.
 *
 * This module is used through inheritance. It will make available the modifier
 * `onlyOwner`, which can be applied to your functions to restrict their use to
 * the owner.
 */
abstract contract Ownable is Context {
    address private _owner;

    /**
     * @dev The caller account is not authorized to perform an operation.
     */
    error OwnableUnauthorizedAccount(address account);

    /**
     * @dev The owner is not a valid owner account. (eg. `address(0)`)
     */
    error OwnableInvalidOwner(address owner);

    event OwnershipTransferred(address indexed previousOwner, address indexed newOwner);

    /**
     * @dev Initializes the contract setting the address provided by the deployer as the initial owner.
     */
    constructor(address initialOwner) {
        if (initialOwner == address(0)) {
            revert OwnableInvalidOwner(address(0));
        }
        _transferOwnership(initialOwner);
    }

    /**
     * @dev Throws if called by any account other than the owner.
     */
    modifier onlyOwner() {
        _checkOwner();
        _;
    }

    /**
     * @dev Returns the address of the current owner.
     */
    function owner() public view virtual returns (address) {
        return _owner;
    }

    /**
     * @dev Throws if the sender is not the owner.
     */
    function _checkOwner() internal view virtual {
        if (owner() != _msgSender()) {
            revert OwnableUnauthorizedAccount(_msgSender());
        }
    }

    /**
     * @dev Leaves the contract without owner. It will not be possible to call
     * `onlyOwner` functions. Can only be called by the current owner.
     *
     * NOTE: Renouncing ownership will leave the contract without an owner,
     * thereby disabling any functionality that is only available to the owner.
     */
    function renounceOwnership() public virtual onlyOwner {
        _transferOwnership(address(0));
    }

    /**
     * @dev Transfers ownership of the contract to a new account (`newOwner`).
     * Can only be called by the current owner.
     */
    function transferOwnership(address newOwner) public virtual onlyOwner {
        if (newOwner == address(0)) {
            revert OwnableInvalidOwner(address(0));
        }
        _transferOwnership(newOwner);
    }

    /**
     * @dev Transfers ownership of the contract to a new account (`newOwner`).
     * Internal function without access restriction.
     */
    function _transferOwnership(address newOwner) internal virtual {
        address oldOwner = _owner;
        _owner = newOwner;
        emit OwnershipTransferred(oldOwner, newOwner);
    }
}

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

pragma solidity ^0.8.20;

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

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

// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v5.5.0) (utils/cryptography/ECDSA.sol)

pragma solidity ^0.8.20;

/**
 * @dev Elliptic Curve Digital Signature Algorithm (ECDSA) operations.
 *
 * These functions can be used to verify that a message was signed by the holder
 * of the private keys of a given address.
 */
library ECDSA {
    enum RecoverError {
        NoError,
        InvalidSignature,
        InvalidSignatureLength,
        InvalidSignatureS
    }

    /**
     * @dev The signature derives the `address(0)`.
     */
    error ECDSAInvalidSignature();

    /**
     * @dev The signature has an invalid length.
     */
    error ECDSAInvalidSignatureLength(uint256 length);

    /**
     * @dev The signature has an S value that is in the upper half order.
     */
    error ECDSAInvalidSignatureS(bytes32 s);

    /**
     * @dev Returns the address that signed a hashed message (`hash`) with `signature` or an error. This will not
     * return address(0) without also returning an error description. Errors are documented using an enum (error type)
     * and a bytes32 providing additional information about the error.
     *
     * If no error is returned, then the address can be used for verification purposes.
     *
     * The `ecrecover` EVM precompile allows for malleable (non-unique) signatures:
     * this function rejects them by requiring the `s` value to be in the lower
     * half order, and the `v` value to be either 27 or 28.
     *
     * NOTE: This function only supports 65-byte signatures. ERC-2098 short signatures are rejected. This restriction
     * is DEPRECATED and will be removed in v6.0. Developers SHOULD NOT use signatures as unique identifiers; use hash
     * invalidation or nonces for replay protection.
     *
     * IMPORTANT: `hash` _must_ be the result of a hash operation for the
     * verification to be secure: it is possible to craft signatures that
     * recover to arbitrary addresses for non-hashed data. A safe way to ensure
     * this is by receiving a hash of the original message (which may otherwise
     * be too long), and then calling {MessageHashUtils-toEthSignedMessageHash} on it.
     *
     * Documentation for signature generation:
     *
     * - with https://web3js.readthedocs.io/en/v1.3.4/web3-eth-accounts.html#sign[Web3.js]
     * - with https://docs.ethers.io/v5/api/signer/#Signer-signMessage[ethers]
     */
    function tryRecover(
        bytes32 hash,
        bytes memory signature
    ) internal pure returns (address recovered, RecoverError err, bytes32 errArg) {
        if (signature.length == 65) {
            bytes32 r;
            bytes32 s;
            uint8 v;
            // ecrecover takes the signature parameters, and the only way to get them
            // currently is to use assembly.
            assembly ("memory-safe") {
                r := mload(add(signature, 0x20))
                s := mload(add(signature, 0x40))
                v := byte(0, mload(add(signature, 0x60)))
            }
            return tryRecover(hash, v, r, s);
        } else {
            return (address(0), RecoverError.InvalidSignatureLength, bytes32(signature.length));
        }
    }

    /**
     * @dev Variant of {tryRecover} that takes a signature in calldata
     */
    function tryRecoverCalldata(
        bytes32 hash,
        bytes calldata signature
    ) internal pure returns (address recovered, RecoverError err, bytes32 errArg) {
        if (signature.length == 65) {
            bytes32 r;
            bytes32 s;
            uint8 v;
            // ecrecover takes the signature parameters, calldata slices would work here, but are
            // significantly more expensive (length check) than using calldataload in assembly.
            assembly ("memory-safe") {
                r := calldataload(signature.offset)
                s := calldataload(add(signature.offset, 0x20))
                v := byte(0, calldataload(add(signature.offset, 0x40)))
            }
            return tryRecover(hash, v, r, s);
        } else {
            return (address(0), RecoverError.InvalidSignatureLength, bytes32(signature.length));
        }
    }

    /**
     * @dev Returns the address that signed a hashed message (`hash`) with
     * `signature`. This address can then be used for verification purposes.
     *
     * The `ecrecover` EVM precompile allows for malleable (non-unique) signatures:
     * this function rejects them by requiring the `s` value to be in the lower
     * half order, and the `v` value to be either 27 or 28.
     *
     * NOTE: This function only supports 65-byte signatures. ERC-2098 short signatures are rejected. This restriction
     * is DEPRECATED and will be removed in v6.0. Developers SHOULD NOT use signatures as unique identifiers; use hash
     * invalidation or nonces for replay protection.
     *
     * IMPORTANT: `hash` _must_ be the result of a hash operation for the
     * verification to be secure: it is possible to craft signatures that
     * recover to arbitrary addresses for non-hashed data. A safe way to ensure
     * this is by receiving a hash of the original message (which may otherwise
     * be too long), and then calling {MessageHashUtils-toEthSignedMessageHash} on it.
     */
    function recover(bytes32 hash, bytes memory signature) internal pure returns (address) {
        (address recovered, RecoverError error, bytes32 errorArg) = tryRecover(hash, signature);
        _throwError(error, errorArg);
        return recovered;
    }

    /**
     * @dev Variant of {recover} that takes a signature in calldata
     */
    function recoverCalldata(bytes32 hash, bytes calldata signature) internal pure returns (address) {
        (address recovered, RecoverError error, bytes32 errorArg) = tryRecoverCalldata(hash, signature);
        _throwError(error, errorArg);
        return recovered;
    }

    /**
     * @dev Overload of {ECDSA-tryRecover} that receives the `r` and `vs` short-signature fields separately.
     *
     * See https://eips.ethereum.org/EIPS/eip-2098[ERC-2098 short signatures]
     */
    function tryRecover(
        bytes32 hash,
        bytes32 r,
        bytes32 vs
    ) internal pure returns (address recovered, RecoverError err, bytes32 errArg) {
        unchecked {
            bytes32 s = vs & bytes32(0x7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff);
            // We do not check for an overflow here since the shift operation results in 0 or 1.
            uint8 v = uint8((uint256(vs) >> 255) + 27);
            return tryRecover(hash, v, r, s);
        }
    }

    /**
     * @dev Overload of {ECDSA-recover} that receives the `r and `vs` short-signature fields separately.
     */
    function recover(bytes32 hash, bytes32 r, bytes32 vs) internal pure returns (address) {
        (address recovered, RecoverError error, bytes32 errorArg) = tryRecover(hash, r, vs);
        _throwError(error, errorArg);
        return recovered;
    }

    /**
     * @dev Overload of {ECDSA-tryRecover} that receives the `v`,
     * `r` and `s` signature fields separately.
     */
    function tryRecover(
        bytes32 hash,
        uint8 v,
        bytes32 r,
        bytes32 s
    ) internal pure returns (address recovered, RecoverError err, bytes32 errArg) {
        // EIP-2 still allows signature malleability for ecrecover(). Remove this possibility and make the signature
        // unique. Appendix F in the Ethereum Yellow paper (https://ethereum.github.io/yellowpaper/paper.pdf), defines
        // the valid range for s in (301): 0 < s < secp256k1n ÷ 2 + 1, and for v in (302): v ∈ {27, 28}. Most
        // signatures from current libraries generate a unique signature with an s-value in the lower half order.
        //
        // If your library generates malleable signatures, such as s-values in the upper range, calculate a new s-value
        // with 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEBAAEDCE6AF48A03BBFD25E8CD0364141 - s1 and flip v from 27 to 28 or
        // vice versa. If your library also generates signatures with 0/1 for v instead 27/28, add 27 to v to accept
        // these malleable signatures as well.
        if (uint256(s) > 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5D576E7357A4501DDFE92F46681B20A0) {
            return (address(0), RecoverError.InvalidSignatureS, s);
        }

        // If the signature is valid (and not malleable), return the signer address
        address signer = ecrecover(hash, v, r, s);
        if (signer == address(0)) {
            return (address(0), RecoverError.InvalidSignature, bytes32(0));
        }

        return (signer, RecoverError.NoError, bytes32(0));
    }

    /**
     * @dev Overload of {ECDSA-recover} that receives the `v`,
     * `r` and `s` signature fields separately.
     */
    function recover(bytes32 hash, uint8 v, bytes32 r, bytes32 s) internal pure returns (address) {
        (address recovered, RecoverError error, bytes32 errorArg) = tryRecover(hash, v, r, s);
        _throwError(error, errorArg);
        return recovered;
    }

    /**
     * @dev Parse a signature into its `v`, `r` and `s` components. Supports 65-byte and 64-byte (ERC-2098)
     * formats. Returns (0,0,0) for invalid signatures.
     *
     * For 64-byte signatures, `v` is automatically normalized to 27 or 28.
     * For 65-byte signatures, `v` is returned as-is and MUST already be 27 or 28 for use with ecrecover.
     *
     * Consider validating the result before use, or use {tryRecover}/{recover} which perform full validation.
     */
    function parse(bytes memory signature) internal pure returns (uint8 v, bytes32 r, bytes32 s) {
        assembly ("memory-safe") {
            // Check the signature length
            switch mload(signature)
            // - case 65: r,s,v signature (standard)
            case 65 {
                r := mload(add(signature, 0x20))
                s := mload(add(signature, 0x40))
                v := byte(0, mload(add(signature, 0x60)))
            }
            // - case 64: r,vs signature (cf https://eips.ethereum.org/EIPS/eip-2098)
            case 64 {
                let vs := mload(add(signature, 0x40))
                r := mload(add(signature, 0x20))
                s := and(vs, shr(1, not(0)))
                v := add(shr(255, vs), 27)
            }
            default {
                r := 0
                s := 0
                v := 0
            }
        }
    }

    /**
     * @dev Variant of {parse} that takes a signature in calldata
     */
    function parseCalldata(bytes calldata signature) internal pure returns (uint8 v, bytes32 r, bytes32 s) {
        assembly ("memory-safe") {
            // Check the signature length
            switch signature.length
            // - case 65: r,s,v signature (standard)
            case 65 {
                r := calldataload(signature.offset)
                s := calldataload(add(signature.offset, 0x20))
                v := byte(0, calldataload(add(signature.offset, 0x40)))
            }
            // - case 64: r,vs signature (cf https://eips.ethereum.org/EIPS/eip-2098)
            case 64 {
                let vs := calldataload(add(signature.offset, 0x20))
                r := calldataload(signature.offset)
                s := and(vs, shr(1, not(0)))
                v := add(shr(255, vs), 27)
            }
            default {
                r := 0
                s := 0
                v := 0
            }
        }
    }

    /**
     * @dev Optionally reverts with the corresponding custom error according to the `error` argument provided.
     */
    function _throwError(RecoverError error, bytes32 errorArg) private pure {
        if (error == RecoverError.NoError) {
            return; // no error: do nothing
        } else if (error == RecoverError.InvalidSignature) {
            revert ECDSAInvalidSignature();
        } else if (error == RecoverError.InvalidSignatureLength) {
            revert ECDSAInvalidSignatureLength(uint256(errorArg));
        } else if (error == RecoverError.InvalidSignatureS) {
            revert ECDSAInvalidSignatureS(errorArg);
        }
    }
}

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

/// @notice Interface for expressing contract features not visible from the ABI.
/// @dev Interface selector: `0x582de3e7`
interface IERC7996 {
    /// @notice Check if a feature is supported.
    /// @param featureId The feature identifier.
    /// @return `true` if the feature is supported by the contract.
    function supportsFeature(bytes4 featureId) external view returns (bool);
}

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

library ResolverFeatures {
    /// @notice Implements `resolve(multicall([...]))`.
    /// @dev Feature: `0x96b62db8`
    bytes4 constant RESOLVE_MULTICALL =
        bytes4(keccak256("eth.ens.resolver.extended.multicall"));

    /// @notice Returns the same records independent of name or node.
    /// @dev Feature: `0x86fb8da8`
    bytes4 constant SINGULAR = bytes4(keccak256("eth.ens.resolver.singular"));
}

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

interface IExtendedResolver {
    function resolve(
        bytes memory name,
        bytes memory data
    ) external view returns (bytes memory);
}

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

/// @dev https://eips.ethereum.org/EIPS/eip-3668
/// Error selector: `0x556f1830`
error OffchainLookup(
    address sender,
    string[] urls,
    bytes callData,
    bytes4 callbackFunction,
    bytes extraData
);

/// @dev Simple library for decoding `OffchainLookup` error data.
/// Avoids "stack too deep" issues as the natural decoding consumes 5 variables.
library EIP3668 {
    /// @dev Struct with members matching `OffchainLookup`.
    struct Params {
        address sender;
        string[] urls;
        bytes callData;
        bytes4 callbackFunction;
        bytes extraData;
    }

    /// @dev Decode an `OffchainLookup` into a struct from the data after the error selector.
    function decode(bytes memory v) internal pure returns (Params memory p) {
        (p.sender, p.urls, p.callData, p.callbackFunction, p.extraData) = abi
            .decode(v, (address, string[], bytes, bytes4, bytes));
    }
}

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

/// @notice Interface for shared gateway URLs.
/// @dev Interface selector: `0x093a86d3`
interface IGatewayProvider {
    /// @notice Get the gateways.
    /// @return The gateway URLs.
    function gateways() external view returns (string[] memory);
}

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

/// @notice Library for efficiently performing keccak256 hashes.
/// @author Solady (https://github.com/vectorized/solady/blob/main/src/utils/EfficientHashLib.sol)
/// @dev To avoid stack-too-deep, you can use:
/// ```
/// bytes32[] memory buffer = EfficientHashLib.malloc(10);
/// EfficientHashLib.set(buffer, 0, value0);
/// ..
/// EfficientHashLib.set(buffer, 9, value9);
/// bytes32 finalHash = EfficientHashLib.hash(buffer);
/// ```
library EfficientHashLib {
    /*´:°•.°+.*•´.*:˚.°*.˚•´.°:°•.°•.*•´.*:˚.°*.˚•´.°:°•.°+.*•´.*:*/
    /*               MALLOC-LESS HASHING OPERATIONS               */
    /*.•°:°.´+˚.*°.˚:*.´•*.+°.•°:´*.´•*.•°.•°:°.´:•˚°.*°.˚:*.´+°.•*/

    /// @dev Returns `keccak256(abi.encode(v0))`.
    function hash(bytes32 v0) internal pure returns (bytes32 result) {
        /// @solidity memory-safe-assembly
        assembly {
            mstore(0x00, v0)
            result := keccak256(0x00, 0x20)
        }
    }

    /// @dev Returns `keccak256(abi.encode(v0))`.
    function hash(uint256 v0) internal pure returns (bytes32 result) {
        /// @solidity memory-safe-assembly
        assembly {
            mstore(0x00, v0)
            result := keccak256(0x00, 0x20)
        }
    }

    /// @dev Returns `keccak256(abi.encode(v0, v1))`.
    function hash(bytes32 v0, bytes32 v1) internal pure returns (bytes32 result) {
        /// @solidity memory-safe-assembly
        assembly {
            mstore(0x00, v0)
            mstore(0x20, v1)
            result := keccak256(0x00, 0x40)
        }
    }

    /// @dev Returns `keccak256(abi.encode(v0, v1))`.
    function hash(uint256 v0, uint256 v1) internal pure returns (bytes32 result) {
        /// @solidity memory-safe-assembly
        assembly {
            mstore(0x00, v0)
            mstore(0x20, v1)
            result := keccak256(0x00, 0x40)
        }
    }

    /// @dev Returns `keccak256(abi.encode(v0, v1, v2))`.
    function hash(bytes32 v0, bytes32 v1, bytes32 v2) internal pure returns (bytes32 result) {
        /// @solidity memory-safe-assembly
        assembly {
            let m := mload(0x40)
            mstore(m, v0)
            mstore(add(m, 0x20), v1)
            mstore(add(m, 0x40), v2)
            result := keccak256(m, 0x60)
        }
    }

    /// @dev Returns `keccak256(abi.encode(v0, v1, v2))`.
    function hash(uint256 v0, uint256 v1, uint256 v2) internal pure returns (bytes32 result) {
        /// @solidity memory-safe-assembly
        assembly {
            let m := mload(0x40)
            mstore(m, v0)
            mstore(add(m, 0x20), v1)
            mstore(add(m, 0x40), v2)
            result := keccak256(m, 0x60)
        }
    }

    /// @dev Returns `keccak256(abi.encode(v0, v1, v2, v3))`.
    function hash(bytes32 v0, bytes32 v1, bytes32 v2, bytes32 v3)
        internal
        pure
        returns (bytes32 result)
    {
        /// @solidity memory-safe-assembly
        assembly {
            let m := mload(0x40)
            mstore(m, v0)
            mstore(add(m, 0x20), v1)
            mstore(add(m, 0x40), v2)
            mstore(add(m, 0x60), v3)
            result := keccak256(m, 0x80)
        }
    }

    /// @dev Returns `keccak256(abi.encode(v0, v1, v2, v3))`.
    function hash(uint256 v0, uint256 v1, uint256 v2, uint256 v3)
        internal
        pure
        returns (bytes32 result)
    {
        /// @solidity memory-safe-assembly
        assembly {
            let m := mload(0x40)
            mstore(m, v0)
            mstore(add(m, 0x20), v1)
            mstore(add(m, 0x40), v2)
            mstore(add(m, 0x60), v3)
            result := keccak256(m, 0x80)
        }
    }

    /// @dev Returns `keccak256(abi.encode(v0, .., v4))`.
    function hash(bytes32 v0, bytes32 v1, bytes32 v2, bytes32 v3, bytes32 v4)
        internal
        pure
        returns (bytes32 result)
    {
        /// @solidity memory-safe-assembly
        assembly {
            let m := mload(0x40)
            mstore(m, v0)
            mstore(add(m, 0x20), v1)
            mstore(add(m, 0x40), v2)
            mstore(add(m, 0x60), v3)
            mstore(add(m, 0x80), v4)
            result := keccak256(m, 0xa0)
        }
    }

    /// @dev Returns `keccak256(abi.encode(v0, .., v4))`.
    function hash(uint256 v0, uint256 v1, uint256 v2, uint256 v3, uint256 v4)
        internal
        pure
        returns (bytes32 result)
    {
        /// @solidity memory-safe-assembly
        assembly {
            let m := mload(0x40)
            mstore(m, v0)
            mstore(add(m, 0x20), v1)
            mstore(add(m, 0x40), v2)
            mstore(add(m, 0x60), v3)
            mstore(add(m, 0x80), v4)
            result := keccak256(m, 0xa0)
        }
    }

    /// @dev Returns `keccak256(abi.encode(v0, .., v5))`.
    function hash(bytes32 v0, bytes32 v1, bytes32 v2, bytes32 v3, bytes32 v4, bytes32 v5)
        internal
        pure
        returns (bytes32 result)
    {
        /// @solidity memory-safe-assembly
        assembly {
            let m := mload(0x40)
            mstore(m, v0)
            mstore(add(m, 0x20), v1)
            mstore(add(m, 0x40), v2)
            mstore(add(m, 0x60), v3)
            mstore(add(m, 0x80), v4)
            mstore(add(m, 0xa0), v5)
            result := keccak256(m, 0xc0)
        }
    }

    /// @dev Returns `keccak256(abi.encode(v0, .., v5))`.
    function hash(uint256 v0, uint256 v1, uint256 v2, uint256 v3, uint256 v4, uint256 v5)
        internal
        pure
        returns (bytes32 result)
    {
        /// @solidity memory-safe-assembly
        assembly {
            let m := mload(0x40)
            mstore(m, v0)
            mstore(add(m, 0x20), v1)
            mstore(add(m, 0x40), v2)
            mstore(add(m, 0x60), v3)
            mstore(add(m, 0x80), v4)
            mstore(add(m, 0xa0), v5)
            result := keccak256(m, 0xc0)
        }
    }

    /// @dev Returns `keccak256(abi.encode(v0, .., v6))`.
    function hash(
        bytes32 v0,
        bytes32 v1,
        bytes32 v2,
        bytes32 v3,
        bytes32 v4,
        bytes32 v5,
        bytes32 v6
    ) internal pure returns (bytes32 result) {
        /// @solidity memory-safe-assembly
        assembly {
            let m := mload(0x40)
            mstore(m, v0)
            mstore(add(m, 0x20), v1)
            mstore(add(m, 0x40), v2)
            mstore(add(m, 0x60), v3)
            mstore(add(m, 0x80), v4)
            mstore(add(m, 0xa0), v5)
            mstore(add(m, 0xc0), v6)
            result := keccak256(m, 0xe0)
        }
    }

    /// @dev Returns `keccak256(abi.encode(v0, .., v6))`.
    function hash(
        uint256 v0,
        uint256 v1,
        uint256 v2,
        uint256 v3,
        uint256 v4,
        uint256 v5,
        uint256 v6
    ) internal pure returns (bytes32 result) {
        /// @solidity memory-safe-assembly
        assembly {
            let m := mload(0x40)
            mstore(m, v0)
            mstore(add(m, 0x20), v1)
            mstore(add(m, 0x40), v2)
            mstore(add(m, 0x60), v3)
            mstore(add(m, 0x80), v4)
            mstore(add(m, 0xa0), v5)
            mstore(add(m, 0xc0), v6)
            result := keccak256(m, 0xe0)
        }
    }

    /// @dev Returns `keccak256(abi.encode(v0, .., v7))`.
    function hash(
        bytes32 v0,
        bytes32 v1,
        bytes32 v2,
        bytes32 v3,
        bytes32 v4,
        bytes32 v5,
        bytes32 v6,
        bytes32 v7
    ) internal pure returns (bytes32 result) {
        /// @solidity memory-safe-assembly
        assembly {
            let m := mload(0x40)
            mstore(m, v0)
            mstore(add(m, 0x20), v1)
            mstore(add(m, 0x40), v2)
            mstore(add(m, 0x60), v3)
            mstore(add(m, 0x80), v4)
            mstore(add(m, 0xa0), v5)
            mstore(add(m, 0xc0), v6)
            mstore(add(m, 0xe0), v7)
            result := keccak256(m, 0x100)
        }
    }

    /// @dev Returns `keccak256(abi.encode(v0, .., v7))`.
    function hash(
        uint256 v0,
        uint256 v1,
        uint256 v2,
        uint256 v3,
        uint256 v4,
        uint256 v5,
        uint256 v6,
        uint256 v7
    ) internal pure returns (bytes32 result) {
        /// @solidity memory-safe-assembly
        assembly {
            let m := mload(0x40)
            mstore(m, v0)
            mstore(add(m, 0x20), v1)
            mstore(add(m, 0x40), v2)
            mstore(add(m, 0x60), v3)
            mstore(add(m, 0x80), v4)
            mstore(add(m, 0xa0), v5)
            mstore(add(m, 0xc0), v6)
            mstore(add(m, 0xe0), v7)
            result := keccak256(m, 0x100)
        }
    }

    /// @dev Returns `keccak256(abi.encode(v0, .., v8))`.
    function hash(
        bytes32 v0,
        bytes32 v1,
        bytes32 v2,
        bytes32 v3,
        bytes32 v4,
        bytes32 v5,
        bytes32 v6,
        bytes32 v7,
        bytes32 v8
    ) internal pure returns (bytes32 result) {
        /// @solidity memory-safe-assembly
        assembly {
            let m := mload(0x40)
            mstore(m, v0)
            mstore(add(m, 0x20), v1)
            mstore(add(m, 0x40), v2)
            mstore(add(m, 0x60), v3)
            mstore(add(m, 0x80), v4)
            mstore(add(m, 0xa0), v5)
            mstore(add(m, 0xc0), v6)
            mstore(add(m, 0xe0), v7)
            mstore(add(m, 0x100), v8)
            result := keccak256(m, 0x120)
        }
    }

    /// @dev Returns `keccak256(abi.encode(v0, .., v8))`.
    function hash(
        uint256 v0,
        uint256 v1,
        uint256 v2,
        uint256 v3,
        uint256 v4,
        uint256 v5,
        uint256 v6,
        uint256 v7,
        uint256 v8
    ) internal pure returns (bytes32 result) {
        /// @solidity memory-safe-assembly
        assembly {
            let m := mload(0x40)
            mstore(m, v0)
            mstore(add(m, 0x20), v1)
            mstore(add(m, 0x40), v2)
            mstore(add(m, 0x60), v3)
            mstore(add(m, 0x80), v4)
            mstore(add(m, 0xa0), v5)
            mstore(add(m, 0xc0), v6)
            mstore(add(m, 0xe0), v7)
            mstore(add(m, 0x100), v8)
            result := keccak256(m, 0x120)
        }
    }

    /// @dev Returns `keccak256(abi.encode(v0, .., v9))`.
    function hash(
        bytes32 v0,
        bytes32 v1,
        bytes32 v2,
        bytes32 v3,
        bytes32 v4,
        bytes32 v5,
        bytes32 v6,
        bytes32 v7,
        bytes32 v8,
        bytes32 v9
    ) internal pure returns (bytes32 result) {
        /// @solidity memory-safe-assembly
        assembly {
            let m := mload(0x40)
            mstore(m, v0)
            mstore(add(m, 0x20), v1)
            mstore(add(m, 0x40), v2)
            mstore(add(m, 0x60), v3)
            mstore(add(m, 0x80), v4)
            mstore(add(m, 0xa0), v5)
            mstore(add(m, 0xc0), v6)
            mstore(add(m, 0xe0), v7)
            mstore(add(m, 0x100), v8)
            mstore(add(m, 0x120), v9)
            result := keccak256(m, 0x140)
        }
    }

    /// @dev Returns `keccak256(abi.encode(v0, .., v9))`.
    function hash(
        uint256 v0,
        uint256 v1,
        uint256 v2,
        uint256 v3,
        uint256 v4,
        uint256 v5,
        uint256 v6,
        uint256 v7,
        uint256 v8,
        uint256 v9
    ) internal pure returns (bytes32 result) {
        /// @solidity memory-safe-assembly
        assembly {
            let m := mload(0x40)
            mstore(m, v0)
            mstore(add(m, 0x20), v1)
            mstore(add(m, 0x40), v2)
            mstore(add(m, 0x60), v3)
            mstore(add(m, 0x80), v4)
            mstore(add(m, 0xa0), v5)
            mstore(add(m, 0xc0), v6)
            mstore(add(m, 0xe0), v7)
            mstore(add(m, 0x100), v8)
            mstore(add(m, 0x120), v9)
            result := keccak256(m, 0x140)
        }
    }

    /// @dev Returns `keccak256(abi.encode(v0, .., v10))`.
    function hash(
        bytes32 v0,
        bytes32 v1,
        bytes32 v2,
        bytes32 v3,
        bytes32 v4,
        bytes32 v5,
        bytes32 v6,
        bytes32 v7,
        bytes32 v8,
        bytes32 v9,
        bytes32 v10
    ) internal pure returns (bytes32 result) {
        /// @solidity memory-safe-assembly
        assembly {
            let m := mload(0x40)
            mstore(m, v0)
            mstore(add(m, 0x20), v1)
            mstore(add(m, 0x40), v2)
            mstore(add(m, 0x60), v3)
            mstore(add(m, 0x80), v4)
            mstore(add(m, 0xa0), v5)
            mstore(add(m, 0xc0), v6)
            mstore(add(m, 0xe0), v7)
            mstore(add(m, 0x100), v8)
            mstore(add(m, 0x120), v9)
            mstore(add(m, 0x140), v10)
            result := keccak256(m, 0x160)
        }
    }

    /// @dev Returns `keccak256(abi.encode(v0, .., v10))`.
    function hash(
        uint256 v0,
        uint256 v1,
        uint256 v2,
        uint256 v3,
        uint256 v4,
        uint256 v5,
        uint256 v6,
        uint256 v7,
        uint256 v8,
        uint256 v9,
        uint256 v10
    ) internal pure returns (bytes32 result) {
        /// @solidity memory-safe-assembly
        assembly {
            let m := mload(0x40)
            mstore(m, v0)
            mstore(add(m, 0x20), v1)
            mstore(add(m, 0x40), v2)
            mstore(add(m, 0x60), v3)
            mstore(add(m, 0x80), v4)
            mstore(add(m, 0xa0), v5)
            mstore(add(m, 0xc0), v6)
            mstore(add(m, 0xe0), v7)
            mstore(add(m, 0x100), v8)
            mstore(add(m, 0x120), v9)
            mstore(add(m, 0x140), v10)
            result := keccak256(m, 0x160)
        }
    }

    /// @dev Returns `keccak256(abi.encode(v0, .., v11))`.
    function hash(
        bytes32 v0,
        bytes32 v1,
        bytes32 v2,
        bytes32 v3,
        bytes32 v4,
        bytes32 v5,
        bytes32 v6,
        bytes32 v7,
        bytes32 v8,
        bytes32 v9,
        bytes32 v10,
        bytes32 v11
    ) internal pure returns (bytes32 result) {
        /// @solidity memory-safe-assembly
        assembly {
            let m := mload(0x40)
            mstore(m, v0)
            mstore(add(m, 0x20), v1)
            mstore(add(m, 0x40), v2)
            mstore(add(m, 0x60), v3)
            mstore(add(m, 0x80), v4)
            mstore(add(m, 0xa0), v5)
            mstore(add(m, 0xc0), v6)
            mstore(add(m, 0xe0), v7)
            mstore(add(m, 0x100), v8)
            mstore(add(m, 0x120), v9)
            mstore(add(m, 0x140), v10)
            mstore(add(m, 0x160), v11)
            result := keccak256(m, 0x180)
        }
    }

    /// @dev Returns `keccak256(abi.encode(v0, .., v11))`.
    function hash(
        uint256 v0,
        uint256 v1,
        uint256 v2,
        uint256 v3,
        uint256 v4,
        uint256 v5,
        uint256 v6,
        uint256 v7,
        uint256 v8,
        uint256 v9,
        uint256 v10,
        uint256 v11
    ) internal pure returns (bytes32 result) {
        /// @solidity memory-safe-assembly
        assembly {
            let m := mload(0x40)
            mstore(m, v0)
            mstore(add(m, 0x20), v1)
            mstore(add(m, 0x40), v2)
            mstore(add(m, 0x60), v3)
            mstore(add(m, 0x80), v4)
            mstore(add(m, 0xa0), v5)
            mstore(add(m, 0xc0), v6)
            mstore(add(m, 0xe0), v7)
            mstore(add(m, 0x100), v8)
            mstore(add(m, 0x120), v9)
            mstore(add(m, 0x140), v10)
            mstore(add(m, 0x160), v11)
            result := keccak256(m, 0x180)
        }
    }

    /// @dev Returns `keccak256(abi.encode(v0, .., v12))`.
    function hash(
        bytes32 v0,
        bytes32 v1,
        bytes32 v2,
        bytes32 v3,
        bytes32 v4,
        bytes32 v5,
        bytes32 v6,
        bytes32 v7,
        bytes32 v8,
        bytes32 v9,
        bytes32 v10,
        bytes32 v11,
        bytes32 v12
    ) internal pure returns (bytes32 result) {
        /// @solidity memory-safe-assembly
        assembly {
            let m := mload(0x40)
            mstore(m, v0)
            mstore(add(m, 0x20), v1)
            mstore(add(m, 0x40), v2)
            mstore(add(m, 0x60), v3)
            mstore(add(m, 0x80), v4)
            mstore(add(m, 0xa0), v5)
            mstore(add(m, 0xc0), v6)
            mstore(add(m, 0xe0), v7)
            mstore(add(m, 0x100), v8)
            mstore(add(m, 0x120), v9)
            mstore(add(m, 0x140), v10)
            mstore(add(m, 0x160), v11)
            mstore(add(m, 0x180), v12)
            result := keccak256(m, 0x1a0)
        }
    }

    /// @dev Returns `keccak256(abi.encode(v0, .., v12))`.
    function hash(
        uint256 v0,
        uint256 v1,
        uint256 v2,
        uint256 v3,
        uint256 v4,
        uint256 v5,
        uint256 v6,
        uint256 v7,
        uint256 v8,
        uint256 v9,
        uint256 v10,
        uint256 v11,
        uint256 v12
    ) internal pure returns (bytes32 result) {
        /// @solidity memory-safe-assembly
        assembly {
            let m := mload(0x40)
            mstore(m, v0)
            mstore(add(m, 0x20), v1)
            mstore(add(m, 0x40), v2)
            mstore(add(m, 0x60), v3)
            mstore(add(m, 0x80), v4)
            mstore(add(m, 0xa0), v5)
            mstore(add(m, 0xc0), v6)
            mstore(add(m, 0xe0), v7)
            mstore(add(m, 0x100), v8)
            mstore(add(m, 0x120), v9)
            mstore(add(m, 0x140), v10)
            mstore(add(m, 0x160), v11)
            mstore(add(m, 0x180), v12)
            result := keccak256(m, 0x1a0)
        }
    }

    /// @dev Returns `keccak256(abi.encode(v0, .., v13))`.
    function hash(
        bytes32 v0,
        bytes32 v1,
        bytes32 v2,
        bytes32 v3,
        bytes32 v4,
        bytes32 v5,
        bytes32 v6,
        bytes32 v7,
        bytes32 v8,
        bytes32 v9,
        bytes32 v10,
        bytes32 v11,
        bytes32 v12,
        bytes32 v13
    ) internal pure returns (bytes32 result) {
        /// @solidity memory-safe-assembly
        assembly {
            let m := mload(0x40)
            mstore(m, v0)
            mstore(add(m, 0x20), v1)
            mstore(add(m, 0x40), v2)
            mstore(add(m, 0x60), v3)
            mstore(add(m, 0x80), v4)
            mstore(add(m, 0xa0), v5)
            mstore(add(m, 0xc0), v6)
            mstore(add(m, 0xe0), v7)
            mstore(add(m, 0x100), v8)
            mstore(add(m, 0x120), v9)
            mstore(add(m, 0x140), v10)
            mstore(add(m, 0x160), v11)
            mstore(add(m, 0x180), v12)
            mstore(add(m, 0x1a0), v13)
            result := keccak256(m, 0x1c0)
        }
    }

    /// @dev Returns `keccak256(abi.encode(v0, .., v13))`.
    function hash(
        uint256 v0,
        uint256 v1,
        uint256 v2,
        uint256 v3,
        uint256 v4,
        uint256 v5,
        uint256 v6,
        uint256 v7,
        uint256 v8,
        uint256 v9,
        uint256 v10,
        uint256 v11,
        uint256 v12,
        uint256 v13
    ) internal pure returns (bytes32 result) {
        /// @solidity memory-safe-assembly
        assembly {
            let m := mload(0x40)
            mstore(m, v0)
            mstore(add(m, 0x20), v1)
            mstore(add(m, 0x40), v2)
            mstore(add(m, 0x60), v3)
            mstore(add(m, 0x80), v4)
            mstore(add(m, 0xa0), v5)
            mstore(add(m, 0xc0), v6)
            mstore(add(m, 0xe0), v7)
            mstore(add(m, 0x100), v8)
            mstore(add(m, 0x120), v9)
            mstore(add(m, 0x140), v10)
            mstore(add(m, 0x160), v11)
            mstore(add(m, 0x180), v12)
            mstore(add(m, 0x1a0), v13)
            result := keccak256(m, 0x1c0)
        }
    }

    /*´:°•.°+.*•´.*:˚.°*.˚•´.°:°•.°•.*•´.*:˚.°*.˚•´.°:°•.°+.*•´.*:*/
    /*             BYTES32 BUFFER HASHING OPERATIONS              */
    /*.•°:°.´+˚.*°.˚:*.´•*.+°.•°:´*.´•*.•°.•°:°.´:•˚°.*°.˚:*.´+°.•*/

    /// @dev Returns `keccak256(abi.encode(buffer[0], .., buffer[buffer.length - 1]))`.
    function hash(bytes32[] memory buffer) internal pure returns (bytes32 result) {
        /// @solidity memory-safe-assembly
        assembly {
            result := keccak256(add(buffer, 0x20), shl(5, mload(buffer)))
        }
    }

    /// @dev Sets `buffer[i]` to `value`, without a bounds check.
    /// Returns the `buffer` for function chaining.
    function set(bytes32[] memory buffer, uint256 i, bytes32 value)
        internal
        pure
        returns (bytes32[] memory)
    {
        /// @solidity memory-safe-assembly
        assembly {
            mstore(add(buffer, shl(5, add(1, i))), value)
        }
        return buffer;
    }

    /// @dev Sets `buffer[i]` to `value`, without a bounds check.
    /// Returns the `buffer` for function chaining.
    function set(bytes32[] memory buffer, uint256 i, uint256 value)
        internal
        pure
        returns (bytes32[] memory)
    {
        /// @solidity memory-safe-assembly
        assembly {
            mstore(add(buffer, shl(5, add(1, i))), value)
        }
        return buffer;
    }

    /// @dev Returns `new bytes32[](n)`, without zeroing out the memory.
    function malloc(uint256 n) internal pure returns (bytes32[] memory buffer) {
        /// @solidity memory-safe-assembly
        assembly {
            buffer := mload(0x40)
            mstore(buffer, n)
            mstore(0x40, add(shl(5, add(1, n)), buffer))
        }
    }

    /// @dev Frees memory that has been allocated for `buffer`.
    /// No-op if `buffer.length` is zero, or if new memory has been allocated after `buffer`.
    function free(bytes32[] memory buffer) internal pure {
        /// @solidity memory-safe-assembly
        assembly {
            let n := mload(buffer)
            mstore(shl(6, lt(iszero(n), eq(add(shl(5, add(1, n)), buffer), mload(0x40)))), buffer)
        }
    }

    /*´:°•.°+.*•´.*:˚.°*.˚•´.°:°•.°•.*•´.*:˚.°*.˚•´.°:°•.°+.*•´.*:*/
    /*                      EQUALITY CHECKS                       */
    /*.•°:°.´+˚.*°.˚:*.´•*.+°.•°:´*.´•*.•°.•°:°.´:•˚°.*°.˚:*.´+°.•*/

    /// @dev Returns `a == abi.decode(b, (bytes32))`.
    function eq(bytes32 a, bytes memory b) internal pure returns (bool result) {
        /// @solidity memory-safe-assembly
        assembly {
            result := and(eq(0x20, mload(b)), eq(a, mload(add(b, 0x20))))
        }
    }

    /// @dev Returns `abi.decode(a, (bytes32)) == b`.
    function eq(bytes memory a, bytes32 b) internal pure returns (bool result) {
        /// @solidity memory-safe-assembly
        assembly {
            result := and(eq(0x20, mload(a)), eq(b, mload(add(a, 0x20))))
        }
    }

    /*´:°•.°+.*•´.*:˚.°*.˚•´.°:°•.°•.*•´.*:˚.°*.˚•´.°:°•.°+.*•´.*:*/
    /*               BYTE SLICE HASHING OPERATIONS                */
    /*.•°:°.´+˚.*°.˚:*.´•*.+°.•°:´*.´•*.•°.•°:°.´:•˚°.*°.˚:*.´+°.•*/

    /// @dev Returns the keccak256 of the slice from `start` to `end` (exclusive).
    /// `start` and `end` are byte offsets.
    function hash(bytes memory b, uint256 start, uint256 end)
        internal
        pure
        returns (bytes32 result)
    {
        /// @solidity memory-safe-assembly
        assembly {
            let n := mload(b)
            end := xor(end, mul(xor(end, n), lt(n, end)))
            start := xor(start, mul(xor(start, n), lt(n, start)))
            result := keccak256(add(add(b, 0x20), start), mul(gt(end, start), sub(end, start)))
        }
    }

    /// @dev Returns the keccak256 of the slice from `start` to the end of the bytes.
    function hash(bytes memory b, uint256 start) internal pure returns (bytes32 result) {
        /// @solidity memory-safe-assembly
        assembly {
            let n := mload(b)
            start := xor(start, mul(xor(start, n), lt(n, start)))
            result := keccak256(add(add(b, 0x20), start), mul(gt(n, start), sub(n, start)))
        }
    }

    /// @dev Returns the keccak256 of the bytes.
    function hash(bytes memory b) internal pure returns (bytes32 result) {
        /// @solidity memory-safe-assembly
        assembly {
            result := keccak256(add(b, 0x20), mload(b))
        }
    }

    /// @dev Returns the keccak256 of the slice from `start` to `end` (exclusive).
    /// `start` and `end` are byte offsets.
    function hashCalldata(bytes calldata b, uint256 start, uint256 end)
        internal
        pure
        returns (bytes32 result)
    {
        /// @solidity memory-safe-assembly
        assembly {
            end := xor(end, mul(xor(end, b.length), lt(b.length, end)))
            start := xor(start, mul(xor(start, b.length), lt(b.length, start)))
            let n := mul(gt(end, start), sub(end, start))
            calldatacopy(mload(0x40), add(b.offset, start), n)
            result := keccak256(mload(0x40), n)
        }
    }

    /// @dev Returns the keccak256 of the slice from `start` to the end of the bytes.
    function hashCalldata(bytes calldata b, uint256 start) internal pure returns (bytes32 result) {
        /// @solidity memory-safe-assembly
        assembly {
            start := xor(start, mul(xor(start, b.length), lt(b.length, start)))
            let n := mul(gt(b.length, start), sub(b.length, start))
            calldatacopy(mload(0x40), add(b.offset, start), n)
            result := keccak256(mload(0x40), n)
        }
    }

    /// @dev Returns the keccak256 of the bytes.
    function hashCalldata(bytes calldata b) internal pure returns (bytes32 result) {
        /// @solidity memory-safe-assembly
        assembly {
            calldatacopy(mload(0x40), b.offset, b.length)
            result := keccak256(mload(0x40), b.length)
        }
    }

    /*´:°•.°+.*•´.*:˚.°*.˚•´.°:°•.°•.*•´.*:˚.°*.˚•´.°:°•.°+.*•´.*:*/
    /*                      SHA2-256 HELPERS                      */
    /*.•°:°.´+˚.*°.˚:*.´•*.+°.•°:´*.´•*.•°.•°:°.´:•˚°.*°.˚:*.´+°.•*/

    /// @dev Returns `sha256(abi.encode(b))`. Yes, it's more efficient.
    function sha2(bytes32 b) internal view returns (bytes32 result) {
        /// @solidity memory-safe-assembly
        assembly {
            mstore(0x00, b)
            result := mload(staticcall(gas(), 2, 0x00, 0x20, 0x01, 0x20))
            if iszero(returndatasize()) { invalid() }
        }
    }

    /// @dev Returns the sha256 of the slice from `start` to `end` (exclusive).
    /// `start` and `end` are byte offsets.
    function sha2(bytes memory b, uint256 start, uint256 end)
        internal
        view
        returns (bytes32 result)
    {
        /// @solidity memory-safe-assembly
        assembly {
            let n := mload(b)
            end := xor(end, mul(xor(end, n), lt(n, end)))
            start := xor(start, mul(xor(start, n), lt(n, start)))
            // forgefmt: disable-next-item
            result := mload(staticcall(gas(), 2, add(add(b, 0x20), start),
                mul(gt(end, start), sub(end, start)), 0x01, 0x20))
            if iszero(returndatasize()) { invalid() }
        }
    }

    /// @dev Returns the sha256 of the slice from `start` to the end of the bytes.
    function sha2(bytes memory b, uint256 start) internal view returns (bytes32 result) {
        /// @solidity memory-safe-assembly
        assembly {
            let n := mload(b)
            start := xor(start, mul(xor(start, n), lt(n, start)))
            // forgefmt: disable-next-item
            result := mload(staticcall(gas(), 2, add(add(b, 0x20), start),
                mul(gt(n, start), sub(n, start)), 0x01, 0x20))
            if iszero(returndatasize()) { invalid() }
        }
    }

    /// @dev Returns the sha256 of the bytes.
    function sha2(bytes memory b) internal view returns (bytes32 result) {
        /// @solidity memory-safe-assembly
        assembly {
            result := mload(staticcall(gas(), 2, add(b, 0x20), mload(b), 0x01, 0x20))
            if iszero(returndatasize()) { invalid() }
        }
    }

    /// @dev Returns the sha256 of the slice from `start` to `end` (exclusive).
    /// `start` and `end` are byte offsets.
    function sha2Calldata(bytes calldata b, uint256 start, uint256 end)
        internal
        view
        returns (bytes32 result)
    {
        /// @solidity memory-safe-assembly
        assembly {
            end := xor(end, mul(xor(end, b.length), lt(b.length, end)))
            start := xor(start, mul(xor(start, b.length), lt(b.length, start)))
            let n := mul(gt(end, start), sub(end, start))
            calldatacopy(mload(0x40), add(b.offset, start), n)
            result := mload(staticcall(gas(), 2, mload(0x40), n, 0x01, 0x20))
            if iszero(returndatasize()) { invalid() }
        }
    }

    /// @dev Returns the sha256 of the slice from `start` to the end of the bytes.
    function sha2Calldata(bytes calldata b, uint256 start) internal view returns (bytes32 result) {
        /// @solidity memory-safe-assembly
        assembly {
            start := xor(start, mul(xor(start, b.length), lt(b.length, start)))
            let n := mul(gt(b.length, start), sub(b.length, start))
            calldatacopy(mload(0x40), add(b.offset, start), n)
            result := mload(staticcall(gas(), 2, mload(0x40), n, 0x01, 0x20))
            if iszero(returndatasize()) { invalid() }
        }
    }

    /// @dev Returns the sha256 of the bytes.
    function sha2Calldata(bytes calldata b) internal view returns (bytes32 result) {
        /// @solidity memory-safe-assembly
        assembly {
            calldatacopy(mload(0x40), b.offset, b.length)
            result := mload(staticcall(gas(), 2, mload(0x40), b.length, 0x01, 0x20))
            if iszero(returndatasize()) { invalid() }
        }
    }
}

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

pragma solidity ^0.8.20;

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

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

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

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

pragma solidity >=0.4.16;

/**
 * @dev Interface of the ERC-165 standard, as defined in the
 * https://eips.ethereum.org/EIPS/eip-165[ERC].
 *
 * 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[ERC section]
     * to learn more about how these ids are created.
     *
     * This function call must use less than 30 000 gas.
     */
    function supportsInterface(bytes4 interfaceId) external view returns (bool);
}

Settings
{
  "remappings": [
    "forge-std/=lib/forge-std/src/",
    "@ens/=lib/ens-contracts/contracts/",
    "@oz/=lib/openzeppelin-contracts/contracts/",
    "solady/=lib/solady/src/",
    "@openzeppelin/contracts/=lib/openzeppelin-contracts/contracts/",
    "ens-contracts/=lib/ens-contracts/contracts/",
    "erc4626-tests/=lib/openzeppelin-contracts/lib/erc4626-tests/",
    "halmos-cheatcodes/=lib/openzeppelin-contracts/lib/halmos-cheatcodes/src/",
    "openzeppelin-contracts/=lib/openzeppelin-contracts/"
  ],
  "optimizer": {
    "enabled": false,
    "runs": 200
  },
  "metadata": {
    "useLiteralContent": false,
    "bytecodeHash": "ipfs",
    "appendCBOR": true
  },
  "outputSelection": {
    "*": {
      "*": [
        "evm.bytecode",
        "evm.deployedBytecode",
        "devdoc",
        "userdoc",
        "metadata",
        "abi"
      ]
    }
  },
  "evmVersion": "prague",
  "viaIR": false
}

Contract Security Audit

Contract ABI

API
[{"inputs":[{"internalType":"address","name":"signer_","type":"address"},{"internalType":"string[]","name":"gateways_","type":"string[]"}],"stateMutability":"nonpayable","type":"constructor"},{"inputs":[{"internalType":"uint64","name":"expiry","type":"uint64"}],"name":"CCIPReadExpired","type":"error"},{"inputs":[{"internalType":"address","name":"signed","type":"address"},{"internalType":"address","name":"expected","type":"address"}],"name":"CCIPReadUntrusted","type":"error"},{"inputs":[],"name":"ECDSAInvalidSignature","type":"error"},{"inputs":[{"internalType":"uint256","name":"length","type":"uint256"}],"name":"ECDSAInvalidSignatureLength","type":"error"},{"inputs":[{"internalType":"bytes32","name":"s","type":"bytes32"}],"name":"ECDSAInvalidSignatureS","type":"error"},{"inputs":[{"internalType":"address","name":"sender","type":"address"},{"internalType":"string[]","name":"urls","type":"string[]"},{"internalType":"bytes","name":"callData","type":"bytes"},{"internalType":"bytes4","name":"callbackFunction","type":"bytes4"},{"internalType":"bytes","name":"extraData","type":"bytes"}],"name":"OffchainLookup","type":"error"},{"inputs":[{"internalType":"address","name":"owner","type":"address"}],"name":"OwnableInvalidOwner","type":"error"},{"inputs":[{"internalType":"address","name":"account","type":"address"}],"name":"OwnableUnauthorizedAccount","type":"error"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"previousOwner","type":"address"},{"indexed":true,"internalType":"address","name":"newOwner","type":"address"}],"name":"OwnershipTransferred","type":"event"},{"inputs":[],"name":"gateways","outputs":[{"internalType":"string[]","name":"","type":"string[]"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"owner","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"renounceOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes","name":"","type":"bytes"},{"internalType":"bytes","name":"","type":"bytes"}],"name":"resolve","outputs":[{"internalType":"bytes","name":"","type":"bytes"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes","name":"response","type":"bytes"},{"internalType":"bytes","name":"request","type":"bytes"}],"name":"resolveCallback","outputs":[{"internalType":"bytes","name":"","type":"bytes"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"string[]","name":"gateways_","type":"string[]"}],"name":"setGateways","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"signer_","type":"address"}],"name":"setSigner","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"signer","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes4","name":"featureId","type":"bytes4"}],"name":"supportsFeature","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"pure","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":"newOwner","type":"address"}],"name":"transferOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"}]

608060405234801561000f575f5ffd5b5060405161252e38038061252e8339818101604052810190610031919061052c565b335f73ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff16036100a2575f6040517f1e4fbdf70000000000000000000000000000000000000000000000000000000081526004016100999190610595565b60405180910390fd5b6100b18161011060201b60201c565b508160025f6101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555080600190805190602001906101089291906101d1565b50505061088d565b5f5f5f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff169050815f5f6101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055508173ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e060405160405180910390a35050565b828054828255905f5260205f20908101928215610217579160200282015b8281111561021657825182908161020691906107be565b50916020019190600101906101ef565b5b5090506102249190610228565b5090565b5b80821115610247575f818161023e919061024b565b50600101610229565b5090565b508054610257906105e5565b5f825580601f106102685750610285565b601f0160209004905f5260205f20908101906102849190610288565b5b50565b5b8082111561029f575f815f905550600101610289565b5090565b5f604051905090565b5f5ffd5b5f5ffd5b5f73ffffffffffffffffffffffffffffffffffffffff82169050919050565b5f6102dd826102b4565b9050919050565b6102ed816102d3565b81146102f7575f5ffd5b50565b5f81519050610308816102e4565b92915050565b5f5ffd5b5f601f19601f8301169050919050565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52604160045260245ffd5b61035882610312565b810181811067ffffffffffffffff8211171561037757610376610322565b5b80604052505050565b5f6103896102a3565b9050610395828261034f565b919050565b5f67ffffffffffffffff8211156103b4576103b3610322565b5b602082029050602081019050919050565b5f5ffd5b5f5ffd5b5f67ffffffffffffffff8211156103e7576103e6610322565b5b6103f082610312565b9050602081019050919050565b8281835e5f83830152505050565b5f61041d610418846103cd565b610380565b905082815260208101848484011115610439576104386103c9565b5b6104448482856103fd565b509392505050565b5f82601f8301126104605761045f61030e565b5b815161047084826020860161040b565b91505092915050565b5f61048b6104868461039a565b610380565b905080838252602082019050602084028301858111156104ae576104ad6103c5565b5b835b818110156104f557805167ffffffffffffffff8111156104d3576104d261030e565b5b8086016104e0898261044c565b855260208501945050506020810190506104b0565b5050509392505050565b5f82601f8301126105135761051261030e565b5b8151610523848260208601610479565b91505092915050565b5f5f60408385031215610542576105416102ac565b5b5f61054f858286016102fa565b925050602083015167ffffffffffffffff8111156105705761056f6102b0565b5b61057c858286016104ff565b9150509250929050565b61058f816102d3565b82525050565b5f6020820190506105a85f830184610586565b92915050565b5f81519050919050565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52602260045260245ffd5b5f60028204905060018216806105fc57607f821691505b60208210810361060f5761060e6105b8565b5b50919050565b5f819050815f5260205f209050919050565b5f6020601f8301049050919050565b5f82821b905092915050565b5f600883026106717fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff82610636565b61067b8683610636565b95508019841693508086168417925050509392505050565b5f819050919050565b5f819050919050565b5f6106bf6106ba6106b584610693565b61069c565b610693565b9050919050565b5f819050919050565b6106d8836106a5565b6106ec6106e4826106c6565b848454610642565b825550505050565b5f5f905090565b6107036106f4565b61070e8184846106cf565b505050565b5b81811015610731576107265f826106fb565b600181019050610714565b5050565b601f8211156107765761074781610615565b61075084610627565b8101602085101561075f578190505b61077361076b85610627565b830182610713565b50505b505050565b5f82821c905092915050565b5f6107965f198460080261077b565b1980831691505092915050565b5f6107ae8383610787565b9150826002028217905092915050565b6107c7826105ae565b67ffffffffffffffff8111156107e0576107df610322565b5b6107ea82546105e5565b6107f5828285610735565b5f60209050601f831160018114610826575f8415610814578287015190505b61081e85826107a3565b865550610885565b601f19841661083486610615565b5f5b8281101561085b57848901518255600182019150602085019450602081019050610836565b868310156108785784890151610874601f891682610787565b8355505b6001600288020188555050505b505050505050565b611c948061089a5f395ff3fe608060405234801561000f575f5ffd5b50600436106100a7575f3560e01c80636c19e7831161006f5780636c19e78314610163578063715018a61461017f5780638da5cb5b146101895780639061b923146101a7578063b4a85801146101d7578063f2fde38b14610207576100a7565b806301ffc9a7146100ab578063093a86d3146100db578063238ac933146100f95780632792207414610117578063582de3e714610133575b5f5ffd5b6100c560048036038101906100c09190610de7565b610223565b6040516100d29190610e2c565b60405180910390f35b6100e361036c565b6040516100f09190610f70565b60405180910390f35b610101610440565b60405161010e9190610fcf565b60405180910390f35b610131600480360381019061012c91906111f6565b610465565b005b61014d60048036038101906101489190610de7565b610487565b60405161015a9190610e2c565b60405180910390f35b61017d60048036038101906101789190611267565b6104f0565b005b61018761053b565b005b61019161054e565b60405161019e9190610fcf565b60405180910390f35b6101c160048036038101906101bc91906112eb565b610575565b6040516101ce91906113bb565b60405180910390f35b6101f160048036038101906101ec91906112eb565b6105c8565b6040516101fe91906113bb565b60405180910390f35b610221600480360381019061021c9190611267565b610622565b005b5f7f9061b923000000000000000000000000000000000000000000000000000000007bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff191614806102ed57507f582de3e7000000000000000000000000000000000000000000000000000000007bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916145b8061035557507f093a86d3000000000000000000000000000000000000000000000000000000007bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916145b806103655750610364826106a6565b5b9050919050565b60606001805480602002602001604051908101604052809291908181526020015f905b82821015610437578382905f5260205f200180546103ac90611408565b80601f01602080910402602001604051908101604052809291908181526020018280546103d890611408565b80156104235780601f106103fa57610100808354040283529160200191610423565b820191905f5260205f20905b81548152906001019060200180831161040657829003601f168201915b50505050508152602001906001019061038f565b50505050905090565b60025f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b61046d61070f565b8060019080519060200190610483929190610caf565b5050565b5f7f96b62db84925e7addc1a7d6189ebbe954ad1b17a9bb8cd65bb2d92eac894d9147bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916149050919050565b6104f861070f565b8060025f6101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555050565b61054361070f565b61054c5f610796565b565b5f5f5f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff16905090565b60603060015f3663b4a8580160e01b5f366040517f556f18300000000000000000000000000000000000000000000000000000000081526004016105bf97969594939291906115b3565b60405180910390fd5b606061061883838080601f0160208091040260200160405190810160405280939291908181526020018383808284375f81840152601f19601f820116905080830192505050505050508686610857565b9050949350505050565b61062a61070f565b5f73ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff160361069a575f6040517f1e4fbdf70000000000000000000000000000000000000000000000000000000081526004016106919190610fcf565b60405180910390fd5b6106a381610796565b50565b5f7f01ffc9a7000000000000000000000000000000000000000000000000000000007bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916149050919050565b6107176109d1565b73ffffffffffffffffffffffffffffffffffffffff1661073561054e565b73ffffffffffffffffffffffffffffffffffffffff1614610794576107586109d1565b6040517f118cdaa700000000000000000000000000000000000000000000000000000000815260040161078b9190610fcf565b60405180910390fd5b565b5f5f5f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff169050815f5f6101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055508173ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e060405160405180910390a35050565b60605f5f5f858581019061086b91906116f8565b925092509250428267ffffffffffffffff1610156108c057816040517fa477f5f30000000000000000000000000000000000000000000000000000000081526004016108b7919061178f565b60405180910390fd5b5f6108ff30846108cf8b6109d8565b6108d8886109d8565b6040516020016108eb949392919061189e565b6040516020818303038152906040526109d8565b90505f61090c82846109e7565b905060025f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff16146109c2578060025f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff166040517fb2187bcd0000000000000000000000000000000000000000000000000000000081526004016109b99291906118f6565b60405180910390fd5b84955050505050509392505050565b5f33905090565b5f815160208301209050919050565b5f5f5f5f6109f58686610a11565b925092509250610a058282610a66565b82935050505092915050565b5f5f5f6041845103610a51575f5f5f602087015192506040870151915060608701515f1a9050610a4388828585610bc8565b955095509550505050610a5f565b5f600285515f1b9250925092505b9250925092565b5f6003811115610a7957610a7861191d565b5b826003811115610a8c57610a8b61191d565b5b0315610bc45760016003811115610aa657610aa561191d565b5b826003811115610ab957610ab861191d565b5b03610af0576040517ff645eedf00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60026003811115610b0457610b0361191d565b5b826003811115610b1757610b1661191d565b5b03610b5b57805f1c6040517ffce698f7000000000000000000000000000000000000000000000000000000008152600401610b529190611962565b60405180910390fd5b600380811115610b6e57610b6d61191d565b5b826003811115610b8157610b8061191d565b5b03610bc357806040517fd78bce0c000000000000000000000000000000000000000000000000000000008152600401610bba919061198a565b60405180910390fd5b5b5050565b5f5f5f7f7fffffffffffffffffffffffffffffff5d576e7357a4501ddfe92f46681b20a0845f1c1115610c04575f600385925092509250610ca5565b5f6001888888886040515f8152602001604052604051610c2794939291906119be565b6020604051602081039080840390855afa158015610c47573d5f5f3e3d5ffd5b5050506020604051035190505f73ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1603610c98575f60015f5f1b93509350935050610ca5565b805f5f5f1b935093509350505b9450945094915050565b828054828255905f5260205f20908101928215610cf5579160200282015b82811115610cf4578251829081610ce49190611b8f565b5091602001919060010190610ccd565b5b509050610d029190610d06565b5090565b5b80821115610d25575f8181610d1c9190610d29565b50600101610d07565b5090565b508054610d3590611408565b5f825580601f10610d465750610d63565b601f0160209004905f5260205f2090810190610d629190610d66565b5b50565b5b80821115610d7d575f815f905550600101610d67565b5090565b5f604051905090565b5f5ffd5b5f5ffd5b5f7fffffffff0000000000000000000000000000000000000000000000000000000082169050919050565b610dc681610d92565b8114610dd0575f5ffd5b50565b5f81359050610de181610dbd565b92915050565b5f60208284031215610dfc57610dfb610d8a565b5b5f610e0984828501610dd3565b91505092915050565b5f8115159050919050565b610e2681610e12565b82525050565b5f602082019050610e3f5f830184610e1d565b92915050565b5f81519050919050565b5f82825260208201905092915050565b5f819050602082019050919050565b5f81519050919050565b5f82825260208201905092915050565b8281835e5f83830152505050565b5f601f19601f8301169050919050565b5f610eb082610e6e565b610eba8185610e78565b9350610eca818560208601610e88565b610ed381610e96565b840191505092915050565b5f610ee98383610ea6565b905092915050565b5f602082019050919050565b5f610f0782610e45565b610f118185610e4f565b935083602082028501610f2385610e5f565b805f5b85811015610f5e5784840389528151610f3f8582610ede565b9450610f4a83610ef1565b925060208a01995050600181019050610f26565b50829750879550505050505092915050565b5f6020820190508181035f830152610f888184610efd565b905092915050565b5f73ffffffffffffffffffffffffffffffffffffffff82169050919050565b5f610fb982610f90565b9050919050565b610fc981610faf565b82525050565b5f602082019050610fe25f830184610fc0565b92915050565b5f5ffd5b7f4e487b71000000000000000000000000000000000000000000000000000000005f52604160045260245ffd5b61102282610e96565b810181811067ffffffffffffffff8211171561104157611040610fec565b5b80604052505050565b5f611053610d81565b905061105f8282611019565b919050565b5f67ffffffffffffffff82111561107e5761107d610fec565b5b602082029050602081019050919050565b5f5ffd5b5f5ffd5b5f67ffffffffffffffff8211156110b1576110b0610fec565b5b6110ba82610e96565b9050602081019050919050565b828183375f83830152505050565b5f6110e76110e284611097565b61104a565b90508281526020810184848401111561110357611102611093565b5b61110e8482856110c7565b509392505050565b5f82601f83011261112a57611129610fe8565b5b813561113a8482602086016110d5565b91505092915050565b5f61115561115084611064565b61104a565b905080838252602082019050602084028301858111156111785761117761108f565b5b835b818110156111bf57803567ffffffffffffffff81111561119d5761119c610fe8565b5b8086016111aa8982611116565b8552602085019450505060208101905061117a565b5050509392505050565b5f82601f8301126111dd576111dc610fe8565b5b81356111ed848260208601611143565b91505092915050565b5f6020828403121561120b5761120a610d8a565b5b5f82013567ffffffffffffffff81111561122857611227610d8e565b5b611234848285016111c9565b91505092915050565b61124681610faf565b8114611250575f5ffd5b50565b5f813590506112618161123d565b92915050565b5f6020828403121561127c5761127b610d8a565b5b5f61128984828501611253565b91505092915050565b5f5ffd5b5f5f83601f8401126112ab576112aa610fe8565b5b8235905067ffffffffffffffff8111156112c8576112c7611292565b5b6020830191508360018202830111156112e4576112e361108f565b5b9250929050565b5f5f5f5f6040858703121561130357611302610d8a565b5b5f85013567ffffffffffffffff8111156113205761131f610d8e565b5b61132c87828801611296565b9450945050602085013567ffffffffffffffff81111561134f5761134e610d8e565b5b61135b87828801611296565b925092505092959194509250565b5f81519050919050565b5f82825260208201905092915050565b5f61138d82611369565b6113978185611373565b93506113a7818560208601610e88565b6113b081610e96565b840191505092915050565b5f6020820190508181035f8301526113d38184611383565b905092915050565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52602260045260245ffd5b5f600282049050600182168061141f57607f821691505b602082108103611432576114316113db565b5b50919050565b5f81549050919050565b5f819050815f5260205f209050919050565b5f819050815f5260205f209050919050565b5f815461147281611408565b61147c8186610e78565b9450600182165f811461149657600181146114ac576114de565b60ff1983168652811515602002860193506114de565b6114b585611454565b5f5b838110156114d6578154818901526001820191506020810190506114b7565b808801955050505b50505092915050565b5f6114f28383611466565b905092915050565b5f600182019050919050565b5f61151082611438565b61151a8185610e4f565b93508360208202850161152c85611442565b805f5b858110156115665784840389528161154785826114e7565b9450611552836114fa565b925060208a0199505060018101905061152f565b50829750879550505050505092915050565b5f6115838385611373565b93506115908385846110c7565b61159983610e96565b840190509392505050565b6115ad81610d92565b82525050565b5f60a0820190506115c65f83018a610fc0565b81810360208301526115d88189611506565b905081810360408301526115ed818789611578565b90506115fc60608301866115a4565b818103608083015261160f818486611578565b905098975050505050505050565b5f67ffffffffffffffff82111561163757611636610fec565b5b61164082610e96565b9050602081019050919050565b5f61165f61165a8461161d565b61104a565b90508281526020810184848401111561167b5761167a611093565b5b6116868482856110c7565b509392505050565b5f82601f8301126116a2576116a1610fe8565b5b81356116b284826020860161164d565b91505092915050565b5f67ffffffffffffffff82169050919050565b6116d7816116bb565b81146116e1575f5ffd5b50565b5f813590506116f2816116ce565b92915050565b5f5f5f6060848603121561170f5761170e610d8a565b5b5f84013567ffffffffffffffff81111561172c5761172b610d8e565b5b6117388682870161168e565b9350506020611749868287016116e4565b925050604084013567ffffffffffffffff81111561176a57611769610d8e565b5b6117768682870161168e565b9150509250925092565b611789816116bb565b82525050565b5f6020820190506117a25f830184611780565b92915050565b5f81905092915050565b7f19000000000000000000000000000000000000000000000000000000000000005f82015250565b5f6117e66002836117a8565b91506117f1826117b2565b600282019050919050565b5f8160601b9050919050565b5f611812826117fc565b9050919050565b5f61182382611808565b9050919050565b61183b61183682610faf565b611819565b82525050565b5f8160c01b9050919050565b5f61185782611841565b9050919050565b61186f61186a826116bb565b61184d565b82525050565b5f819050919050565b5f819050919050565b61189861189382611875565b61187e565b82525050565b5f6118a8826117da565b91506118b4828761182a565b6014820191506118c4828661185e565b6008820191506118d48285611887565b6020820191506118e48284611887565b60208201915081905095945050505050565b5f6040820190506119095f830185610fc0565b6119166020830184610fc0565b9392505050565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52602160045260245ffd5b5f819050919050565b61195c8161194a565b82525050565b5f6020820190506119755f830184611953565b92915050565b61198481611875565b82525050565b5f60208201905061199d5f83018461197b565b92915050565b5f60ff82169050919050565b6119b8816119a3565b82525050565b5f6080820190506119d15f83018761197b565b6119de60208301866119af565b6119eb604083018561197b565b6119f8606083018461197b565b95945050505050565b5f6020601f8301049050919050565b5f82821b905092915050565b5f60088302611a4b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff82611a10565b611a558683611a10565b95508019841693508086168417925050509392505050565b5f819050919050565b5f611a90611a8b611a868461194a565b611a6d565b61194a565b9050919050565b5f819050919050565b611aa983611a76565b611abd611ab582611a97565b848454611a1c565b825550505050565b5f5f905090565b611ad4611ac5565b611adf818484611aa0565b505050565b5b81811015611b0257611af75f82611acc565b600181019050611ae5565b5050565b601f821115611b4757611b1881611454565b611b2184611a01565b81016020851015611b30578190505b611b44611b3c85611a01565b830182611ae4565b50505b505050565b5f82821c905092915050565b5f611b675f1984600802611b4c565b1980831691505092915050565b5f611b7f8383611b58565b9150826002028217905092915050565b611b9882610e6e565b67ffffffffffffffff811115611bb157611bb0610fec565b5b611bbb8254611408565b611bc6828285611b06565b5f60209050601f831160018114611bf7575f8415611be5578287015190505b611bef8582611b74565b865550611c56565b601f198416611c0586611454565b5f5b82811015611c2c57848901518255600182019150602085019450602081019050611c07565b86831015611c495784890151611c45601f891682611b58565b8355505b6001600288020188555050505b50505050505056fea26469706673582212208e949cfdb26a2620484e64238127fb119268358a92cab6fa128aceed74302a5964736f6c634300081e0033000000000000000000000000dfc622f06efdd0e830d82f30679a3c9302bc7940000000000000000000000000000000000000000000000000000000000000004000000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000003a68747470733a2f2f6170692e73746179636c6f616b65642e78797a2f656e732f676174657761792f7b68617264636f6465642d73656e6465727d000000000000

Deployed Bytecode

0x608060405234801561000f575f5ffd5b50600436106100a7575f3560e01c80636c19e7831161006f5780636c19e78314610163578063715018a61461017f5780638da5cb5b146101895780639061b923146101a7578063b4a85801146101d7578063f2fde38b14610207576100a7565b806301ffc9a7146100ab578063093a86d3146100db578063238ac933146100f95780632792207414610117578063582de3e714610133575b5f5ffd5b6100c560048036038101906100c09190610de7565b610223565b6040516100d29190610e2c565b60405180910390f35b6100e361036c565b6040516100f09190610f70565b60405180910390f35b610101610440565b60405161010e9190610fcf565b60405180910390f35b610131600480360381019061012c91906111f6565b610465565b005b61014d60048036038101906101489190610de7565b610487565b60405161015a9190610e2c565b60405180910390f35b61017d60048036038101906101789190611267565b6104f0565b005b61018761053b565b005b61019161054e565b60405161019e9190610fcf565b60405180910390f35b6101c160048036038101906101bc91906112eb565b610575565b6040516101ce91906113bb565b60405180910390f35b6101f160048036038101906101ec91906112eb565b6105c8565b6040516101fe91906113bb565b60405180910390f35b610221600480360381019061021c9190611267565b610622565b005b5f7f9061b923000000000000000000000000000000000000000000000000000000007bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff191614806102ed57507f582de3e7000000000000000000000000000000000000000000000000000000007bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916145b8061035557507f093a86d3000000000000000000000000000000000000000000000000000000007bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916145b806103655750610364826106a6565b5b9050919050565b60606001805480602002602001604051908101604052809291908181526020015f905b82821015610437578382905f5260205f200180546103ac90611408565b80601f01602080910402602001604051908101604052809291908181526020018280546103d890611408565b80156104235780601f106103fa57610100808354040283529160200191610423565b820191905f5260205f20905b81548152906001019060200180831161040657829003601f168201915b50505050508152602001906001019061038f565b50505050905090565b60025f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b61046d61070f565b8060019080519060200190610483929190610caf565b5050565b5f7f96b62db84925e7addc1a7d6189ebbe954ad1b17a9bb8cd65bb2d92eac894d9147bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916149050919050565b6104f861070f565b8060025f6101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555050565b61054361070f565b61054c5f610796565b565b5f5f5f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff16905090565b60603060015f3663b4a8580160e01b5f366040517f556f18300000000000000000000000000000000000000000000000000000000081526004016105bf97969594939291906115b3565b60405180910390fd5b606061061883838080601f0160208091040260200160405190810160405280939291908181526020018383808284375f81840152601f19601f820116905080830192505050505050508686610857565b9050949350505050565b61062a61070f565b5f73ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff160361069a575f6040517f1e4fbdf70000000000000000000000000000000000000000000000000000000081526004016106919190610fcf565b60405180910390fd5b6106a381610796565b50565b5f7f01ffc9a7000000000000000000000000000000000000000000000000000000007bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916149050919050565b6107176109d1565b73ffffffffffffffffffffffffffffffffffffffff1661073561054e565b73ffffffffffffffffffffffffffffffffffffffff1614610794576107586109d1565b6040517f118cdaa700000000000000000000000000000000000000000000000000000000815260040161078b9190610fcf565b60405180910390fd5b565b5f5f5f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff169050815f5f6101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055508173ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e060405160405180910390a35050565b60605f5f5f858581019061086b91906116f8565b925092509250428267ffffffffffffffff1610156108c057816040517fa477f5f30000000000000000000000000000000000000000000000000000000081526004016108b7919061178f565b60405180910390fd5b5f6108ff30846108cf8b6109d8565b6108d8886109d8565b6040516020016108eb949392919061189e565b6040516020818303038152906040526109d8565b90505f61090c82846109e7565b905060025f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff16146109c2578060025f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff166040517fb2187bcd0000000000000000000000000000000000000000000000000000000081526004016109b99291906118f6565b60405180910390fd5b84955050505050509392505050565b5f33905090565b5f815160208301209050919050565b5f5f5f5f6109f58686610a11565b925092509250610a058282610a66565b82935050505092915050565b5f5f5f6041845103610a51575f5f5f602087015192506040870151915060608701515f1a9050610a4388828585610bc8565b955095509550505050610a5f565b5f600285515f1b9250925092505b9250925092565b5f6003811115610a7957610a7861191d565b5b826003811115610a8c57610a8b61191d565b5b0315610bc45760016003811115610aa657610aa561191d565b5b826003811115610ab957610ab861191d565b5b03610af0576040517ff645eedf00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60026003811115610b0457610b0361191d565b5b826003811115610b1757610b1661191d565b5b03610b5b57805f1c6040517ffce698f7000000000000000000000000000000000000000000000000000000008152600401610b529190611962565b60405180910390fd5b600380811115610b6e57610b6d61191d565b5b826003811115610b8157610b8061191d565b5b03610bc357806040517fd78bce0c000000000000000000000000000000000000000000000000000000008152600401610bba919061198a565b60405180910390fd5b5b5050565b5f5f5f7f7fffffffffffffffffffffffffffffff5d576e7357a4501ddfe92f46681b20a0845f1c1115610c04575f600385925092509250610ca5565b5f6001888888886040515f8152602001604052604051610c2794939291906119be565b6020604051602081039080840390855afa158015610c47573d5f5f3e3d5ffd5b5050506020604051035190505f73ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1603610c98575f60015f5f1b93509350935050610ca5565b805f5f5f1b935093509350505b9450945094915050565b828054828255905f5260205f20908101928215610cf5579160200282015b82811115610cf4578251829081610ce49190611b8f565b5091602001919060010190610ccd565b5b509050610d029190610d06565b5090565b5b80821115610d25575f8181610d1c9190610d29565b50600101610d07565b5090565b508054610d3590611408565b5f825580601f10610d465750610d63565b601f0160209004905f5260205f2090810190610d629190610d66565b5b50565b5b80821115610d7d575f815f905550600101610d67565b5090565b5f604051905090565b5f5ffd5b5f5ffd5b5f7fffffffff0000000000000000000000000000000000000000000000000000000082169050919050565b610dc681610d92565b8114610dd0575f5ffd5b50565b5f81359050610de181610dbd565b92915050565b5f60208284031215610dfc57610dfb610d8a565b5b5f610e0984828501610dd3565b91505092915050565b5f8115159050919050565b610e2681610e12565b82525050565b5f602082019050610e3f5f830184610e1d565b92915050565b5f81519050919050565b5f82825260208201905092915050565b5f819050602082019050919050565b5f81519050919050565b5f82825260208201905092915050565b8281835e5f83830152505050565b5f601f19601f8301169050919050565b5f610eb082610e6e565b610eba8185610e78565b9350610eca818560208601610e88565b610ed381610e96565b840191505092915050565b5f610ee98383610ea6565b905092915050565b5f602082019050919050565b5f610f0782610e45565b610f118185610e4f565b935083602082028501610f2385610e5f565b805f5b85811015610f5e5784840389528151610f3f8582610ede565b9450610f4a83610ef1565b925060208a01995050600181019050610f26565b50829750879550505050505092915050565b5f6020820190508181035f830152610f888184610efd565b905092915050565b5f73ffffffffffffffffffffffffffffffffffffffff82169050919050565b5f610fb982610f90565b9050919050565b610fc981610faf565b82525050565b5f602082019050610fe25f830184610fc0565b92915050565b5f5ffd5b7f4e487b71000000000000000000000000000000000000000000000000000000005f52604160045260245ffd5b61102282610e96565b810181811067ffffffffffffffff8211171561104157611040610fec565b5b80604052505050565b5f611053610d81565b905061105f8282611019565b919050565b5f67ffffffffffffffff82111561107e5761107d610fec565b5b602082029050602081019050919050565b5f5ffd5b5f5ffd5b5f67ffffffffffffffff8211156110b1576110b0610fec565b5b6110ba82610e96565b9050602081019050919050565b828183375f83830152505050565b5f6110e76110e284611097565b61104a565b90508281526020810184848401111561110357611102611093565b5b61110e8482856110c7565b509392505050565b5f82601f83011261112a57611129610fe8565b5b813561113a8482602086016110d5565b91505092915050565b5f61115561115084611064565b61104a565b905080838252602082019050602084028301858111156111785761117761108f565b5b835b818110156111bf57803567ffffffffffffffff81111561119d5761119c610fe8565b5b8086016111aa8982611116565b8552602085019450505060208101905061117a565b5050509392505050565b5f82601f8301126111dd576111dc610fe8565b5b81356111ed848260208601611143565b91505092915050565b5f6020828403121561120b5761120a610d8a565b5b5f82013567ffffffffffffffff81111561122857611227610d8e565b5b611234848285016111c9565b91505092915050565b61124681610faf565b8114611250575f5ffd5b50565b5f813590506112618161123d565b92915050565b5f6020828403121561127c5761127b610d8a565b5b5f61128984828501611253565b91505092915050565b5f5ffd5b5f5f83601f8401126112ab576112aa610fe8565b5b8235905067ffffffffffffffff8111156112c8576112c7611292565b5b6020830191508360018202830111156112e4576112e361108f565b5b9250929050565b5f5f5f5f6040858703121561130357611302610d8a565b5b5f85013567ffffffffffffffff8111156113205761131f610d8e565b5b61132c87828801611296565b9450945050602085013567ffffffffffffffff81111561134f5761134e610d8e565b5b61135b87828801611296565b925092505092959194509250565b5f81519050919050565b5f82825260208201905092915050565b5f61138d82611369565b6113978185611373565b93506113a7818560208601610e88565b6113b081610e96565b840191505092915050565b5f6020820190508181035f8301526113d38184611383565b905092915050565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52602260045260245ffd5b5f600282049050600182168061141f57607f821691505b602082108103611432576114316113db565b5b50919050565b5f81549050919050565b5f819050815f5260205f209050919050565b5f819050815f5260205f209050919050565b5f815461147281611408565b61147c8186610e78565b9450600182165f811461149657600181146114ac576114de565b60ff1983168652811515602002860193506114de565b6114b585611454565b5f5b838110156114d6578154818901526001820191506020810190506114b7565b808801955050505b50505092915050565b5f6114f28383611466565b905092915050565b5f600182019050919050565b5f61151082611438565b61151a8185610e4f565b93508360208202850161152c85611442565b805f5b858110156115665784840389528161154785826114e7565b9450611552836114fa565b925060208a0199505060018101905061152f565b50829750879550505050505092915050565b5f6115838385611373565b93506115908385846110c7565b61159983610e96565b840190509392505050565b6115ad81610d92565b82525050565b5f60a0820190506115c65f83018a610fc0565b81810360208301526115d88189611506565b905081810360408301526115ed818789611578565b90506115fc60608301866115a4565b818103608083015261160f818486611578565b905098975050505050505050565b5f67ffffffffffffffff82111561163757611636610fec565b5b61164082610e96565b9050602081019050919050565b5f61165f61165a8461161d565b61104a565b90508281526020810184848401111561167b5761167a611093565b5b6116868482856110c7565b509392505050565b5f82601f8301126116a2576116a1610fe8565b5b81356116b284826020860161164d565b91505092915050565b5f67ffffffffffffffff82169050919050565b6116d7816116bb565b81146116e1575f5ffd5b50565b5f813590506116f2816116ce565b92915050565b5f5f5f6060848603121561170f5761170e610d8a565b5b5f84013567ffffffffffffffff81111561172c5761172b610d8e565b5b6117388682870161168e565b9350506020611749868287016116e4565b925050604084013567ffffffffffffffff81111561176a57611769610d8e565b5b6117768682870161168e565b9150509250925092565b611789816116bb565b82525050565b5f6020820190506117a25f830184611780565b92915050565b5f81905092915050565b7f19000000000000000000000000000000000000000000000000000000000000005f82015250565b5f6117e66002836117a8565b91506117f1826117b2565b600282019050919050565b5f8160601b9050919050565b5f611812826117fc565b9050919050565b5f61182382611808565b9050919050565b61183b61183682610faf565b611819565b82525050565b5f8160c01b9050919050565b5f61185782611841565b9050919050565b61186f61186a826116bb565b61184d565b82525050565b5f819050919050565b5f819050919050565b61189861189382611875565b61187e565b82525050565b5f6118a8826117da565b91506118b4828761182a565b6014820191506118c4828661185e565b6008820191506118d48285611887565b6020820191506118e48284611887565b60208201915081905095945050505050565b5f6040820190506119095f830185610fc0565b6119166020830184610fc0565b9392505050565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52602160045260245ffd5b5f819050919050565b61195c8161194a565b82525050565b5f6020820190506119755f830184611953565b92915050565b61198481611875565b82525050565b5f60208201905061199d5f83018461197b565b92915050565b5f60ff82169050919050565b6119b8816119a3565b82525050565b5f6080820190506119d15f83018761197b565b6119de60208301866119af565b6119eb604083018561197b565b6119f8606083018461197b565b95945050505050565b5f6020601f8301049050919050565b5f82821b905092915050565b5f60088302611a4b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff82611a10565b611a558683611a10565b95508019841693508086168417925050509392505050565b5f819050919050565b5f611a90611a8b611a868461194a565b611a6d565b61194a565b9050919050565b5f819050919050565b611aa983611a76565b611abd611ab582611a97565b848454611a1c565b825550505050565b5f5f905090565b611ad4611ac5565b611adf818484611aa0565b505050565b5b81811015611b0257611af75f82611acc565b600181019050611ae5565b5050565b601f821115611b4757611b1881611454565b611b2184611a01565b81016020851015611b30578190505b611b44611b3c85611a01565b830182611ae4565b50505b505050565b5f82821c905092915050565b5f611b675f1984600802611b4c565b1980831691505092915050565b5f611b7f8383611b58565b9150826002028217905092915050565b611b9882610e6e565b67ffffffffffffffff811115611bb157611bb0610fec565b5b611bbb8254611408565b611bc6828285611b06565b5f60209050601f831160018114611bf7575f8415611be5578287015190505b611bef8582611b74565b865550611c56565b601f198416611c0586611454565b5f5b82811015611c2c57848901518255600182019150602085019450602081019050611c07565b86831015611c495784890151611c45601f891682611b58565b8355505b6001600288020188555050505b50505050505056fea26469706673582212208e949cfdb26a2620484e64238127fb119268358a92cab6fa128aceed74302a5964736f6c634300081e0033

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

000000000000000000000000dfc622f06efdd0e830d82f30679a3c9302bc7940000000000000000000000000000000000000000000000000000000000000004000000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000003a68747470733a2f2f6170692e73746179636c6f616b65642e78797a2f656e732f676174657761792f7b68617264636f6465642d73656e6465727d000000000000

-----Decoded View---------------
Arg [0] : signer_ (address): 0xDFc622F06EfDD0E830d82f30679A3C9302BC7940
Arg [1] : gateways_ (string[]): https://api.staycloaked.xyz/ens/gateway/{hardcoded-sender}

-----Encoded View---------------
7 Constructor Arguments found :
Arg [0] : 000000000000000000000000dfc622f06efdd0e830d82f30679a3c9302bc7940
Arg [1] : 0000000000000000000000000000000000000000000000000000000000000040
Arg [2] : 0000000000000000000000000000000000000000000000000000000000000001
Arg [3] : 0000000000000000000000000000000000000000000000000000000000000020
Arg [4] : 000000000000000000000000000000000000000000000000000000000000003a
Arg [5] : 68747470733a2f2f6170692e73746179636c6f616b65642e78797a2f656e732f
Arg [6] : 676174657761792f7b68617264636f6465642d73656e6465727d000000000000


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.