false
true
0

Contract Address Details

0x6a4fF1950Be05995dEe75920cf27CD8FEbB6597A

Contract Name
PaymentVerifierRegistry
Creator
0xc3c7e0–8a5d11 at 0xc3acb6–e11960
Balance
0 PLS ( )
Tokens
Fetching tokens...
Transactions
14 Transactions
Transfers
0 Transfers
Gas Used
0
Last Balance Update
25960309
Warning! Contract bytecode has been changed and doesn't match the verified one. Therefore, interaction with this smart contract may be risky.
Contract name:
PaymentVerifierRegistry




Optimization enabled
true
Compiler version
v0.8.18+commit.87f61d96




Optimization runs
200
EVM Version
default




Verified at
2026-01-12T22:08:38.572619Z

contracts/registries/PaymentVerifierRegistry.sol

//SPDX-License-Identifier: MIT

import { Ownable } from "@openzeppelin/contracts/access/Ownable.sol";
import { Bytes32ArrayUtils } from "../external/Bytes32ArrayUtils.sol";
import { IPaymentVerifierRegistry } from "../interfaces/IPaymentVerifierRegistry.sol";

pragma solidity ^0.8.18;

contract PaymentVerifierRegistry is Ownable, IPaymentVerifierRegistry {

    using Bytes32ArrayUtils for bytes32[];

    /* ============ Structs ============ */

    struct PaymentMethodConfig {
        bool initialized;
        address verifier;
        mapping(bytes32 => bool) isCurrency;
        bytes32[] currencies;
    }
    
    /* ============ Events ============ */

    event PaymentMethodAdded(bytes32 indexed paymentMethod);
    event PaymentMethodRemoved(bytes32 indexed paymentMethod);
    event CurrencyAdded(bytes32 indexed paymentMethod, bytes32 indexed currencyCode);
    event CurrencyRemoved(bytes32 indexed paymentMethod, bytes32 indexed currencyCode);

    /* ============ State Variables ============ */
    mapping(bytes32 => PaymentMethodConfig) public store;
    bytes32[] public paymentMethods;

    /* ============ Constructor ============ */
    constructor() Ownable() {}
    
    /* ============ External Functions ============ */

    /**
     * Adds a new payment method with processors and currencies
     * @param _paymentMethod The payment method hash; Hash the payment method name in lowercase
     * @param _verifier The verifier address to add for this payment method
     * @param _currencies Array of currency code hashes to support
     */
    function addPaymentMethod(
        bytes32 _paymentMethod,
        address _verifier,
        bytes32[] calldata _currencies
    ) external onlyOwner {
        require(!store[_paymentMethod].initialized, "Payment method already exists");
        require(_verifier != address(0), "Invalid verifier");
        require(_currencies.length > 0, "Invalid currencies length");
        
        store[_paymentMethod].initialized = true;
        store[_paymentMethod].verifier = _verifier;
        
        addCurrencies(_paymentMethod, _currencies);

        paymentMethods.push(_paymentMethod);
        
        emit PaymentMethodAdded(_paymentMethod);
    }
    
    /**
     * Removes a payment method and associated configuration
     * @param _paymentMethod The payment method to remove
     * @dev Only callable by owner
     */
    function removePaymentMethod(bytes32 _paymentMethod) external onlyOwner {
        require(store[_paymentMethod].initialized, "Payment method does not exist");
        
        bytes32[] memory currencies = store[_paymentMethod].currencies;
        for (uint256 i = 0; i < currencies.length; i++) {
            _removeCurrency(_paymentMethod, currencies[i]);
        }
        
        delete store[_paymentMethod];
        
        paymentMethods.removeStorage(_paymentMethod);
        
        emit PaymentMethodRemoved(_paymentMethod);
    }

    /**
     * Adds supported currencies for a specific payment method
     * @param _paymentMethod The payment method hash
     * @param _currencies Array of currency code hashes (e.g., keccak256("USD"), keccak256("EUR"))
     */
    function addCurrencies(bytes32 _paymentMethod, bytes32[] calldata _currencies) public onlyOwner {
        require(store[_paymentMethod].initialized, "Payment method does not exist");
        require(_currencies.length > 0, "Invalid currencies length");
        
        for (uint256 i = 0; i < _currencies.length; i++) {
            _addCurrency(_paymentMethod, _currencies[i]);
        }
    }
    
    /**
     * Removes supported currencies for a specific payment method
     * @param _paymentMethod The payment method hash
     * @param _currencies Array of currency code hashes to remove
     */
    function removeCurrencies(bytes32 _paymentMethod, bytes32[] calldata _currencies) external onlyOwner {
        require(_currencies.length > 0, "Invalid currencies length");
        
        for (uint256 i = 0; i < _currencies.length; i++) {
            _removeCurrency(_paymentMethod, _currencies[i]);
        }
    }

    /* ============ External View Functions ============ */
    
    function isPaymentMethod(bytes32 _paymentMethod) external view returns (bool) {
        return store[_paymentMethod].initialized;
    }

    function getPaymentMethods() external view returns (bytes32[] memory) {
        return paymentMethods;
    }
    
    function getVerifier(bytes32 _paymentMethod) external view returns (address) {
        return store[_paymentMethod].verifier;
    }

    function isCurrency(bytes32 _paymentMethod, bytes32 _currencyCode) external view returns (bool) {
        return store[_paymentMethod].isCurrency[_currencyCode];
    }
    
    function getCurrencies(bytes32 _paymentMethod) external view returns (bytes32[] memory) {
        return store[_paymentMethod].currencies;
    }

    /* ============ Internal Functions ============ */

    function _addCurrency(bytes32 _paymentMethod, bytes32 _currencyCode) internal {
        require(_currencyCode != bytes32(0), "Invalid currency code");
        require(!store[_paymentMethod].isCurrency[_currencyCode], "Currency already exists");

        store[_paymentMethod].isCurrency[_currencyCode] = true;
        store[_paymentMethod].currencies.push(_currencyCode);
        emit CurrencyAdded(_paymentMethod, _currencyCode);
    }
    
    function _removeCurrency(bytes32 _paymentMethod, bytes32 _currencyCode) internal {
        require(store[_paymentMethod].isCurrency[_currencyCode], "Currency does not exist");

        store[_paymentMethod].isCurrency[_currencyCode] = false;
        store[_paymentMethod].currencies.removeStorage(_currencyCode);
        emit CurrencyRemoved(_paymentMethod, _currencyCode);
    }
} 
        

