false
false
0

Contract Address Details

0x50a64d05bB8618D8d96A83CbBb12b3044ec3489A

Contract Name
Supervisor
Creator
0x013261–3cce0b at 0x6baaab–b602df
Balance
0 NUM ( )
Tokens
Fetching tokens...
Transactions
0 Transactions
Transfers
0 Transfers
Gas Used
Fetching gas used...
Last Balance Update
449391
Warning! Contract bytecode has been changed and doesn't match the verified one. Therefore, interaction with this smart contract may be risky.
Contract name:
Supervisor




Optimization enabled
true
Compiler version
v0.8.2+commit.661d1103




Optimization runs
200
EVM Version
istanbul




Verified at
2024-07-02T12:17:07.029457Z

Constructor Arguments

000000000000000000000000000000000000000000000000000000000000290b000000000000000000000000000000000000000000000000000000000000006000000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000002000000000000000000000000517beb62d45e7637a2db115679f36936bdbb05d2000000000000000000000000207d2d9c74f4c8acdfcb5765d7dccc92e2861094
              

Supervisor.sol

Sol2uml
new
// SPDX-License-Identifier: BUSL-1.1
pragma solidity 0.8.2;

import "ECDSA.sol";

/// @title Supervisor is the guardian of YPool. It requires multiple validators to valid
/// the requests from users and workers and sign on them if valid.
contract Supervisor {
    using ECDSA for bytes32;

    /* ========== STATE VARIABLES ========== */

    bytes32 public constant SET_THRESHOLD_IDENTIFIER = 'SET_THRESHOLD';
    bytes32 public constant SET_VALIDATOR_IDENTIFIER = 'SET_VALIDATOR';
    bytes32 public constant VALIDATE_XY_CROSS_CHAIN_IDENTIFIER = 'VALIDATE_XY_XCHAIN_IDENTIFIER';

    // the chain ID contract located at
    uint32 immutable public chainId;

    // number of validators
    uint256 public validatorsNum;
    // threshold to pass the signature validation
    uint256 public threshold;
    // current nonce for write functions
    uint256 public nonce;

    // check if the address is one of the validators
    mapping (address => bool) public validators;

    /// @dev Constuctor with chainId / validators / threshold
    /// @param _chainId The chain ID located with
    /// @param _validators Initial validator addresses
    /// @param _threshold Initial threshold to pass the request validation
    constructor(uint32 _chainId, address [] memory _validators, uint256 _threshold) {
        chainId = _chainId;

        for (uint256 i; i < _validators.length; i++) {
            validators[_validators[i]] = true;
        }
        validatorsNum = _validators.length;
        require(_threshold <= validatorsNum, "ERR_INVALID_THRESHOLD");
        threshold = _threshold;
    }

    /* ========== VIEW FUNCTIONS ========== */

    /// @notice Check if there are enough signed signatures to the signature hash
    /// @param sigIdHash The signature hash to be signed
    /// @param signatures Signed signatures by different validators
    function checkSignatures(bytes32 sigIdHash, bytes[] memory signatures) public view {
        require(signatures.length >= threshold, "ERR_NOT_ENOUGH_SIGNATURES");
        address prevAddress = address(0);
        for (uint i; i < threshold; i++) {
            address recovered = sigIdHash.recover(signatures[i]);
            require(validators[recovered], "ERR_NOT_VALIDATOR");
            require(recovered > prevAddress, "ERR_WRONG_SIGNER_ORDER");
            prevAddress = recovered;
        }
    }

    /* ========== WRITE FUNCTIONS ========== */

    /// @notice Change `threshold` by providing a correct nonce and enough signatures from validators
    /// @param _threshold New `threshold`
    /// @param _nonce The nonce to be processed
    /// @param signatures Signed signatures by validators
    function setThreshold(uint256 _threshold, uint256 _nonce, bytes[] memory signatures) external {
        require(signatures.length >= threshold, "ERR_NOT_ENOUGH_SIGNATURES");
        require(_nonce == nonce, "ERR_INVALID_NONCE");
        require(_threshold > 0, "ERR_INVALID_THRESHOLD");
        require(_threshold <= validatorsNum, "ERR_INVALID_THRESHOLD");

        bytes32 sigId = keccak256(abi.encodePacked(SET_THRESHOLD_IDENTIFIER, address(this), chainId, _threshold, _nonce));
        bytes32 sigIdHash = sigId.toEthSignedMessageHash();
        checkSignatures(sigIdHash, signatures);

        threshold = _threshold;
        nonce++;
    }

    /// @notice Set / remove the validator address to be part of signatures committee
    /// @param _validator The address to add or remove
    /// @param flag `true` to add, `false` to remove
    /// @param _nonce The nonce to be processed
    /// @param signatures Signed signatures by validators
    function setValidator(address _validator, bool flag, uint256 _nonce, bytes[] memory signatures) external {
        require(_validator != address(0), "ERR_INVALID_VALIDATOR");
        require(signatures.length >= threshold, "ERR_NOT_ENOUGH_SIGNATURES");
        require(_nonce == nonce, "ERR_INVALID_NONCE");
        require(flag != validators[_validator], "ERR_OPERATION_TO_VALIDATOR");

        bytes32 sigId = keccak256(abi.encodePacked(SET_VALIDATOR_IDENTIFIER, address(this), chainId, _validator, flag, _nonce));
        bytes32 sigIdHash = sigId.toEthSignedMessageHash();
        checkSignatures(sigIdHash, signatures);

        if (validators[_validator]) {
            validatorsNum--;
            validators[_validator] = false;
            if (validatorsNum < threshold) threshold--;
        } else {
            validatorsNum++;
            validators[_validator] = true;
        }
        nonce++;
    }
}
        

