ETH Price: $3,355.35 (-2.78%)

Contract

0x839B3B540A9572448FD1B2335e0EB09Ac1A02885
 

Overview

ETH Balance

0 ETH

Eth Value

$0.00

Token Holdings

Multichain Info

No addresses found
Transaction Hash
Method
Block
From
To
Set Short Record...202107532024-07-01 9:24:35201 days ago1719825875IN
0x839B3B54...Ac1A02885
0 ETH0.000226545.40102728
Set Short Record...201690742024-06-25 13:44:23207 days ago1719323063IN
0x839B3B54...Ac1A02885
0 ETH0.0004559910.87153974
Set Short Ownerh...197763482024-05-01 16:02:59262 days ago1714579379IN
0x839B3B54...Ac1A02885
0 ETH0.0003639210.25358182
Set Short Ownerh...197758032024-05-01 14:13:35262 days ago1714572815IN
0x839B3B54...Ac1A02885
0 ETH0.0007515310.38830051
Set Short Record...197756722024-05-01 13:47:23262 days ago1714571243IN
0x839B3B54...Ac1A02885
0 ETH0.0005916513.17835837
Set Recordhash194760932024-03-20 13:05:11304 days ago1710939911IN
0x839B3B54...Ac1A02885
0 ETH0.0019335334.27836132
Set Recordhash193128532024-02-26 16:12:47327 days ago1708963967IN
0x839B3B54...Ac1A02885
0 ETH0.0024180757.22032301
Set Recordhash193116682024-02-26 12:13:23327 days ago1708949603IN
0x839B3B54...Ac1A02885
0 ETH0.0020285332.63455999
Set Ownerhash193097492024-02-26 5:47:35327 days ago1708926455IN
0x839B3B54...Ac1A02885
0 ETH0.0013976828.30806738
Set Short Ownerh...191340312024-02-01 13:59:23352 days ago1706795963IN
0x839B3B54...Ac1A02885
0 ETH0.0017381324.0219981
Set Short Ownerh...185843662023-11-16 12:12:11429 days ago1700136731IN
0x839B3B54...Ac1A02885
0 ETH0.0025457735.18406275
Set Recordhash182953312023-10-07 1:28:35470 days ago1696642115IN
0x839B3B54...Ac1A02885
0 ETH0.000340175.47264997
Set Short Record...182952742023-10-07 1:17:11470 days ago1696641431IN
0x839B3B54...Ac1A02885
0 ETH0.000448545.69164249
Set Short Record...182742502023-10-04 2:43:59472 days ago1696387439IN
0x839B3B54...Ac1A02885
0 ETH0.000479436.08355832
Set Short Record...181127432023-09-11 11:13:59495 days ago1694430839IN
0x839B3B54...Ac1A02885
0 ETH0.0010792113.69417877
Set Short Record...181126932023-09-11 11:03:59495 days ago1694430239IN
0x839B3B54...Ac1A02885
0 ETH0.0012941516.42417715
Set Ownerhash181126802023-09-11 11:01:23495 days ago1694430083IN
0x839B3B54...Ac1A02885
0 ETH0.0004122612.61367744
Set Recordhash181103542023-09-11 3:12:23495 days ago1694401943IN
0x839B3B54...Ac1A02885
0 ETH0.000526679.3369869
Set Short Record...180876102023-09-07 22:44:23499 days ago1694126663IN
0x839B3B54...Ac1A02885
0 ETH0.0015945820.23382582
Set Short Record...180749212023-09-06 4:05:23500 days ago1693973123IN
0x839B3B54...Ac1A02885
0 ETH0.0004294210.97045469
Set Short Record...180749112023-09-06 4:03:23500 days ago1693973003IN
0x839B3B54...Ac1A02885
0 ETH0.0009090211.53463748
Set Short Record...180637752023-09-04 14:41:11502 days ago1693838471IN
0x839B3B54...Ac1A02885
0 ETH0.0016359620.75886754
Set Short Ownerh...180390132023-09-01 3:26:47505 days ago1693538807IN
0x839B3B54...Ac1A02885
0 ETH0.0008570111.8444214
Set Short Ownerh...180329572023-08-31 7:07:23506 days ago1693465643IN
0x839B3B54...Ac1A02885
0 ETH0.0010491414.49969857
Set Short Ownerh...180328262023-08-31 6:40:47506 days ago1693464047IN
0x839B3B54...Ac1A02885
0 ETH0.0009329912.89446015
View all transactions

View more zero value Internal Transactions in Advanced View mode

Advanced mode:
Loading...
Loading

Contract Source Code Verified (Exact Match)

Contract Name:
CCIP2ETH

Compiler Version
v0.8.19+commit.7dd6d404

Optimization Enabled:
Yes with 200 runs

Other Settings:
paris EvmVersion
File 1 of 2 : CCIP2ETH.sol
// SPDX-License-Identifier: WTFPL.ETH
pragma solidity >0.8.0 <0.9.0;

import "./Interface.sol";

/**
 * @title Off-Chain ENS Records Manager
 * @author freetib.eth, sshmatrix.eth [https://github.com/namesys-eth]
 * Github : https://github.com/namesys-eth/ccip2-eth-resolver
 * Client : https://namesys.eth.limo
 */