@openzeppelin/contracts/access/Ownable.sol

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

pragma solidity ^0.8.0;

import "../utils/Context.sol";

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

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

    /**
     * @dev Initializes the contract setting the deployer as the initial owner.
     */
    constructor() {
        _transferOwnership(_msgSender());
    }

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

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

    /**
     * @dev Throws if the sender is not the owner.
     */
    function _checkOwner() internal view virtual {
        require(owner() == _msgSender(), "Ownable: caller is not the owner");
    }

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

    /**
     * @dev Transfers ownership of the contract to a new account (`newOwner`).
     * Can only be called by the current owner.
     */
    function transferOwnership(address newOwner) public virtual onlyOwner {
        require(newOwner != address(0), "Ownable: new owner is the zero address");
        _transferOwnership(newOwner);
    }

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

@openzeppelin/contracts/utils/Context.sol

// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts v4.4.1 (utils/Context.sol)

pragma solidity ^0.8.0;

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

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

contracts/external/Bytes32ArrayUtils.sol

//SPDX-License-Identifier: MIT

pragma solidity ^0.8.17;

/**
 * @title Bytes32ArrayUtils
 * @author ZKP2P
 *
 * Fork of Set Protocol's AddressArrayUtils library adapted for usage with bytes32 arrays.
 */