ECDSA.sol

// SPDX-License-Identifier: MIT

pragma solidity ^0.8.0;

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

    function _throwError(RecoverError error) private pure {
        if (error == RecoverError.NoError) {
            return; // no error: do nothing
        } else if (error == RecoverError.InvalidSignature) {
            revert("ECDSA: invalid signature");
        } else if (error == RecoverError.InvalidSignatureLength) {
            revert("ECDSA: invalid signature length");
        } else if (error == RecoverError.InvalidSignatureS) {
            revert("ECDSA: invalid signature 's' value");
        } else if (error == RecoverError.InvalidSignatureV) {
            revert("ECDSA: invalid signature 'v' value");
        }
    }

    /**
     * @dev Returns the address that signed a hashed message (`hash`) with
     * `signature` or error string. This address can then be used for verification purposes.
     *
     * The `ecrecover` EVM opcode allows for malleable (non-unique) signatures:
     * this function rejects them by requiring the `s` value to be in the lower
     * half order, and the `v` value to be either 27 or 28.
     *
     * IMPORTANT: `hash` _must_ be the result of a hash operation for the
     * verification to be secure: it is possible to craft signatures that
     * recover to arbitrary addresses for non-hashed data. A safe way to ensure
     * this is by receiving a hash of the original message (which may otherwise
     * be too long), and then calling {toEthSignedMessageHash} on it.
     *
     * Documentation for signature generation:
     * - with https://web3js.readthedocs.io/en/v1.3.4/web3-eth-accounts.html#sign[Web3.js]
     * - with https://docs.ethers.io/v5/api/signer/#Signer-signMessage[ethers]
     *
     * _Available since v4.3._
     */
    function tryRecover(bytes32 hash, bytes memory signature) internal pure returns (address, RecoverError) {
        // Check the signature length
        // - case 65: r,s,v signature (standard)
        // - case 64: r,vs signature (cf https://eips.ethereum.org/EIPS/eip-2098) _Available since v4.1._
        if (signature.length == 65) {
            bytes32 r;
            bytes32 s;
            uint8 v;
            // ecrecover takes the signature parameters, and the only way to get them
            // currently is to use assembly.
            assembly {
                r := mload(add(signature, 0x20))
                s := mload(add(signature, 0x40))
                v := byte(0, mload(add(signature, 0x60)))
            }
            return tryRecover(hash, v, r, s);
        } else if (signature.length == 64) {
            bytes32 r;
            bytes32 vs;
            // ecrecover takes the signature parameters, and the only way to get them
            // currently is to use assembly.
            assembly {
                r := mload(add(signature, 0x20))
                vs := mload(add(signature, 0x40))
            }
            return tryRecover(hash, r, vs);
        } else {
            return (address(0), RecoverError.InvalidSignatureLength);
        }
    }

    /**
     * @dev Returns the address that signed a hashed message (`hash`) with
     * `signature`. This address can then be used for verification purposes.
     *
     * The `ecrecover` EVM opcode allows for malleable (non-unique) signatures:
     * this function rejects them by requiring the `s` value to be in the lower
     * half order, and the `v` value to be either 27 or 28.
     *
     * IMPORTANT: `hash` _must_ be the result of a hash operation for the
     * verification to be secure: it is possible to craft signatures that
     * recover to arbitrary addresses for non-hashed data. A safe way to ensure
     * this is by receiving a hash of the original message (which may otherwise
     * be too long), and then calling {toEthSignedMessageHash} on it.
     */
    function recover(bytes32 hash, bytes memory signature) internal pure returns (address) {
        (address recovered, RecoverError error) = tryRecover(hash, signature);
        _throwError(error);
        return recovered;
    }

    /**
     * @dev Overload of {ECDSA-tryRecover} that receives the `r` and `vs` short-signature fields separately.
     *
     * See https://eips.ethereum.org/EIPS/eip-2098[EIP-2098 short signatures]
     *
     * _Available since v4.3._
     */
    function tryRecover(
        bytes32 hash,
        bytes32 r,
        bytes32 vs
    ) internal pure returns (address, RecoverError) {
        bytes32 s;
        uint8 v;
        assembly {
            s := and(vs, 0x7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff)
            v := add(shr(255, vs), 27)
        }
        return tryRecover(hash, v, r, s);
    }

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

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

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

        return (signer, RecoverError.NoError);
    }

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

    /**
     * @dev Returns an Ethereum Signed Message, created from a `hash`. This
     * produces hash corresponding to the one signed with the
     * https://eth.wiki/json-rpc/API#eth_sign[`eth_sign`]
     * JSON-RPC method as part of EIP-191.
     *
     * See {recover}.
     */
    function toEthSignedMessageHash(bytes32 hash) internal pure returns (bytes32) {
        // 32 is the length in bytes of hash,
        // enforced by the type signature above
        return keccak256(abi.encodePacked("\x19Ethereum Signed Message:\n32", hash));
    }

    /**
     * @dev Returns an Ethereum Signed Typed Data, created from a
     * `domainSeparator` and a `structHash`. This produces hash corresponding
     * to the one signed with the
     * https://eips.ethereum.org/EIPS/eip-712[`eth_signTypedData`]
     * JSON-RPC method as part of EIP-712.
     *
     * See {recover}.
     */
    function toTypedDataHash(bytes32 domainSeparator, bytes32 structHash) internal pure returns (bytes32) {
        return keccak256(abi.encodePacked("\x19\x01", domainSeparator, structHash));
    }
}
          