contract CCIP2ETH is iCCIP2ETH {
    /// @dev - Revert on fallback
    fallback() external payable {
        revert();
    }

    /// @dev - Receive donation
    receive() external payable {
        emit ThankYou(msg.sender, msg.value);
    }

    /// Events
    event ThankYou(address indexed addr, uint256 indexed value);
    event GatewayUpdated(address indexed oldAddr, address indexed newAddr);
    event RecordhashUpdated(address indexed owner, bytes32 indexed node, bytes contenthash);
    event UpdatedWrapper(address indexed newAddr, bool indexed status);
    event ApprovedSigner(address owner, bytes32 indexed node, address indexed delegate, bool indexed approved);
    event InterfaceUpdated(bytes4 indexed sig, bool indexed status);

    /// Errors
    error InvalidSignature(string _message);
    error InvalidRequest(string _message);
    error BadConfig(string _message);
    error NotAuthorised(string _message);
    error PlsFundDevs();

    /// @dev - ENS Legacy Registry
    iENS public immutable ENS = iENS(0x00000000000C2E074eC69A0dFb2997BA6C7d2e1e);
    /// @dev - CCIP-Read Gateways
    iGatewayManager public gateway;
    /// @dev - Deployed Chain ID
    string chainID;
    /// @dev - Fee to set ownerhash
    uint256 public ownerhashFees = 0;

    /// Mappings
    /**
     * @dev - Domain-specific contenthash storing all other records
     * @notice - Should be in generic ENS contenthash format or base32/base36 string URL format
     */
    mapping(bytes32 => bytes) public recordhash;
    /// @dev - On-chain singular Manager database
    /// Note - Manager (= isApprovedSigner) is someone who can manage off-chain records for a domain on behalf of its owner
    mapping(address => mapping(bytes32 => mapping(address => bool))) public isApprovedSigner;
    /// @dev - List of all wrapping contracts to be declared in contructor
    mapping(address => bool) public isWrapper;

    /// Interfaces
    mapping(bytes4 => bool) public supportsInterface;

    /// @dev - Constructor
    constructor(address _gateway) {
        gateway = iGatewayManager(_gateway);
        chainID = block.chainid == 1 ? "1" : "5"; // Set ChainID
        /// @dev - Sets ENS Mainnet wrapper as Wrapper
        isWrapper[0xD4416b13d2b3a9aBae7AcD5D6C2BbDBE25686401] = true;
        emit UpdatedWrapper(0xD4416b13d2b3a9aBae7AcD5D6C2BbDBE25686401, true);

        /// @dev - Set necessary interfaces
        supportsInterface[iERC165.supportsInterface.selector] = true;
        supportsInterface[iENSIP10.resolve.selector] = true;
        supportsInterface[type(iERC173).interfaceId] = true;
        supportsInterface[iCCIP2ETH.setRecordhash.selector] = true;
        supportsInterface[iCCIP2ETH.setOwnerhash.selector] = true;
        supportsInterface[iCallbackType.signedRecord.selector] = true;
        supportsInterface[iCallbackType.signedRedirect.selector] = true;
    }

    /**
     * @dev Gets recordhash for a node
     * @param _node - Namehash of domain.eth, or bytes32(address _Owner)
     * @return _recordhash - IPNS contenthash that is set as recordhash
     */
    function getRecordhash(bytes32 _node) external view returns (bytes memory _recordhash) {
        _recordhash = recordhash[_node];
        if (_recordhash.length == 0) {
            address _owner = ENS.owner(_node);
            if (isWrapper[_owner]) {
                _owner = iToken(_owner).ownerOf(uint256(_node));
            }
            _recordhash = recordhash[bytes32(uint256(uint160(_owner)))];
        }
        if (_recordhash.length == 32 && !gateway.isWeb2(_recordhash)) {
            _recordhash = abi.encodePacked(hex"e5010172002408011220", _recordhash);
        }
    }

    /**
     * @dev Sets regular recordhash for a node
     * Note - Only ENS owner or manager of node can call
     * @param _node - Namehash of domain.eth
     * @param _recordhash - Regular IPNS contenthash to set as recordhash
     */
    function setRecordhash(bytes32 _node, bytes calldata _recordhash) external payable {
        address _owner = ENS.owner(_node);
        if (isWrapper[_owner]) {
            _owner = iToken(_owner).ownerOf(uint256(_node));
        }
        if (msg.sender != _owner && !isApprovedSigner[_owner][_node][msg.sender]) {
            revert NotAuthorised("NOT_APPROVED");
        }
        recordhash[_node] = _recordhash;
        emit RecordhashUpdated(msg.sender, _node, _recordhash);
    }

    /**
     * @dev Sets short recordhash for a node
     * Note - Without the constant prefix hex'e5010172002408011220'
     * Note - Only ENS owner or manager of node can call
     * @param _node - Namehash of domain.eth
     * @param _recordhash - Short IPNS contenthash to set as recordhash
     */
    function setShortRecordhash(bytes32 _node, bytes32 _recordhash) external payable {
        address _owner = ENS.owner(_node);
        if (isWrapper[_owner]) {
            _owner = iToken(_owner).ownerOf(uint256(_node));
        }
        if (msg.sender != _owner && !isApprovedSigner[_owner][_node][msg.sender]) {
            revert NotAuthorised("NOT_APPROVED");
        }
        recordhash[_node] = abi.encodePacked(_recordhash);
        emit RecordhashUpdated(msg.sender, _node, abi.encodePacked(hex"e5010172002408011220", _recordhash));
    }

    /**
     * @dev Sets ownerhash for an owner
     * Note - Wallet-specific fallback recordhash
     * @param _recordhash - Regular IPNS contenthash to set as ownerhash
     */
    function setOwnerhash(bytes calldata _recordhash) external payable {
        if (msg.value < ownerhashFees) {
            revert PlsFundDevs();
        }
        recordhash[bytes32(uint256(uint160(msg.sender)))] = _recordhash;
        emit RecordhashUpdated(msg.sender, bytes32(uint256(uint160(msg.sender))), _recordhash);
    }

    /**
     * @dev Sets short ownerhash for an owner
     * Note - Without the constant prefix hex'e5010172002408011220'
     * Note - Wallet-specific fallback recordhash
     * @param _recordhash - Short IPNS contenthash to set as ownerhash
     */
    function setShortOwnerhash(bytes32 _recordhash) external payable {
        if (msg.value < ownerhashFees) {
            revert PlsFundDevs();
        }
        recordhash[bytes32(uint256(uint160(msg.sender)))] = abi.encodePacked(_recordhash);
        emit RecordhashUpdated(
            msg.sender, bytes32(uint256(uint160(msg.sender))), abi.encodePacked(hex"e5010172002408011220", _recordhash)
        );
    }

    /**
     * @dev Sets recordhash for a subnode
     * Note - Only ENS owner or manager of parent node can call
     * @param _node - Namehash of domain.eth
     * @param _subdomain - Subdomain labels; sub.domain.eth = "sub"
     * @param _recordhash - Regular IPNS contenthash to set as recordhash
     */
    function setSubRecordhash(bytes32 _node, string calldata _subdomain, bytes calldata _recordhash) external payable {
        address _owner = ENS.owner(_node);
        if (isWrapper[_owner]) {
            _owner = iToken(_owner).ownerOf(uint256(_node));
        }
        if (msg.sender != _owner && !isApprovedSigner[_owner][_node][msg.sender]) {
            revert NotAuthorised("NOT_APPROVED");
        }
        bytes32 _namehash = keccak256(abi.encodePacked(_node, keccak256(bytes(_subdomain))));
        recordhash[_namehash] = _recordhash;
        emit RecordhashUpdated(msg.sender, _namehash, _recordhash);
    }

    /**
     * @dev Sets recordhash for a subnode
     * Note - Only ENS owner or manager of parent node can call
     * @param _node - Namehash of domain.eth
     * @param _subdomain - Subdomain labels; a.b.c.domain.eth = [a, b, c]
     * @param _recordhash - Regular IPNS contenthash to set as recordhash
     */
    function setDeepSubRecordhash(bytes32 _node, string[] calldata _subdomain, bytes calldata _recordhash)
        external
        payable
    {
        bytes32 _namehash = _node;
        address _owner = ENS.owner(_node);
        if (isWrapper[_owner]) {
            _owner = iToken(_owner).ownerOf(uint256(_node));
        }
        if (msg.sender != _owner && !isApprovedSigner[_owner][_node][msg.sender]) {
            revert NotAuthorised("NOT_APPROVED");
        }
        uint256 len = _subdomain.length;
        unchecked {
            while (len > 0) {
                _namehash = keccak256(abi.encodePacked(_namehash, keccak256(bytes(_subdomain[--len]))));
            }
        }
        recordhash[_namehash] = _recordhash;
        emit RecordhashUpdated(msg.sender, _namehash, _recordhash);
    }

    /**
     * @dev EIP-2544/EIP-3668 core resolve() function; aka CCIP-Read
     * @param name - ENS domain to resolve; must be DNS encoded
     * @param request - Encoding-specific function to resolve
     * @return result - Triggers Off-chain Lookup
     * Note - Return value is not used
     */
    function resolve(bytes calldata name, bytes calldata request) external view returns (bytes memory) {
        unchecked {
            /// @dev - DNSDecode() routine
            uint256 index = 1;
            uint256 n = 1;
            uint256 len = uint8(bytes1(name[0]));
            bytes[] memory _labels = new bytes[](42);
            _labels[0] = name[1:n += len];
            string memory _path = string(_labels[0]);
            string memory _domain = _path;
            while (name[n] > 0x0) {
                len = uint8(bytes1(name[n:++n]));
                _labels[index] = name[n:n += len];
                _domain = string.concat(_domain, ".", string(_labels[index]));
                _path = string.concat(string(_labels[index++]), "/", _path);
            }
            bytes32 _namehash = keccak256(abi.encodePacked(bytes32(0), keccak256(_labels[--index])));
            bytes32 _node;
            bytes memory _recordhash;
            // Evaluate 'closest-set' parent node
            while (index > 0) {
                _namehash = keccak256(abi.encodePacked(_namehash, keccak256(_labels[--index])));
                // Check if sub(domain) exists on-chain or off-chain
                if (ENS.recordExists(_namehash)) {
                    _node = _namehash;
                    _recordhash = recordhash[_namehash];
                } else if (bytes(recordhash[_namehash]).length > 0) {
                    _recordhash = recordhash[_namehash];
                }
            }
            address _owner = ENS.owner(_node);
            // Update ownership if domain is wrapped
            if (isWrapper[_owner]) {
                _owner = iToken(_owner).ownerOf(uint256(_node));
            }
            if (_recordhash.length == 0) {
                _recordhash = recordhash[bytes32(uint256(uint160(_owner)))];
            }
            string memory _recType = gateway.funcToJson(request); // Filename for the requested record
            bytes32 _checkhash =
                keccak256(abi.encodePacked(this, blockhash(block.number - 1), _owner, _domain, _recType, request));
            revert OffchainLookup(
                address(this),
                gateway.randomGateways(
                    _recordhash, string.concat("/.well-known/", _path, "/", _recType), uint256(_checkhash)
                ), // Generate pseudo-random list of gateways for record resolution
                abi.encodePacked(uint16(block.timestamp / 60)), // Cache = 60 seconds
                iCCIP2ETH.__callback.selector, // Callback function
                abi.encode(_node, block.number - 1, _checkhash, _domain, _recType, _path, name, request)
            );
        }
    }

    /**
     * @dev Default Callback function
     * @param response - Response of CCIP-Read call
     * @param extradata - Extra data used by callback
     * @return result - Concludes Off-chain Lookup
     * Note - Return value is not used
     */
    function __callback(bytes calldata response, bytes calldata extradata)
        external
        view
        returns (bytes memory result)
    {
        /// Get signer-type from response identifier
        bytes4 _type = bytes4(response[:4]);
        if (!supportsInterface[_type]) {
            /// @dev Future features in __fallback
            return gateway.__fallback(response, extradata);
        }
        (
            bytes32 _node, // Namehash of base owned ENS domain
            uint256 _blocknumber, // Blocknumber for timeout checks
            bytes32 _checkhash, // Extra checkhash
            string memory _domain, // String-formatted complete 'a.b.c.domain.eth'
            string memory _recType, // Record type
            , // Complete reverse-DNS path for __fallback()
            , // DNS-encoded domain.eth
            bytes memory _request // Format: <bytes4> + <namehash> + <extradata>
        ) = abi.decode(extradata, (bytes32, uint256, bytes32, string, string, string, bytes, bytes));
        address _owner = ENS.owner(_node);
        if (isWrapper[_owner]) {
            _owner = iToken(_owner).ownerOf(uint256(_node));
        }
        /// @dev - Timeout in 6 blocks
        if (block.number > _blocknumber + 7) {
            revert InvalidRequest("BLOCK_TIMEOUT");
        }
        /// @dev - Verify checkhash
        if (
            _checkhash
                != keccak256(abi.encodePacked(this, blockhash(_blocknumber), _owner, _domain, _recType, _request))
        ) {
            revert InvalidRequest("BAD_CHECKSUM");
        }
        // Signer could be:
        // a) Owner
        // OR, b) On-chain approved manager
        // OR, c) Off-chain approved signer
        address _signer;
        /// Signature associated with the record
        bytes memory _recordSignature;
        /// Init off-chain manager's signature request
        string memory signRequest;
        /// Off-chain signature approving record signer (if signer != owner or on-chain manager)
        bytes memory _approvedSig;
        /// @dev CCIP-Read response decode
        (_signer, _recordSignature, _approvedSig, result) = abi.decode(response[4:], (address, bytes, bytes, bytes));
        if (_approvedSig.length < 64) {
            if (_signer != _owner && !isApprovedSigner[_owner][_node][_signer]) {
                revert NotAuthorised("NOT_APPROVED");
            }
        } else if (!approvedSigner(_owner, _signer, _node, _approvedSig, _domain)) {
            revert NotAuthorised("BAD_APPROVAL");
        }
        if (_type == iCallbackType.signedRecord.selector) {
            /// @dev If 'signedRecord()' bytes4 selector; handles signed records
            signRequest = string.concat(
                "Requesting Signature To Update ENS Record\n",
                "\nOrigin: ",
                _domain,
                "\nRecord Type: ",
                _recType,
                "\nExtradata: 0x",
                gateway.bytesToHexString(abi.encodePacked(keccak256(result)), 0),
                "\nSigned By: eip155:",
                chainID,
                ":",
                gateway.toChecksumAddress(_signer)
            );
            if (_signer != iCCIP2ETH(this).getSigner(signRequest, _recordSignature)) {
                revert InvalidRequest("BAD_SIGNED_RECORD");
            }
        } else if (_type == iCallbackType.signedRedirect.selector) {
            /// @dev If 'signedRedirect()' bytes4 selector; handles redirected records
            if (result[0] == 0x0 || result[result.length - 1] != 0x0) {
                revert InvalidRequest("BAD_REDIRECT_REQUEST");
            }
            // ENS dApp redirect
            // Result should be DNS encoded; result should NOT be ABI-encoded
            // Note Last byte is 0x00, meaning end of DNS-encoded stream
            (bytes4 _req, bytes32 _redirectNamehash, bytes memory _redirectRequest, string memory _redirectDomain) =
                iCCIP2ETH(this).redirectService(result, _request);
            signRequest = string.concat(
                "Requesting Signature To Install dApp Service\n",
                "\nOrigin: ",
                _domain, // e.g. ens.domain.eth
                "\nApp: ",
                _redirectDomain, // e.g. app.ens.eth
                "\nExtradata: 0x",
                gateway.bytesToHexString(abi.encodePacked(keccak256(result)), 0),
                "\nSigned By: eip155:",
                chainID,
                ":",
                gateway.toChecksumAddress(_signer)
            );
            if (_signer != iCCIP2ETH(this).getSigner(signRequest, _recordSignature)) {
                revert InvalidRequest("BAD_DAPP_SIGNATURE");
            }
            address _resolver = ENS.resolver(_redirectNamehash); // Owned node
            if (iERC165(_resolver).supportsInterface(iENSIP10.resolve.selector)) {
                return iENSIP10(_resolver).resolve(result, _redirectRequest);
            } else if (iERC165(_resolver).supportsInterface(_req)) {
                bool ok;
                (ok, result) = _resolver.staticcall(_redirectRequest);
                if (!ok) {
                    revert InvalidRequest("BAD_RESOLVER");
                }
            } else {
                revert InvalidRequest("BAD_FUNCTION");
            }
        } else {
            /// @dev Future features in __fallback
            return gateway.__fallback(response, extradata);
        }
    }

    /**
     * @dev Redirects the CCIP-Read request to another ENS Domain
     * @param _encoded - ENS domain to resolve; must be DNS encoded
     * @param _requested - Originally requested encoding-specific function to resolve
     * @return _selector - Redirected function selector
     * @return _namehash - Redirected namehash
     * @return _redirectRequest - Redirected request
     * @return domain - String-formatted ENS domain
     */
    function redirectService(bytes calldata _encoded, bytes calldata _requested)
        external
        view
        returns (bytes4 _selector, bytes32 _namehash, bytes memory _redirectRequest, string memory domain)
    {
        uint256 index = 1;
        uint256 n = 1;
        uint256 len = uint8(bytes1(_encoded[0]));
        bytes[] memory _labels = new bytes[](42);
        _labels[0] = _encoded[1:n += len];
        domain = string(_labels[0]);
        while (_encoded[n] > 0x0) {
            len = uint8(bytes1(_encoded[n:++n]));
            _labels[index] = _encoded[n:n += len];
            domain = string.concat(domain, ".", string(_labels[index]));
        }
        bytes32 _owned;
        _namehash = keccak256(abi.encodePacked(bytes32(0), keccak256(_labels[--index])));
        while (index > 0) {
            _namehash = keccak256(abi.encodePacked(_namehash, keccak256(_labels[--index])));
            if (ENS.recordExists(_namehash)) {
                _owned = _namehash;
            }
        }
        if (_owned == bytes32(0)) {
            revert InvalidRequest("NOT_REGISTERED");
        }
        _selector = bytes4(_requested[:4]);
        _redirectRequest = abi.encodePacked(_selector, _namehash, _requested.length > 36 ? _requested[36:] : bytes(""));
        _namehash = _owned;
    }

    /**
     * @dev Checks for manager access to an ENS domain for record management
     * @param _owner - Owner of ENS domain
     * @param _approvedSigner - Manager address to check
     * @param _node - Namehash of ENS domain
     * @param _signature - Signature to verify
     * @param _domain - String-formatted ENS domain
     * @return  - Whether manager is approved by the owner
     */
    function approvedSigner(
        address _owner,
        address _approvedSigner,
        bytes32 _node,
        bytes memory _signature,
        string memory _domain
    ) public view returns (bool) {
        address _signer = iCCIP2ETH(this).getSigner(
            string.concat(
                "Requesting Signature To Approve ENS Records Signer\n",
                "\nOrigin: ",
                _domain,
                "\nApproved Signer: eip155:",
                chainID,
                ":",
                gateway.toChecksumAddress(_approvedSigner),
                "\nApproved By: eip155:",
                chainID,
                ":",
                gateway.toChecksumAddress(_owner)
            ),
            _signature
        );
        return (_signer == _owner || isApprovedSigner[_owner][_node][_signer]);
    }

    /**
     * @dev Checks if a signature is valid
     * @param _message - String-formatted message that was signed
     * @param _signature - Compact signature to verify
     * @return _signer - Signer of message
     * @notice - Signature Format:
     * a) 64 bytes - bytes32(r) + bytes32(vs) ~ compact, or
     * b) 65 bytes - bytes32(r) + bytes32(s) + uint8(v) ~ packed, or
     * c) 96 bytes - bytes32(r) + bytes32(s) + uint256(v) ~ longest
     */
    function getSigner(string calldata _message, bytes calldata _signature) external view returns (address _signer) {
        bytes32 r = bytes32(_signature[:32]);
        bytes32 s;
        uint8 v;
        uint256 len = _signature.length;
        if (len == 64) {
            bytes32 vs = bytes32(_signature[32:]);
            s = vs & bytes32(0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF);
            v = uint8((uint256(vs) >> 255) + 27);
        } else if (len == 65) {
            s = bytes32(_signature[32:64]);
            v = uint8(bytes1(_signature[64:]));
        } else if (len == 96) {
            s = bytes32(_signature[32:64]);
            v = uint8(uint256(bytes32(_signature[64:])));
        } else {
            revert InvalidSignature("BAD_SIG_LENGTH");
        }
        if (s > 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5D576E7357A4501DDFE92F46681B20A0) {
            revert InvalidSignature("INVALID_S_VALUE");
        }
        bytes32 digest = keccak256(
            abi.encodePacked("\x19Ethereum Signed Message:\n", gateway.uintToString(bytes(_message).length), _message)
        );
        _signer = ecrecover(digest, v, r, s);
        if (_signer == address(0)) {
            revert InvalidSignature("ZERO_ADDR");
        }
    }

    /**
     * @dev Sets a signer (= manager) as approved to manage records for a node
     * @param _node - Namehash of ENS domain
     * @param _signer - Address of signer (= manager)
     * @param _approval - Status to set
     */
    function approve(bytes32 _node, address _signer, bool _approval) external {
        isApprovedSigner[msg.sender][_node][_signer] = _approval;
        emit ApprovedSigner(msg.sender, _node, _signer, _approval);
    }

    /**
     * @dev Sets multiple signers (= managers) as approved to manage records for a node
     * @param _node - Namehash[] of ENS domains
     * @param _signer - Address[] of signers (= managers)
     * @param _approval - Status[] to set
     */
    function multiApprove(bytes32[] calldata _node, address[] calldata _signer, bool[] calldata _approval) external {
        uint256 len = _node.length;
        for (uint256 i = 0; i < len; i++) {
            isApprovedSigner[msg.sender][_node[i]][_signer[i]] = _approval[i];
            emit ApprovedSigner(msg.sender, _node[i], _signer[i], _approval[i]);
        }
    }

    /**
     * @dev Checks if a signer (= manager) is approved to manage records for a node
     * @param _node - Namehash of ENS domain
     * @param _signer - Address of signer (= manager)
     */
    function approved(bytes32 _node, address _signer) public view returns (bool) {
        address _owner = ENS.owner(_node);
        if (isWrapper[_owner]) {
            _owner = iToken(_owner).ownerOf(uint256(_node));
        }
        return _owner == _signer || isApprovedSigner[_owner][_node][_signer];
    }

    /// @dev : Management functions

    /// @dev - Checks for admin privileges
    modifier OnlyDev() {
        if (msg.sender != gateway.owner()) {
            revert NotAuthorised("NOT_DEV");
        }
        _;
    }

    /// @dev - Returns owner of the contract
    function owner() public view returns (address) {
        return gateway.owner();
    }

    /// @dev - Updates ChainID in case of a hardfork
    function updateChainID() public {
        chainID = gateway.uintToString(block.chainid);
    }
    /**
     * @dev Sets fees for ownerhash
     * Note - Set to 0 at launch
     * @param _wei - Fees in WEI per EOA
     */

    function updateOwnerhashFees(uint256 _wei) external OnlyDev {
        ownerhashFees = _wei;
    }

    /**
     * @dev Updates supported interfaces
     * @param _sig - 4-byte interface selector
     * @param _set - State to set for selector
     */
    function updateInterface(bytes4 _sig, bool _set) external OnlyDev {
        if (_sig == iCallbackType.signedRecord.selector || _sig == iENSIP10.resolve.selector) {
            revert BadConfig("LOCKED_CALLBACK");
        }
        supportsInterface[_sig] = _set;
        emit InterfaceUpdated(_sig, _set);
    }

    /**
     * @dev Set new Gateway Manager Contract
     * @param _gateway - Address of new Gateway Manager Contract
     */
    function updateGateway(address _gateway) external OnlyDev {
        if (_gateway.code.length == 0) {
            revert BadConfig("BAD_GATEWAY");
        }
        if (msg.sender != iGatewayManager(_gateway).owner()) {
            revert NotAuthorised("BAD_OWNER");
        }
        emit GatewayUpdated(address(gateway), _gateway);
        gateway = iGatewayManager(_gateway);
    }

    /**
     * @dev Add or remove ENS wrapper
     * @param _addr - Address of ENS wrapper
     * @param _set - State to set for new ENS wrapper
     */
    function updateWrapper(address _addr, bool _set) external OnlyDev {
        if (_addr.code.length == 0) {
            revert BadConfig("BAD_WRAPPER");
        }
        isWrapper[_addr] = _set;
        emit UpdatedWrapper(_addr, _set);
    }

    /**
     * @dev Withdraw Ether to owner; to be used for tips or in case some Ether gets locked in the contract
     */
    function withdraw() external {
        payable(gateway.owner()).transfer(address(this).balance);
    }

    /**
     * @dev To be used for tips or in case some fungible tokens get locked in the contract
     * @param _contract - Token contract address
     * @param _balance - Amount to release
     */
    function withdraw(address _contract, uint256 _balance) external {
        iToken(_contract).transferFrom(address(this), gateway.owner(), _balance);
    }

    /**
     * @dev To be used for tips or in case some non-fungible tokens get locked in the contract
     * @param _contract - Token contract address
     * @param _token - Token ID to release
     */
    function safeWithdraw(address _contract, uint256 _token) external {
        iToken(_contract).safeTransferFrom(address(this), gateway.owner(), _token);
    }
}