library Bytes32ArrayUtils {

    uint256 constant internal MAX_INT = 2**256 - 1;

    /**
     * Finds the index of the first occurrence of the given element.
     * @param A The input array to search
     * @param a The value to find
     * @return Returns (index and isIn) for the first occurrence starting from index 0
     */
    function indexOf(bytes32[] memory A, bytes32 a) internal pure returns (uint256, bool) {
        uint256 length = A.length;
        for (uint256 i = 0; i < length; i++) {
            if (A[i] == a) {
                return (i, true);
            }
        }
        return (MAX_INT, false);
    }

    /**
    * Returns true if the value is present in the list. Uses indexOf internally.
    * @param A The input array to search
    * @param a The value to find
    * @return Returns isIn for the first occurrence starting from index 0
    */
    function contains(bytes32[] memory A, bytes32 a) internal pure returns (bool) {
        (, bool isIn) = indexOf(A, a);
        return isIn;
    }

    /**
    * Returns true if there are 2 elements that are the same in an array
    * @param A The input array to search
    * @return Returns boolean for the first occurrence of a duplicate
    */
    function hasDuplicate(bytes32[] memory A) internal pure returns(bool) {
        require(A.length > 0, "A is empty");

        for (uint256 i = 0; i < A.length - 1; i++) {
            bytes32 current = A[i];
            for (uint256 j = i + 1; j < A.length; j++) {
                if (current == A[j]) {
                    return true;
                }
            }
        }
        return false;
    }

    /**
     * @param A The input array to search
     * @param a The bytes32 to remove
     * @return Returns the array with the object removed.
     */
    function remove(bytes32[] memory A, bytes32 a)
        internal
        pure
        returns (bytes32[] memory)
    {
        (uint256 index, bool isIn) = indexOf(A, a);
        if (!isIn) {
            revert("bytes32 not in array.");
        } else {
            (bytes32[] memory _A,) = pop(A, index);
            return _A;
        }
    }

    /**
     * @param A The input array to search
     * @param a The bytes32 to remove
     */
    function removeStorage(bytes32[] storage A, bytes32 a)
        internal
    {
        (uint256 index, bool isIn) = indexOf(A, a);
        if (!isIn) {
            revert("bytes32 not in array.");
        } else {
            uint256 lastIndex = A.length - 1; // If the array would be empty, the previous line would throw, so no underflow here
            if (index != lastIndex) { A[index] = A[lastIndex]; }
            A.pop();
        }
    }

    /**
    * Removes specified index from array
    * @param A The input array to search
    * @param index The index to remove
    * @return Returns the new array and the removed entry
    */
    function pop(bytes32[] memory A, uint256 index)
        internal
        pure
        returns (bytes32[] memory, bytes32)
    {
        uint256 length = A.length;
        require(index < A.length, "Index must be < A length");
        bytes32[] memory newBytes = new bytes32[](length - 1);
        for (uint256 i = 0; i < index; i++) {
            newBytes[i] = A[i];
        }
        for (uint256 j = index + 1; j < length; j++) {
            newBytes[j - 1] = A[j];
        }
        return (newBytes, A[index]);
    }
}
          

contracts/interfaces/IPaymentVerifierRegistry.sol

//SPDX-License-Identifier: MIT

pragma solidity ^0.8.18;

interface IPaymentVerifierRegistry {
    function isPaymentMethod(bytes32 _paymentMethod) external view returns (bool);
    function getPaymentMethods() external view returns (bytes32[] memory);
    function getVerifier(bytes32 _paymentMethod) external view returns (address);
    function isCurrency(bytes32 _paymentMethod, bytes32 _currencyCode) external view returns (bool);
    function getCurrencies(bytes32 _paymentMethod) external view returns (bytes32[] memory);
}
          

Compiler Settings

{"viaIR":true,"outputSelection":{"*":{"*":["abi","evm.bytecode","evm.deployedBytecode","evm.methodIdentifiers","metadata","devdoc","userdoc","storageLayout","evm.gasEstimates"],"":["ast"]}},"optimizer":{"runs":200,"enabled":true},"metadata":{"useLiteralContent":true},"libraries":{}}
              

Contract ABI