Compiler Settings

{"outputSelection":{"*":{"*":["abi","evm.bytecode","evm.deployedBytecode","evm.methodIdentifiers"]}},"optimizer":{"runs":200,"enabled":true},"libraries":{"Supervisor.sol":{}},"evmVersion":"istanbul"}
              

Contract ABI

[{"type":"constructor","inputs":[{"type":"uint32","name":"_chainId","internalType":"uint32"},{"type":"address[]","name":"_validators","internalType":"address[]"},{"type":"uint256","name":"_threshold","internalType":"uint256"}]},{"type":"function","stateMutability":"view","outputs":[{"type":"bytes32","name":"","internalType":"bytes32"}],"name":"SET_THRESHOLD_IDENTIFIER","inputs":[]},{"type":"function","stateMutability":"view","outputs":[{"type":"bytes32","name":"","internalType":"bytes32"}],"name":"SET_VALIDATOR_IDENTIFIER","inputs":[]},{"type":"function","stateMutability":"view","outputs":[{"type":"bytes32","name":"","internalType":"bytes32"}],"name":"VALIDATE_XY_CROSS_CHAIN_IDENTIFIER","inputs":[]},{"type":"function","stateMutability":"view","outputs":[{"type":"uint32","name":"","internalType":"uint32"}],"name":"chainId","inputs":[]},{"type":"function","stateMutability":"view","outputs":[],"name":"checkSignatures","inputs":[{"type":"bytes32","name":"sigIdHash","internalType":"bytes32"},{"type":"bytes[]","name":"signatures","internalType":"bytes[]"}]},{"type":"function","stateMutability":"view","outputs":[{"type":"uint256","name":"","internalType":"uint256"}],"name":"nonce","inputs":[]},{"type":"function","stateMutability":"nonpayable","outputs":[],"name":"setThreshold","inputs":[{"type":"uint256","name":"_threshold","internalType":"uint256"},{"type":"uint256","name":"_nonce","internalType":"uint256"},{"type":"bytes[]","name":"signatures","internalType":"bytes[]"}]},{"type":"function","stateMutability":"nonpayable","outputs":[],"name":"setValidator","inputs":[{"type":"address","name":"_validator","internalType":"address"},{"type":"bool","name":"flag","internalType":"bool"},{"type":"uint256","name":"_nonce","internalType":"uint256"},{"type":"bytes[]","name":"signatures","internalType":"bytes[]"}]},{"type":"function","stateMutability":"view","outputs":[{"type":"uint256","name":"","internalType":"uint256"}],"name":"threshold","inputs":[]},{"type":"function","stateMutability":"view","outputs":[{"type":"bool","name":"","internalType":"bool"}],"name":"validators","inputs":[{"type":"address","name":"","internalType":"address"}]},{"type":"function","stateMutability":"view","outputs":[{"type":"uint256","name":"","internalType":"uint256"}],"name":"validatorsNum","inputs":[]}]
              