File 2 of 2 : Interface.sol
// SPDX-License-Identifier: WTFPL.ETH
pragma solidity >0.8.0 <0.9.0;

interface iERC165 {
    function supportsInterface(bytes4 interfaceID) external view returns (bool);
}

interface iERC173 {
    event OwnershipTransferred(address indexed previousOwner, address indexed newOwner);

    function owner() external view returns (address);
    function transferOwnership(address _newOwner) external;
}

interface iENS {
    function owner(bytes32 node) external view returns (address);
    function resolver(bytes32 node) external view returns (address);
    function ttl(bytes32 node) external view returns (uint64);
    function recordExists(bytes32 node) external view returns (bool);
    function isApprovedForAll(address owner, address operator) external view returns (bool);
}

interface iENSIP10 {
    error OffchainLookup(address _to, string[] _gateways, bytes _data, bytes4 _callbackFunction, bytes _extradata);

    function resolve(bytes memory _name, bytes memory _data) external view returns (bytes memory);
}

interface iCCIP2ETH is iENSIP10 {
    function __callback(bytes calldata _response, bytes calldata _extraData)
        external
        view
        returns (bytes memory _result);

    function getSigner(string calldata _signRequest, bytes calldata _signature)
        external
        view
        returns (address _signer);
    function setRecordhash(bytes32 _node, bytes calldata _recordhash) external payable;
    function setShortRecordhash(bytes32 _node, bytes32 _recordhash) external payable;
    function setSubRecordhash(bytes32 _node, string memory _subdomain, bytes calldata _recordhash) external payable;
    function setDeepSubRecordhash(bytes32 _node, string[] memory _subdomains, bytes calldata _recordhash)
        external
        payable;
    function setOwnerhash(bytes calldata _recordhash) external payable;
    function redirectService(bytes calldata _encoded, bytes calldata _requested)
        external
        view
        returns (bytes4 _selector, bytes32 _namehash, bytes memory _redirectRequest, string memory _domain);
}

interface iGatewayManager is iERC173 {
    function randomGateways(bytes calldata _recordhash, string memory _path, uint256 k)
        external
        view
        returns (string[] memory gateways);
    function uintToString(uint256 value) external pure returns (string memory);
    function bytesToHexString(bytes calldata _buffer, uint256 _start) external pure returns (string memory);
    function bytes32ToHexString(bytes32 _buffer) external pure returns (string memory);
    function funcToJson(bytes calldata _request) external view returns (string memory _jsonPath);
    function toChecksumAddress(address _addr) external pure returns (string memory);
    function __fallback(bytes calldata response, bytes calldata extradata)
        external
        view
        returns (bytes memory result);
    function addFuncMap(bytes4 _func, string calldata _name) external;
    function listWeb2Gateways() external view returns (string[] memory list);
    function addWeb2Gateway(string calldata _domain) external;
    function removeWeb2Gateway(uint256 _index) external;
    function replaceWeb2Gateway(uint256 _index, string calldata _domain) external;
    function listWeb3Gateways() external view returns (string[] memory list);
    function addWeb3Gateway(string calldata _domain) external;
    function removeWeb3Gateway(uint256 _index) external;
    function replaceWeb3Gateway(uint256 _index, string calldata _domain) external;
    function formatSubdomain(bytes calldata _recordhash) external pure returns (string memory result);
    function isWeb2(bytes calldata _recordhash) external pure returns (bool);
}

interface iResolver {
    function contenthash(bytes32 node) external view returns (bytes memory);
    function addr(bytes32 node) external view returns (address payable);
    function pubkey(bytes32 node) external view returns (bytes32 x, bytes32 y);
    function text(bytes32 node, string calldata key) external view returns (string memory value);
    function name(bytes32 node) external view returns (string memory);
    function ABI(bytes32 node, uint256 contentTypes) external view returns (uint256, bytes memory);
    function interfaceImplementer(bytes32 node, bytes4 interfaceID) external view returns (address);
    function zonehash(bytes32 node) external view returns (bytes memory);
    function dnsRecord(bytes32 node, bytes32 name, uint16 resource) external view returns (bytes memory);
    function recordVersions(bytes32 node) external view returns (uint64);
    function approved(bytes32 _node, address _signer) external view returns (bool);
}

interface iOverloadResolver {
    function addr(bytes32 node, uint256 coinType) external view returns (bytes memory);
    function dnsRecord(bytes32 node, bytes memory name, uint16 resource) external view returns (bytes memory);
}

interface iToken {
    function ownerOf(uint256 id) external view returns (address);
    function transferFrom(address from, address to, uint256 bal) external;
    function safeTransferFrom(address from, address to, uint256 bal) external;
}

// Note - Owner = Owner of domain.eth
// Note - Manager = On-/Off-Chain address approved by Owner
// Note - Signer = Record signer
interface iCallbackType {
    function signedRecord(
        address recordSigner, // Owner OR On-Chain Manager OR Off-Chain Manager
        bytes memory recordSignature, // Signature from signer for result value
        bytes memory approvedSignature, // bytes length >0 & <64 IF signer is owner or on-chain approved manager
        bytes memory result // ABI-encoded result
    ) external view returns (bytes memory);

    function signedRedirect(
        address recordSigner, // Owner OR On-Chain Manager OR Off-Chain Manager
        bytes memory recordSignature, // Signature from signer for redirect value
        bytes memory approvedSignature, // bytes length >0 & <64 IF signer is owner or on-chain approved manager
        bytes memory redirect // DNS-encoded sub/domain.eth to redirect
    ) external view returns (bytes memory);
}

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

Contract Security Audit

Contract ABI

[{"inputs":[{"internalType":"address","name":"_gateway","type":"address"}],"stateMutability":"nonpayable","type":"constructor"},{"inputs":[{"internalType":"string","name":"_message","type":"string"}],"name":"BadConfig","type":"error"},{"inputs":[{"internalType":"string","name":"_message","type":"string"}],"name":"InvalidRequest","type":"error"},{"inputs":[{"internalType":"string","name":"_message","type":"string"}],"name":"InvalidSignature","type":"error"},{"inputs":[{"internalType":"string","name":"_message","type":"string"}],"name":"NotAuthorised","type":"error"},{"inputs":[{"internalType":"address","name":"_to","type":"address"},{"internalType":"string[]","name":"_gateways","type":"string[]"},{"internalType":"bytes","name":"_data","type":"bytes"},{"internalType":"bytes4","name":"_callbackFunction","type":"bytes4"},{"internalType":"bytes","name":"_extradata","type":"bytes"}],"name":"OffchainLookup","type":"error"},{"inputs":[],"name":"PlsFundDevs","type":"error"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"owner","type":"address"},{"indexed":true,"internalType":"bytes32","name":"node","type":"bytes32"},{"indexed":true,"internalType":"address","name":"delegate","type":"address"},{"indexed":true,"internalType":"bool","name":"approved","type":"bool"}],"name":"ApprovedSigner","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"oldAddr","type":"address"},{"indexed":true,"internalType":"address","name":"newAddr","type":"address"}],"name":"GatewayUpdated","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"bytes4","name":"sig","type":"bytes4"},{"indexed":true,"internalType":"bool","name":"status","type":"bool"}],"name":"InterfaceUpdated","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"owner","type":"address"},{"indexed":true,"internalType":"bytes32","name":"node","type":"bytes32"},{"indexed":false,"internalType":"bytes","name":"contenthash","type":"bytes"}],"name":"RecordhashUpdated","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"addr","type":"address"},{"indexed":true,"internalType":"uint256","name":"value","type":"uint256"}],"name":"ThankYou","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"newAddr","type":"address"},{"indexed":true,"internalType":"bool","name":"status","type":"bool"}],"name":"UpdatedWrapper","type":"event"},{"stateMutability":"payable","type":"fallback"},{"inputs":[],"name":"ENS","outputs":[{"internalType":"contract iENS","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes","name":"response","type":"bytes"},{"internalType":"bytes","name":"extradata","type":"bytes"}],"name":"__callback","outputs":[{"internalType":"bytes","name":"result","type":"bytes"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes32","name":"_node","type":"bytes32"},{"internalType":"address","name":"_signer","type":"address"},{"internalType":"bool","name":"_approval","type":"bool"}],"name":"approve","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes32","name":"_node","type":"bytes32"},{"internalType":"address","name":"_signer","type":"address"}],"name":"approved","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_owner","type":"address"},{"internalType":"address","name":"_approvedSigner","type":"address"},{"internalType":"bytes32","name":"_node","type":"bytes32"},{"internalType":"bytes","name":"_signature","type":"bytes"},{"internalType":"string","name":"_domain","type":"string"}],"name":"approvedSigner","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"gateway","outputs":[{"internalType":"contract iGatewayManager","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes32","name":"_node","type":"bytes32"}],"name":"getRecordhash","outputs":[{"internalType":"bytes","name":"_recordhash","type":"bytes"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"string","name":"_message","type":"string"},{"internalType":"bytes","name":"_signature","type":"bytes"}],"name":"getSigner","outputs":[{"internalType":"address","name":"_signer","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"},{"internalType":"bytes32","name":"","type":"bytes32"},{"internalType":"address","name":"","type":"address"}],"name":"isApprovedSigner","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"isWrapper","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes32[]","name":"_node","type":"bytes32[]"},{"internalType":"address[]","name":"_signer","type":"address[]"},{"internalType":"bool[]","name":"_approval","type":"bool[]"}],"name":"multiApprove","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"owner","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"ownerhashFees","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"name":"recordhash","outputs":[{"internalType":"bytes","name":"","type":"bytes"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes","name":"_encoded","type":"bytes"},{"internalType":"bytes","name":"_requested","type":"bytes"}],"name":"redirectService","outputs":[{"internalType":"bytes4","name":"_selector","type":"bytes4"},{"internalType":"bytes32","name":"_namehash","type":"bytes32"},{"internalType":"bytes","name":"_redirectRequest","type":"bytes"},{"internalType":"string","name":"domain","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes","name":"name","type":"bytes"},{"internalType":"bytes","name":"request","type":"bytes"}],"name":"resolve","outputs":[{"internalType":"bytes","name":"","type":"bytes"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_contract","type":"address"},{"internalType":"uint256","name":"_token","type":"uint256"}],"name":"safeWithdraw","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes32","name":"_node","type":"bytes32"},{"internalType":"string[]","name":"_subdomain","type":"string[]"},{"internalType":"bytes","name":"_recordhash","type":"bytes"}],"name":"setDeepSubRecordhash","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"bytes","name":"_recordhash","type":"bytes"}],"name":"setOwnerhash","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"bytes32","name":"_node","type":"bytes32"},{"internalType":"bytes","name":"_recordhash","type":"bytes"}],"name":"setRecordhash","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"bytes32","name":"_recordhash","type":"bytes32"}],"name":"setShortOwnerhash","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"bytes32","name":"_node","type":"bytes32"},{"internalType":"bytes32","name":"_recordhash","type":"bytes32"}],"name":"setShortRecordhash","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"bytes32","name":"_node","type":"bytes32"},{"internalType":"string","name":"_subdomain","type":"string"},{"internalType":"bytes","name":"_recordhash","type":"bytes"}],"name":"setSubRecordhash","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"bytes4","name":"","type":"bytes4"}],"name":"supportsInterface","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"updateChainID","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_gateway","type":"address"}],"name":"updateGateway","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes4","name":"_sig","type":"bytes4"},{"internalType":"bool","name":"_set","type":"bool"}],"name":"updateInterface","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_wei","type":"uint256"}],"name":"updateOwnerhashFees","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_addr","type":"address"},{"internalType":"bool","name":"_set","type":"bool"}],"name":"updateWrapper","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"withdraw","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_contract","type":"address"},{"internalType":"uint256","name":"_balance","type":"uint256"}],"name":"withdraw","outputs":[],"stateMutability":"nonpayable","type":"function"},{"stateMutability":"payable","type":"receive"}]