[{"type":"constructor","stateMutability":"nonpayable","inputs":[]},{"type":"event","name":"CurrencyAdded","inputs":[{"type":"bytes32","name":"paymentMethod","internalType":"bytes32","indexed":true},{"type":"bytes32","name":"currencyCode","internalType":"bytes32","indexed":true}],"anonymous":false},{"type":"event","name":"CurrencyRemoved","inputs":[{"type":"bytes32","name":"paymentMethod","internalType":"bytes32","indexed":true},{"type":"bytes32","name":"currencyCode","internalType":"bytes32","indexed":true}],"anonymous":false},{"type":"event","name":"OwnershipTransferred","inputs":[{"type":"address","name":"previousOwner","internalType":"address","indexed":true},{"type":"address","name":"newOwner","internalType":"address","indexed":true}],"anonymous":false},{"type":"event","name":"PaymentMethodAdded","inputs":[{"type":"bytes32","name":"paymentMethod","internalType":"bytes32","indexed":true}],"anonymous":false},{"type":"event","name":"PaymentMethodRemoved","inputs":[{"type":"bytes32","name":"paymentMethod","internalType":"bytes32","indexed":true}],"anonymous":false},{"type":"function","stateMutability":"nonpayable","outputs":[],"name":"addCurrencies","inputs":[{"type":"bytes32","name":"_paymentMethod","internalType":"bytes32"},{"type":"bytes32[]","name":"_currencies","internalType":"bytes32[]"}]},{"type":"function","stateMutability":"nonpayable","outputs":[],"name":"addPaymentMethod","inputs":[{"type":"bytes32","name":"_paymentMethod","internalType":"bytes32"},{"type":"address","name":"_verifier","internalType":"address"},{"type":"bytes32[]","name":"_currencies","internalType":"bytes32[]"}]},{"type":"function","stateMutability":"view","outputs":[{"type":"bytes32[]","name":"","internalType":"bytes32[]"}],"name":"getCurrencies","inputs":[{"type":"bytes32","name":"_paymentMethod","internalType":"bytes32"}]},{"type":"function","stateMutability":"view","outputs":[{"type":"bytes32[]","name":"","internalType":"bytes32[]"}],"name":"getPaymentMethods","inputs":[]},{"type":"function","stateMutability":"view","outputs":[{"type":"address","name":"","internalType":"address"}],"name":"getVerifier","inputs":[{"type":"bytes32","name":"_paymentMethod","internalType":"bytes32"}]},{"type":"function","stateMutability":"view","outputs":[{"type":"bool","name":"","internalType":"bool"}],"name":"isCurrency","inputs":[{"type":"bytes32","name":"_paymentMethod","internalType":"bytes32"},{"type":"bytes32","name":"_currencyCode","internalType":"bytes32"}]},{"type":"function","stateMutability":"view","outputs":[{"type":"bool","name":"","internalType":"bool"}],"name":"isPaymentMethod","inputs":[{"type":"bytes32","name":"_paymentMethod","internalType":"bytes32"}]},{"type":"function","stateMutability":"view","outputs":[{"type":"address","name":"","internalType":"address"}],"name":"owner","inputs":[]},{"type":"function","stateMutability":"view","outputs":[{"type":"bytes32","name":"","internalType":"bytes32"}],"name":"paymentMethods","inputs":[{"type":"uint256","name":"","internalType":"uint256"}]},{"type":"function","stateMutability":"nonpayable","outputs":[],"name":"removeCurrencies","inputs":[{"type":"bytes32","name":"_paymentMethod","internalType":"bytes32"},{"type":"bytes32[]","name":"_currencies","internalType":"bytes32[]"}]},{"type":"function","stateMutability":"nonpayable","outputs":[],"name":"removePaymentMethod","inputs":[{"type":"bytes32","name":"_paymentMethod","internalType":"bytes32"}]},{"type":"function","stateMutability":"nonpayable","outputs":[],"name":"renounceOwnership","inputs":[]},{"type":"function","stateMutability":"view","outputs":[{"type":"bool","name":"initialized","internalType":"bool"},{"type":"address","name":"verifier","internalType":"address"}],"name":"store","inputs":[{"type":"bytes32","name":"","internalType":"bytes32"}]},{"type":"function","stateMutability":"nonpayable","outputs":[],"name":"transferOwnership","inputs":[{"type":"address","name":"newOwner","internalType":"address"}]}]
              

Contract Creation Code