Contract Creation Code

Verify & Publish
0x60a06040523480156200001157600080fd5b506040516200114b3803806200114b833981016040819052620000349162000146565b6001600160e01b031960e084901b1660805260005b8251811015620000c1576001600360008584815181106200007a57634e487b7160e01b600052603260045260246000fd5b6020908102919091018101516001600160a01b03168252810191909152604001600020805460ff191691151591909117905580620000b88162000242565b91505062000049565b50815160008190558111156200011d5760405162461bcd60e51b815260206004820152601560248201527f4552525f494e56414c49445f5448524553484f4c440000000000000000000000604482015260640160405180910390fd5b60015550620002809050565b80516001600160a01b03811681146200014157600080fd5b919050565b6000806000606084860312156200015b578283fd5b835163ffffffff811681146200016f578384fd5b602085810151919450906001600160401b03808211156200018e578485fd5b818701915087601f830112620001a2578485fd5b815181811115620001b757620001b76200026a565b838102604051601f19603f83011681018181108582111715620001de57620001de6200026a565b604052828152858101935084860182860187018c1015620001fd578889fd5b8895505b838610156200022a57620002158162000129565b85526001959095019493860193860162000201565b50809750505050505050604084015190509250925092565b60006000198214156200026357634e487b7160e01b81526011600452602481fd5b5060010190565b634e487b7160e01b600052604160045260246000fd5b60805160e01c610e9e620002ad600039600081816101550152818161045d01526106510152610e9e6000f3fe608060405234801561001057600080fd5b50600436106100a95760003560e01c806371aca57e1161007157806371aca57e14610116578063935d91dd1461013d5780639a8a059214610150578063affed0e01461018c578063da8bd3fe14610195578063fa52c7d8146101a8576100a9565b80633c0e39bf146100ae57806342cde4e8146100d85780634f9c36b4146100e157806351f61efa146100ea5780635a0f883014610101575b600080fd5b6100c56c14d15517d512149154d213d311609a1b81565b6040519081526020015b60405180910390f35b6100c560015481565b6100c560005481565b6100c56c29a2aa2fab20a624a220aa27a960991b81565b61011461010f366004610d0f565b6101db565b005b6100c57f56414c49444154455f58595f58434841494e5f4944454e54494649455200000081565b61011461014b366004610d54565b610324565b6101777f000000000000000000000000000000000000000000000000000000000000000081565b60405163ffffffff90911681526020016100cf565b6100c560025481565b6101146101a3366004610ca3565b6104e9565b6101cb6101b6366004610c82565b60036020526000908152604090205460ff1681565b60405190151581526020016100cf565b600154815110156102075760405162461bcd60e51b81526004016101fe90610da2565b60405180910390fd5b6000805b60015481101561031e57600061025184838151811061023a57634e487b7160e01b600052603260045260246000fd5b60200260200101518661079390919063ffffffff16565b6001600160a01b03811660009081526003602052604090205490915060ff166102b05760405162461bcd60e51b815260206004820152601160248201527022a9292fa727aa2fab20a624a220aa27a960791b60448201526064016101fe565b826001600160a01b0316816001600160a01b03161161030a5760405162461bcd60e51b815260206004820152601660248201527522a9292faba927a723afa9a4a3a722a92fa7a92222a960511b60448201526064016101fe565b91508061031681610e21565b91505061020b565b50505050565b600154815110156103475760405162461bcd60e51b81526004016101fe90610da2565b600254821461038c5760405162461bcd60e51b81526020600482015260116024820152704552525f494e56414c49445f4e4f4e434560781b60448201526064016101fe565b600083116103d45760405162461bcd60e51b815260206004820152601560248201527411549497d253959053125117d512149154d213d311605a1b60448201526064016101fe565b60005483111561041e5760405162461bcd60e51b815260206004820152601560248201527411549497d253959053125117d512149154d213d311605a1b60448201526064016101fe565b604080516c14d15517d512149154d213d311609a1b60208201526bffffffffffffffffffffffff193060601b16918101919091526001600160e01b03197f000000000000000000000000000000000000000000000000000000000000000060e01b166054820152605881018490526078810183905260009060980160405160208183030381529060405280519060200120905060006104bc826107b7565b90506104c881846101db565b6001859055600280549060006104dd83610e21565b91905055505050505050565b6001600160a01b0384166105375760405162461bcd60e51b815260206004820152601560248201527422a9292fa4a72b20a624a22fab20a624a220aa27a960591b60448201526064016101fe565b6001548151101561055a5760405162461bcd60e51b81526004016101fe90610da2565b600254821461059f5760405162461bcd60e51b81526020600482015260116024820152704552525f494e56414c49445f4e4f4e434560781b60448201526064016101fe565b6001600160a01b03841660009081526003602052604090205460ff161515831515141561060e5760405162461bcd60e51b815260206004820152601a60248201527f4552525f4f5045524154494f4e5f544f5f56414c494441544f5200000000000060448201526064016101fe565b604080516c29a2aa2fab20a624a220aa27a960991b6020808301919091526bffffffffffffffffffffffff1930606090811b8216848601526001600160e01b03197f000000000000000000000000000000000000000000000000000000000000000060e01b16605485015288901b16605883015285151560f81b606c830152606d80830186905283518084039091018152608d909201909252805191012060006106b7826107b7565b90506106c381846101db565b6001600160a01b03861660009081526003602052604090205460ff161561073e576000805490806106f383610e0a565b90915550506001600160a01b0386166000908152600360205260408120805460ff1916905560015490541015610739576001805490600061073383610e0a565b91905055505b610776565b60008054908061074d83610e21565b90915550506001600160a01b0386166000908152600360205260409020805460ff191660011790555b6002805490600061078683610e21565b9190505550505050505050565b60008060006107a2858561080b565b915091506107af8161087b565b509392505050565b6040517f19457468657265756d205369676e6564204d6573736167653a0a3332000000006020820152603c8101829052600090605c016040516020818303038152906040528051906020012090505b919050565b6000808251604114156108425760208301516040840151606085015160001a61083687828585610a81565b94509450505050610874565b82516040141561086c5760208301516040840151610861868383610b6e565b935093505050610874565b506000905060025b9250929050565b600081600481111561089d57634e487b7160e01b600052602160045260246000fd5b14156108a857610a7e565b60018160048111156108ca57634e487b7160e01b600052602160045260246000fd5b14156109185760405162461bcd60e51b815260206004820152601860248201527f45434453413a20696e76616c6964207369676e6174757265000000000000000060448201526064016101fe565b600281600481111561093a57634e487b7160e01b600052602160045260246000fd5b14156109885760405162461bcd60e51b815260206004820152601f60248201527f45434453413a20696e76616c6964207369676e6174757265206c656e6774680060448201526064016101fe565b60038160048111156109aa57634e487b7160e01b600052602160045260246000fd5b1415610a035760405162461bcd60e51b815260206004820152602260248201527f45434453413a20696e76616c6964207369676e6174757265202773272076616c604482015261756560f01b60648201526084016101fe565b6004816004811115610a2557634e487b7160e01b600052602160045260246000fd5b1415610a7e5760405162461bcd60e51b815260206004820152602260248201527f45434453413a20696e76616c6964207369676e6174757265202776272076616c604482015261756560f01b60648201526084016101fe565b50565b6000807f7fffffffffffffffffffffffffffffff5d576e7357a4501ddfe92f46681b20a0831115610ab85750600090506003610b65565b8460ff16601b14158015610ad057508460ff16601c14155b15610ae15750600090506004610b65565b6040805160008082526020820180845289905260ff881692820192909252606081018690526080810185905260019060a0016020604051602081039080840390855afa158015610b35573d6000803e3d6000fd5b5050604051601f1901519150506001600160a01b038116610b5e57600060019250925050610b65565b9150600090505b94509492505050565b6000806001600160ff1b03831660ff84901c601b01610b8f87828885610a81565b935093505050935093915050565b80356001600160a01b038116811461080657600080fd5b6000601f8381840112610bc5578182fd5b8235602067ffffffffffffffff80831115610be257610be2610e52565b610bef8283850201610dd9565b83815282810190878401875b86811015610c735781358a018b603f820112610c1557898afd5b86810135604087821115610c2b57610c2b610e52565b610c3c828c01601f19168a01610dd9565b8281528e82848601011115610c4f578c8dfd5b828285018b83013791820189018c9052508552509285019290850190600101610bfb565b50909998505050505050505050565b600060208284031215610c93578081fd5b610c9c82610b9d565b9392505050565b60008060008060808587031215610cb8578283fd5b610cc185610b9d565b935060208501358015158114610cd5578384fd5b925060408501359150606085013567ffffffffffffffff811115610cf7578182fd5b610d0387828801610bb4565b91505092959194509250565b60008060408385031215610d21578182fd5b82359150602083013567ffffffffffffffff811115610d3e578182fd5b610d4a85828601610bb4565b9150509250929050565b600080600060608486031215610d68578283fd5b8335925060208401359150604084013567ffffffffffffffff811115610d8c578182fd5b610d9886828701610bb4565b9150509250925092565b60208082526019908201527f4552525f4e4f545f454e4f5547485f5349474e41545552455300000000000000604082015260600190565b604051601f8201601f1916810167ffffffffffffffff81118282101715610e0257610e02610e52565b604052919050565b600081610e1957610e19610e3c565b506000190190565b6000600019821415610e3557610e35610e3c565b5060010190565b634e487b7160e01b600052601160045260246000fd5b634e487b7160e01b600052604160045260246000fdfea2646970667358221220807a01d045d9d25157eb6cac5454038894c5b54450502d0c3c8d1f4be4fa5db664736f6c63430008020033000000000000000000000000000000000000000000000000000000000000290b000000000000000000000000000000000000000000000000000000000000006000000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000002000000000000000000000000517beb62d45e7637a2db115679f36936bdbb05d2000000000000000000000000207d2d9c74f4c8acdfcb5765d7dccc92e2861094