60a03462000367576001600160401b0390601f19601f620047fa388190039182018316840191858311858410176200036c57808592604094855283396020948591810103126200036757516001600160a01b038116949085900362000367576e0c2e074ec69a0dfb2997ba6c7d2e1e6080526000600281905580546001600160a01b03191690951785556001924684036200034b576200009e62000382565b848152603160f81b868201525b8051928311620003375784548581811c911680156200032c575b8782101462000318579081601f85949311620002c1575b508691601f8411600114620002605750879262000254575b5050600019600383901b1c191690831b1782555b73d4416b13d2b3a9abae7acd5d6c2bbdbe25686401938481526005845260068282209460ff19958587825416179055848451977f976fe5c61b46a2e3e8c0330103e8b00d2e561ff8bec93bb1ff3bfb59fd754c758580a36301ffc9a760e01b8352528181208054851684179055639061b92360e01b815281812080548516841790556307f5828d60e41b815281812080548516841790556371dca99d60e11b81528181208054851684179055636166b77960e01b81528181208054851684179055632b45eb2b60e01b8152818120805485168417905563308045e960e21b81522080549092161790556144579081620003a3823960805181818161039f01528181610a1101528181610d73015281816111510152818161153101528181611b9c01528181612116015281816123f5015281816128c301528181612cd90152818161349a0152613b850152f35b015190503880620000f4565b86895287892087959093929116895b89828210620002aa575050841162000290575b505050811b01825562000108565b015160001960f88460031b161c1916905538808062000282565b83850151865589979095019493840193016200026f565b90919250858852868820601f850160051c8101918886106200030d575b8594939291601f89920160051c01915b828110620002fe575050620000dc565b8a8155869550889101620002ee565b9091508190620002de565b634e487b7160e01b88526022600452602488fd5b90607f1690620000c5565b634e487b7160e01b87526041600452602487fd5b6200035562000382565b848152603560f81b86820152620000ab565b600080fd5b634e487b7160e01b600052604160045260246000fd5b60408051919082016001600160401b038111838210176200036c5760405256fe6080806040526004361015610044575b50361561001b57600080fd5b34337f9a064d674ddc42ac41b38566457161f1ded37e65a59162da003dd25bcb057b60600080a3005b600090813560e01c90816301ffc9a714612d4d57508063116191b614612d2657806315c3867914612d085780631d2e2cc414612cc35780633ccfd60b14612c36578063417ab3eb14612c0b5780635058c46014612b4257806353b5946814612ade5780636166b779146129a757806363a786b91461279257806376a810f2146126605780637ceb95f91461237b5780638384976f146122675780638da5cb5b146121f65780639061b923146119f257806393c52fbf1461197a5780639503d22f1461181c578063a4b91a011461177d578063a6704e76146114f4578063a8e547fb1461125b578063b984b2cd1461110b578063c0346b2014610f9f578063c55a5d5914610f6d578063c6a84da314610cfb578063cc49dd951461095c578063d5d7d981146107ec578063d8dd805c14610624578063e0aa2797146105e5578063e3b9533a14610345578063f3fef3a3146102685763f8ab6bce0361000f5734610265576020366003190112610265578054604051638da5cb5b60e01b81526001600160a01b03916020908290600490829086165afa90811561025a57839161022c575b501633036101f85760043560025580f35b604051630e5fbf5b60e31b81526020600482015260076024820152662727aa2fa222ab60c91b6044820152606490fd5b0390fd5b61024d915060203d8111610253575b6102458183612e21565b810190613082565b386101e7565b503d61023b565b6040513d85823e3d90fd5b80fd5b5034610265576040366003190112610265578060046001600160a01b03602081610290612f30565b169184541660405193848092638da5cb5b60e01b82525afa91821561025a578392610325575b50803b15610321576040516323b872dd60e01b81523060048201526001600160a01b039290921660248084019190915235604483015282908290606490829084905af18015610316576103065750f35b61030f90612dd8565b6102655780f35b6040513d84823e3d90fd5b5050fd5b61033e91925060203d8111610253576102458183612e21565b90386102b6565b506040366003190112610265576001600160401b03906004356024358381116105e157610376903690600401612f5c565b6040516302571be360e01b81526004810184905260209291906001600160a01b039084816024817f000000000000000000000000000000000000000000000000000000000000000086165afa9081156105b95787916105c4575b50848282168089526005825260ff60408a205416610569575b50501680331415908161053e575b506105095783855260038352604085209581116104f5576104228161041c8854612d9e565b886130d0565b8495601f8211600114610485578186976000805160206144028339815191529596979161047a575b508260011b906000198460031b1c19161790555b610474604051928392868452339684019161310a565b0390a380f35b90508301353861044a565b808652838620601f19831697875b8981106104de57508360008051602061440283398151915296979899106104c4575b5050600182811b01905561045e565b840135600019600385901b60f8161c1916905538806104b5565b909186600181928589013581550193019101610493565b634e487b7160e01b85526041600452602485fd5b604051630e5fbf5b60e31b815260206004820152600c60248201526b1393d517d054141493d5915160a21b6044820152606490fd5b90508552600483526040852084865283526040852033600052835260ff6040600020541615386103f7565b60249250604051928380926331a9108f60e11b82528a60048301525afa9081156105b957879161059c575b5084386103e9565b6105b39150853d8711610253576102458183612e21565b38610594565b6040513d89823e3d90fd5b6105db9150853d8711610253576102458183612e21565b386103d0565b8280fd5b50346102655760203660031901126102655760209060ff906040906001600160a01b03610610612f30565b168152600584522054166040519015158152f35b5034610265578060031936011261026557805460405163e939567960e01b815246600482015291908190839060249082906001600160a01b03165afa9182156107df5781926107bb575b5081516001600160401b0381116107a75760019061068c8254612d9e565b601f811161074e575b50602080601f83116001146106d157508394829394926106c6575b5050600019600383901b1c191690821b17905580f35b0151905038806106b0565b838552601f198316957fb10e2d527612073b26eecdfd717e6a320cf44b4afac2b0732d9fcbe2b7fa0cf6929186905b888210610737575050838596971061071e575b505050811b01905580f35b015160001960f88460031b161c19169055388080610713565b808785968294968601518155019501930190610700565b61079790836000527fb10e2d527612073b26eecdfd717e6a320cf44b4afac2b0732d9fcbe2b7fa0cf6601f840160051c8101916020851061079d575b601f0160051c01906130b9565b38610695565b909150819061078a565b634e487b7160e01b82526041600452602482fd5b6107d89192503d8084833e6107d08183612e21565b810190613298565b903861066e565b50604051903d90823e3d90fd5b506020806003193601126109585760043590600254341061094657604051828282015281815261081b81612e06565b3384526003825260408420908051906001600160401b03821161093257819061084e826108488654612d9e565b866130d0565b8490601f83116001146108cf5787926108c4575b50508160011b916000199060031b1c19161790555b60405191690728080b90012040089160b51b82840152602a830152602a825261089f82612deb565b6000805160206144028339815191526040518281528061047433953395830190612f0b565b015190503880610862565b8488528588209250601f198416885b8782821061091c575050908460019594939210610903575b505050811b019055610877565b015160001960f88460031b161c191690553880806108f6565b60018596829396860151815501950193016108de565b634e487b7160e01b86526041600452602486fd5b60405163f8a1cfbb60e01b8152600490fd5b5080fd5b50346102655761096b36612fc8565b93909260019291908215610ce75760f8928135841c9061098961314d565b9482870192838811610cd357828411610ccf57906109af8895949392369087870161302d565b6109b8886131a9565b526109c2876131a9565b506109cc876131a9565b51975b610c24575b50505050508080956109e5846131a9565b5196875160208099012060405189810191858352604082015260408152610a0b81612deb565b519020947f00000000000000000000000000000000000000000000000000000000000000006001600160a01b031691805b610b79575050508215610b4257806004116109585785356001600160e01b0319169560249283831115610af4578284116102655750604483610a93610ae29694610ac694610af09a9997369260231901910161302d565b945b6040519586918b8d84015283830152610ab78c82519283918786019101612ee8565b81010390810185520183612e21565b6040519687968752860152608060408601526080850190612f0b565b908382036060850152612f0b565b0390f35b915050604051908782018281106001600160401b03821117610b2d57610af0969593610ae29593610ac693604493604052815294610a95565b83634e487b7160e01b60005260416004526000fd5b6040516306e0450760e31b815260048101889052600e60248201526d1393d517d49151d254d51154915160921b6044820152606490fd5b6000190195610b8887836131c6565b518a8151910120604051908b8201928352604082015260408152610bab81612deb565b51902095604051631ef3fca760e31b81528760048201528a81602481875afa908115610c19578691610bec575b50610be4575b80610a3c565b869550610bde565b610c0c91508b3d8d11610c12575b610c048183612e21565b8101906130a1565b38610bd8565b503d610bfa565b6040513d88823e3d90fd5b909192939660ff60f81b610c3985858861312b565b351615610cc957610c5e610c58610c4f8661412f565b80968689613191565b906131da565b821c840190818511610cb357610c84610c7d83610ca89497878a613191565b369161302d565b610c8d896131b6565b52610c97886131b6565b50610ca1886131b6565b5190613206565b9693929190846109cf565b634e487b7160e01b600052601160045260246000fd5b966109d4565b8580fd5b634e487b7160e01b86526011600452602486fd5b634e487b7160e01b82526032600452602482fd5b506060366003190112610265576001600160401b03906004356024358381116105e157610d2c903690600401612f5c565b604435858111610f6957610d44903690600401612f5c565b6040516302571be360e01b81526004810186905290946020949293909290916001600160a01b039086816024817f000000000000000000000000000000000000000000000000000000000000000086165afa908115610f41578991610f4c575b5086828216808b526005825260ff60408c205416610ef1575b505016803314159081610ec6575b5061050957610ddb91369161302d565b83815191012060405190848201928352604082015260408152610dfd81612deb565b5190209283855260038352604085209581116104f557610e218161041c8854612d9e565b8495601f8211600114610e71578186976000805160206144028339815191529596979161047a57508260011b906000198460031b1c1916179055610474604051928392868452339684019161310a565b808652838620601f19831697875b898110610eaf57508360008051602061440283398151915296979899106104c4575050600182811b01905561045e565b909186600181928589013581550193019101610e7f565b90508752600485526040872083885285526040872033600052855260ff604060002054161538610dcb565b60249250604051928380926331a9108f60e11b82528960048301525afa908115610f41578991610f24575b508638610dbd565b610f3b9150873d8911610253576102458183612e21565b38610f1c565b6040513d8b823e3d90fd5b610f639150873d8911610253576102458183612e21565b38610da4565b8480fd5b503461026557610af0610f8b610f8236612fc8565b92919091613397565b604051918291602083526020830190612f0b565b50346102655760208060031936011261095857610fba612f30565b8254604051638da5cb5b60e01b8082529391926001600160a01b0380851693929091908381600481885afa801561110057839189916110e3575b501633036101f857803b156110af578116946040519081528281600481895afa9081156105b9578791611092575b50163303611061575082907f68e84423772dadc3e4047f8b5bd221ddb02dc67796e7852533fd976947d86c518580a36001600160a01b03191617815580f35b60649060405190630e5fbf5b60e31b8252600482015260096024820152682120a22fa7aba722a960b91b6044820152fd5b6110a99150833d8511610253576102458183612e21565b38611022565b6040516301cfc2ef60e61b815260048101849052600b60248201526a4241445f4741544557415960a81b6044820152606490fd5b6110fa9150853d8711610253576102458183612e21565b38610ff4565b6040513d8a823e3d90fd5b503461026557604036600319011261026557600435611128612f46565b6040516302571be360e01b81526004810183905260209390916001600160a01b039085846024817f000000000000000000000000000000000000000000000000000000000000000086165afa93841561025a57839461123c575b50858285168085526005825260ff6040862054166111e5575b505081169216928284149384156111b9575b85856040519015158152f35b604093945082526004855282822090825284522090600052815260ff60406000205416388080806111ad565b6024929550604051928380926331a9108f60e11b82528960048301525afa90811561025a57908291849161121f575b50939050853861119b565b6112369150873d8911610253576102458183612e21565b38611214565b611254919450863d8811610253576102458183612e21565b9238611182565b50346102655761126a36612fc8565b93919060209480861161148b576040810361145c5761128f90601f19018287016143b3565b9060018060ff1b0382169160ff1c601b81018091116114485760ff16925b7f7fffffffffffffffffffffffffffffff5d576e7357a4501ddfe92f46681b20a0831161141057845460405163e939567960e01b8152600481018390526001600160a01b039790918790839060249082908c165afa9182156105b957898461137f603a8b9996849b9860809a9760ff978d936113f3575b50604051958693611364898601997f19457468657265756d205369676e6564204d6573736167653a0a0000000000008b5282519283918989019101612ee8565b84019185830137018b8382015203601a810184520182612e21565b519020936040519485521686840152356040830152606082015282805260015afa156113e757511680156113b557604051908152f35b60405163151a7bff60e11b81526004810183905260096024820152682d22a927afa0a2222960b91b6044820152606490fd5b604051903d90823e3d90fd5b6114099193508d3d8091833e6107d08183612e21565b9138611324565b60405163151a7bff60e11b815260048101889052600f60248201526e494e56414c49445f535f56414c554560881b6044820152606490fd5b634e487b7160e01b85526011600452602485fd5b906041820361148f578160401161148b576114828682013592603f1901604083016131da565b60f81c926112ad565b8380fd5b606082036114bd578160401161148b5760ff6114b68783013593603f1901604084016143b3565b16926112ad565b60405163151a7bff60e11b815260048101879052600e60248201526d0848288bea6928ebe988a9c8ea8960931b6044820152606490fd5b506040366003190112610265576040516302571be360e01b8152600480359082018190529060209060248035916001600160a01b039184908290817f000000000000000000000000000000000000000000000000000000000000000086165afa908115610c19578691611760575b50838282168088526005825260ff604089205416611710575b5050168033141590816116e5575b506105095760405181838201528281526115a281612e06565b8385526003835260408520908051906001600160401b0382116116d1576115d3826115cd8554612d9e565b856130d0565b8490601f831160011461165a579180610474949260008051602061440283398151915296948a9261164f575b50508160011b916000199060031b1c19161790555b60405190690728080b90012040089160b51b85830152602a820152602a815261163c81612deb565b6040519182918583523395830190612f0b565b0151905038806115ff565b8388528588209190601f198416895b888282106116bb57505092600192859260008051602061440283398151915298966104749896106116a2575b505050811b019055611614565b015160001960f88460031b161c19169055388080611695565b6001859682939686015181550195019301611669565b634e487b7160e01b87526041600452602487fd5b90508452600482526040842083855282526040842033600052825260ff604060002054161538611589565b60249250604051928380926331a9108f60e11b82528960048301525afa908115610c19578691611743575b50833861157b565b61175a9150843d8611610253576102458183612e21565b3861173b565b6117779150843d8611610253576102458183612e21565b38611562565b50346102655760603660031901126102655760043561179a612f46565b6044359182151592838103611817576117ea90338652600460205260408620838752602052604086209360018060a01b0316938460005260205260406000209060ff801983541691151516179055565b7fc23d87d033a4cc3a7b6b27eccbda789e76f9bcd5ce948e8a03192df3159f17686020604051338152a480f35b600080fd5b5034610265576060366003190112610265576001600160401b036004358181116105e15761184e903690600401612f98565b602492919235828111610f6957611869903690600401612f98565b919092604435908111610ccf57611884903690600401612f98565b93865b838110611892578780f35b61189d8187856143d0565b6118a6906143e0565b33895260206004815260408a206118be84888c6143d0565b358b52815260408a206001600160a01b039290836118dd868b896143d0565b6118e6906143ed565b166000528252604060002090611907919060ff801983541691151516179055565b61191283878b6143d0565b3561191e8489876143d0565b611927906143ed565b92611933858b896143d0565b61193c906143e0565b906040519133835215159416927fc23d87d033a4cc3a7b6b27eccbda789e76f9bcd5ce948e8a03192df3159f176891a46119759061412f565b611887565b50346102655760a036600319011261026557611994612f30565b9061199d612f46565b916001600160401b0360643581811161148b576119be903690600401613064565b926084359182116102655760206119e88686866119de3660048901613064565b926044359161413e565b6040519015158152f35b503461026557611a0136612fc8565b919260019380156121e25760f8908235821c611a1b61314d565b95818801918289116121de578383116121de57611a4190999192969936908a880161302d565b611a4a886131a9565b52611a54876131a9565b50611a5e876131a9565b519586905b6001600160f81b0319611a7782878a61312b565b351615611b315784939291611aae610c7d600184611aa1610c588d8385611ace9a019c8d92613191565b8b1c01018097898c613191565b611ab88c8c6131c6565b52611ac38b8b6131c6565b50610ca18b8b6131c6565b96611b28611ae060018c019b8b6131c6565b5160405180938251611afa81602095868087019101612ee8565b8201602f60f81b84820152611b19825180936021968785019101612ee8565b01036001810184520182612e21565b96909192611a63565b50919892969350966000190197611b4889856131c6565b516020815191012060405160208101918a8352604082015260408152611b6d81612deb565b51902088948a60609b5b6120bd5750506040516302571be360e01b8152600481018690529590506020866024817f00000000000000000000000000000000000000000000000000000000000000006001600160a01b03165afa958615610f4157899661209c575b506001600160a01b038616808a52600560205260408a205460ff16612046575b5089511561201f575b8854604051630bb6dffb60e41b8152602060048201526001600160a01b039091169890968a8880611c3260248201888b61310a565b03818d5afa97881561201457908b918299611ff8575b50604051903060601b602083015260001943014060348301526bffffffffffffffffffffffff199060601b16605482015280858751606883018160208b0191611c9092612ee8565b8b51908c828286016068019160200191611ca992612ee8565b830101818a60688301370183606882015203604881018252606801611cce9082612e21565b805190602001209b8c9a60405191602083016c2f2e77656c6c2d6b6e6f776e2f60981b9052828c518d81602d84019160200191611d0a92612ee8565b8101602d8101602f60f81b90528c51908d82602e83019160200191611d2e92612ee8565b0103600e81018452602e01611d439084612e21565b604051809d8194829363d4a964f160e01b8452600484016060905260648401611d6b91612f0b565b838103600319016024850152611d8091612f0b565b90604483015203915afa988915611fed578a99611efa575b50604051603c420460f01b6001600160f01b03191660208201526002815297611dc089612e06565b6040519b8c976020890152600019430160408901526060880152610100948560808901526101208801611df291612f0b565b97601f1998898982030160a08a0152611e0a91612f0b565b888882030160c0890152611e1d91612f0b565b90878783030160e0880152611e319261310a565b91858584030190850152611e449261310a565b039081018552611e549085612e21565b60405192630556f18360e41b845260a484013060048601526024850160a09052835180915260c485018160051b860160c4019460200192905b828210611ecf5786860360031901604488015286806102288a611eb08a8a612f0b565b63c55a5d5960e01b606485015283810360031901608485015290612f0b565b90919294602080611eec60019360c3198b82030186528951612f0b565b970192019201909291611e8d565b9098503d808b833e611f0c8183612e21565b6020828281010312611fe9578151906001600160401b038211611fe557808301601f838501011215611fe55781830151926001600160401b038411611fcf578360051b9260405194611f616020860187612e21565b85526020808601948284010101928083018411611fcb57602082840101945b848610611f94575050505050509738611d98565b85516001600160401b038111611fc657602091611fbb83928386890191888a010101613256565b815201950194611f80565b508f80fd5b8e80fd5b634e487b7160e01b600052604160045260246000fd5b8b80fd5b8a80fd5b6040513d8c823e3d90fd5b61200d9199503d8084833e6107d08183612e21565b9738611c48565b6040513d8d823e3d90fd5b6001600160a01b038616895260036020526040892090995061204090612e42565b98611bfd565b6024919650602090604051928380926331a9108f60e11b82528960048301525afa908115610f4157899161207d575b509438611bf4565b612096915060203d602011610253576102458183612e21565b38612075565b6120b691965060203d602011610253576102458183612e21565b9438611bd4565b600019019a9095916120cf8c886131c6565b516020815191012060405190602082019283526040820152604081526120f481612deb565b519020604051631ef3fca760e31b8152600481018290529092906020816024817f00000000000000000000000000000000000000000000000000000000000000006001600160a01b03165afa9081156121d3578c916121b4575b50156121735750508094818a5260036020528a61216d60408c20612e42565b9b611b77565b95909a828b5260038060205261218c60408d2054612d9e565b612198575b5080611b77565b909b50828b526020528a6121ae60408c20612e42565b9b612191565b6121cd915060203d602011610c1257610c048183612e21565b3861214e565b6040513d8e823e3d90fd5b8980fd5b634e487b7160e01b86526032600452602486fd5b50346102655780600319360112610265578054604051638da5cb5b60e01b8152906001600160a01b03906020908390600490829085165afa91821561025a5760209392612248575b5060405191168152f35b612260919250833d8111610253576102458183612e21565b903861223e565b503461026557604036600319011261026557612281612f30565b612289612f89565b8254604051638da5cb5b60e01b815291926001600160a01b039290916020908290600490829087165afa80156123705783918691612352575b501633036101f857803b1561231e57169081835260056020526122f481604085209060ff801983541691151516179055565b1515907f976fe5c61b46a2e3e8c0330103e8b00d2e561ff8bec93bb1ff3bfb59fd754c758380a380f35b6040516301cfc2ef60e61b815260206004820152600b60248201526a2120a22faba920a82822a960a91b6044820152606490fd5b61236a915060203d8111610253576102458183612e21565b386122c2565b6040513d87823e3d90fd5b506060366003190112610265576001600160401b03906024600435813584811161148b576123ad903690600401612f98565b92604435868111610ccf576123c6903690600401612f5c565b6040516302571be360e01b8152600481018690529495602095929491939287906001600160a01b0390888187817f000000000000000000000000000000000000000000000000000000000000000086165afa90811561201457908b9392918491612643575b50868a83831680875260ff60406005988985522054166125f1575b50505016908133141591826125c4575b50506105095781805b61253f5750505050848652600384526040862096821161252d57506124888161041c8854612d9e565b8495601f82116001146124d8578186976000805160206144028339815191529596979161047a57508260011b906000198460031b1c1916179055610474604051928392868452339684019161310a565b808652838620601f19831697875b89811061251657508360008051602061440283398151915296979899106104c4575050600182811b01905561045e565b9091866001819285890135815501930191016124e6565b634e487b7160e01b8652604160045285fd5b6000190197828910156125b15788821b840135601e1985360301811215611fe95784018035908c8211611fe5578901908036038213611fe5578a929161258691369161302d565b898151910120604051908a82019283526040820152604081526125a881612deb565b5190209861245f565b634e487b7160e01b8a526032600452848afd5b9091508a526004885260408a20908a5287526040892033600052875260ff60406000205416153880612456565b6040516331a9108f60e11b81526004810187905293509091839182905afa9081156121d3578c91612626575b50868a38612446565b61263d91508a3d8c11610253576102458183612e21565b3861261d565b61265a91508a3d8c11610253576102458183612e21565b3861242b565b50346102655760403660031901126102655761267a612d87565b612682612f89565b8254604051638da5cb5b60e01b81529192916001600160a01b03916020908290600490829086165afa908115612370578591612774575b501633036101f8576001600160e01b03191690632b45eb2b60e01b82148015612764575b61272c57818352600660205261270281604085209060ff801983541691151516179055565b1515907fe9314059add66b39b1853e125d5a356101752cede174a4df4d475ae5d060c9018380a380f35b6040516301cfc2ef60e61b815260206004820152600f60248201526e4c4f434b45445f43414c4c4241434b60881b6044820152606490fd5b50639061b92360e01b82146126dd565b61278c915060203d8111610253576102458183612e21565b386126b9565b5034610265576020806003193601126109585760043591828152600382526127bc60408220612e42565b9283511561289b575b50818351149081612830575b506127eb575b610af0604051928284938452830190612f0b565b9061282a602a6040518093690728080b90012040089160b51b8683015261281a81518092888686019101612ee8565b810103600a810184520182612e21565b906127d7565b80546040516338d630a760e21b815260048101859052919250839082906001600160a01b03168180612865602482018a612f0b565b03915afa9182156113e7579161287e575b5015386127d1565b6128959150823d8411610c1257610c048183612e21565b38612876565b6040516302571be360e01b8152600481018290529193506001600160a01b03919083826024817f000000000000000000000000000000000000000000000000000000000000000087165afa918215612370578592612988575b5083838316918287526005825260ff60408820541661292b575b5050501682526003815261292460408320612e42565b91386127c5565b909192506024604051809481936331a9108f60e11b835260048301525afa90811561297d578491612960575b5038838161290e565b6129779150833d8511610253576102458183612e21565b38612957565b6040513d86823e3d90fd5b6129a0919250843d8611610253576102458183612e21565b90386128f4565b50602080600319360112610958576001600160401b039060043582811161148b576129d6903690600401612f5c565b9260025434106109465733855260038352604085209084116104f557612a0684612a008354612d9e565b836130d0565b8385601f8211600114612a6457916000805160206144028339815191529391610474938891612a59575b508660011b906000198860031b1c19161790555b6040519182918583523396339684019161310a565b905082013538612a30565b828752848720915085601f198116885b87828210612ac557505091600080516020614402833981519152959391610474959310612aab575b5050600186811b019055612a44565b830135600019600389901b60f8161c191690553880612a9c565b8785013586556001909501949384019389935001612a74565b503461026557606036600319011261026557612af8612f30565b6044356001600160a01b03818116939184900361181757604092168152600460205281812060243582526020522090600052602052602060ff604060002054166040519015158152f35b503461026557604036600319011261026557806001600160a01b036004602082612b6a612f30565b169284541660405192838092638da5cb5b60e01b82525afa90811561025a578391612bed575b50813b1561032157604051632142170760e11b81523060048201526001600160a01b039190911660248083019190915235604482015291908290606490829084905af1801561031657612be1575080f35b612bea90612dd8565b80f35b612c05915060203d8111610253576102458183612e21565b38612b90565b503461026557602036600319011261026557610f8b6040610af0926004358152600360205220612e42565b50346102655780600319360112610265578054604051638da5cb5b60e01b815282916001600160a01b0391906020908290600490829086165afa90811561025a578392839283928391612ca5575b50479183918315612c9b575b1690f1156113e75780f35b6108fc9250612c90565b612cbd915060203d8111610253576102458183612e21565b38612c84565b50346102655780600319360112610265576040517f00000000000000000000000000000000000000000000000000000000000000006001600160a01b03168152602090f35b50346102655780600319360112610265576020600254604051908152f35b5034610265578060031936011261026557546040516001600160a01b039091168152602090f35b9050346109585760203660031901126109585760ff604060209363ffffffff60e01b612d77612d87565b1681526006855220541615158152f35b600435906001600160e01b03198216820361181757565b90600182811c92168015612dce575b6020831014612db857565b634e487b7160e01b600052602260045260246000fd5b91607f1691612dad565b6001600160401b038111611fcf57604052565b606081019081106001600160401b03821117611fcf57604052565b604081019081106001600160401b03821117611fcf57604052565b90601f801991011681019081106001600160401b03821117611fcf57604052565b9060405191826000825492612e5684612d9e565b908184526001948581169081600014612ec55750600114612e82575b5050612e8092500383612e21565b565b9093915060005260209081600020936000915b818310612ead575050612e8093508201013880612e72565b85548884018501529485019487945091830191612e95565b915050612e8094506020925060ff191682840152151560051b8201013880612e72565b60005b838110612efb5750506000910152565b8181015183820152602001612eeb565b90602091612f2481518092818552858086019101612ee8565b601f01601f1916010190565b600435906001600160a01b038216820361181757565b602435906001600160a01b038216820361181757565b9181601f84011215611817578235916001600160401b038311611817576020838186019501011161181757565b60243590811515820361181757565b9181601f84011215611817578235916001600160401b038311611817576020808501948460051b01011161181757565b6040600319820112611817576001600160401b03916004358381116118175782612ff491600401612f5c565b939093926024359182116118175761300e91600401612f5c565b9091565b6001600160401b038111611fcf57601f01601f191660200190565b92919261303982613012565b916130476040519384612e21565b829481845281830111611817578281602093846000960137010152565b9080601f830112156118175781602061307f9335910161302d565b90565b9081602091031261181757516001600160a01b03811681036118175790565b90816020910312611817575180151581036118175790565b8181106130c4575050565b600081556001016130b9565b9190601f81116130df57505050565b612e80926000526020600020906020601f840160051c8301931061079d57601f0160051c01906130b9565b908060209392818452848401376000828201840152601f01601f1916010190565b90821015613137570190565b634e487b7160e01b600052603260045260246000fd5b6040519061056082018281106001600160401b03821117611fcf57604052602a82528160005b6105408110613180575050565b806060602080938501015201613173565b90939293848311611817578411611817578101920390565b8051156131375760200190565b8051600110156131375760400190565b80518210156131375760209160051b010190565b6001600160f81b031990358181169392600181106131f757505050565b60010360031b82901b16169150565b6021612e80919392936040519481613228879351809260208087019101612ee8565b8201601760f91b60208201526132478251809360208785019101612ee8565b01036001810185520183612e21565b81601f8201121561181757805161326c81613012565b9261327a6040519485612e21565b818452602082840101116118175761307f9160208085019101612ee8565b906020828203126118175781516001600160401b0381116118175761307f9201613256565b92906132d69061307f959360408652604086019161310a565b92602081850391015261310a565b90916132fb61307f93604084526040840190612f0b565b916020818403910152612f0b565b9060009160019081549161331c83612d9e565b92818116908115613384575060011461333457505050565b8091929394506000527fb10e2d527612073b26eecdfd717e6a320cf44b4afac2b0732d9fcbe2b7fa0cf6906000915b848310613371575050500190565b8181602092548587015201920191613363565b60ff191683525050811515909102019150565b91939290806004116118175763ffffffff60e01b833516600052600660205260ff60406000205416156140f957818501610100868203126118175760608601356001600160401b03811161181757816133f1918801613064565b9260808701356001600160401b0381116118175782613411918901613064565b916001600160401b0360a089013511611817576134348160a08a01358a01613064565b506001600160401b0360c089013511611817576134578160c08a01358a01613064565b506001600160401b0360e0890135116118175761347a9060e08901358901613064565b6040516302571be360e01b815288356004820152979091906020896024817f00000000000000000000000000000000000000000000000000000000000000006001600160a01b03165afa9889156138f1576000996140d8575b506001600160a01b038916600090815260056020526040902054899060ff16614076575b50602081013560078101908110610cb3574311614040576040513060601b602082015260208201354060348201526bffffffffffffffffffffffff198a60601b1660548201526135906068828951613556818c60208686019101612ee8565b88519061356b82858386010160208d01612ee8565b8201018751906135818285830160208c01612ee8565b01036048810184520182612e21565b6020815191012060408201350361400b576080600319888781010301126118175760048701356001600160a01b0381169003611817576001600160401b03602488013511611817576135ed858801600460248a01358a0101613064565b946001600160401b0360448901351161181757613615818901600460448b01358b0101613064565b996001600160401b0360648a013511611817578761363e838b01600460648d01358d0101613064565b9b6040815110600014613fb757505060048901356001600160a01b039081169116908114159081613f78575b50610509575b87356001600160e01b031916632b45eb2b60e01b036139405750505050906136de9160018060a01b03600054166000885160208a0120604051906020820152602081526136bc81612e06565b604051809681926308ead44760e21b8352604060048401526044830190612f0b565b8360248301520381845afa9081156138f157602494600092613921575b50604051636789a9a960e11b81526004888101356001600160a01b0316908201529460009186919082905afa9384156138f15761386a9560209561384f936001936000926138fd575b506082613826916040519788957f52657175657374696e67205369676e617475726520546f2055706461746520458c880152692729902932b1b7b9320560b11b604088015267527b934b3b4b71d160bd1b604a8801526137ad815180928e60538b019101612ee8565b86016c52932b1b7b932102a3cb8329d160951b60538201526137d8825180938e606185019101612ee8565b016d0148af0e8e4c2c8c2e8c2744060f60931b6061820152613803825180938d606f85019101612ee8565b01720529b4b3b732b210213c9d1032b4b8189a9a9d60691b606f82015201613309565b601d60f91b815261383f825180938a8785019101612ee8565b0103601e19810184520182612e21565b60405163a8e547fb60e01b81529384928392600484016132e4565b0381305afa9081156138f1576000916138d2575b506001600160a01b03908116600490920135160361389857565b6040516306e0450760e31b815260206004820152601160248201527010905117d4d251d3915117d49150d3d491607a1b6044820152606490fd5b6138eb915060203d602011610253576102458183612e21565b3861387e565b6040513d6000823e3d90fd5b6138269192506139196082913d806000833e6107d08183612e21565b929150613744565b6000919250613939903d8084833e6107d08183612e21565b91906136fb565b9798929795969295929350909183356001600160e01b03191663308045e960e21b03613f40575050508251156131375760208301516001600160f81b031916158015613f0e575b613ed15760006139ac956040518097819263cc49dd9560e01b835287600484016132e4565b0381305afa9384156138f157600092600095600097600091613e40575b50906139f99160018060a01b03600054166000885160208a0120604051906020820152602081526136bc81612e06565b8360248301520381845afa9081156138f157602494600092613e21575b50604051636789a9a960e11b81526004888101356001600160a01b0316908201529460009186919082905afa9384156138f157613b3c9560209561384f93600193600092613dfd575b50607d613826916040519788957f52657175657374696e67205369676e617475726520546f20496e7374616c6c208c8801526c3220b8381029b2b93b34b1b28560991b604088015267527b934b3b4b71d160bd1b604d880152613acb815180928e60568b019101612ee8565b860164520b8381d160d51b6056820152613aee825180938e605c85019101612ee8565b016d0148af0e8e4c2c8c2e8c2744060f60931b605c820152613b19825180938d606a85019101612ee8565b01720529b4b3b732b210213c9d1032b4b8189a9a9d60691b606a82015201613309565b0381305afa9081156138f157600091613dde575b506001600160a01b039081166004909201351603613da357604051630178b8bf60e01b815260048101939093526020836024817f00000000000000000000000000000000000000000000000000000000000000006001600160a01b03165afa9283156138f157600093613d82575b506040516301ffc9a760e01b808252639061b92360e01b600483018190526001600160a01b03861695909390929091906020816024818a5afa9081156138f157600091613d63575b5015613c585750505091613c2d9391600093604051958694859384938452600484016132e4565b03915afa9081156138f157600091613c43575090565b61307f91503d806000833e6107d08183612e21565b60249192959450602093506040519485938492835263ffffffff60e01b1660048301525afa9081156138f157600091613d44575b5015613d0f57816000929160208493519201905afa903d15613d08573d613cb281613012565b90613cc06040519283612e21565b81523d6000602083013e5b9115613cd357565b6040516306e0450760e31b815260206004820152600c60248201526b2120a22fa922a9a7a62b22a960a11b6044820152606490fd5b6060613ccb565b6040516306e0450760e31b815260206004820152600c60248201526b2120a22fa32aa721aa24a7a760a11b6044820152606490fd5b613d5d915060203d602011610c1257610c048183612e21565b38613c8c565b613d7c915060203d602011610c1257610c048183612e21565b38613c06565b613d9c91935060203d602011610253576102458183612e21565b9138613bbe565b6040516306e0450760e31b81526020600482015260126024820152714241445f444150505f5349474e415455524560701b6044820152606490fd5b613df7915060203d602011610253576102458183612e21565b38613b50565b613826919250613e19607d913d806000833e6107d08183612e21565b929150613a5f565b6000919250613e39903d8084833e6107d08183612e21565b9190613a16565b975050925093503d93846000873e613e588587612e21565b6080868681010312611817578551956001600160e01b0319871687036118175760208101519360408201516001600160401b03811161181757613ea090888401908401613256565b966060830151926001600160401b038411611817576139f993613ec69282019101613256565b9794969790916139c9565b6040516306e0450760e31b815260206004820152601460248201527310905117d4915112549150d517d49154555154d560621b6044820152606490fd5b50825180600019810111610cb357835160001982011015613137578301601f01516001600160f81b0319161515613987565b6000805460405162c29a2d60e61b815299509097508896506001600160a01b0316945085938493613c2d9390929091600486016132bd565b9050600052600460205260406000208235600052602052604060002060018060a01b0360048a01351660005260205260ff60406000205416153861366a565b613fd29285359060048d01356001600160a01b03169061413e565b61367057604051630e5fbf5b60e31b815260206004820152600c60248201526b10905117d054141493d5905360a21b6044820152606490fd5b6040516306e0450760e31b815260206004820152600c60248201526b4241445f434845434b53554d60a01b6044820152606490fd5b6040516306e0450760e31b815260206004820152600d60248201526c109313d0d2d7d512535153d555609a1b6044820152606490fd5b6040516331a9108f60e11b815282356004820152919950602090829060249082906001600160a01b03165afa9081156138f1576000916140b9575b5097386134f7565b6140d2915060203d602011610253576102458183612e21565b386140b1565b6140f291995060203d602011610253576102458183612e21565b97386134d3565b6000805460405162c29a2d60e61b81529596919486946001600160a01b039092169385938493613c2d93909290600486016132bd565b6000198114610cb35760010190565b6000805460408051636789a9a960e11b8082526001600160a01b039687166004830152928616989197939695929490939087856024818d5afa9485156143a957908891829661438a575b5060248596978b5196879384928352169c8d60048301525afa928315614380578793614364575b508751809360209687948584017f52657175657374696e67205369676e617475726520546f20417070726f76652090527222a729902932b1b7b932399029b4b3b732b90560691b8c85015267527b934b3b4b71d160bd1b60538501528051908187605c870192019161422092612ee8565b8301605c81017f0a417070726f766564205369676e65723a206569703135353a00000000000000905260750161425590613309565b90601d60f91b9182815281519182886001840192019161427492612ee8565b01740520b8383937bb32b210213c9d1032b4b8189a9a9d60591b600182015260160161429f90613309565b9081528151918286600184019201916142b792612ee8565b0103601e19810184526001016142cd9084612e21565b875163a8e547fb60e01b815292839182916142ec9190600484016132e4565b0381305afa90811561435a57859161433d575b501691858314958615614316575b50505050505090565b60ff965084526004825284842090845281528383209183525220541638808080808061430d565b6143549150833d8511610253576102458183612e21565b386142ff565b86513d87823e3d90fd5b6143799193503d8089833e6107d08183612e21565b91386141af565b88513d89823e3d90fd5b8596506143a26024913d8086833e6107d08183612e21565b9650614188565b89513d8a823e3d90fd5b3590602081106143c1575090565b6000199060200360031b1b1690565b91908110156131375760051b0190565b3580151581036118175790565b356001600160a01b0381168103611817579056fedbe4e2174ccc483f322f3a0dd9c15970dab6fc1673ea519ba3f22064b7b0332ca2646970667358221220c7d42f94c686e0b08950d68a07ff0a6df6e3da00680daa8a1776ba589af267a364736f6c634300081300330000000000000000000000009d79ff2ec00b812e32d9768d88782101cb08d875