0x6080806040523461005b5760008054336001600160a01b0319821681178355916001600160a01b03909116907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e09080a3610fa890816100618239f35b600080fdfe60406080815260048036101561001457600080fd5b600091823560e01c806312b1fe9314610953578063334c2ef31461071157806358aabeeb146106bc5780635e5658d21461067e578063654cf88c14610640578063715018a6146105e65780638b90cdc9146105aa5780638da5cb5b1461057e5780639072ec4e14610551578063a1627cd0146104d8578063a9ce20aa1461049f578063dbcb3005146101bd578063eeb7b248146101865763f2fde38b146100ba57600080fd5b34610182576020366003190112610182576001600160a01b0382358181169391929084900361017e576100eb610ba5565b831561012c57505082546001600160a01b0319811683178455167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e08380a380f35b906020608492519162461bcd60e51b8352820152602660248201527f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160448201526564647265737360d01b6064820152fd5b8480fd5b8280fd5b50903461018257602036600319011261018257358252600160209081529181902054905160089190911c6001600160a01b03168152f35b5090346101825760603660031901126101825780359160248035916001600160a01b0383169081840361049b5760449182359067ffffffffffffffff82116104975761020d839236908901610aad565b610218959195610ba5565b898b526001976020938985528c60ff9788912054166104565715610422578861029087878f8f610295968815159661024f88610bfd565b828452808c5284842080546001600160a81b03191660089390931b610100600160a81b031692909217179055610283610ba5565b81528d8952205416610c84565b610bfd565b8a5b81811061031b575050505050505060025492600160401b84101561030a5750506102ca8284926102e39401600255610b52565b90919082549060031b91821b91600019901b1916179055565b7fa8b7ef1cdeb8ecb963885f69266685a6c19778bdbe18fd82fb494d536ae5ede88280a280f35b634e487b7160e01b86526041905284fd5b610326818389610dac565b3580156103e95786868e8e81528c88528c8282200184825288522054166103ae57906103a9918c7fc8f017475bca3c28175d8dbac507c62a1cd9150a8da85f8b39e8947d4f5464408f8281528d89528d8a82200184825289528d8a82209060ff198254161790558281528d89526103a28460028c842001610c49565b80a3610d2f565b610297565b855162461bcd60e51b8152808c018690526017818b01527643757272656e637920616c72656164792065786973747360481b81860152606490fd5b855162461bcd60e51b8152808c018690526015818b015274496e76616c69642063757272656e637920636f646560581b81860152606490fd5b845162461bcd60e51b8152808b018590526010818a01526f24b73b30b634b2103b32b934b334b2b960811b81850152606490fd5b855162461bcd60e51b8152808c01869052601d818b01527f5061796d656e74206d6574686f6420616c72656164792065786973747300000081860152606490fd5b8880fd5b8680fd5b5090346101825781600319360112610182578160209360ff92358152600185526001828220016024358252855220541690519015158152f35b50823461054e578060031936011261054e57815191829160025480855260208095019460028352600080516020610f5383398151915292905b828210610537576105338686610529828b0383610d0d565b5191829182610b17565b0390f35b835487529586019560019384019390910190610511565b80fd5b509034610182576020366003190112610182578160209360ff923581526001855220541690519015158152f35b8382346105a657816003193601126105a657905490516001600160a01b039091168152602090f35b5080fd5b509034610182576020366003190112610182573560025481101561018257600260209352600080516020610f5383398151915201549051908152f35b833461054e578060031936011261054e576105ff610ba5565b80546001600160a01b03198116825581906001600160a01b03167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e08280a380f35b509034610182576020366003190112610182579181923581526001602052205481519060ff81161515825260018060a01b039060081c166020820152f35b5090346101825760203660031901126101825790610529600282610533956106b59535815260016020522001825193848092610cd0565b0383610d0d565b833461054e576106cb36610ae3565b6106d6929192610ba5565b6106e1811515610bfd565b835b8181106106ee578480f35b8061070761070061070c938588610dac565b3585610dbc565b610d2f565b6106e3565b5034610182576020908160031936011261094f57823593610730610ba5565b84815260019485845261074860ff8484205416610c84565b80825285845260028661076761076e8387872001875192838092610cd0565b0382610d0d565b84825b610923575b505050818352868552808484208481550180549084815581610900575b50508351815480825282855297839087830190600080516020610f5383398151915290875b8a8d82106108ea5750505050916107d4816107d9940382610d0d565b610d68565b90979061081b57845162461bcd60e51b81528088018790526015602482015274313cba32b99999103737ba1034b71030b93930bc9760591b6044820152606490fd5b8688600019928381019081116108d757808203610899575b505082549081156108865750019061085e61084d83610b52565b8154906000199060031b1b19169055565b557f0c831f94d9f98b9753b9607b5f1d9b1758d364178abe6e854ee65e97519c57648280a280f35b634e487b7160e01b865260319052602485fd5b6108d0916108a96108b292610b52565b92905491610b52565b91909260031b1c9082549060031b91821b91600019901b1916179055565b8580610833565b634e487b7160e01b875260118352602487fd5b83548552889550909301929181019181016107b8565b845287868520918201915b8281106109185750610793565b85815501889061090b565b815181101561094a578061070761093d6109449385610d54565b5187610dbc565b82610771565b610776565b8380fd5b5090346101825761096336610ae3565b91909261096e610ba5565b81865260019060209082825260ff9461098b86898b205416610c84565b610996811515610bfd565b885b8181106109a3578980f35b6109ae81838a610dac565b358015610a7257868b52858552858a8c2001818c528552878a8c205416610a35579081610a06610a309360028d8f8c81528b8b528b828220018482528b528181208c60ff198254161790558c81528b8b522001610c49565b877fc8f017475bca3c28175d8dbac507c62a1cd9150a8da85f8b39e8947d4f5464408d80a3610d2f565b610998565b895162461bcd60e51b8152808501869052601760248201527643757272656e637920616c72656164792065786973747360481b6044820152606490fd5b895162461bcd60e51b81528085018690526015602482015274496e76616c69642063757272656e637920636f646560581b6044820152606490fd5b9181601f84011215610ade5782359167ffffffffffffffff8311610ade576020808501948460051b010111610ade57565b600080fd5b906040600319830112610ade57600435916024359067ffffffffffffffff8211610ade57610b1391600401610aad565b9091565b6020908160408183019282815285518094520193019160005b828110610b3e575050505090565b835185529381019392810192600101610b30565b600254811015610b77576002600052600080516020610f538339815191520190600090565b634e487b7160e01b600052603260045260246000fd5b8054821015610b775760005260206000200190600090565b6000546001600160a01b03163303610bb957565b606460405162461bcd60e51b815260206004820152602060248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e65726044820152fd5b15610c0457565b60405162461bcd60e51b815260206004820152601960248201527f496e76616c69642063757272656e63696573206c656e677468000000000000006044820152606490fd5b90815491600160401b831015610c6e57826102ca916001610c6c95018155610b8d565b565b634e487b7160e01b600052604160045260246000fd5b15610c8b57565b60405162461bcd60e51b815260206004820152601d60248201527f5061796d656e74206d6574686f6420646f6573206e6f742065786973740000006044820152606490fd5b90815480825260208092019260005281600020916000905b828210610cf6575050505090565b835485529384019360019384019390910190610ce8565b90601f8019910116810190811067ffffffffffffffff821117610c6e57604052565b6000198114610d3e5760010190565b634e487b7160e01b600052601160045260246000fd5b8051821015610b775760209160051b010190565b9081519160005b838110610d83575050505060001990600090565b82610d8e8284610d54565b5114610da257610d9d90610d2f565b610d6f565b9250505090600190565b9190811015610b775760051b0190565b9060009082825260209260018452604092600184822001838252855260ff848220541615610f0e5781815260018552600184822001838252855283812060ff19815416905581815260018552600284822001610e228486516107d4816107678187610cd0565b610e6257855162461bcd60e51b8152600481018890526015602482015274313cba32b99999103737ba1034b71030b93930bc9760591b6044820152606490fd5b9193955080929450549060001991828101908111610efa57808203610ed8575b505081548015610ec4577f55afc4295737baf9bf7759d75fb64ad7bf91bf4c80c9a6a22b23d61a7924b4b59392910190610ebf61084d8383610b8d565b5580a3565b634e487b7160e01b84526031600452602484fd5b610ef391610ee96108b29286610b8d565b9290549186610b8d565b3880610e82565b634e487b7160e01b85526011600452602485fd5b835162461bcd60e51b815260048101869052601760248201527f43757272656e637920646f6573206e6f742065786973740000000000000000006044820152606490fdfe405787fa12a823e0f2b7631cc41b3ba8828b3321ca811111fa75cd3aa3bb5acea26469706673582212201c03713117a101562cd66986eee1a37132fbd3fbac3f787f597d0a9662d70c1f64736f6c63430008120033