Deployed ByteCode

0x608060405234801561001057600080fd5b50600436106100a95760003560e01c806371aca57e1161007157806371aca57e14610116578063935d91dd1461013d5780639a8a059214610150578063affed0e01461018c578063da8bd3fe14610195578063fa52c7d8146101a8576100a9565b80633c0e39bf146100ae57806342cde4e8146100d85780634f9c36b4146100e157806351f61efa146100ea5780635a0f883014610101575b600080fd5b6100c56c14d15517d512149154d213d311609a1b81565b6040519081526020015b60405180910390f35b6100c560015481565b6100c560005481565b6100c56c29a2aa2fab20a624a220aa27a960991b81565b61011461010f366004610d0f565b6101db565b005b6100c57f56414c49444154455f58595f58434841494e5f4944454e54494649455200000081565b61011461014b366004610d54565b610324565b6101777f000000000000000000000000000000000000000000000000000000000000290b81565b60405163ffffffff90911681526020016100cf565b6100c560025481565b6101146101a3366004610ca3565b6104e9565b6101cb6101b6366004610c82565b60036020526000908152604090205460ff1681565b60405190151581526020016100cf565b600154815110156102075760405162461bcd60e51b81526004016101fe90610da2565b60405180910390fd5b6000805b60015481101561031e57600061025184838151811061023a57634e487b7160e01b600052603260045260246000fd5b60200260200101518661079390919063ffffffff16565b6001600160a01b03811660009081526003602052604090205490915060ff166102b05760405162461bcd60e51b815260206004820152601160248201527022a9292fa727aa2fab20a624a220aa27a960791b60448201526064016101fe565b826001600160a01b0316816001600160a01b03161161030a5760405162461bcd60e51b815260206004820152601660248201527522a9292faba927a723afa9a4a3a722a92fa7a92222a960511b60448201526064016101fe565b91508061031681610e21565b91505061020b565b50505050565b600154815110156103475760405162461bcd60e51b81526004016101fe90610da2565b600254821461038c5760405162461bcd60e51b81526020600482015260116024820152704552525f494e56414c49445f4e4f4e434560781b60448201526064016101fe565b600083116103d45760405162461bcd60e51b815260206004820152601560248201527411549497d253959053125117d512149154d213d311605a1b60448201526064016101fe565b60005483111561041e5760405162461bcd60e51b815260206004820152601560248201527411549497d253959053125117d512149154d213d311605a1b60448201526064016101fe565b604080516c14d15517d512149154d213d311609a1b60208201526bffffffffffffffffffffffff193060601b16918101919091526001600160e01b03197f000000000000000000000000000000000000000000000000000000000000290b60e01b166054820152605881018490526078810183905260009060980160405160208183030381529060405280519060200120905060006104bc826107b7565b90506104c881846101db565b6001859055600280549060006104dd83610e21565b91905055505050505050565b6001600160a01b0384166105375760405162461bcd60e51b815260206004820152601560248201527422a9292fa4a72b20a624a22fab20a624a220aa27a960591b60448201526064016101fe565b6001548151101561055a5760405162461bcd60e51b81526004016101fe90610da2565b600254821461059f5760405162461bcd60e51b81526020600482015260116024820152704552525f494e56414c49445f4e4f4e434560781b60448201526064016101fe565b6001600160a01b03841660009081526003602052604090205460ff161515831515141561060e5760405162461bcd60e51b815260206004820152601a60248201527f4552525f4f5045524154494f4e5f544f5f56414c494441544f5200000000000060448201526064016101fe565b604080516c29a2aa2fab20a624a220aa27a960991b6020808301919091526bffffffffffffffffffffffff1930606090811b8216848601526001600160e01b03197f000000000000000000000000000000000000000000000000000000000000290b60e01b16605485015288901b16605883015285151560f81b606c830152606d80830186905283518084039091018152608d909201909252805191012060006106b7826107b7565b90506106c381846101db565b6001600160a01b03861660009081526003602052604090205460ff161561073e576000805490806106f383610e0a565b90915550506001600160a01b0386166000908152600360205260408120805460ff1916905560015490541015610739576001805490600061073383610e0a565b91905055505b610776565b60008054908061074d83610e21565b90915550506001600160a01b0386166000908152600360205260409020805460ff191660011790555b6002805490600061078683610e21565b9190505550505050505050565b60008060006107a2858561080b565b915091506107af8161087b565b509392505050565b6040517f19457468657265756d205369676e6564204d6573736167653a0a3332000000006020820152603c8101829052600090605c016040516020818303038152906040528051906020012090505b919050565b6000808251604114156108425760208301516040840151606085015160001a61083687828585610a81565b94509450505050610874565b82516040141561086c5760208301516040840151610861868383610b6e565b935093505050610874565b506000905060025b9250929050565b600081600481111561089d57634e487b7160e01b600052602160045260246000fd5b14156108a857610a7e565b60018160048111156108ca57634e487b7160e01b600052602160045260246000fd5b14156109185760405162461bcd60e51b815260206004820152601860248201527f45434453413a20696e76616c6964207369676e6174757265000000000000000060448201526064016101fe565b600281600481111561093a57634e487b7160e01b600052602160045260246000fd5b14156109885760405162461bcd60e51b815260206004820152601f60248201527f45434453413a20696e76616c6964207369676e6174757265206c656e6774680060448201526064016101fe565b60038160048111156109aa57634e487b7160e01b600052602160045260246000fd5b1415610a035760405162461bcd60e51b815260206004820152602260248201527f45434453413a20696e76616c6964207369676e6174757265202773272076616c604482015261756560f01b60648201526084016101fe565b6004816004811115610a2557634e487b7160e01b600052602160045260246000fd5b1415610a7e5760405162461bcd60e51b815260206004820152602260248201527f45434453413a20696e76616c6964207369676e6174757265202776272076616c604482015261756560f01b60648201526084016101fe565b50565b6000807f7fffffffffffffffffffffffffffffff5d576e7357a4501ddfe92f46681b20a0831115610ab85750600090506003610b65565b8460ff16601b14158015610ad057508460ff16601c14155b15610ae15750600090506004610b65565b6040805160008082526020820180845289905260ff881692820192909252606081018690526080810185905260019060a0016020604051602081039080840390855afa158015610b35573d6000803e3d6000fd5b5050604051601f1901519150506001600160a01b038116610b5e57600060019250925050610b65565b9150600090505b94509492505050565b6000806001600160ff1b03831660ff84901c601b01610b8f87828885610a81565b935093505050935093915050565b80356001600160a01b038116811461080657600080fd5b6000601f8381840112610bc5578182fd5b8235602067ffffffffffffffff80831115610be257610be2610e52565b610bef8283850201610dd9565b83815282810190878401875b86811015610c735781358a018b603f820112610c1557898afd5b86810135604087821115610c2b57610c2b610e52565b610c3c828c01601f19168a01610dd9565b8281528e82848601011115610c4f578c8dfd5b828285018b83013791820189018c9052508552509285019290850190600101610bfb565b50909998505050505050505050565b600060208284031215610c93578081fd5b610c9c82610b9d565b9392505050565b60008060008060808587031215610cb8578283fd5b610cc185610b9d565b935060208501358015158114610cd5578384fd5b925060408501359150606085013567ffffffffffffffff811115610cf7578182fd5b610d0387828801610bb4565b91505092959194509250565b60008060408385031215610d21578182fd5b82359150602083013567ffffffffffffffff811115610d3e578182fd5b610d4a85828601610bb4565b9150509250929050565b600080600060608486031215610d68578283fd5b8335925060208401359150604084013567ffffffffffffffff811115610d8c578182fd5b610d9886828701610bb4565b9150509250925092565b60208082526019908201527f4552525f4e4f545f454e4f5547485f5349474e41545552455300000000000000604082015260600190565b604051601f8201601f1916810167ffffffffffffffff81118282101715610e0257610e02610e52565b604052919050565b600081610e1957610e19610e3c565b506000190190565b6000600019821415610e3557610e35610e3c565b5060010190565b634e487b7160e01b600052601160045260246000fd5b634e487b7160e01b600052604160045260246000fdfea2646970667358221220807a01d045d9d25157eb6cac5454038894c5b54450502d0c3c8d1f4be4fa5db664736f6c63430008020033