Deployed Bytecode

0x6080806040526004361015610044575b50361561001b57600080fd5b34337f9a064d674ddc42ac41b38566457161f1ded37e65a59162da003dd25bcb057b60600080a3005b600090813560e01c90816301ffc9a714612d4d57508063116191b614612d2657806315c3867914612d085780631d2e2cc414612cc35780633ccfd60b14612c36578063417ab3eb14612c0b5780635058c46014612b4257806353b5946814612ade5780636166b779146129a757806363a786b91461279257806376a810f2146126605780637ceb95f91461237b5780638384976f146122675780638da5cb5b146121f65780639061b923146119f257806393c52fbf1461197a5780639503d22f1461181c578063a4b91a011461177d578063a6704e76146114f4578063a8e547fb1461125b578063b984b2cd1461110b578063c0346b2014610f9f578063c55a5d5914610f6d578063c6a84da314610cfb578063cc49dd951461095c578063d5d7d981146107ec578063d8dd805c14610624578063e0aa2797146105e5578063e3b9533a14610345578063f3fef3a3146102685763f8ab6bce0361000f5734610265576020366003190112610265578054604051638da5cb5b60e01b81526001600160a01b03916020908290600490829086165afa90811561025a57839161022c575b501633036101f85760043560025580f35b604051630e5fbf5b60e31b81526020600482015260076024820152662727aa2fa222ab60c91b6044820152606490fd5b0390fd5b61024d915060203d8111610253575b6102458183612e21565b810190613082565b386101e7565b503d61023b565b6040513d85823e3d90fd5b80fd5b5034610265576040366003190112610265578060046001600160a01b03602081610290612f30565b169184541660405193848092638da5cb5b60e01b82525afa91821561025a578392610325575b50803b15610321576040516323b872dd60e01b81523060048201526001600160a01b039290921660248084019190915235604483015282908290606490829084905af18015610316576103065750f35b61030f90612dd8565b6102655780f35b6040513d84823e3d90fd5b5050fd5b61033e91925060203d8111610253576102458183612e21565b90386102b6565b506040366003190112610265576001600160401b03906004356024358381116105e157610376903690600401612f5c565b6040516302571be360e01b81526004810184905260209291906001600160a01b039084816024817f00000000000000000000000000000000000c2e074ec69a0dfb2997ba6c7d2e1e86165afa9081156105b95787916105c4575b50848282168089526005825260ff60408a205416610569575b50501680331415908161053e575b506105095783855260038352604085209581116104f5576104228161041c8854612d9e565b886130d0565b8495601f8211600114610485578186976000805160206144028339815191529596979161047a575b508260011b906000198460031b1c19161790555b610474604051928392868452339684019161310a565b0390a380f35b90508301353861044a565b808652838620601f19831697875b8981106104de57508360008051602061440283398151915296979899106104c4575b5050600182811b01905561045e565b840135600019600385901b60f8161c1916905538806104b5565b909186600181928589013581550193019101610493565b634e487b7160e01b85526041600452602485fd5b604051630e5fbf5b60e31b815260206004820152600c60248201526b1393d517d054141493d5915160a21b6044820152606490fd5b90508552600483526040852084865283526040852033600052835260ff6040600020541615386103f7565b60249250604051928380926331a9108f60e11b82528a60048301525afa9081156105b957879161059c575b5084386103e9565b6105b39150853d8711610253576102458183612e21565b38610594565b6040513d89823e3d90fd5b6105db9150853d8711610253576102458183612e21565b386103d0565b8280fd5b50346102655760203660031901126102655760209060ff906040906001600160a01b03610610612f30565b168152600584522054166040519015158152f35b5034610265578060031936011261026557805460405163e939567960e01b815246600482015291908190839060249082906001600160a01b03165afa9182156107df5781926107bb575b5081516001600160401b0381116107a75760019061068c8254612d9e565b601f811161074e575b50602080601f83116001146106d157508394829394926106c6575b5050600019600383901b1c191690821b17905580f35b0151905038806106b0565b838552601f198316957fb10e2d527612073b26eecdfd717e6a320cf44b4afac2b0732d9fcbe2b7fa0cf6929186905b888210610737575050838596971061071e575b505050811b01905580f35b015160001960f88460031b161c19169055388080610713565b808785968294968601518155019501930190610700565b61079790836000527fb10e2d527612073b26eecdfd717e6a320cf44b4afac2b0732d9fcbe2b7fa0cf6601f840160051c8101916020851061079d575b601f0160051c01906130b9565b38610695565b909150819061078a565b634e487b7160e01b82526041600452602482fd5b6107d89192503d8084833e6107d08183612e21565b810190613298565b903861066e565b50604051903d90823e3d90fd5b506020806003193601126109585760043590600254341061094657604051828282015281815261081b81612e06565b3384526003825260408420908051906001600160401b03821161093257819061084e826108488654612d9e565b866130d0565b8490601f83116001146108cf5787926108c4575b50508160011b916000199060031b1c19161790555b60405191690728080b90012040089160b51b82840152602a830152602a825261089f82612deb565b6000805160206144028339815191526040518281528061047433953395830190612f0b565b015190503880610862565b8488528588209250601f198416885b8782821061091c575050908460019594939210610903575b505050811b019055610877565b015160001960f88460031b161c191690553880806108f6565b60018596829396860151815501950193016108de565b634e487b7160e01b86526041600452602486fd5b60405163f8a1cfbb60e01b8152600490fd5b5080fd5b50346102655761096b36612fc8565b93909260019291908215610ce75760f8928135841c9061098961314d565b9482870192838811610cd357828411610ccf57906109af8895949392369087870161302d565b6109b8886131a9565b526109c2876131a9565b506109cc876131a9565b51975b610c24575b50505050508080956109e5846131a9565b5196875160208099012060405189810191858352604082015260408152610a0b81612deb565b519020947f00000000000000000000000000000000000c2e074ec69a0dfb2997ba6c7d2e1e6001600160a01b031691805b610b79575050508215610b4257806004116109585785356001600160e01b0319169560249283831115610af4578284116102655750604483610a93610ae29694610ac694610af09a9997369260231901910161302d565b945b6040519586918b8d84015283830152610ab78c82519283918786019101612ee8565b81010390810185520183612e21565b6040519687968752860152608060408601526080850190612f0b565b908382036060850152612f0b565b0390f35b915050604051908782018281106001600160401b03821117610b2d57610af0969593610ae29593610ac693604493604052815294610a95565b83634e487b7160e01b60005260416004526000fd5b6040516306e0450760e31b815260048101889052600e60248201526d1393d517d49151d254d51154915160921b6044820152606490fd5b6000190195610b8887836131c6565b518a8151910120604051908b8201928352604082015260408152610bab81612deb565b51902095604051631ef3fca760e31b81528760048201528a81602481875afa908115610c19578691610bec575b50610be4575b80610a3c565b869550610bde565b610c0c91508b3d8d11610c12575b610c048183612e21565b8101906130a1565b38610bd8565b503d610bfa565b6040513d88823e3d90fd5b909192939660ff60f81b610c3985858861312b565b351615610cc957610c5e610c58610c4f8661412f565b80968689613191565b906131da565b821c840190818511610cb357610c84610c7d83610ca89497878a613191565b369161302d565b610c8d896131b6565b52610c97886131b6565b50610ca1886131b6565b5190613206565b9693929190846109cf565b634e487b7160e01b600052601160045260246000fd5b966109d4565b8580fd5b634e487b7160e01b86526011600452602486fd5b634e487b7160e01b82526032600452602482fd5b506060366003190112610265576001600160401b03906004356024358381116105e157610d2c903690600401612f5c565b604435858111610f6957610d44903690600401612f5c565b6040516302571be360e01b81526004810186905290946020949293909290916001600160a01b039086816024817f00000000000000000000000000000000000c2e074ec69a0dfb2997ba6c7d2e1e86165afa908115610f41578991610f4c575b5086828216808b526005825260ff60408c205416610ef1575b505016803314159081610ec6575b5061050957610ddb91369161302d565b83815191012060405190848201928352604082015260408152610dfd81612deb565b5190209283855260038352604085209581116104f557610e218161041c8854612d9e565b8495601f8211600114610e71578186976000805160206144028339815191529596979161047a57508260011b906000198460031b1c1916179055610474604051928392868452339684019161310a565b808652838620601f19831697875b898110610eaf57508360008051602061440283398151915296979899106104c4575050600182811b01905561045e565b909186600181928589013581550193019101610e7f565b90508752600485526040872083885285526040872033600052855260ff604060002054161538610dcb565b60249250604051928380926331a9108f60e11b82528960048301525afa908115610f41578991610f24575b508638610dbd565b610f3b9150873d8911610253576102458183612e21565b38610f1c565b6040513d8b823e3d90fd5b610f639150873d8911610253576102458183612e21565b38610da4565b8480fd5b503461026557610af0610f8b610f8236612fc8565b92919091613397565b604051918291602083526020830190612f0b565b50346102655760208060031936011261095857610fba612f30565b8254604051638da5cb5b60e01b8082529391926001600160a01b0380851693929091908381600481885afa801561110057839189916110e3575b501633036101f857803b156110af578116946040519081528281600481895afa9081156105b9578791611092575b50163303611061575082907f68e84423772dadc3e4047f8b5bd221ddb02dc67796e7852533fd976947d86c518580a36001600160a01b03191617815580f35b60649060405190630e5fbf5b60e31b8252600482015260096024820152682120a22fa7aba722a960b91b6044820152fd5b6110a99150833d8511610253576102458183612e21565b38611022565b6040516301cfc2ef60e61b815260048101849052600b60248201526a4241445f4741544557415960a81b6044820152606490fd5b6110fa9150853d8711610253576102458183612e21565b38610ff4565b6040513d8a823e3d90fd5b503461026557604036600319011261026557600435611128612f46565b6040516302571be360e01b81526004810183905260209390916001600160a01b039085846024817f00000000000000000000000000000000000c2e074ec69a0dfb2997ba6c7d2e1e86165afa93841561025a57839461123c575b50858285168085526005825260ff6040862054166111e5575b505081169216928284149384156111b9575b85856040519015158152f35b604093945082526004855282822090825284522090600052815260ff60406000205416388080806111ad565b6024929550604051928380926331a9108f60e11b82528960048301525afa90811561025a57908291849161121f575b50939050853861119b565b6112369150873d8911610253576102458183612e21565b38611214565b611254919450863d8811610253576102458183612e21565b9238611182565b50346102655761126a36612fc8565b93919060209480861161148b576040810361145c5761128f90601f19018287016143b3565b9060018060ff1b0382169160ff1c601b81018091116114485760ff16925b7f7fffffffffffffffffffffffffffffff5d576e7357a4501ddfe92f46681b20a0831161141057845460405163e939567960e01b8152600481018390526001600160a01b039790918790839060249082908c165afa9182156105b957898461137f603a8b9996849b9860809a9760ff978d936113f3575b50604051958693611364898601997f19457468657265756d205369676e6564204d6573736167653a0a0000000000008b5282519283918989019101612ee8565b84019185830137018b8382015203601a810184520182612e21565b519020936040519485521686840152356040830152606082015282805260015afa156113e757511680156113b557604051908152f35b60405163151a7bff60e11b81526004810183905260096024820152682d22a927afa0a2222960b91b6044820152606490fd5b604051903d90823e3d90fd5b6114099193508d3d8091833e6107d08183612e21565b9138611324565b60405163151a7bff60e11b815260048101889052600f60248201526e494e56414c49445f535f56414c554560881b6044820152606490fd5b634e487b7160e01b85526011600452602485fd5b906041820361148f578160401161148b576114828682013592603f1901604083016131da565b60f81c926112ad565b8380fd5b606082036114bd578160401161148b5760ff6114b68783013593603f1901604084016143b3565b16926112ad565b60405163151a7bff60e11b815260048101879052600e60248201526d0848288bea6928ebe988a9c8ea8960931b6044820152606490fd5b506040366003190112610265576040516302571be360e01b8152600480359082018190529060209060248035916001600160a01b039184908290817f00000000000000000000000000000000000c2e074ec69a0dfb2997ba6c7d2e1e86165afa908115610c19578691611760575b50838282168088526005825260ff604089205416611710575b5050168033141590816116e5575b506105095760405181838201528281526115a281612e06565b8385526003835260408520908051906001600160401b0382116116d1576115d3826115cd8554612d9e565b856130d0565b8490601f831160011461165a579180610474949260008051602061440283398151915296948a9261164f575b50508160011b916000199060031b1c19161790555b60405190690728080b90012040089160b51b85830152602a820152602a815261163c81612deb565b6040519182918583523395830190612f0b565b0151905038806115ff565b8388528588209190601f198416895b888282106116bb57505092600192859260008051602061440283398151915298966104749896106116a2575b505050811b019055611614565b015160001960f88460031b161c19169055388080611695565b6001859682939686015181550195019301611669565b634e487b7160e01b87526041600452602487fd5b90508452600482526040842083855282526040842033600052825260ff604060002054161538611589565b60249250604051928380926331a9108f60e11b82528960048301525afa908115610c19578691611743575b50833861157b565b61175a9150843d8611610253576102458183612e21565b3861173b565b6117779150843d8611610253576102458183612e21565b38611562565b50346102655760603660031901126102655760043561179a612f46565b6044359182151592838103611817576117ea90338652600460205260408620838752602052604086209360018060a01b0316938460005260205260406000209060ff801983541691151516179055565b7fc23d87d033a4cc3a7b6b27eccbda789e76f9bcd5ce948e8a03192df3159f17686020604051338152a480f35b600080fd5b5034610265576060366003190112610265576001600160401b036004358181116105e15761184e903690600401612f98565b602492919235828111610f6957611869903690600401612f98565b919092604435908111610ccf57611884903690600401612f98565b93865b838110611892578780f35b61189d8187856143d0565b6118a6906143e0565b33895260206004815260408a206118be84888c6143d0565b358b52815260408a206001600160a01b039290836118dd868b896143d0565b6118e6906143ed565b166000528252604060002090611907919060ff801983541691151516179055565b61191283878b6143d0565b3561191e8489876143d0565b611927906143ed565b92611933858b896143d0565b61193c906143e0565b906040519133835215159416927fc23d87d033a4cc3a7b6b27eccbda789e76f9bcd5ce948e8a03192df3159f176891a46119759061412f565b611887565b50346102655760a036600319011261026557611994612f30565b9061199d612f46565b916001600160401b0360643581811161148b576119be903690600401613064565b926084359182116102655760206119e88686866119de3660048901613064565b926044359161413e565b6040519015158152f35b503461026557611a0136612fc8565b919260019380156121e25760f8908235821c611a1b61314d565b95818801918289116121de578383116121de57611a4190999192969936908a880161302d565b611a4a886131a9565b52611a54876131a9565b50611a5e876131a9565b519586905b6001600160f81b0319611a7782878a61312b565b351615611b315784939291611aae610c7d600184611aa1610c588d8385611ace9a019c8d92613191565b8b1c01018097898c613191565b611ab88c8c6131c6565b52611ac38b8b6131c6565b50610ca18b8b6131c6565b96611b28611ae060018c019b8b6131c6565b5160405180938251611afa81602095868087019101612ee8565b8201602f60f81b84820152611b19825180936021968785019101612ee8565b01036001810184520182612e21565b96909192611a63565b50919892969350966000190197611b4889856131c6565b516020815191012060405160208101918a8352604082015260408152611b6d81612deb565b51902088948a60609b5b6120bd5750506040516302571be360e01b8152600481018690529590506020866024817f00000000000000000000000000000000000c2e074ec69a0dfb2997ba6c7d2e1e6001600160a01b03165afa958615610f4157899661209c575b506001600160a01b038616808a52600560205260408a205460ff16612046575b5089511561201f575b8854604051630bb6dffb60e41b8152602060048201526001600160a01b039091169890968a8880611c3260248201888b61310a565b03818d5afa97881561201457908b918299611ff8575b50604051903060601b602083015260001943014060348301526bffffffffffffffffffffffff199060601b16605482015280858751606883018160208b0191611c9092612ee8565b8b51908c828286016068019160200191611ca992612ee8565b830101818a60688301370183606882015203604881018252606801611cce9082612e21565b805190602001209b8c9a60405191602083016c2f2e77656c6c2d6b6e6f776e2f60981b9052828c518d81602d84019160200191611d0a92612ee8565b8101602d8101602f60f81b90528c51908d82602e83019160200191611d2e92612ee8565b0103600e81018452602e01611d439084612e21565b604051809d8194829363d4a964f160e01b8452600484016060905260648401611d6b91612f0b565b838103600319016024850152611d8091612f0b565b90604483015203915afa988915611fed578a99611efa575b50604051603c420460f01b6001600160f01b03191660208201526002815297611dc089612e06565b6040519b8c976020890152600019430160408901526060880152610100948560808901526101208801611df291612f0b565b97601f1998898982030160a08a0152611e0a91612f0b565b888882030160c0890152611e1d91612f0b565b90878783030160e0880152611e319261310a565b91858584030190850152611e449261310a565b039081018552611e549085612e21565b60405192630556f18360e41b845260a484013060048601526024850160a09052835180915260c485018160051b860160c4019460200192905b828210611ecf5786860360031901604488015286806102288a611eb08a8a612f0b565b63c55a5d5960e01b606485015283810360031901608485015290612f0b565b90919294602080611eec60019360c3198b82030186528951612f0b565b970192019201909291611e8d565b9098503d808b833e611f0c8183612e21565b6020828281010312611fe9578151906001600160401b038211611fe557808301601f838501011215611fe55781830151926001600160401b038411611fcf578360051b9260405194611f616020860187612e21565b85526020808601948284010101928083018411611fcb57602082840101945b848610611f94575050505050509738611d98565b85516001600160401b038111611fc657602091611fbb83928386890191888a010101613256565b815201950194611f80565b508f80fd5b8e80fd5b634e487b7160e01b600052604160045260246000fd5b8b80fd5b8a80fd5b6040513d8c823e3d90fd5b61200d9199503d8084833e6107d08183612e21565b9738611c48565b6040513d8d823e3d90fd5b6001600160a01b038616895260036020526040892090995061204090612e42565b98611bfd565b6024919650602090604051928380926331a9108f60e11b82528960048301525afa908115610f4157899161207d575b509438611bf4565b612096915060203d602011610253576102458183612e21565b38612075565b6120b691965060203d602011610253576102458183612e21565b9438611bd4565b600019019a9095916120cf8c886131c6565b516020815191012060405190602082019283526040820152604081526120f481612deb565b519020604051631ef3fca760e31b8152600481018290529092906020816024817f00000000000000000000000000000000000c2e074ec69a0dfb2997ba6c7d2e1e6001600160a01b03165afa9081156121d3578c916121b4575b50156121735750508094818a5260036020528a61216d60408c20612e42565b9b611b77565b95909a828b5260038060205261218c60408d2054612d9e565b612198575b5080611b77565b909b50828b526020528a6121ae60408c20612e42565b9b612191565b6121cd915060203d602011610c1257610c048183612e21565b3861214e565b6040513d8e823e3d90fd5b8980fd5b634e487b7160e01b86526032600452602486fd5b50346102655780600319360112610265578054604051638da5cb5b60e01b8152906001600160a01b03906020908390600490829085165afa91821561025a5760209392612248575b5060405191168152f35b612260919250833d8111610253576102458183612e21565b903861223e565b503461026557604036600319011261026557612281612f30565b612289612f89565b8254604051638da5cb5b60e01b815291926001600160a01b039290916020908290600490829087165afa80156123705783918691612352575b501633036101f857803b1561231e57169081835260056020526122f481604085209060ff801983541691151516179055565b1515907f976fe5c61b46a2e3e8c0330103e8b00d2e561ff8bec93bb1ff3bfb59fd754c758380a380f35b6040516301cfc2ef60e61b815260206004820152600b60248201526a2120a22faba920a82822a960a91b6044820152606490fd5b61236a915060203d8111610253576102458183612e21565b386122c2565b6040513d87823e3d90fd5b506060366003190112610265576001600160401b03906024600435813584811161148b576123ad903690600401612f98565b92604435868111610ccf576123c6903690600401612f5c565b6040516302571be360e01b8152600481018690529495602095929491939287906001600160a01b0390888187817f00000000000000000000000000000000000c2e074ec69a0dfb2997ba6c7d2e1e86165afa90811561201457908b9392918491612643575b50868a83831680875260ff60406005988985522054166125f1575b50505016908133141591826125c4575b50506105095781805b61253f5750505050848652600384526040862096821161252d57506124888161041c8854612d9e565b8495601f82116001146124d8578186976000805160206144028339815191529596979161047a57508260011b906000198460031b1c1916179055610474604051928392868452339684019161310a565b808652838620601f19831697875b89811061251657508360008051602061440283398151915296979899106104c4575050600182811b01905561045e565b9091866001819285890135815501930191016124e6565b634e487b7160e01b8652604160045285fd5b6000190197828910156125b15788821b840135601e1985360301811215611fe95784018035908c8211611fe5578901908036038213611fe5578a929161258691369161302d565b898151910120604051908a82019283526040820152604081526125a881612deb565b5190209861245f565b634e487b7160e01b8a526032600452848afd5b9091508a526004885260408a20908a5287526040892033600052875260ff60406000205416153880612456565b6040516331a9108f60e11b81526004810187905293509091839182905afa9081156121d3578c91612626575b50868a38612446565b61263d91508a3d8c11610253576102458183612e21565b3861261d565b61265a91508a3d8c11610253576102458183612e21565b3861242b565b50346102655760403660031901126102655761267a612d87565b612682612f89565b8254604051638da5cb5b60e01b81529192916001600160a01b03916020908290600490829086165afa908115612370578591612774575b501633036101f8576001600160e01b03191690632b45eb2b60e01b82148015612764575b61272c57818352600660205261270281604085209060ff801983541691151516179055565b1515907fe9314059add66b39b1853e125d5a356101752cede174a4df4d475ae5d060c9018380a380f35b6040516301cfc2ef60e61b815260206004820152600f60248201526e4c4f434b45445f43414c4c4241434b60881b6044820152606490fd5b50639061b92360e01b82146126dd565b61278c915060203d8111610253576102458183612e21565b386126b9565b5034610265576020806003193601126109585760043591828152600382526127bc60408220612e42565b9283511561289b575b50818351149081612830575b506127eb575b610af0604051928284938452830190612f0b565b9061282a602a6040518093690728080b90012040089160b51b8683015261281a81518092888686019101612ee8565b810103600a810184520182612e21565b906127d7565b80546040516338d630a760e21b815260048101859052919250839082906001600160a01b03168180612865602482018a612f0b565b03915afa9182156113e7579161287e575b5015386127d1565b6128959150823d8411610c1257610c048183612e21565b38612876565b6040516302571be360e01b8152600481018290529193506001600160a01b03919083826024817f00000000000000000000000000000000000c2e074ec69a0dfb2997ba6c7d2e1e87165afa918215612370578592612988575b5083838316918287526005825260ff60408820541661292b575b5050501682526003815261292460408320612e42565b91386127c5565b909192506024604051809481936331a9108f60e11b835260048301525afa90811561297d578491612960575b5038838161290e565b6129779150833d8511610253576102458183612e21565b38612957565b6040513d86823e3d90fd5b6129a0919250843d8611610253576102458183612e21565b90386128f4565b50602080600319360112610958576001600160401b039060043582811161148b576129d6903690600401612f5c565b9260025434106109465733855260038352604085209084116104f557612a0684612a008354612d9e565b836130d0565b8385601f8211600114612a6457916000805160206144028339815191529391610474938891612a59575b508660011b906000198860031b1c19161790555b6040519182918583523396339684019161310a565b905082013538612a30565b828752848720915085601f198116885b87828210612ac557505091600080516020614402833981519152959391610474959310612aab575b5050600186811b019055612a44565b830135600019600389901b60f8161c191690553880612a9c565b8785013586556001909501949384019389935001612a74565b503461026557606036600319011261026557612af8612f30565b6044356001600160a01b03818116939184900361181757604092168152600460205281812060243582526020522090600052602052602060ff604060002054166040519015158152f35b503461026557604036600319011261026557806001600160a01b036004602082612b6a612f30565b169284541660405192838092638da5cb5b60e01b82525afa90811561025a578391612bed575b50813b1561032157604051632142170760e11b81523060048201526001600160a01b039190911660248083019190915235604482015291908290606490829084905af1801561031657612be1575080f35b612bea90612dd8565b80f35b612c05915060203d8111610253576102458183612e21565b38612b90565b503461026557602036600319011261026557610f8b6040610af0926004358152600360205220612e42565b50346102655780600319360112610265578054604051638da5cb5b60e01b815282916001600160a01b0391906020908290600490829086165afa90811561025a578392839283928391612ca5575b50479183918315612c9b575b1690f1156113e75780f35b6108fc9250612c90565b612cbd915060203d8111610253576102458183612e21565b38612c84565b50346102655780600319360112610265576040517f00000000000000000000000000000000000c2e074ec69a0dfb2997ba6c7d2e1e6001600160a01b03168152602090f35b50346102655780600319360112610265576020600254604051908152f35b5034610265578060031936011261026557546040516001600160a01b039091168152602090f35b9050346109585760203660031901126109585760ff604060209363ffffffff60e01b612d77612d87565b1681526006855220541615158152f35b600435906001600160e01b03198216820361181757565b90600182811c92168015612dce575b6020831014612db857565b634e487b7160e01b600052602260045260246000fd5b91607f1691612dad565b6001600160401b038111611fcf57604052565b606081019081106001600160401b03821117611fcf57604052565b604081019081106001600160401b03821117611fcf57604052565b90601f801991011681019081106001600160401b03821117611fcf57604052565b9060405191826000825492612e5684612d9e565b908184526001948581169081600014612ec55750600114612e82575b5050612e8092500383612e21565b565b9093915060005260209081600020936000915b818310612ead575050612e8093508201013880612e72565b85548884018501529485019487945091830191612e95565b915050612e8094506020925060ff191682840152151560051b8201013880612e72565b60005b838110612efb5750506000910152565b8181015183820152602001612eeb565b90602091612f2481518092818552858086019101612ee8565b601f01601f1916010190565b600435906001600160a01b038216820361181757565b602435906001600160a01b038216820361181757565b9181601f84011215611817578235916001600160401b038311611817576020838186019501011161181757565b60243590811515820361181757565b9181601f84011215611817578235916001600160401b038311611817576020808501948460051b01011161181757565b6040600319820112611817576001600160401b03916004358381116118175782612ff491600401612f5c565b939093926024359182116118175761300e91600401612f5c565b9091565b6001600160401b038111611fcf57601f01601f191660200190565b92919261303982613012565b916130476040519384612e21565b829481845281830111611817578281602093846000960137010152565b9080601f830112156118175781602061307f9335910161302d565b90565b9081602091031261181757516001600160a01b03811681036118175790565b90816020910312611817575180151581036118175790565b8181106130c4575050565b600081556001016130b9565b9190601f81116130df57505050565b612e80926000526020600020906020601f840160051c8301931061079d57601f0160051c01906130b9565b908060209392818452848401376000828201840152601f01601f1916010190565b90821015613137570190565b634e487b7160e01b600052603260045260246000fd5b6040519061056082018281106001600160401b03821117611fcf57604052602a82528160005b6105408110613180575050565b806060602080938501015201613173565b90939293848311611817578411611817578101920390565b8051156131375760200190565b8051600110156131375760400190565b80518210156131375760209160051b010190565b6001600160f81b031990358181169392600181106131f757505050565b60010360031b82901b16169150565b6021612e80919392936040519481613228879351809260208087019101612ee8565b8201601760f91b60208201526132478251809360208785019101612ee8565b01036001810185520183612e21565b81601f8201121561181757805161326c81613012565b9261327a6040519485612e21565b818452602082840101116118175761307f9160208085019101612ee8565b906020828203126118175781516001600160401b0381116118175761307f9201613256565b92906132d69061307f959360408652604086019161310a565b92602081850391015261310a565b90916132fb61307f93604084526040840190612f0b565b916020818403910152612f0b565b9060009160019081549161331c83612d9e565b92818116908115613384575060011461333457505050565b8091929394506000527fb10e2d527612073b26eecdfd717e6a320cf44b4afac2b0732d9fcbe2b7fa0cf6906000915b848310613371575050500190565b8181602092548587015201920191613363565b60ff191683525050811515909102019150565b91939290806004116118175763ffffffff60e01b833516600052600660205260ff60406000205416156140f957818501610100868203126118175760608601356001600160401b03811161181757816133f1918801613064565b9260808701356001600160401b0381116118175782613411918901613064565b916001600160401b0360a089013511611817576134348160a08a01358a01613064565b506001600160401b0360c089013511611817576134578160c08a01358a01613064565b506001600160401b0360e0890135116118175761347a9060e08901358901613064565b6040516302571be360e01b815288356004820152979091906020896024817f00000000000000000000000000000000000c2e074ec69a0dfb2997ba6c7d2e1e6001600160a01b03165afa9889156138f1576000996140d8575b506001600160a01b038916600090815260056020526040902054899060ff16614076575b50602081013560078101908110610cb3574311614040576040513060601b602082015260208201354060348201526bffffffffffffffffffffffff198a60601b1660548201526135906068828951613556818c60208686019101612ee8565b88519061356b82858386010160208d01612ee8565b8201018751906135818285830160208c01612ee8565b01036048810184520182612e21565b6020815191012060408201350361400b576080600319888781010301126118175760048701356001600160a01b0381169003611817576001600160401b03602488013511611817576135ed858801600460248a01358a0101613064565b946001600160401b0360448901351161181757613615818901600460448b01358b0101613064565b996001600160401b0360648a013511611817578761363e838b01600460648d01358d0101613064565b9b6040815110600014613fb757505060048901356001600160a01b039081169116908114159081613f78575b50610509575b87356001600160e01b031916632b45eb2b60e01b036139405750505050906136de9160018060a01b03600054166000885160208a0120604051906020820152602081526136bc81612e06565b604051809681926308ead44760e21b8352604060048401526044830190612f0b565b8360248301520381845afa9081156138f157602494600092613921575b50604051636789a9a960e11b81526004888101356001600160a01b0316908201529460009186919082905afa9384156138f15761386a9560209561384f936001936000926138fd575b506082613826916040519788957f52657175657374696e67205369676e617475726520546f2055706461746520458c880152692729902932b1b7b9320560b11b604088015267527b934b3b4b71d160bd1b604a8801526137ad815180928e60538b019101612ee8565b86016c52932b1b7b932102a3cb8329d160951b60538201526137d8825180938e606185019101612ee8565b016d0148af0e8e4c2c8c2e8c2744060f60931b6061820152613803825180938d606f85019101612ee8565b01720529b4b3b732b210213c9d1032b4b8189a9a9d60691b606f82015201613309565b601d60f91b815261383f825180938a8785019101612ee8565b0103601e19810184520182612e21565b60405163a8e547fb60e01b81529384928392600484016132e4565b0381305afa9081156138f1576000916138d2575b506001600160a01b03908116600490920135160361389857565b6040516306e0450760e31b815260206004820152601160248201527010905117d4d251d3915117d49150d3d491607a1b6044820152606490fd5b6138eb915060203d602011610253576102458183612e21565b3861387e565b6040513d6000823e3d90fd5b6138269192506139196082913d806000833e6107d08183612e21565b929150613744565b6000919250613939903d8084833e6107d08183612e21565b91906136fb565b9798929795969295929350909183356001600160e01b03191663308045e960e21b03613f40575050508251156131375760208301516001600160f81b031916158015613f0e575b613ed15760006139ac956040518097819263cc49dd9560e01b835287600484016132e4565b0381305afa9384156138f157600092600095600097600091613e40575b50906139f99160018060a01b03600054166000885160208a0120604051906020820152602081526136bc81612e06565b8360248301520381845afa9081156138f157602494600092613e21575b50604051636789a9a960e11b81526004888101356001600160a01b0316908201529460009186919082905afa9384156138f157613b3c9560209561384f93600193600092613dfd575b50607d613826916040519788957f52657175657374696e67205369676e617475726520546f20496e7374616c6c208c8801526c3220b8381029b2b93b34b1b28560991b604088015267527b934b3b4b71d160bd1b604d880152613acb815180928e60568b019101612ee8565b860164520b8381d160d51b6056820152613aee825180938e605c85019101612ee8565b016d0148af0e8e4c2c8c2e8c2744060f60931b605c820152613b19825180938d606a85019101612ee8565b01720529b4b3b732b210213c9d1032b4b8189a9a9d60691b606a82015201613309565b0381305afa9081156138f157600091613dde575b506001600160a01b039081166004909201351603613da357604051630178b8bf60e01b815260048101939093526020836024817f00000000000000000000000000000000000c2e074ec69a0dfb2997ba6c7d2e1e6001600160a01b03165afa9283156138f157600093613d82575b506040516301ffc9a760e01b808252639061b92360e01b600483018190526001600160a01b03861695909390929091906020816024818a5afa9081156138f157600091613d63575b5015613c585750505091613c2d9391600093604051958694859384938452600484016132e4565b03915afa9081156138f157600091613c43575090565b61307f91503d806000833e6107d08183612e21565b60249192959450602093506040519485938492835263ffffffff60e01b1660048301525afa9081156138f157600091613d44575b5015613d0f57816000929160208493519201905afa903d15613d08573d613cb281613012565b90613cc06040519283612e21565b81523d6000602083013e5b9115613cd357565b6040516306e0450760e31b815260206004820152600c60248201526b2120a22fa922a9a7a62b22a960a11b6044820152606490fd5b6060613ccb565b6040516306e0450760e31b815260206004820152600c60248201526b2120a22fa32aa721aa24a7a760a11b6044820152606490fd5b613d5d915060203d602011610c1257610c048183612e21565b38613c8c565b613d7c915060203d602011610c1257610c048183612e21565b38613c06565b613d9c91935060203d602011610253576102458183612e21565b9138613bbe565b6040516306e0450760e31b81526020600482015260126024820152714241445f444150505f5349474e415455524560701b6044820152606490fd5b613df7915060203d602011610253576102458183612e21565b38613b50565b613826919250613e19607d913d806000833e6107d08183612e21565b929150613a5f565b6000919250613e39903d8084833e6107d08183612e21565b9190613a16565b975050925093503d93846000873e613e588587612e21565b6080868681010312611817578551956001600160e01b0319871687036118175760208101519360408201516001600160401b03811161181757613ea090888401908401613256565b966060830151926001600160401b038411611817576139f993613ec69282019101613256565b9794969790916139c9565b6040516306e0450760e31b815260206004820152601460248201527310905117d4915112549150d517d49154555154d560621b6044820152606490fd5b50825180600019810111610cb357835160001982011015613137578301601f01516001600160f81b0319161515613987565b6000805460405162c29a2d60e61b815299509097508896506001600160a01b0316945085938493613c2d9390929091600486016132bd565b9050600052600460205260406000208235600052602052604060002060018060a01b0360048a01351660005260205260ff60406000205416153861366a565b613fd29285359060048d01356001600160a01b03169061413e565b61367057604051630e5fbf5b60e31b815260206004820152600c60248201526b10905117d054141493d5905360a21b6044820152606490fd5b6040516306e0450760e31b815260206004820152600c60248201526b4241445f434845434b53554d60a01b6044820152606490fd5b6040516306e0450760e31b815260206004820152600d60248201526c109313d0d2d7d512535153d555609a1b6044820152606490fd5b6040516331a9108f60e11b815282356004820152919950602090829060249082906001600160a01b03165afa9081156138f1576000916140b9575b5097386134f7565b6140d2915060203d602011610253576102458183612e21565b386140b1565b6140f291995060203d602011610253576102458183612e21565b97386134d3565b6000805460405162c29a2d60e61b81529596919486946001600160a01b039092169385938493613c2d93909290600486016132bd565b6000198114610cb35760010190565b6000805460408051636789a9a960e11b8082526001600160a01b039687166004830152928616989197939695929490939087856024818d5afa9485156143a957908891829661438a575b5060248596978b5196879384928352169c8d60048301525afa928315614380578793614364575b508751809360209687948584017f52657175657374696e67205369676e617475726520546f20417070726f76652090527222a729902932b1b7b932399029b4b3b732b90560691b8c85015267527b934b3b4b71d160bd1b60538501528051908187605c870192019161422092612ee8565b8301605c81017f0a417070726f766564205369676e65723a206569703135353a00000000000000905260750161425590613309565b90601d60f91b9182815281519182886001840192019161427492612ee8565b01740520b8383937bb32b210213c9d1032b4b8189a9a9d60591b600182015260160161429f90613309565b9081528151918286600184019201916142b792612ee8565b0103601e19810184526001016142cd9084612e21565b875163a8e547fb60e01b815292839182916142ec9190600484016132e4565b0381305afa90811561435a57859161433d575b501691858314958615614316575b50505050505090565b60ff965084526004825284842090845281528383209183525220541638808080808061430d565b6143549150833d8511610253576102458183612e21565b386142ff565b86513d87823e3d90fd5b6143799193503d8089833e6107d08183612e21565b91386141af565b88513d89823e3d90fd5b8596506143a26024913d8086833e6107d08183612e21565b9650614188565b89513d8a823e3d90fd5b3590602081106143c1575090565b6000199060200360031b1b1690565b91908110156131375760051b0190565b3580151581036118175790565b356001600160a01b0381168103611817579056fedbe4e2174ccc483f322f3a0dd9c15970dab6fc1673ea519ba3f22064b7b0332ca2646970667358221220c7d42f94c686e0b08950d68a07ff0a6df6e3da00680daa8a1776ba589af267a364736f6c63430008130033

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

0000000000000000000000009d79ff2ec00b812e32d9768d88782101cb08d875

-----Decoded View---------------
Arg [0] : _gateway (address): 0x9d79FF2EC00b812E32D9768d88782101cB08D875

-----Encoded View---------------
1 Constructor Arguments found :
Arg [0] : 0000000000000000000000009d79ff2ec00b812e32d9768d88782101cb08d875


Block Transaction Difficulty Gas Used Reward
View All Blocks Produced

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

Validator Index Block Amount
View All Withdrawals

Transaction Hash Block Value Eth2 PubKey Valid
View All Deposits
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.