Deployed ByteCode

0x60406080815260048036101561001457600080fd5b600091823560e01c806312b1fe9314610953578063334c2ef31461071157806358aabeeb146106bc5780635e5658d21461067e578063654cf88c14610640578063715018a6146105e65780638b90cdc9146105aa5780638da5cb5b1461057e5780639072ec4e14610551578063a1627cd0146104d8578063a9ce20aa1461049f578063dbcb3005146101bd578063eeb7b248146101865763f2fde38b146100ba57600080fd5b34610182576020366003190112610182576001600160a01b0382358181169391929084900361017e576100eb610ba5565b831561012c57505082546001600160a01b0319811683178455167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e08380a380f35b906020608492519162461bcd60e51b8352820152602660248201527f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160448201526564647265737360d01b6064820152fd5b8480fd5b8280fd5b50903461018257602036600319011261018257358252600160209081529181902054905160089190911c6001600160a01b03168152f35b5090346101825760603660031901126101825780359160248035916001600160a01b0383169081840361049b5760449182359067ffffffffffffffff82116104975761020d839236908901610aad565b610218959195610ba5565b898b526001976020938985528c60ff9788912054166104565715610422578861029087878f8f610295968815159661024f88610bfd565b828452808c5284842080546001600160a81b03191660089390931b610100600160a81b031692909217179055610283610ba5565b81528d8952205416610c84565b610bfd565b8a5b81811061031b575050505050505060025492600160401b84101561030a5750506102ca8284926102e39401600255610b52565b90919082549060031b91821b91600019901b1916179055565b7fa8b7ef1cdeb8ecb963885f69266685a6c19778bdbe18fd82fb494d536ae5ede88280a280f35b634e487b7160e01b86526041905284fd5b610326818389610dac565b3580156103e95786868e8e81528c88528c8282200184825288522054166103ae57906103a9918c7fc8f017475bca3c28175d8dbac507c62a1cd9150a8da85f8b39e8947d4f5464408f8281528d89528d8a82200184825289528d8a82209060ff198254161790558281528d89526103a28460028c842001610c49565b80a3610d2f565b610297565b855162461bcd60e51b8152808c018690526017818b01527643757272656e637920616c72656164792065786973747360481b81860152606490fd5b855162461bcd60e51b8152808c018690526015818b015274496e76616c69642063757272656e637920636f646560581b81860152606490fd5b845162461bcd60e51b8152808b018590526010818a01526f24b73b30b634b2103b32b934b334b2b960811b81850152606490fd5b855162461bcd60e51b8152808c01869052601d818b01527f5061796d656e74206d6574686f6420616c72656164792065786973747300000081860152606490fd5b8880fd5b8680fd5b5090346101825781600319360112610182578160209360ff92358152600185526001828220016024358252855220541690519015158152f35b50823461054e578060031936011261054e57815191829160025480855260208095019460028352600080516020610f5383398151915292905b828210610537576105338686610529828b0383610d0d565b5191829182610b17565b0390f35b835487529586019560019384019390910190610511565b80fd5b509034610182576020366003190112610182578160209360ff923581526001855220541690519015158152f35b8382346105a657816003193601126105a657905490516001600160a01b039091168152602090f35b5080fd5b509034610182576020366003190112610182573560025481101561018257600260209352600080516020610f5383398151915201549051908152f35b833461054e578060031936011261054e576105ff610ba5565b80546001600160a01b03198116825581906001600160a01b03167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e08280a380f35b509034610182576020366003190112610182579181923581526001602052205481519060ff81161515825260018060a01b039060081c166020820152f35b5090346101825760203660031901126101825790610529600282610533956106b59535815260016020522001825193848092610cd0565b0383610d0d565b833461054e576106cb36610ae3565b6106d6929192610ba5565b6106e1811515610bfd565b835b8181106106ee578480f35b8061070761070061070c938588610dac565b3585610dbc565b610d2f565b6106e3565b5034610182576020908160031936011261094f57823593610730610ba5565b84815260019485845261074860ff8484205416610c84565b80825285845260028661076761076e8387872001875192838092610cd0565b0382610d0d565b84825b610923575b505050818352868552808484208481550180549084815581610900575b50508351815480825282855297839087830190600080516020610f5383398151915290875b8a8d82106108ea5750505050916107d4816107d9940382610d0d565b610d68565b90979061081b57845162461bcd60e51b81528088018790526015602482015274313cba32b99999103737ba1034b71030b93930bc9760591b6044820152606490fd5b8688600019928381019081116108d757808203610899575b505082549081156108865750019061085e61084d83610b52565b8154906000199060031b1b19169055565b557f0c831f94d9f98b9753b9607b5f1d9b1758d364178abe6e854ee65e97519c57648280a280f35b634e487b7160e01b865260319052602485fd5b6108d0916108a96108b292610b52565b92905491610b52565b91909260031b1c9082549060031b91821b91600019901b1916179055565b8580610833565b634e487b7160e01b875260118352602487fd5b83548552889550909301929181019181016107b8565b845287868520918201915b8281106109185750610793565b85815501889061090b565b815181101561094a578061070761093d6109449385610d54565b5187610dbc565b82610771565b610776565b8380fd5b5090346101825761096336610ae3565b91909261096e610ba5565b81865260019060209082825260ff9461098b86898b205416610c84565b610996811515610bfd565b885b8181106109a3578980f35b6109ae81838a610dac565b358015610a7257868b52858552858a8c2001818c528552878a8c205416610a35579081610a06610a309360028d8f8c81528b8b528b828220018482528b528181208c60ff198254161790558c81528b8b522001610c49565b877fc8f017475bca3c28175d8dbac507c62a1cd9150a8da85f8b39e8947d4f5464408d80a3610d2f565b610998565b895162461bcd60e51b8152808501869052601760248201527643757272656e637920616c72656164792065786973747360481b6044820152606490fd5b895162461bcd60e51b81528085018690526015602482015274496e76616c69642063757272656e637920636f646560581b6044820152606490fd5b9181601f84011215610ade5782359167ffffffffffffffff8311610ade576020808501948460051b010111610ade57565b600080fd5b906040600319830112610ade57600435916024359067ffffffffffffffff8211610ade57610b1391600401610aad565b9091565b6020908160408183019282815285518094520193019160005b828110610b3e575050505090565b835185529381019392810192600101610b30565b600254811015610b77576002600052600080516020610f538339815191520190600090565b634e487b7160e01b600052603260045260246000fd5b8054821015610b775760005260206000200190600090565b6000546001600160a01b03163303610bb957565b606460405162461bcd60e51b815260206004820152602060248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e65726044820152fd5b15610c0457565b60405162461bcd60e51b815260206004820152601960248201527f496e76616c69642063757272656e63696573206c656e677468000000000000006044820152606490fd5b90815491600160401b831015610c6e57826102ca916001610c6c95018155610b8d565b565b634e487b7160e01b600052604160045260246000fd5b15610c8b57565b60405162461bcd60e51b815260206004820152601d60248201527f5061796d656e74206d6574686f6420646f6573206e6f742065786973740000006044820152606490fd5b90815480825260208092019260005281600020916000905b828210610cf6575050505090565b835485529384019360019384019390910190610ce8565b90601f8019910116810190811067ffffffffffffffff821117610c6e57604052565b6000198114610d3e5760010190565b634e487b7160e01b600052601160045260246000fd5b8051821015610b775760209160051b010190565b9081519160005b838110610d83575050505060001990600090565b82610d8e8284610d54565b5114610da257610d9d90610d2f565b610d6f565b9250505090600190565b9190811015610b775760051b0190565b9060009082825260209260018452604092600184822001838252855260ff848220541615610f0e5781815260018552600184822001838252855283812060ff19815416905581815260018552600284822001610e228486516107d4816107678187610cd0565b610e6257855162461bcd60e51b8152600481018890526015602482015274313cba32b99999103737ba1034b71030b93930bc9760591b6044820152606490fd5b9193955080929450549060001991828101908111610efa57808203610ed8575b505081548015610ec4577f55afc4295737baf9bf7759d75fb64ad7bf91bf4c80c9a6a22b23d61a7924b4b59392910190610ebf61084d8383610b8d565b5580a3565b634e487b7160e01b84526031600452602484fd5b610ef391610ee96108b29286610b8d565b9290549186610b8d565b3880610e82565b634e487b7160e01b85526011600452602485fd5b835162461bcd60e51b815260048101869052601760248201527f43757272656e637920646f6573206e6f742065786973740000000000000000006044820152606490fdfe405787fa12a823e0f2b7631cc41b3ba8828b3321ca811111fa75cd3aa3bb5acea26469706673582212201c03713117a101562cd66986eee1a37132fbd3fbac3f787f597d0a9662d70c1f64736f6c63430008120033