ETH Price: $3,918.47 (+5.08%)

Contract

0xc662a8Ce36392d4B9489D0B59605a1874711BFc6
 

Overview

ETH Balance

0 ETH

Eth Value

$0.00

Token Holdings

Multichain Info

No addresses found
Transaction Hash
Method
Block
From
To
Change Name188875192023-12-28 23:56:59342 days ago1703807819IN
NFTR: NFTRegistry
0 ETH0.0073301339.33068727
Change Name187151992023-12-04 19:50:59366 days ago1701719459IN
NFTR: NFTRegistry
0.01 ETH0.009095950
Change Name187149132023-12-04 18:53:35366 days ago1701716015IN
NFTR: NFTRegistry
0.01 ETH0.0104559657
Change Name187141312023-12-04 16:16:23366 days ago1701706583IN
NFTR: NFTRegistry
0 ETH0.0110518560.94277552
Change Name186152302023-11-20 19:58:11380 days ago1700510291IN
NFTR: NFTRegistry
0 ETH0.0058380930.57124278
Assign Naming Cr...186152162023-11-20 19:55:23380 days ago1700510123IN
NFTR: NFTRegistry
0 ETH0.0025954731.91756947
Change Name183898402023-10-20 6:46:11412 days ago1697784371IN
NFTR: NFTRegistry
0.01 ETH0.001191716.80983879
Allow Transfer183263992023-10-11 9:47:11421 days ago1697017631IN
NFTR: NFTRegistry
0 ETH0.000389236.89728148
Allow Transfer183263912023-10-11 9:45:35421 days ago1697017535IN
NFTR: NFTRegistry
0 ETH0.000375866.6603671
Allow Transfer183263802023-10-11 9:43:23421 days ago1697017403IN
NFTR: NFTRegistry
0 ETH0.000372586.60228257
Allow Transfer183263452023-10-11 9:36:23421 days ago1697016983IN
NFTR: NFTRegistry
0 ETH0.000404397.16585906
Allow Transfer183263372023-10-11 9:34:47421 days ago1697016887IN
NFTR: NFTRegistry
0 ETH0.000534859.47769342
Allow Transfer183260652023-10-11 8:39:23421 days ago1697013563IN
NFTR: NFTRegistry
0 ETH0.000368216.52479441
Allow Transfer183024802023-10-08 1:26:35424 days ago1696728395IN
NFTR: NFTRegistry
0 ETH0.000281175.14641185
Change Name182806052023-10-05 0:02:35427 days ago1696464155IN
NFTR: NFTRegistry
0.01 ETH0.00152439.04252397
Change Name182793882023-10-04 19:57:35427 days ago1696449455IN
NFTR: NFTRegistry
0.01 ETH0.0019753611.34465023
Change Name182633062023-10-02 14:00:11429 days ago1696255211IN
NFTR: NFTRegistry
0.01 ETH0.0031326517.99106586
Change Name182593592023-10-02 0:47:23430 days ago1696207643IN
NFTR: NFTRegistry
0.01 ETH0.001016596.5964739
Allow Transfer182593432023-10-02 0:44:11430 days ago1696207451IN
NFTR: NFTRegistry
0 ETH0.000364286.66210454
Change Name182445762023-09-29 23:14:11432 days ago1696029251IN
NFTR: NFTRegistry
0 ETH0.001044966.45700666
Allow Transfer182436772023-09-29 20:13:11432 days ago1696018391IN
NFTR: NFTRegistry
0 ETH0.0005507710.15576881
Change Name182435722023-09-29 19:51:35432 days ago1696017095IN
NFTR: NFTRegistry
0.01 ETH0.001292417.34192868
Change Name182435512023-09-29 19:47:23432 days ago1696016843IN
NFTR: NFTRegistry
0.01 ETH0.001714618.87796939
Allow Transfer182435122023-09-29 19:39:23432 days ago1696016363IN
NFTR: NFTRegistry
0 ETH0.000405627.47938734
Change Name182073152023-09-24 18:02:35437 days ago1695578555IN
NFTR: NFTRegistry
0.01 ETH0.001596769.50054212
View all transactions

Latest 25 internal transactions (View All)

Advanced mode:
Parent Transaction Hash Block From To
188221432023-12-19 19:42:35351 days ago1703014955
NFTR: NFTRegistry
0.01 ETH
188221432023-12-19 19:42:35351 days ago1703014955
NFTR: NFTRegistry
0.01 ETH
187151992023-12-04 19:50:59366 days ago1701719459
NFTR: NFTRegistry
0.01 ETH
187149132023-12-04 18:53:35366 days ago1701716015
NFTR: NFTRegistry
0.01 ETH
183898402023-10-20 6:46:11412 days ago1697784371
NFTR: NFTRegistry
0.01 ETH
182806052023-10-05 0:02:35427 days ago1696464155
NFTR: NFTRegistry
0.01 ETH
182793882023-10-04 19:57:35427 days ago1696449455
NFTR: NFTRegistry
0.01 ETH
182633062023-10-02 14:00:11429 days ago1696255211
NFTR: NFTRegistry
0.01 ETH
182593592023-10-02 0:47:23430 days ago1696207643
NFTR: NFTRegistry
0.01 ETH
182435722023-09-29 19:51:35432 days ago1696017095
NFTR: NFTRegistry
0.01 ETH
182435512023-09-29 19:47:23432 days ago1696016843
NFTR: NFTRegistry
0.01 ETH
182073152023-09-24 18:02:35437 days ago1695578555
NFTR: NFTRegistry
0.01 ETH
182072992023-09-24 17:59:23437 days ago1695578363
NFTR: NFTRegistry
0.01 ETH
182018012023-09-23 23:29:59438 days ago1695511799
NFTR: NFTRegistry
0.01 ETH
182017452023-09-23 23:18:47438 days ago1695511127
NFTR: NFTRegistry
0.01 ETH
182017362023-09-23 23:16:59438 days ago1695511019
NFTR: NFTRegistry
0.01 ETH
182016992023-09-23 23:09:35438 days ago1695510575
NFTR: NFTRegistry
0.01 ETH
182013732023-09-23 22:03:47438 days ago1695506627
NFTR: NFTRegistry
0.01 ETH
180443032023-09-01 21:13:11460 days ago1693602791
NFTR: NFTRegistry
0.01 ETH
180188902023-08-29 7:48:11464 days ago1693295291
NFTR: NFTRegistry
0.01 ETH
180188852023-08-29 7:47:11464 days ago1693295231
NFTR: NFTRegistry
0.01 ETH
180188592023-08-29 7:41:59464 days ago1693294919
NFTR: NFTRegistry
0.01 ETH
179967182023-08-26 5:19:11467 days ago1693027151
NFTR: NFTRegistry
0.01 ETH
179901462023-08-25 7:13:47468 days ago1692947627
NFTR: NFTRegistry
0.01 ETH
179630702023-08-21 12:20:35471 days ago1692620435
NFTR: NFTRegistry
0.01 ETH
View All Internal Transactions
Loading...
Loading

Contract Source Code Verified (Exact Match)

Contract Name:
NFTRegistry

Compiler Version
v0.8.4+commit.c7e474f2

Optimization Enabled:
Yes with 200 runs

Other Settings:
default evmVersion, MIT license
File 1 of 13 : NFTRegistry.sol
pragma solidity >=0.8.0 <0.9.0;
//SPDX-License-Identifier: MIT

import "./Ownable.sol";
import "./IERC20.sol";
import "./IPunks.sol";
import "./IERC721.sol"; 
import "./ReentrancyGuard.sol";
import "./INamingCredits.sol";
import "./IWETH.sol";
import "./INFTRegistry.sol";
import "./IHoldFarming.sol";
import "./IRNM.sol"; 

/**
 * @title NFTRegistry
 * @notice NFTR's main contract. The registry. Where the magic happens.
 */
contract NFTRegistry is ReentrancyGuard, Ownable {

    // Structs
    struct Token {
        address collectionAddress;
        uint256 tokenId;
    }

    // Enums
    enum NamingCurrency {
        Ether,
        RNM,
        NamingCredits
    }
 
    enum NamingState {
        NotReadyYet,
        ReadyForNaming
    }

    NamingState public namingState = NamingState.NotReadyYet;

    // Naming prices, fee recipients, and control parameters
    uint256 public namingPriceEther = 0.05 ether;
    uint256 public immutable MIN_NAMING_PRICE_ETHER;
    uint256 public immutable MIN_NAMING_PRICE_RNM;
    uint256 public namingPriceRNM = 1000 * 10**18;
    address public protocolFeeRecipient;
    uint256 public constant INFINITE_BLOCK = 100000000000;
    uint256 public rnmNamingStartBlock = INFINITE_BLOCK;
    uint256 public constant MAX_NUMBER_CURATED_COLLECTIONS = 10;
    uint256 public numberCuratedCollections;
    uint256 public constant MAX_ASSIGNABLE_NAMING_CREDITS = 10;
    uint256 public constant MAX_TOTAL_ASSIGNABLE_NAMING_CREDITS = 1000;
    uint256 public totalNumberAssignedCredits;
    bool public allowUpdatingFeeRecipient = true;

    // Golden Tickets & Special Names
    uint256 public constant MAX_SPECIAL_NAMES_COUNT = 1000;
    uint256 public numberSpecialNames = 0;
    IERC20 public immutable goldenTicketAddress;
    mapping(string => bool) public specialNames; // List of special (reserved) names. Stored in lowercase.

    // Relevant contract addresses
    IPunks public immutable punksAddress;
    address public immutable WETH;
    IRNM public rnmToken;
    INamingCredits public namingCreditsAddress;
    IHoldFarming public holdFarmingAddress;
    address public marketplaceAddress;

    // Marketplace transfer allowance
    mapping(address => mapping(address => mapping(uint256 => bool)))
        public allowances;

    // Name mappings
    mapping(address => mapping(uint256 => string)) public tokenName;
    mapping(string => Token) public tokenByName; // Stored in lowercase
    mapping(address => mapping(uint256 => uint256)) public firstNamed;

    // Events
    event NameChange(
        address indexed nftAddress,
        uint256 indexed tokenId,
        string newName,
        address sender,
        NamingCurrency namingCurrency,
        uint256 currencyQuantity
    );
    event NewProtocolFeeRecipient(address indexed protocolFeeRecipient);
    event NewNamingPriceEther(uint256 namingPriceEther);
    event NewNamingPriceRNM(uint256 namingPriceRNM);
    event NewRnmNamingStartBlock(uint256 rnmNamingStartBlock);
    event TransferAllowed(
        address indexed owner,
        address indexed nftAddress,
        uint256 tokenId
    );
    event TransferDisAllowed(
        address indexed owner,
        address indexed nftAddress,
        uint256 tokenId
    );
    event NameTransfer(
        address indexed nftAddressFrom,
        uint256 tokenIdFrom,
        address indexed nftAddressTo,
        uint256 tokenIdTo,
        string name,
        address transferer
    );

    /**
     * @notice Constructor
     * @param _punksAddress address of the CryptoPunks contract. Input to constructor for testing purposes
     * @param _goldenTicketAddress address of Golden Ticket contract
     * @param _WETH address of the WETH contract. Input to constructor for testing purposes
     * @param _protocolFeeRecipient protocol fee recipient
     * @param _minNamingPriceEther min naming price that can be set (in Ether)
     * @param _minNamingPriceRNM minimum naming price that can be set (in RNM)
     */
    constructor(
        address _punksAddress,
        address _goldenTicketAddress,
        address _WETH,
        address _protocolFeeRecipient,
        uint256 _minNamingPriceEther,
        uint256 _minNamingPriceRNM
    ) {
        require(_punksAddress != address(0), "NFTRegistry: In constructor, can't set punksAddress to zero");
        require(_goldenTicketAddress != address(0), "NFTRegistry: In constructor, can't set goldenTicketAddress to zero");
        require(_WETH != address(0), "NFTRegistry: In constructor, can't set WETH address to zero");
        require(_protocolFeeRecipient != address(0), "NFTRegistry: In constructor, can't set protocolFeeRecipient to zero");
        require(_minNamingPriceEther > 0, "NFTRegistry: min naming price in Ether must be non-zero");
        require(_minNamingPriceRNM > 0, "NFTRegistry: min naming price in RNM must be non-zero");
        punksAddress = IPunks(_punksAddress);
        goldenTicketAddress = IERC20(_goldenTicketAddress);
        WETH = address(_WETH);
        protocolFeeRecipient = _protocolFeeRecipient;
        MIN_NAMING_PRICE_ETHER = _minNamingPriceEther;
        MIN_NAMING_PRICE_RNM = _minNamingPriceRNM;
    }

    /**
     * @notice Set the RNM address (only once)
     * @param _rnmToken address of the RNM token
     */
    function setRnmTokenAddress(IRNM _rnmToken) external onlyOwner {
        require(
            address(rnmToken) == address(0),
            "NFTRegistry: RNM address has already been set"
        );
        rnmToken = _rnmToken;
    }

    /**
     * @notice Set the Naming Credits contract address once deployed
     * @param _namingCreditsAddress address of the marketplace contract
     */
    function setNamingCreditsAddress(INamingCredits _namingCreditsAddress)
        external
        onlyOwner
    {
        require(
            address(namingCreditsAddress) == address(0),
            "NFTRegistry: naming credits contract address can only be set once"
        );
        namingCreditsAddress = _namingCreditsAddress;
    }

    /**
     * @notice Set the Hold Farming contract address once deployed
     * @param _holdFarmingAddress address of the marketplace contract
     */
    function setHoldFarmingAddress(IHoldFarming _holdFarmingAddress)
        external
        onlyOwner
    {
        require(
            address(holdFarmingAddress) == address(0),
            "NFTRegistry: hold farming contract address can only be set once"
        );
        holdFarmingAddress = _holdFarmingAddress;
    }

    /**
     * @notice Set the Marketplace contract address once deployed
     * @param _marketplaceAddress address of the marketplace contract
     */
    function setMarketplaceAddress(address _marketplaceAddress)
        external
        onlyOwner
    {
        require(
            marketplaceAddress == address(0),
            "NFTRegistry: marketplace contract address can only be set once"
        );
        marketplaceAddress = _marketplaceAddress;
    }

    /**
     * @notice Give the marketplace contract permission to transfer name (for a name sale) for a particular NFT. Care is taken so that if the NFT changes owners, the allowance doesn't hold.
     * @param nftAddress address of the NFT Collection from which name is being transferred
     * @param tokenId token id of the NFT from which the name is being transferred
     */
    function allowTransfer(address nftAddress, uint256 tokenId) external {
        require(
            marketplaceAddress != address(0),
            "NFTRegistry: Marketplace address hasn't been set yet"
        );
        checkOwnership(nftAddress, tokenId); // allowance setter must be the NFT owner

        allowances[msg.sender][nftAddress][tokenId] = true;

        emit TransferAllowed(msg.sender, nftAddress, tokenId);
    }

    /**
     * @notice Disallow marketplace contract to transfer name for a particular NFT
     * @param nftAddress address of the NFT Collection from which name is being transferred
     * @param tokenId token id of the NFT from which the name is being transferred
     */
    function disallowTransfer(address nftAddress, uint256 tokenId) external {
        require(
            marketplaceAddress != address(0),
            "NFTRegistry: Marketplace address hasn't been set yet"
        );
        checkOwnership(nftAddress, tokenId);

        allowances[msg.sender][nftAddress][tokenId] = false;

        emit TransferDisAllowed(msg.sender, nftAddress, tokenId);
    }

    /**
     * @notice Used by the marketplace contract to transfer a name from one NFT to another. Transfer allowance isn't reset, so if the NFT is named again it doesn't have to be allowed again to transfer its name, as long as it's still owned by the same allower. Transfer allowance is per owner, so doesn't travel with the NFT.
     * @param nftAddressFrom address of the NFT Collection from which name is being transferred
     * @param tokenIdFrom token id of the NFT from which the name is being transferred
     * @param nftAddressTo address of the NFT Collection to which name is being transferred
     * @param tokenIdTo token id of the NFT to which the name is being transferred
     */
    function transferName(
        address nftAddressFrom,
        uint256 tokenIdFrom,
        address nftAddressTo,
        uint256 tokenIdTo
    ) external {
        require(
            marketplaceAddress != address(0),
            "NFTRegistry: Marketplace address hasn't been set yet"
        );
        require(
            msg.sender == marketplaceAddress,
            "NFTRegistry: Only the Marketplace contract can make this call"
        );

        // Obtain current NFT owner
        address nftOwner = getOwner(nftAddressFrom, tokenIdFrom);

        // Check that name can be transferred
        require(
            allowances[nftOwner][nftAddressFrom][tokenIdFrom],
            "NFTRegistry: NFT hasn't been allowed for name transfer"
        );

        // Check that token mapping is set
        string memory _tokenName = tokenName[nftAddressFrom][tokenIdFrom];
        require(
            bytes(_tokenName).length > 0,
            "NFTRegistry: Can't transfer name as it isn't set"
        );
        // Transfer name
        tokenName[nftAddressFrom][tokenIdFrom] = "";
        tokenName[nftAddressTo][tokenIdTo] = _tokenName;
        tokenByName[toLower(_tokenName)] = Token(nftAddressTo, tokenIdTo);

        emit NameTransfer(
            nftAddressFrom,
            tokenIdFrom,
            nftAddressTo,
            tokenIdTo,
            _tokenName,
            nftOwner
        );
    }

    /**
     * @notice Update the naming price in ETH
     * @param _namingPriceEther naming price in Ether
     */
    function updateNamingPriceEther(uint256 _namingPriceEther)
        external
        onlyOwner
    {
        require(
            _namingPriceEther >= MIN_NAMING_PRICE_ETHER,
            "NFTRegistry: ETHER naming price too low"
        );
        namingPriceEther = _namingPriceEther;

        emit NewNamingPriceEther(namingPriceEther);
    }

    /**
     * @notice Update the naming price in RNM
     * @param _namingPriceRNM naming price in RNM
     */
    function updateNamingPriceRNM(uint256 _namingPriceRNM) external onlyOwner {
        require(
            _namingPriceRNM >= MIN_NAMING_PRICE_RNM,
            "NFTRegistry: RNM naming price too low"
        );
        namingPriceRNM = _namingPriceRNM;

        emit NewNamingPriceRNM(namingPriceRNM);
    }

    /**
     * @notice Update the recipient of protocol (naming) fees in WETH
     * @param _protocolFeeRecipient protocol fee recipient
     */
    function updateProtocolFeeRecipient(address _protocolFeeRecipient)
        external
        onlyOwner
    {
        require(allowUpdatingFeeRecipient, "NFTRegistry: Updating the protocol fee recipient has been shut off");
        protocolFeeRecipient = _protocolFeeRecipient;

        emit NewProtocolFeeRecipient(protocolFeeRecipient);
    }

    /**
     * @notice Update starting block for RNM naming
     * @param _rnmNamingStartBlock starting block of RNM naming
     */
    function updateRnmNamingStartBlock(uint256 _rnmNamingStartBlock)
        external
        onlyOwner
    {
        require(
            rnmNamingStartBlock == INFINITE_BLOCK,
            "NFTRegistry: rnmNamingStartBlock can only be set once"
        );
        require(
            _rnmNamingStartBlock > block.number,
            "NFTRegistry: RNM naming start block can't be set to past"
        );
        require(
            _rnmNamingStartBlock < block.number + 192000, // + 1 month
            "NFTRegistry: RNM naming start block can't be set so far in advance"
        );
        rnmNamingStartBlock = _rnmNamingStartBlock;

        emit NewRnmNamingStartBlock(rnmNamingStartBlock);
    }

    /**
     * @notice Returns name of the NFT at (address, index).
     * @param nftAddress Address of NFT collection
     * @param index token index of NFT within collection
     */
    function tokenNameByIndex(address nftAddress, uint256 index)
        external
        view
        returns (string memory)
    {
        return tokenName[nftAddress][index];
    }

    /**
     * @notice Sets/Changes the name of an NFT
     * @param nftAddress address of the NFT collection
     * @param tokenId NFT token id
     * @param newName name to register for the NFT with tokenId
     * @param namingCurrency currency used for naming fee
     * @param currencyQuantity quantity of naming currency to spend. This disables the contract owner from being able to front-run naming to extract unintended quantiy of assets (WETH or RNM)
     */
    function changeName(
        address nftAddress,
        uint256 tokenId,
        string memory newName,
        NamingCurrency namingCurrency,
        uint256 currencyQuantity
    ) external payable nonReentrant {
        require(
            namingState == NamingState.ReadyForNaming,
            "NFTRegistry: Not ready for naming yet"
        );
        checkOwnership(nftAddress, tokenId);
        require(
            validateName(newName),
            "NFTRegistry: Not a valid new name"
        );
        require(
            sha256(bytes(newName)) !=
                sha256(bytes(tokenName[nftAddress][tokenId])),
            "NFTRegistry: New name is same as the current one"
        );
        require(
            isTokenStructEmpty(tokenByName[toLower(newName)]),
            "NFTRegistry: Name already reserved"
        );
        if (namingCurrency == NamingCurrency.NamingCredits) {
            require(currencyQuantity == 1, "NFTRegistry: currencyQuantity must be 1 when naming with Naming Credits");
        }
        else if (namingCurrency == NamingCurrency.RNM) {
            require(currencyQuantity == namingPriceRNM, "NFTRegistry: currencyQuantity must be equal to namingPriceRNM when naming with RNM");            
        }
        else { // namingCurrency is Ether
            require(currencyQuantity == namingPriceEther, "NFTRegistry: currencyQuantity must be equal to namingPriceEther when naming with Ether");               
        }

        // Check if the name is from the special list and thus golden ticket is required and available
        if (specialNames[toLower(newName)]) {
            IERC20(goldenTicketAddress).transferFrom(
                msg.sender,
                address(this),
                1
            );
        }

        if (
            namingCurrency == NamingCurrency.RNM &&
            block.number < rnmNamingStartBlock
        ) {
            revert("NFTRegistry: Not ready for naming paid with RNM");
        }

        bool freeNaming = false;
        if (address(holdFarmingAddress) != address(0) && firstNamed[nftAddress][tokenId] == 0) {
            // Check if the NFT being named is curated and is still in hold farming period
            (uint256 startBlock, uint256 lastBlock) = 
                holdFarmingAddress.holdFarmingBlocks(nftAddress);
            if (block.number >= startBlock && block.number <= lastBlock) {
                // Hold farming is still enabled for this collection. Allow free naming.
                holdFarmingAddress.initiateHoldFarmingForNFT(
                    nftAddress,
                    tokenId
                );

                freeNaming = true;
            }
        }

        if (!freeNaming) {
            if (namingCurrency == NamingCurrency.Ether) {
                // If not enough ETH to cover the price, use WETH
                if (namingPriceEther > msg.value) {
                    require(
                        IERC20(WETH).balanceOf(msg.sender) >=
                            (namingPriceEther - msg.value),
                        "NFTRegistry: Not enough ETH sent or WETH available"
                    );
                    IERC20(WETH).transferFrom(
                        msg.sender,
                        address(this),
                        (namingPriceEther - msg.value)
                    );
                } else {
                    require(
                        namingPriceEther == msg.value,
                        "NFTRegistry: Too much Ether sent for naming"
                    );
                }

                // Wrap ETH sent to this contract 
                IWETH(WETH).deposit{value: msg.value}();
                IERC20(WETH).transfer(
                    protocolFeeRecipient,
                    namingPriceEther
                );
            } else if (namingCurrency == NamingCurrency.NamingCredits) {
                require(
                    address(namingCreditsAddress) != address(0),
                    "NFTRegistry: Naming Credits contract isn't set yet"
                );
                namingCreditsAddress.reduceNamingCredits(
                    msg.sender,
                    1
                );
            } else if (namingCurrency == NamingCurrency.RNM) {
                require(
                    address(rnmToken) != address(0),
                    "NFTRegistry: RNM contract isn't set yet"
                );
                IERC20(rnmToken).transferFrom(
                    msg.sender,
                    address(this),
                    namingPriceRNM
                );
                IRNM(rnmToken).burn(namingPriceRNM);
            } else {
                revert("NFTRegistry: The currency isn't supported for naming");
            }   
        }

        // If already named, dereserve old name
        if (bytes(tokenName[nftAddress][tokenId]).length > 0) {
            releaseTokenByName(tokenName[nftAddress][tokenId]);
        }
        tokenByName[toLower(newName)] = Token(nftAddress, tokenId);
        tokenName[nftAddress][tokenId] = newName;

        if (firstNamed[nftAddress][tokenId] == 0) {
            firstNamed[nftAddress][tokenId] = block.number;
        }
        emit NameChange(
            nftAddress,
            tokenId,
            newName,
            msg.sender,
            namingCurrency,
            currencyQuantity
        );
    }

    /**
     * @notice Check if the message sender owns the NFT
     * @param nftAddress address of the NFT collection
     * @param tokenId token id of the NFT
     */
    function checkOwnership(address nftAddress, uint256 tokenId) internal view {
        require(msg.sender == getOwner(nftAddress, tokenId), "NFTRegistry: Caller is not the NFT owner");
    }

    /**
     * @notice Get NFT's owner
     * @param nftAddress address of the NFT collection
     * @param tokenId token id of the NFT
     */
    function getOwner(address nftAddress, uint256 tokenId)
        internal
        view
        returns (address)
    {
        if (nftAddress == address(punksAddress)) {
            return IPunks(punksAddress).punkIndexToAddress(tokenId);
        } else {
            return IERC721(nftAddress).ownerOf(tokenId);
        }
    }

    /**
     * @notice Check if a Token structure is empty
     * @param token_in token to check
     */
    function isTokenStructEmpty(Token memory token_in)
        internal
        pure
        returns (bool)
    {
        return (token_in.collectionAddress == address(0) && token_in.tokenId == 0);
    }

    /**
     * @notice Returns NFT collection contract address and tokenId in Token struct if the name is reserved
     * @param nameString name of the NFT
     */
    function getTokenByName(string memory nameString)
        external
        view
        returns (Token memory)
    {
        return tokenByName[toLower(nameString)];
    }

    /**
     * @notice Releases the name so another person can register it
     * @param str name to deregister
     */
    function releaseTokenByName(string memory str) internal {
        delete tokenByName[toLower(str)];
    }

    /**
     * @notice Check if the name string is valid (Alphanumeric and spaces without leading or trailing space)
     * @param str name to validate
     */
    function validateName(string memory str) public pure returns (bool) {
        bytes memory b = bytes(str);
        if (b.length < 1) return false;
        if (b.length > 25) return false; // Cannot be longer than 25 characters
        if (b[0] == 0x20) return false; // Leading space
        if (b[b.length - 1] == 0x20) return false; // Trailing space

        bytes1 lastChar = b[0];

        for (uint256 i; i < b.length; i++) {
            bytes1 char = b[i];

            if (char == 0x20 && lastChar == 0x20) return false; // Cannot contain continous spaces

            if (
                !(char >= 0x30 && char <= 0x39) && //9-0
                !(char >= 0x41 && char <= 0x5A) && //A-Z
                !(char >= 0x61 && char <= 0x7A) && //a-z
                !(char == 0x20) //space
            ) return false;

            lastChar = char;
        }

        return true;
    }

    /**
     * @notice Converts the string to lowercase
     * @param str string to convert
     */
    function toLower(string memory str) public pure returns (string memory) {
        bytes memory bStr = bytes(str);
        bytes memory bLower = new bytes(bStr.length);
        for (uint256 i = 0; i < bStr.length; i++) {
            // Uppercase character
            if ((uint8(bStr[i]) >= 65) && (uint8(bStr[i]) <= 90)) {
                bLower[i] = bytes1(uint8(bStr[i]) + 32);
            } else {
                bLower[i] = bStr[i];
            }
        }
        return string(bLower);
    }

    /**
     * @notice Adds special names to the special names list. Unfortunately can't be handled with a Merkle Tree as they can only be used to prove that a nem is in a set, but not that a name is not in a set. That is, non-special names can't be checked against such Merkle Tree. So we are only left with burning the special names into the contract state.
     * @param _specialNames array of special names to reserve
     */
    function setSpecialNames(string[] memory _specialNames) external onlyOwner {
        require(
            numberSpecialNames + _specialNames.length <=
                MAX_SPECIAL_NAMES_COUNT,
            "NFTRegistry: This would make special names list longer than allowed"
        );
        for (uint256 i = 0; i < _specialNames.length; i++) {
            require(
                !specialNames[toLower(_specialNames[i])],
                "NFTRegistry: At least one of the names is already in the special list"
            );
            specialNames[toLower(_specialNames[i])] = true;
            numberSpecialNames++;
        }
        if (numberSpecialNames == MAX_SPECIAL_NAMES_COUNT) {
            namingState = NamingState.ReadyForNaming;
        }
    }

    /**
     * @notice Assign naming credits in the NamingCredits contract. Avoids mistakes assigning more than 10 credits.
     * @param user address of the user assigning credits to
     * @param numberOfCredits number of credits to assign
     */
    function assignNamingCredits(address user, uint256 numberOfCredits)
        external
        onlyOwner
    {
        require(
            address(namingCreditsAddress) != address(0),
            "NFTRegistry: Naming Credits contract isn't set yet"
        );
        require(numberOfCredits <= MAX_ASSIGNABLE_NAMING_CREDITS, "NFTRegistry: Can't assign that number of credits in a single call");
        require(totalNumberAssignedCredits + numberOfCredits <= MAX_TOTAL_ASSIGNABLE_NAMING_CREDITS, "NFTRegistry: Assigning that number of credits would take total assigned credits over the limit");
        totalNumberAssignedCredits += numberOfCredits;
        namingCreditsAddress.assignNamingCredits(
            user,
            numberOfCredits
        );
    }

    /**
     * @notice Shut off naming credit assignments in the NamingCredits contract
     */
    function shutOffAssignments() external onlyOwner {
        require(
            address(namingCreditsAddress) != address(0),
            "NFTRegistry: Naming Credits contract isn't set yet"
        );
        namingCreditsAddress.shutOffAssignments();
    }

    /**
     * @notice Shut off protocol fee recipient updates
     */
    function shutOffFeeRecipientUpdates() external onlyOwner {
        allowUpdatingFeeRecipient = false;
    }    

    /**
     * @notice Update protocol fee recipient in the NamingCredits contract
     */
    function updateNamingCreditsProtocolFeeRecipient(
        address _protocolFeeRecipient
    ) external onlyOwner {
        require(
            address(namingCreditsAddress) != address(0),
            "NFTRegistry: Naming Credits contract isn't set yet"
        );
        require(allowUpdatingFeeRecipient, "NFTRegistry: Updating the protocol free recipient has been shut off");
        namingCreditsAddress.updateProtocolFeeRecipient(
            _protocolFeeRecipient
        );
    }

    /**
     * @notice Call the HoldFarming contract curateCollection function
     * @param nftAddress address of the NFT collection contract to be curated
     */
    function curateCollection(address nftAddress) external onlyOwner {
        require(
            address(holdFarmingAddress) != address(0),
            "NFTRegistry: Hold Farming contract isn't set yet"
        );
        require(numberCuratedCollections < MAX_NUMBER_CURATED_COLLECTIONS, "NFTRegistry: Number of curated collections has been maxed out");
        numberCuratedCollections++;
        holdFarmingAddress.curateCollection(nftAddress);
    }

    /**
     * @notice Withdraw any RNM that got sent to the contract by accident
     */
    function withdrawRNM() external onlyOwner {
        require(
            address(rnmToken) != address(0),
            "NFTRegistry: RNM contract isn't set yet"
        );
        uint256 withdrawableRNM = IERC20(rnmToken).balanceOf(address(this));
        require(
            withdrawableRNM != 0,
            "NFTRegistry: There is no RNM to withdraw"
        );
        IERC20(rnmToken).transfer(
            msg.sender,
            withdrawableRNM
        );
    }
}

File 2 of 13 : 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;
    }
}

File 3 of 13 : IERC165.sol
// SPDX-License-Identifier: MIT

pragma solidity ^0.8.0;

/**
 * @dev Interface of the ERC165 standard, as defined in the
 * https://eips.ethereum.org/EIPS/eip-165[EIP].
 *
 * Implementers can declare support of contract interfaces, which can then be
 * queried by others ({ERC165Checker}).
 *
 * For an implementation, see {ERC165}.
 */
interface IERC165 {
    /**
     * @dev Returns true if this contract implements the interface defined by
     * `interfaceId`. See the corresponding
     * https://eips.ethereum.org/EIPS/eip-165#how-interfaces-are-identified[EIP section]
     * to learn more about how these ids are created.
     *
     * This function call must use less than 30 000 gas.
     */
    function supportsInterface(bytes4 interfaceId) external view returns (bool);
}

File 4 of 13 : IERC20.sol
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts v4.4.1 (token/ERC20/IERC20.sol)

pragma solidity ^0.8.0;

/**
 * @dev Interface of the ERC20 standard as defined in the EIP.
 */
interface IERC20 {
    /**
     * @dev Returns the amount of tokens in existence.
     */
    function totalSupply() external view returns (uint256);

    /**
     * @dev Returns the amount of tokens owned by `account`.
     */
    function balanceOf(address account) external view returns (uint256);

    /**
     * @dev Moves `amount` tokens from the caller's account to `recipient`.
     *
     * Returns a boolean value indicating whether the operation succeeded.
     *
     * Emits a {Transfer} event.
     */
    function transfer(address recipient, uint256 amount) external returns (bool);

    /**
     * @dev Returns the remaining number of tokens that `spender` will be
     * allowed to spend on behalf of `owner` through {transferFrom}. This is
     * zero by default.
     *
     * This value changes when {approve} or {transferFrom} are called.
     */
    function allowance(address owner, address spender) external view returns (uint256);

    /**
     * @dev Sets `amount` as the allowance of `spender` over the caller's tokens.
     *
     * Returns a boolean value indicating whether the operation succeeded.
     *
     * IMPORTANT: Beware that changing an allowance with this method brings the risk
     * that someone may use both the old and the new allowance by unfortunate
     * transaction ordering. One possible solution to mitigate this race
     * condition is to first reduce the spender's allowance to 0 and set the
     * desired value afterwards:
     * https://github.com/ethereum/EIPs/issues/20#issuecomment-263524729
     *
     * Emits an {Approval} event.
     */
    function approve(address spender, uint256 amount) external returns (bool);

    /**
     * @dev Moves `amount` tokens from `sender` to `recipient` using the
     * allowance mechanism. `amount` is then deducted from the caller's
     * allowance.
     *
     * Returns a boolean value indicating whether the operation succeeded.
     *
     * Emits a {Transfer} event.
     */
    function transferFrom(
        address sender,
        address recipient,
        uint256 amount
    ) external returns (bool);


    /**
     * @dev Emitted when `value` tokens are moved from one account (`from`) to
     * another (`to`).
     *
     * Note that `value` may be zero.
     */
    event Transfer(address indexed from, address indexed to, uint256 value);

    /**
     * @dev Emitted when the allowance of a `spender` for an `owner` is set by
     * a call to {approve}. `value` is the new allowance.
     */
    event Approval(address indexed owner, address indexed spender, uint256 value);
}

File 5 of 13 : IERC721.sol
pragma solidity >=0.8.0 <0.9.0;
//SPDX-License-Identifier: MIT
import "./IERC165.sol";

/**
 * @dev Required interface of an ERC721 compliant contract.
 */
interface IERC721 is IERC165 {
    /**
     * @dev Emitted when `tokenId` token is transferred from `from` to `to`.
     */
    event Transfer(address indexed from, address indexed to, uint256 indexed tokenId);

    /**
     * @dev Emitted when `owner` enables `approved` to manage the `tokenId` token.
     */
    event Approval(address indexed owner, address indexed approved, uint256 indexed tokenId);

    /**
     * @dev Emitted when `owner` enables or disables (`approved`) `operator` to manage all of its assets.
     */
    event ApprovalForAll(address indexed owner, address indexed operator, bool approved);

    /**
     * @dev Returns the number of tokens in ``owner``'s account.
     */
    function balanceOf(address owner) external view returns (uint256 balance);

    /**
     * @dev Returns the owner of the `tokenId` token.
     *
     * Requirements:
     *
     * - `tokenId` must exist.
     */
    function ownerOf(uint256 tokenId) external view returns (address owner);

    /**
     * @dev Safely transfers `tokenId` token from `from` to `to`, checking first that contract recipients
     * are aware of the ERC721 protocol to prevent tokens from being forever locked.
     *
     * Requirements:
     *
     * - `from` cannot be the zero address.
     * - `to` cannot be the zero address.
     * - `tokenId` token must exist and be owned by `from`.
     * - If the caller is not `from`, it must be have been allowed to move this token by either {approve} or {setApprovalForAll}.
     * - If `to` refers to a smart contract, it must implement {IERC721Receiver-onERC721Received}, which is called upon a safe transfer.
     *
     * Emits a {Transfer} event.
     */
    function safeTransferFrom(address from, address to, uint256 tokenId) external;

    /**
     * @dev Transfers `tokenId` token from `from` to `to`.
     *
     * WARNING: Usage of this method is discouraged, use {safeTransferFrom} whenever possible.
     *
     * Requirements:
     *
     * - `from` cannot be the zero address.
     * - `to` cannot be the zero address.
     * - `tokenId` token must be owned by `from`.
     * - If the caller is not `from`, it must be approved to move this token by either {approve} or {setApprovalForAll}.
     *
     * Emits a {Transfer} event.
     */
    function transferFrom(address from, address to, uint256 tokenId) external;

    /**
     * @dev Gives permission to `to` to transfer `tokenId` token to another account.
     * The approval is cleared when the token is transferred.
     *
     * Only a single account can be approved at a time, so approving the zero address clears previous approvals.
     *
     * Requirements:
     *
     * - The caller must own the token or be an approved operator.
     * - `tokenId` must exist.
     *
     * Emits an {Approval} event.
     */
    function approve(address to, uint256 tokenId) external;

    /**
     * @dev Returns the account approved for `tokenId` token.
     *
     * Requirements:
     *
     * - `tokenId` must exist.
     */
    function getApproved(uint256 tokenId) external view returns (address operator);

    /**
     * @dev Approve or remove `operator` as an operator for the caller.
     * Operators can call {transferFrom} or {safeTransferFrom} for any token owned by the caller.
     *
     * Requirements:
     *
     * - The `operator` cannot be the caller.
     *
     * Emits an {ApprovalForAll} event.
     */
    function setApprovalForAll(address operator, bool _approved) external;

    /**
     * @dev Returns if the `operator` is allowed to manage all of the assets of `owner`.
     *
     * See {setApprovalForAll}
     */
    function isApprovedForAll(address owner, address operator) external view returns (bool);

    /**
      * @dev Safely transfers `tokenId` token from `from` to `to`.
      *
      * Requirements:
      *
     * - `from` cannot be the zero address.
     * - `to` cannot be the zero address.
      * - `tokenId` token must exist and be owned by `from`.
      * - If the caller is not `from`, it must be approved to move this token by either {approve} or {setApprovalForAll}.
      * - If `to` refers to a smart contract, it must implement {IERC721Receiver-onERC721Received}, which is called upon a safe transfer.
      *
      * Emits a {Transfer} event.
      */
    function safeTransferFrom(address from, address to, uint256 tokenId, bytes calldata data) external;
}

File 6 of 13 : IHoldFarming.sol
// SPDX-License-Identifier: MIT

pragma solidity ^0.8.0;


interface IHoldFarming {
    function curateCollection (address nftAddress) external;
    function holdFarmingBlocks(address nftAddress) external view returns (uint256, uint256);
    function initiateHoldFarmingForNFT(address nftAddress, uint256 tokenId) external;
    function updateCollectionPools() external;
    function updatePoolFor(address nftAddress) external;
}

File 7 of 13 : INFTRegistry.sol
// SPDX-License-Identifier: GNU
pragma solidity >=0.8.0;

interface INFTRegistry {

    // Enums
    enum NamingCurrency {
        Ether,
        RNM,
        NamingCredits
    }
   
    function changeName(address nftAddress, uint256 tokenId, string calldata newName, NamingCurrency namingCurrency) external payable;
    function namingPriceEther() external view returns (uint256);
    function namingPriceRNM() external view returns (uint256);

}

File 8 of 13 : INamingCredits.sol
// SPDX-License-Identifier: MIT

pragma solidity ^0.8.0;


interface INamingCredits {
    function credits(address sender) external view returns (uint256);
    function reduceNamingCredits(address sender, uint256 numberOfCredits) external;
    function assignNamingCredits(address user, uint256 numberOfCredits) external;
    function shutOffAssignments() external;
    function updateProtocolFeeRecipient(address _protocolFeeRecipient) external;
}

File 9 of 13 : IPunks.sol
pragma solidity >=0.8.0 <0.9.0;
//SPDX-License-Identifier: MIT

interface IPunks {

    function punkIndexToAddress(uint punkIndex) external view returns (address);
    function totalSupply() external view returns (uint256);
    
}

File 10 of 13 : IRNM.sol
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;

import "./IERC20.sol";

interface IRNM is IERC20 {
    function SUPPLY_CAP() external view returns (uint256);

    function mint(address account, uint256 amount) external returns (bool);
    function burn(uint256 amount) external;
}

File 11 of 13 : IWETH.sol
// SPDX-License-Identifier: GNU
pragma solidity >=0.5.0;

interface IWETH {
    function deposit() external payable;

    function transfer(address to, uint256 value) external returns (bool);

    function withdraw(uint256) external;
}

File 12 of 13 : Ownable.sol
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts v4.4.1 (access/Ownable.sol)

pragma solidity ^0.8.0;

import "./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 Returns the address of the current owner.
     */
    function owner() public view virtual returns (address) {
        return _owner;
    }

    /**
     * @dev Throws if called by any account other than the owner.
     */
    modifier onlyOwner() {
        require(owner() == _msgSender(), "Ownable: caller is not the owner");
        _;
    }

    /**
     * @dev Leaves the contract without owner. It will not be possible to call
     * `onlyOwner` functions anymore. Can only be called by the current owner.
     *
     * NOTE: Renouncing ownership will leave the contract without an owner,
     * thereby removing 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);
    }
}

File 13 of 13 : ReentrancyGuard.sol
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts v4.4.1 (security/ReentrancyGuard.sol)

pragma solidity ^0.8.0;

/**
 * @dev Contract module that helps prevent reentrant calls to a function.
 *
 * Inheriting from `ReentrancyGuard` will make the {nonReentrant} modifier
 * available, which can be applied to functions to make sure there are no nested
 * (reentrant) calls to them.
 *
 * Note that because there is a single `nonReentrant` guard, functions marked as
 * `nonReentrant` may not call one another. This can be worked around by making
 * those functions `private`, and then adding `external` `nonReentrant` entry
 * points to them.
 *
 * TIP: If you would like to learn more about reentrancy and alternative ways
 * to protect against it, check out our blog post
 * https://blog.openzeppelin.com/reentrancy-after-istanbul/[Reentrancy After Istanbul].
 */
abstract contract ReentrancyGuard {
    // Booleans are more expensive than uint256 or any type that takes up a full
    // word because each write operation emits an extra SLOAD to first read the
    // slot's contents, replace the bits taken up by the boolean, and then write
    // back. This is the compiler's defense against contract upgrades and
    // pointer aliasing, and it cannot be disabled.

    // The values being non-zero value makes deployment a bit more expensive,
    // but in exchange the refund on every call to nonReentrant will be lower in
    // amount. Since refunds are capped to a percentage of the total
    // transaction's gas, it is best to keep them low in cases like this one, to
    // increase the likelihood of the full refund coming into effect.
    uint256 private constant _NOT_ENTERED = 1;
    uint256 private constant _ENTERED = 2;

    uint256 private _status;

    constructor() {
        _status = _NOT_ENTERED;
    }

    /**
     * @dev Prevents a contract from calling itself, directly or indirectly.
     * Calling a `nonReentrant` function from another `nonReentrant`
     * function is not supported. It is possible to prevent this from happening
     * by making the `nonReentrant` function external, and making it call a
     * `private` function that does the actual work.
     */
    modifier nonReentrant() {
        // On the first call to nonReentrant, _notEntered will be true
        require(_status != _ENTERED, "ReentrancyGuard: reentrant call");

        // Any calls to nonReentrant after this point will fail
        _status = _ENTERED;

        _;

        // By storing the original value once again, a refund is triggered (see
        // https://eips.ethereum.org/EIPS/eip-2200)
        _status = _NOT_ENTERED;
    }
}

Settings
{
  "evmVersion": "istanbul",
  "libraries": {},
  "metadata": {
    "bytecodeHash": "ipfs",
    "useLiteralContent": true
  },
  "optimizer": {
    "enabled": true,
    "runs": 200
  },
  "remappings": [],
  "outputSelection": {
    "*": {
      "*": [
        "evm.bytecode",
        "evm.deployedBytecode",
        "devdoc",
        "userdoc",
        "metadata",
        "abi"
      ]
    }
  }
}

Contract Security Audit

Contract ABI

[{"inputs":[{"internalType":"address","name":"_punksAddress","type":"address"},{"internalType":"address","name":"_goldenTicketAddress","type":"address"},{"internalType":"address","name":"_WETH","type":"address"},{"internalType":"address","name":"_protocolFeeRecipient","type":"address"},{"internalType":"uint256","name":"_minNamingPriceEther","type":"uint256"},{"internalType":"uint256","name":"_minNamingPriceRNM","type":"uint256"}],"stateMutability":"nonpayable","type":"constructor"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"nftAddress","type":"address"},{"indexed":true,"internalType":"uint256","name":"tokenId","type":"uint256"},{"indexed":false,"internalType":"string","name":"newName","type":"string"},{"indexed":false,"internalType":"address","name":"sender","type":"address"},{"indexed":false,"internalType":"enum NFTRegistry.NamingCurrency","name":"namingCurrency","type":"uint8"},{"indexed":false,"internalType":"uint256","name":"currencyQuantity","type":"uint256"}],"name":"NameChange","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"nftAddressFrom","type":"address"},{"indexed":false,"internalType":"uint256","name":"tokenIdFrom","type":"uint256"},{"indexed":true,"internalType":"address","name":"nftAddressTo","type":"address"},{"indexed":false,"internalType":"uint256","name":"tokenIdTo","type":"uint256"},{"indexed":false,"internalType":"string","name":"name","type":"string"},{"indexed":false,"internalType":"address","name":"transferer","type":"address"}],"name":"NameTransfer","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"namingPriceEther","type":"uint256"}],"name":"NewNamingPriceEther","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"namingPriceRNM","type":"uint256"}],"name":"NewNamingPriceRNM","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"protocolFeeRecipient","type":"address"}],"name":"NewProtocolFeeRecipient","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"rnmNamingStartBlock","type":"uint256"}],"name":"NewRnmNamingStartBlock","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"previousOwner","type":"address"},{"indexed":true,"internalType":"address","name":"newOwner","type":"address"}],"name":"OwnershipTransferred","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"owner","type":"address"},{"indexed":true,"internalType":"address","name":"nftAddress","type":"address"},{"indexed":false,"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"TransferAllowed","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"owner","type":"address"},{"indexed":true,"internalType":"address","name":"nftAddress","type":"address"},{"indexed":false,"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"TransferDisAllowed","type":"event"},{"inputs":[],"name":"INFINITE_BLOCK","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"MAX_ASSIGNABLE_NAMING_CREDITS","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"MAX_NUMBER_CURATED_COLLECTIONS","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"MAX_SPECIAL_NAMES_COUNT","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"MAX_TOTAL_ASSIGNABLE_NAMING_CREDITS","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"MIN_NAMING_PRICE_ETHER","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"MIN_NAMING_PRICE_RNM","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"WETH","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"nftAddress","type":"address"},{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"allowTransfer","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"allowUpdatingFeeRecipient","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"},{"internalType":"address","name":"","type":"address"},{"internalType":"uint256","name":"","type":"uint256"}],"name":"allowances","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"user","type":"address"},{"internalType":"uint256","name":"numberOfCredits","type":"uint256"}],"name":"assignNamingCredits","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"nftAddress","type":"address"},{"internalType":"uint256","name":"tokenId","type":"uint256"},{"internalType":"string","name":"newName","type":"string"},{"internalType":"enum NFTRegistry.NamingCurrency","name":"namingCurrency","type":"uint8"},{"internalType":"uint256","name":"currencyQuantity","type":"uint256"}],"name":"changeName","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"address","name":"nftAddress","type":"address"}],"name":"curateCollection","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"nftAddress","type":"address"},{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"disallowTransfer","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"},{"internalType":"uint256","name":"","type":"uint256"}],"name":"firstNamed","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"string","name":"nameString","type":"string"}],"name":"getTokenByName","outputs":[{"components":[{"internalType":"address","name":"collectionAddress","type":"address"},{"internalType":"uint256","name":"tokenId","type":"uint256"}],"internalType":"struct NFTRegistry.Token","name":"","type":"tuple"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"goldenTicketAddress","outputs":[{"internalType":"contract IERC20","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"holdFarmingAddress","outputs":[{"internalType":"contract IHoldFarming","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"marketplaceAddress","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"namingCreditsAddress","outputs":[{"internalType":"contract INamingCredits","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"namingPriceEther","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"namingPriceRNM","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"namingState","outputs":[{"internalType":"enum NFTRegistry.NamingState","name":"","type":"uint8"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"numberCuratedCollections","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"numberSpecialNames","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"owner","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"protocolFeeRecipient","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"punksAddress","outputs":[{"internalType":"contract IPunks","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"renounceOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"rnmNamingStartBlock","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"rnmToken","outputs":[{"internalType":"contract IRNM","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"contract IHoldFarming","name":"_holdFarmingAddress","type":"address"}],"name":"setHoldFarmingAddress","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_marketplaceAddress","type":"address"}],"name":"setMarketplaceAddress","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"contract INamingCredits","name":"_namingCreditsAddress","type":"address"}],"name":"setNamingCreditsAddress","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"contract IRNM","name":"_rnmToken","type":"address"}],"name":"setRnmTokenAddress","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"string[]","name":"_specialNames","type":"string[]"}],"name":"setSpecialNames","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"shutOffAssignments","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"shutOffFeeRecipientUpdates","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"string","name":"","type":"string"}],"name":"specialNames","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"string","name":"str","type":"string"}],"name":"toLower","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"pure","type":"function"},{"inputs":[{"internalType":"string","name":"","type":"string"}],"name":"tokenByName","outputs":[{"internalType":"address","name":"collectionAddress","type":"address"},{"internalType":"uint256","name":"tokenId","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"},{"internalType":"uint256","name":"","type":"uint256"}],"name":"tokenName","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"nftAddress","type":"address"},{"internalType":"uint256","name":"index","type":"uint256"}],"name":"tokenNameByIndex","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"totalNumberAssignedCredits","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"nftAddressFrom","type":"address"},{"internalType":"uint256","name":"tokenIdFrom","type":"uint256"},{"internalType":"address","name":"nftAddressTo","type":"address"},{"internalType":"uint256","name":"tokenIdTo","type":"uint256"}],"name":"transferName","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"newOwner","type":"address"}],"name":"transferOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_protocolFeeRecipient","type":"address"}],"name":"updateNamingCreditsProtocolFeeRecipient","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_namingPriceEther","type":"uint256"}],"name":"updateNamingPriceEther","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_namingPriceRNM","type":"uint256"}],"name":"updateNamingPriceRNM","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_protocolFeeRecipient","type":"address"}],"name":"updateProtocolFeeRecipient","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_rnmNamingStartBlock","type":"uint256"}],"name":"updateRnmNamingStartBlock","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"string","name":"str","type":"string"}],"name":"validateName","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"pure","type":"function"},{"inputs":[],"name":"withdrawRNM","outputs":[],"stateMutability":"nonpayable","type":"function"}]

6101206040526001805460ff60a01b1916815566b1a2bc2ec50000600255683635c9adc5dea0000060035564174876e8006005556008805460ff1916909117905560006009553480156200005257600080fd5b506040516200466b3803806200466b8339810160408190526200007591620003e7565b6001600055620000853362000378565b6001600160a01b038616620000f65760405162461bcd60e51b815260206004820152603b60248201526000805160206200464b83398151915260448201527f2774207365742070756e6b734164647265737320746f207a65726f000000000060648201526084015b60405180910390fd5b6001600160a01b0385166200016e5760405162461bcd60e51b815260206004820152604260248201526000805160206200464b83398151915260448201527f27742073657420676f6c64656e5469636b65744164647265737320746f207a65606482015261726f60f01b608482015260a401620000ed565b6001600160a01b038416620001db5760405162461bcd60e51b815260206004820152603b60248201526000805160206200464b83398151915260448201527f2774207365742057455448206164647265737320746f207a65726f00000000006064820152608401620000ed565b6001600160a01b038316620002545760405162461bcd60e51b815260206004820152604360248201526000805160206200464b83398151915260448201527f2774207365742070726f746f636f6c466565526563697069656e7420746f207a60648201526265726f60e81b608482015260a401620000ed565b60008211620002bb5760405162461bcd60e51b815260206004820152603760248201526000805160206200462b83398151915260448201527f204574686572206d757374206265206e6f6e2d7a65726f0000000000000000006064820152608401620000ed565b60008111620003225760405162461bcd60e51b815260206004820152603560248201526000805160206200462b83398151915260448201527f20524e4d206d757374206265206e6f6e2d7a65726f00000000000000000000006064820152608401620000ed565b606095861b6001600160601b031990811660e05294861b851660c0529290941b90921661010052600480546001600160a01b0319166001600160a01b039093169290921790915560809190915260a05262000455565b600180546001600160a01b038381166001600160a01b0319831681179093556040519116919082907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e090600090a35050565b80516001600160a01b0381168114620003e257600080fd5b919050565b60008060008060008060c0878903121562000400578182fd5b6200040b87620003ca565b95506200041b60208801620003ca565b94506200042b60408801620003ca565b93506200043b60608801620003ca565b92506080870151915060a087015190509295509295509295565b60805160a05160c05160601c60e05160601c6101005160601c614149620004e26000396000818161087e015281816117220152818161180f0152818161194001526119dc0152600081816105c3015281816136fa015261374801526000818161062c015261146301526000818161075701526129ce01526000818161080a0152612ae001526141496000f3fe6080604052600436106103355760003560e01c806384c3f20c116101ab578063bbc5f334116100f7578063e43acea411610095578063f2fde38b1161006f578063f2fde38b14610a08578063f7f343c314610a28578063fc7f921d14610a48578063fc8009b714610a5e57600080fd5b8063e43acea414610999578063e73fc0c3146109af578063e88d1b5c146109f357600080fd5b8063daa17f49116100d1578063daa17f4914610959578063dc13141c14610979578063dc3d1f8b14610710578063e1c24c5c146107c457600080fd5b8063bbc5f33414610900578063c5ebb85f14610920578063cb479e591461094057600080fd5b80638df49ed911610164578063ad5c46481161013e578063ad5c46481461086c578063b47cc556146108a0578063b5a7c806146108c0578063b77564b8146108e057600080fd5b80638df49ed9146107f85780639416b4231461082c5780639ffdb65a1461084c57600080fd5b806384c3f20c14610745578063866f4d67146107795780638a3611dd1461078f5780638bbe43a8146107a45780638d6d1b54146107c45780638da5cb5b146107da57600080fd5b806346fd3b0c11610285578063715018a6116102235780637d6db09e116101fd5780637d6db09e146106b857806380fb45ca146106f0578063838322af1461071057806383e7e5be1461072557600080fd5b8063715018a61461060557806375bf97071461061a5780637b6e79751461064e57600080fd5b806359556b001161025f57806359556b001461057757806364df049e146105915780636b3b88a8146105b157806370f34938146105e557600080fd5b806346fd3b0c146105095780634d0d1cde146105295780635418bb0f1461055757600080fd5b80632922b507116102f25780632f019cc9116102cc5780632f019cc91461045a57806332b5d0e4146104925780633332800e146104a857806341a379b3146104f357600080fd5b80632922b507146103ed5780632af745dd1461040d5780632ce4a66c1461042d57600080fd5b80630dd6794f1461033a578063139a2d7714610351578063186d1b0a1461037157806318e880ac1461039a57806319c02b27146103ad5780631df47f80146103cd575b600080fd5b34801561034657600080fd5b5061034f610a9f565b005b34801561035d57600080fd5b5061034f61036c366004613ad9565b610b64565b34801561037d57600080fd5b5061038760065481565b6040519081526020015b60405180910390f35b61034f6103a8366004613b20565b610ef5565b3480156103b957600080fd5b5061034f6103c8366004613aae565b611eb9565b3480156103d957600080fd5b5061034f6103e8366004613a2f565b611f5b565b3480156103f957600080fd5b5061034f610408366004613aae565b612052565b34801561041957600080fd5b5061034f610428366004613a2f565b612251565b34801561043957600080fd5b5061044d610448366004613aae565b6123dc565b6040516103919190613e02565b34801561046657600080fd5b50600d5461047a906001600160a01b031681565b6040516001600160a01b039091168152602001610391565b34801561049e57600080fd5b5061038760025481565b3480156104b457600080fd5b506104e36104c3366004613c8f565b8051602081830181018051600a8252928201919093012091525460ff1681565b6040519015158152602001610391565b3480156104ff57600080fd5b5061038760055481565b34801561051557600080fd5b5061034f610524366004613cca565b612481565b34801561053557600080fd5b5060015461054a90600160a01b900460ff1681565b6040516103919190613de8565b34801561056357600080fd5b5061034f610572366004613a2f565b61265c565b34801561058357600080fd5b506008546104e39060ff1681565b34801561059d57600080fd5b5060045461047a906001600160a01b031681565b3480156105bd57600080fd5b5061047a7f000000000000000000000000000000000000000000000000000000000000000081565b3480156105f157600080fd5b5061034f610600366004613b95565b612731565b34801561061157600080fd5b5061034f61296c565b34801561062657600080fd5b5061047a7f000000000000000000000000000000000000000000000000000000000000000081565b34801561065a57600080fd5b50610699610669366004613c8f565b8051602081830181018051601182529282019190930120915280546001909101546001600160a01b039091169082565b604080516001600160a01b039093168352602083019190915201610391565b3480156106c457600080fd5b506103876106d3366004613aae565b601260209081526000928352604080842090915290825290205481565b3480156106fc57600080fd5b5061034f61070b366004613cca565b6129a2565b34801561071c57600080fd5b50610387600a81565b34801561073157600080fd5b50600c5461047a906001600160a01b031681565b34801561075157600080fd5b506103877f000000000000000000000000000000000000000000000000000000000000000081565b34801561078557600080fd5b5061038760075481565b34801561079b57600080fd5b5061034f612a7e565b3480156107b057600080fd5b5061034f6107bf366004613cca565b612ab4565b3480156107d057600080fd5b506103876103e881565b3480156107e657600080fd5b506001546001600160a01b031661047a565b34801561080457600080fd5b506103877f000000000000000000000000000000000000000000000000000000000000000081565b34801561083857600080fd5b5061044d610847366004613c8f565b612b93565b34801561085857600080fd5b506104e3610867366004613c8f565b612d58565b34801561087857600080fd5b5061047a7f000000000000000000000000000000000000000000000000000000000000000081565b3480156108ac57600080fd5b5061034f6108bb366004613a2f565b612f9f565b3480156108cc57600080fd5b5061034f6108db366004613a2f565b61306a565b3480156108ec57600080fd5b50600b5461047a906001600160a01b031681565b34801561090c57600080fd5b5061034f61091b366004613aae565b613171565b34801561092c57600080fd5b5061034f61093b366004613a2f565b613208565b34801561094c57600080fd5b5061038764174876e80081565b34801561096557600080fd5b50600e5461047a906001600160a01b031681565b34801561098557600080fd5b5061034f610994366004613a2f565b6132d3565b3480156109a557600080fd5b5061038760095481565b3480156109bb57600080fd5b506109cf6109ca366004613c8f565b61338e565b6040805182516001600160a01b031681526020928301519281019290925201610391565b3480156109ff57600080fd5b5061034f6133ef565b348015610a1457600080fd5b5061034f610a23366004613a2f565b6135a5565b348015610a3457600080fd5b5061044d610a43366004613aae565b61363d565b348015610a5457600080fd5b5061038760035481565b348015610a6a57600080fd5b506104e3610a79366004613a6e565b600f60209081526000938452604080852082529284528284209052825290205460ff1681565b6001546001600160a01b03163314610ad25760405162461bcd60e51b8152600401610ac990613f48565b60405180910390fd5b600c546001600160a01b0316610afa5760405162461bcd60e51b8152600401610ac990613ea2565b600c60009054906101000a90046001600160a01b03166001600160a01b0316630dd6794f6040518163ffffffff1660e01b8152600401600060405180830381600087803b158015610b4a57600080fd5b505af1158015610b5e573d6000803e3d6000fd5b50505050565b600e546001600160a01b0316610b8c5760405162461bcd60e51b8152600401610ac990613ef4565b600e546001600160a01b03163314610c0c5760405162461bcd60e51b815260206004820152603d60248201527f4e465452656769737472793a204f6e6c7920746865204d61726b6574706c616360448201527f6520636f6e74726163742063616e206d616b6520746869732063616c6c0000006064820152608401610ac9565b6000610c1885856136f6565b6001600160a01b038082166000908152600f60209081526040808320938a1683529281528282208883529052205490915060ff16610cb75760405162461bcd60e51b815260206004820152603660248201527f4e465452656769737472793a204e4654206861736e2774206265656e20616c6c60448201527537bbb2b2103337b9103730b6b2903a3930b739b332b960511b6064820152608401610ac9565b6001600160a01b038516600090815260106020908152604080832087845290915281208054610ce590614066565b80601f0160208091040260200160405190810160405280929190818152602001828054610d1190614066565b8015610d5e5780601f10610d3357610100808354040283529160200191610d5e565b820191906000526020600020905b815481529060010190602001808311610d4157829003601f168201915b505050505090506000815111610dcf5760405162461bcd60e51b815260206004820152603060248201527f4e465452656769737472793a2043616e2774207472616e73666572206e616d6560448201526f08185cc81a5d081a5cdb89dd081cd95d60821b6064820152608401610ac9565b60408051602080820180845260008084526001600160a01b038b168152601083528481208a82529092529290209051610e08929061392b565b506001600160a01b038416600090815260106020908152604080832086845282529091208251610e3a9284019061392b565b506040518060400160405280856001600160a01b03168152602001848152506011610e6483612b93565b604051610e719190613d31565b9081526040519081900360209081018220835181546001600160a01b039182166001600160a01b03199091161782559390910151600190910155858216918816907feb477db04e3acb04a54b59dc5662711ce9929dd7b0393b68832f7c998862a57d90610ee5908990889087908990613f7d565b60405180910390a3505050505050565b60026000541415610f485760405162461bcd60e51b815260206004820152601f60248201527f5265656e7472616e637947756172643a207265656e7472616e742063616c6c006044820152606401610ac9565b60026000556001808054600160a01b900460ff1690811115610f7a57634e487b7160e01b600052602160045260246000fd5b14610fd55760405162461bcd60e51b815260206004820152602560248201527f4e465452656769737472793a204e6f7420726561647920666f72206e616d696e60448201526419c81e595d60da1b6064820152608401610ac9565b610fdf85856137ff565b610fe883612d58565b61103e5760405162461bcd60e51b815260206004820152602160248201527f4e465452656769737472793a204e6f7420612076616c6964206e6577206e616d6044820152606560f81b6064820152608401610ac9565b6001600160a01b038516600090815260106020908152604080832087845290915290819020905160029161107191613d4d565b602060405180830381855afa15801561108e573d6000803e3d6000fd5b5050506040513d601f19601f820116820180604052508101906110b19190613c77565b6002846040516110c19190613d31565b602060405180830381855afa1580156110de573d6000803e3d6000fd5b5050506040513d601f19601f820116820180604052508101906111019190613c77565b14156111685760405162461bcd60e51b815260206004820152603060248201527f4e465452656769737472793a204e6577206e616d652069732073616d6520617360448201526f207468652063757272656e74206f6e6560801b6064820152608401610ac9565b6111b7601161117685612b93565b6040516111839190613d31565b90815260408051918290036020908101832083830190925281546001600160a01b031683526001909101549082015261387a565b61120e5760405162461bcd60e51b815260206004820152602260248201527f4e465452656769737472793a204e616d6520616c726561647920726573657276604482015261195960f21b6064820152608401610ac9565b600282600281111561123057634e487b7160e01b600052602160045260246000fd5b14156112c157806001146112bc5760405162461bcd60e51b815260206004820152604760248201527f4e465452656769737472793a2063757272656e63795175616e74697479206d7560448201527f73742062652031207768656e206e616d696e672077697468204e616d696e67206064820152664372656469747360c81b608482015260a401610ac9565b611411565b60018260028111156112e357634e487b7160e01b600052602160045260246000fd5b141561137b5760035481146112bc5760405162461bcd60e51b815260206004820152605260248201527f4e465452656769737472793a2063757272656e63795175616e74697479206d7560448201527f737420626520657175616c20746f206e616d696e675072696365524e4d207768606482015271656e206e616d696e67207769746820524e4d60701b608482015260a401610ac9565b60025481146114115760405162461bcd60e51b815260206004820152605660248201527f4e465452656769737472793a2063757272656e63795175616e74697479206d7560448201527f737420626520657175616c20746f206e616d696e6750726963654574686572206064820152753bb432b7103730b6b4b733903bb4ba341022ba3432b960511b608482015260a401610ac9565b600a61141c84612b93565b6040516114299190613d31565b9081526040519081900360200190205460ff16156114e9576040516323b872dd60e01b8152336004820152306024820152600160448201527f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316906323b872dd90606401602060405180830381600087803b1580156114af57600080fd5b505af11580156114c3573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906114e79190613c57565b505b600182600281111561150b57634e487b7160e01b600052602160045260246000fd5b148015611519575060055443105b1561157e5760405162461bcd60e51b815260206004820152602f60248201527f4e465452656769737472793a204e6f7420726561647920666f72206e616d696e60448201526e672070616964207769746820524e4d60881b6064820152608401610ac9565b600d546000906001600160a01b0316158015906115bc57506001600160a01b0386166000908152601260209081526040808320888452909152902054155b156116c857600d54604051631a0ec30360e31b81526001600160a01b038881166004830152600092839291169063d076181890602401604080518083038186803b15801561160957600080fd5b505afa15801561161d573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906116419190613ce2565b915091508143101580156116555750804311155b156116c557600d5460405163a562f95d60e01b81526001600160a01b038a81166004830152602482018a90529091169063a562f95d90604401600060405180830381600087803b1580156116a857600080fd5b505af11580156116bc573d6000803e3d6000fd5b50505050600192505b50505b80611c955760008360028111156116ef57634e487b7160e01b600052602160045260246000fd5b1415611a62573460025411156118d9573460025461170d9190614023565b6040516370a0823160e01b81523360048201527f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316906370a082319060240160206040518083038186803b15801561176c57600080fd5b505afa158015611780573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906117a49190613c77565b101561180d5760405162461bcd60e51b815260206004820152603260248201527f4e465452656769737472793a204e6f7420656e6f756768204554482073656e74604482015271206f72205745544820617661696c61626c6560701b6064820152608401610ac9565b7f00000000000000000000000000000000000000000000000000000000000000006001600160a01b03166323b872dd33303460025461184c9190614023565b6040516001600160e01b031960e086901b1681526001600160a01b0393841660048201529290911660248301526044820152606401602060405180830381600087803b15801561189b57600080fd5b505af11580156118af573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906118d39190613c57565b5061193e565b346002541461193e5760405162461bcd60e51b815260206004820152602b60248201527f4e465452656769737472793a20546f6f206d7563682045746865722073656e7460448201526a20666f72206e616d696e6760a81b6064820152608401610ac9565b7f00000000000000000000000000000000000000000000000000000000000000006001600160a01b031663d0e30db0346040518263ffffffff1660e01b81526004016000604051808303818588803b15801561199957600080fd5b505af11580156119ad573d6000803e3d6000fd5b50506004805460025460405163a9059cbb60e01b81526001600160a01b039283169381019390935260248301527f000000000000000000000000000000000000000000000000000000000000000016935063a9059cbb92506044019050602060405180830381600087803b158015611a2457600080fd5b505af1158015611a38573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611a5c9190613c57565b50611c95565b6002836002811115611a8457634e487b7160e01b600052602160045260246000fd5b1415611b1c57600c546001600160a01b0316611ab25760405162461bcd60e51b8152600401610ac990613ea2565b600c546040516318f32ab360e31b8152336004820152600160248201526001600160a01b039091169063c7995598906044015b600060405180830381600087803b158015611aff57600080fd5b505af1158015611b13573d6000803e3d6000fd5b50505050611c95565b6001836002811115611b3e57634e487b7160e01b600052602160045260246000fd5b1415611c3057600b546001600160a01b0316611b6c5760405162461bcd60e51b8152600401610ac990613e5b565b600b546003546040516323b872dd60e01b815233600482015230602482015260448101919091526001600160a01b03909116906323b872dd90606401602060405180830381600087803b158015611bc257600080fd5b505af1158015611bd6573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611bfa9190613c57565b50600b54600354604051630852cd8d60e31b81526001600160a01b03909216916342966c6891611ae59160040190815260200190565b60405162461bcd60e51b815260206004820152603460248201527f4e465452656769737472793a205468652063757272656e63792069736e277420604482015273737570706f7274656420666f72206e616d696e6760601b6064820152608401610ac9565b6001600160a01b038616600090815260106020908152604080832088845290915281208054611cc390614066565b90501115611d81576001600160a01b038616600090815260106020908152604080832088845290915290208054611d819190611cfe90614066565b80601f0160208091040260200160405190810160405280929190818152602001828054611d2a90614066565b8015611d775780601f10611d4c57610100808354040283529160200191611d77565b820191906000526020600020905b815481529060010190602001808311611d5a57829003601f168201915b5050505050613899565b6040518060400160405280876001600160a01b03168152602001868152506011611daa86612b93565b604051611db79190613d31565b9081526040805160209281900383019020835181546001600160a01b0319166001600160a01b03918216178255938301516001909101559188166000908152601082528281208882528252919091208551611e149287019061392b565b506001600160a01b0386166000908152601260209081526040808320888452909152902054611e64576001600160a01b038616600090815260126020908152604080832088845290915290204390555b84866001600160a01b03167fdaaef4e21298fe0051de164f9ecb62a3400672506c9dc877928aee534133fbeb86338787604051611ea49493929190613e15565b60405180910390a35050600160005550505050565b600e546001600160a01b0316611ee15760405162461bcd60e51b8152600401610ac990613ef4565b611eeb82826137ff565b336000818152600f602090815260408083206001600160a01b038716808552908352818420868552835292819020805460ff19166001179055518481529192917f3e0dec829a933a85a6f226ab0941c1c07f3f005e507450e2bc7be22246efed4991015b60405180910390a35050565b6001546001600160a01b03163314611f855760405162461bcd60e51b8152600401610ac990613f48565b60085460ff166120085760405162461bcd60e51b815260206004820152604260248201527f4e465452656769737472793a205570646174696e67207468652070726f746f6360448201527f6f6c2066656520726563697069656e7420686173206265656e2073687574206f606482015261333360f11b608482015260a401610ac9565b600480546001600160a01b0319166001600160a01b0383169081179091556040517f8cffb07faa2874440346743bdc0a86b06c3335cc47dc49b327d10e77b73ceb1090600090a250565b6001546001600160a01b0316331461207c5760405162461bcd60e51b8152600401610ac990613f48565b600c546001600160a01b03166120a45760405162461bcd60e51b8152600401610ac990613ea2565b600a8111156121255760405162461bcd60e51b815260206004820152604160248201527f4e465452656769737472793a2043616e27742061737369676e2074686174206e60448201527f756d626572206f66206372656469747320696e20612073696e676c652063616c6064820152601b60fa1b608482015260a401610ac9565b6103e8816007546121369190613fe6565b11156121d05760405162461bcd60e51b815260206004820152605e60248201527f4e465452656769737472793a2041737369676e696e672074686174206e756d6260448201527f6572206f66206372656469747320776f756c642074616b6520746f74616c206160648201527f737369676e65642063726564697473206f76657220746865206c696d69740000608482015260a401610ac9565b80600760008282546121e29190613fe6565b9091555050600c54604051632922b50760e01b81526001600160a01b0384811660048301526024820184905290911690632922b50790604401600060405180830381600087803b15801561223557600080fd5b505af1158015612249573d6000803e3d6000fd5b505050505050565b6001546001600160a01b0316331461227b5760405162461bcd60e51b8152600401610ac990613f48565b600d546001600160a01b03166122ec5760405162461bcd60e51b815260206004820152603060248201527f4e465452656769737472793a20486f6c64204661726d696e6720636f6e74726160448201526f18dd081a5cdb89dd081cd95d081e595d60821b6064820152608401610ac9565b600a600654106123645760405162461bcd60e51b815260206004820152603d60248201527f4e465452656769737472793a204e756d626572206f662063757261746564206360448201527f6f6c6c656374696f6e7320686173206265656e206d61786564206f75740000006064820152608401610ac9565b60068054906000612374836140a1565b9091555050600d54604051632af745dd60e01b81526001600160a01b03838116600483015290911690632af745dd906024015b600060405180830381600087803b1580156123c157600080fd5b505af11580156123d5573d6000803e3d6000fd5b5050505050565b60106020908152600092835260408084209091529082529020805461240090614066565b80601f016020809104026020016040519081016040528092919081815260200182805461242c90614066565b80156124795780601f1061244e57610100808354040283529160200191612479565b820191906000526020600020905b81548152906001019060200180831161245c57829003601f168201915b505050505081565b6001546001600160a01b031633146124ab5760405162461bcd60e51b8152600401610ac990613f48565b64174876e8006005541461251f5760405162461bcd60e51b815260206004820152603560248201527f4e465452656769737472793a20726e6d4e616d696e675374617274426c6f636b6044820152742063616e206f6e6c7920626520736574206f6e636560581b6064820152608401610ac9565b4381116125945760405162461bcd60e51b815260206004820152603860248201527f4e465452656769737472793a20524e4d206e616d696e6720737461727420626c60448201527f6f636b2063616e27742062652073657420746f207061737400000000000000006064820152608401610ac9565b6125a1436202ee00613fe6565b81106126205760405162461bcd60e51b815260206004820152604260248201527f4e465452656769737472793a20524e4d206e616d696e6720737461727420626c60448201527f6f636b2063616e27742062652073657420736f2066617220696e20616476616e606482015261636560f01b608482015260a401610ac9565b60058190556040518181527f439097389fa3099271ae82924d227c95c4b789ef05c14c8249511392775d2f07906020015b60405180910390a150565b6001546001600160a01b031633146126865760405162461bcd60e51b8152600401610ac990613f48565b600c546001600160a01b03161561270f5760405162461bcd60e51b815260206004820152604160248201527f4e465452656769737472793a206e616d696e67206372656469747320636f6e7460448201527f7261637420616464726573732063616e206f6e6c7920626520736574206f6e636064820152606560f81b608482015260a401610ac9565b600c80546001600160a01b0319166001600160a01b0392909216919091179055565b6001546001600160a01b0316331461275b5760405162461bcd60e51b8152600401610ac990613f48565b6103e8815160095461276d9190613fe6565b11156127ed5760405162461bcd60e51b815260206004820152604360248201527f4e465452656769737472793a205468697320776f756c64206d616b652073706560448201527f6369616c206e616d6573206c697374206c6f6e676572207468616e20616c6c6f6064820152621dd95960ea1b608482015260a401610ac9565b60005b815181101561294857600a61282b83838151811061281e57634e487b7160e01b600052603260045260246000fd5b6020026020010151612b93565b6040516128389190613d31565b9081526040519081900360200190205460ff16156128cc5760405162461bcd60e51b815260206004820152604560248201527f4e465452656769737472793a204174206c65617374206f6e65206f662074686560448201527f206e616d657320697320616c726561647920696e20746865207370656369616c606482015264081b1a5cdd60da1b608482015260a401610ac9565b6001600a6128f384848151811061281e57634e487b7160e01b600052603260045260246000fd5b6040516129009190613d31565b908152604051908190036020019020805491151560ff1990921691909117905560098054906000612930836140a1565b91905055508080612940906140a1565b9150506127f0565b506103e86009541415612969576001805460ff60a01b1916600160a01b1790555b50565b6001546001600160a01b031633146129965760405162461bcd60e51b8152600401610ac990613f48565b6129a060006138d9565b565b6001546001600160a01b031633146129cc5760405162461bcd60e51b8152600401610ac990613f48565b7f0000000000000000000000000000000000000000000000000000000000000000811015612a4a5760405162461bcd60e51b815260206004820152602560248201527f4e465452656769737472793a20524e4d206e616d696e6720707269636520746f6044820152646f206c6f7760d81b6064820152608401610ac9565b60038190556040518181527e33c32d7ad6f0120d1a4eab9be1d62b3f8ff0c4b1a24fdfdc2eb3221dcc5e4a90602001612651565b6001546001600160a01b03163314612aa85760405162461bcd60e51b8152600401610ac990613f48565b6008805460ff19169055565b6001546001600160a01b03163314612ade5760405162461bcd60e51b8152600401610ac990613f48565b7f0000000000000000000000000000000000000000000000000000000000000000811015612b5e5760405162461bcd60e51b815260206004820152602760248201527f4e465452656769737472793a204554484552206e616d696e6720707269636520604482015266746f6f206c6f7760c81b6064820152608401610ac9565b60028190556040518181527f28b5c9776fb5d8d7b813bbcdfe31a02505b31efb0b803266bcb60ed493e800f190602001612651565b606060008290506000815167ffffffffffffffff811115612bc457634e487b7160e01b600052604160045260246000fd5b6040519080825280601f01601f191660200182016040528015612bee576020820181803683370190505b50905060005b8251811015612d50576041838281518110612c1f57634e487b7160e01b600052603260045260246000fd5b016020015160f81c10801590612c5d5750605a838281518110612c5257634e487b7160e01b600052603260045260246000fd5b016020015160f81c11155b15612cdb57828181518110612c8257634e487b7160e01b600052603260045260246000fd5b602001015160f81c60f81b60f81c6020612c9c9190613ffe565b60f81b828281518110612cbf57634e487b7160e01b600052603260045260246000fd5b60200101906001600160f81b031916908160001a905350612d3e565b828181518110612cfb57634e487b7160e01b600052603260045260246000fd5b602001015160f81c60f81b828281518110612d2657634e487b7160e01b600052603260045260246000fd5b60200101906001600160f81b031916908160001a9053505b80612d48816140a1565b915050612bf4565b509392505050565b600080829050600181511015612d715750600092915050565b601981511115612d845750600092915050565b80600081518110612da557634e487b7160e01b600052603260045260246000fd5b6020910101516001600160f81b031916600160fd1b1415612dc95750600092915050565b8060018251612dd89190614023565b81518110612df657634e487b7160e01b600052603260045260246000fd5b6020910101516001600160f81b031916600160fd1b1415612e1a5750600092915050565b600081600081518110612e3d57634e487b7160e01b600052603260045260246000fd5b01602001516001600160f81b031916905060005b8251811015612f94576000838281518110612e7c57634e487b7160e01b600052603260045260246000fd5b01602001516001600160f81b0319169050600160fd1b81148015612ead5750600160fd1b6001600160f81b03198416145b15612ebe5750600095945050505050565b600360fc1b6001600160f81b0319821610801590612eea5750603960f81b6001600160f81b0319821611155b158015612f205750604160f81b6001600160f81b0319821610801590612f1e5750602d60f91b6001600160f81b0319821611155b155b8015612f555750606160f81b6001600160f81b0319821610801590612f535750603d60f91b6001600160f81b0319821611155b155b8015612f6f5750600160fd1b6001600160f81b0319821614155b15612f805750600095945050505050565b915080612f8c816140a1565b915050612e51565b506001949350505050565b6001546001600160a01b03163314612fc95760405162461bcd60e51b8152600401610ac990613f48565b600e546001600160a01b0316156130485760405162461bcd60e51b815260206004820152603e60248201527f4e465452656769737472793a206d61726b6574706c61636520636f6e7472616360448201527f7420616464726573732063616e206f6e6c7920626520736574206f6e636500006064820152608401610ac9565b600e80546001600160a01b0319166001600160a01b0392909216919091179055565b6001546001600160a01b031633146130945760405162461bcd60e51b8152600401610ac990613f48565b600c546001600160a01b03166130bc5760405162461bcd60e51b8152600401610ac990613ea2565b60085460ff166131405760405162461bcd60e51b815260206004820152604360248201527f4e465452656769737472793a205570646174696e67207468652070726f746f6360448201527f6f6c206672656520726563697069656e7420686173206265656e20736875742060648201526237b33360e91b608482015260a401610ac9565b600c54604051623be8ff60e71b81526001600160a01b03838116600483015290911690631df47f80906024016123a7565b600e546001600160a01b03166131995760405162461bcd60e51b8152600401610ac990613ef4565b6131a382826137ff565b336000818152600f602090815260408083206001600160a01b038716808552908352818420868552835292819020805460ff19169055518481529192917f6f3e41c3eb642e6be48df2a585aa1e90d91e5984a4941179f65c49e445b2ddd09101611f4f565b6001546001600160a01b031633146132325760405162461bcd60e51b8152600401610ac990613f48565b600d546001600160a01b0316156132b15760405162461bcd60e51b815260206004820152603f60248201527f4e465452656769737472793a20686f6c64206661726d696e6720636f6e74726160448201527f637420616464726573732063616e206f6e6c7920626520736574206f6e6365006064820152608401610ac9565b600d80546001600160a01b0319166001600160a01b0392909216919091179055565b6001546001600160a01b031633146132fd5760405162461bcd60e51b8152600401610ac990613f48565b600b546001600160a01b03161561336c5760405162461bcd60e51b815260206004820152602d60248201527f4e465452656769737472793a20524e4d20616464726573732068617320616c7260448201526c1958591e481899595b881cd95d609a1b6064820152608401610ac9565b600b80546001600160a01b0319166001600160a01b0392909216919091179055565b604080518082019091526000808252602082015260116133ad83612b93565b6040516133ba9190613d31565b90815260408051918290036020908101832083830190925281546001600160a01b031683526001909101549082015292915050565b6001546001600160a01b031633146134195760405162461bcd60e51b8152600401610ac990613f48565b600b546001600160a01b03166134415760405162461bcd60e51b8152600401610ac990613e5b565b600b546040516370a0823160e01b81523060048201526000916001600160a01b0316906370a082319060240160206040518083038186803b15801561348557600080fd5b505afa158015613499573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906134bd9190613c77565b90508061351d5760405162461bcd60e51b815260206004820152602860248201527f4e465452656769737472793a205468657265206973206e6f20524e4d20746f20604482015267776974686472617760c01b6064820152608401610ac9565b600b5460405163a9059cbb60e01b8152336004820152602481018390526001600160a01b039091169063a9059cbb90604401602060405180830381600087803b15801561356957600080fd5b505af115801561357d573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906135a19190613c57565b5050565b6001546001600160a01b031633146135cf5760405162461bcd60e51b8152600401610ac990613f48565b6001600160a01b0381166136345760405162461bcd60e51b815260206004820152602660248201527f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160448201526564647265737360d01b6064820152608401610ac9565b612969816138d9565b6001600160a01b0382166000908152601060209081526040808320848452909152902080546060919061366f90614066565b80601f016020809104026020016040519081016040528092919081815260200182805461369b90614066565b80156136e85780601f106136bd576101008083540402835291602001916136e8565b820191906000526020600020905b8154815290600101906020018083116136cb57829003601f168201915b505050505090505b92915050565b60007f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316836001600160a01b031614156137d257604051630b02f02d60e31b8152600481018390527f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316906358178168906024015b60206040518083038186803b15801561379357600080fd5b505afa1580156137a7573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906137cb9190613a52565b90506136f0565b6040516331a9108f60e11b8152600481018390526001600160a01b03841690636352211e9060240161377b565b61380982826136f6565b6001600160a01b0316336001600160a01b0316146135a15760405162461bcd60e51b815260206004820152602860248201527f4e465452656769737472793a2043616c6c6572206973206e6f7420746865204e604482015267232a1037bbb732b960c11b6064820152608401610ac9565b80516000906001600160a01b03161580156136f0575050602001511590565b60116138a482612b93565b6040516138b19190613d31565b90815260405190819003602001902080546001600160a01b0319168155600060019091015550565b600180546001600160a01b038381166001600160a01b0319831681179093556040519116919082907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e090600090a35050565b82805461393790614066565b90600052602060002090601f016020900481019282613959576000855561399f565b82601f1061397257805160ff191683800117855561399f565b8280016001018555821561399f579182015b8281111561399f578251825591602001919060010190613984565b506139ab9291506139af565b5090565b5b808211156139ab57600081556001016139b0565b600082601f8301126139d4578081fd5b813567ffffffffffffffff8111156139ee576139ee6140e8565b613a01601f8201601f1916602001613fb5565b818152846020838601011115613a15578283fd5b816020850160208301379081016020019190915292915050565b600060208284031215613a40578081fd5b8135613a4b816140fe565b9392505050565b600060208284031215613a63578081fd5b8151613a4b816140fe565b600080600060608486031215613a82578182fd5b8335613a8d816140fe565b92506020840135613a9d816140fe565b929592945050506040919091013590565b60008060408385031215613ac0578182fd5b8235613acb816140fe565b946020939093013593505050565b60008060008060808587031215613aee578081fd5b8435613af9816140fe565b9350602085013592506040850135613b10816140fe565b9396929550929360600135925050565b600080600080600060a08688031215613b37578081fd5b8535613b42816140fe565b945060208601359350604086013567ffffffffffffffff811115613b64578182fd5b613b70888289016139c4565b935050606086013560038110613b84578182fd5b949793965091946080013592915050565b60006020808385031215613ba7578182fd5b823567ffffffffffffffff80821115613bbe578384fd5b818501915085601f830112613bd1578384fd5b813581811115613be357613be36140e8565b8060051b613bf2858201613fb5565b8281528581019085870183870188018b1015613c0c578889fd5b8893505b84841015613c4957803586811115613c2657898afd5b613c348c8a838b01016139c4565b84525060019390930192918701918701613c10565b509998505050505050505050565b600060208284031215613c68578081fd5b81518015158114613a4b578182fd5b600060208284031215613c88578081fd5b5051919050565b600060208284031215613ca0578081fd5b813567ffffffffffffffff811115613cb6578182fd5b613cc2848285016139c4565b949350505050565b600060208284031215613cdb578081fd5b5035919050565b60008060408385031215613cf4578182fd5b505080516020909101519092909150565b60008151808452613d1d81602086016020860161403a565b601f01601f19169290920160200192915050565b60008251613d4381846020870161403a565b9190910192915050565b600080835482600182811c915080831680613d6957607f831692505b6020808410821415613d8957634e487b7160e01b87526022600452602487fd5b818015613d9d5760018114613dae57613dda565b60ff19861689528489019650613dda565b60008a815260209020885b86811015613dd25781548b820152908501908301613db9565b505084890196505b509498975050505050505050565b6020810160028310613dfc57613dfc6140d2565b91905290565b602081526000613a4b6020830184613d05565b608081526000613e286080830187613d05565b6001600160a01b0386166020840152905060038410613e4957613e496140d2565b60408201939093526060015292915050565b60208082526027908201527f4e465452656769737472793a20524e4d20636f6e74726163742069736e2774206040820152661cd95d081e595d60ca1b606082015260800190565b60208082526032908201527f4e465452656769737472793a204e616d696e67204372656469747320636f6e746040820152711c9858dd081a5cdb89dd081cd95d081e595d60721b606082015260800190565b60208082526034908201527f4e465452656769737472793a204d61726b6574706c6163652061646472657373604082015273081a185cdb89dd081899595b881cd95d081e595d60621b606082015260800190565b6020808252818101527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572604082015260600190565b848152836020820152608060408201526000613f9c6080830185613d05565b905060018060a01b038316606083015295945050505050565b604051601f8201601f1916810167ffffffffffffffff81118282101715613fde57613fde6140e8565b604052919050565b60008219821115613ff957613ff96140bc565b500190565b600060ff821660ff84168060ff0382111561401b5761401b6140bc565b019392505050565b600082821015614035576140356140bc565b500390565b60005b8381101561405557818101518382015260200161403d565b83811115610b5e5750506000910152565b600181811c9082168061407a57607f821691505b6020821081141561409b57634e487b7160e01b600052602260045260246000fd5b50919050565b60006000198214156140b5576140b56140bc565b5060010190565b634e487b7160e01b600052601160045260246000fd5b634e487b7160e01b600052602160045260246000fd5b634e487b7160e01b600052604160045260246000fd5b6001600160a01b038116811461296957600080fdfea2646970667358221220205e8e62c259d0c34500e2cab18f9283c275d781e544c91ea96d2a8a0087b3ac64736f6c634300080400334e465452656769737472793a206d696e206e616d696e6720707269636520696e4e465452656769737472793a20496e20636f6e7374727563746f722c2063616e000000000000000000000000b47e3cd837ddf8e4c57f05d70ab865de6e193bbb000000000000000000000000388d7bd34dd59f62bc93c5066ff6c468e68eaaa7000000000000000000000000c02aaa39b223fe8d0a0e5c4f27ead9083c756cc200000000000000000000000004a040bbc188c0a893cccb913a6a93f643761c70000000000000000000000000000000000000000000000000002386f26fc100000000000000000000000000000000000000000000000000008ac7230489e80000

Deployed Bytecode

0x6080604052600436106103355760003560e01c806384c3f20c116101ab578063bbc5f334116100f7578063e43acea411610095578063f2fde38b1161006f578063f2fde38b14610a08578063f7f343c314610a28578063fc7f921d14610a48578063fc8009b714610a5e57600080fd5b8063e43acea414610999578063e73fc0c3146109af578063e88d1b5c146109f357600080fd5b8063daa17f49116100d1578063daa17f4914610959578063dc13141c14610979578063dc3d1f8b14610710578063e1c24c5c146107c457600080fd5b8063bbc5f33414610900578063c5ebb85f14610920578063cb479e591461094057600080fd5b80638df49ed911610164578063ad5c46481161013e578063ad5c46481461086c578063b47cc556146108a0578063b5a7c806146108c0578063b77564b8146108e057600080fd5b80638df49ed9146107f85780639416b4231461082c5780639ffdb65a1461084c57600080fd5b806384c3f20c14610745578063866f4d67146107795780638a3611dd1461078f5780638bbe43a8146107a45780638d6d1b54146107c45780638da5cb5b146107da57600080fd5b806346fd3b0c11610285578063715018a6116102235780637d6db09e116101fd5780637d6db09e146106b857806380fb45ca146106f0578063838322af1461071057806383e7e5be1461072557600080fd5b8063715018a61461060557806375bf97071461061a5780637b6e79751461064e57600080fd5b806359556b001161025f57806359556b001461057757806364df049e146105915780636b3b88a8146105b157806370f34938146105e557600080fd5b806346fd3b0c146105095780634d0d1cde146105295780635418bb0f1461055757600080fd5b80632922b507116102f25780632f019cc9116102cc5780632f019cc91461045a57806332b5d0e4146104925780633332800e146104a857806341a379b3146104f357600080fd5b80632922b507146103ed5780632af745dd1461040d5780632ce4a66c1461042d57600080fd5b80630dd6794f1461033a578063139a2d7714610351578063186d1b0a1461037157806318e880ac1461039a57806319c02b27146103ad5780631df47f80146103cd575b600080fd5b34801561034657600080fd5b5061034f610a9f565b005b34801561035d57600080fd5b5061034f61036c366004613ad9565b610b64565b34801561037d57600080fd5b5061038760065481565b6040519081526020015b60405180910390f35b61034f6103a8366004613b20565b610ef5565b3480156103b957600080fd5b5061034f6103c8366004613aae565b611eb9565b3480156103d957600080fd5b5061034f6103e8366004613a2f565b611f5b565b3480156103f957600080fd5b5061034f610408366004613aae565b612052565b34801561041957600080fd5b5061034f610428366004613a2f565b612251565b34801561043957600080fd5b5061044d610448366004613aae565b6123dc565b6040516103919190613e02565b34801561046657600080fd5b50600d5461047a906001600160a01b031681565b6040516001600160a01b039091168152602001610391565b34801561049e57600080fd5b5061038760025481565b3480156104b457600080fd5b506104e36104c3366004613c8f565b8051602081830181018051600a8252928201919093012091525460ff1681565b6040519015158152602001610391565b3480156104ff57600080fd5b5061038760055481565b34801561051557600080fd5b5061034f610524366004613cca565b612481565b34801561053557600080fd5b5060015461054a90600160a01b900460ff1681565b6040516103919190613de8565b34801561056357600080fd5b5061034f610572366004613a2f565b61265c565b34801561058357600080fd5b506008546104e39060ff1681565b34801561059d57600080fd5b5060045461047a906001600160a01b031681565b3480156105bd57600080fd5b5061047a7f000000000000000000000000b47e3cd837ddf8e4c57f05d70ab865de6e193bbb81565b3480156105f157600080fd5b5061034f610600366004613b95565b612731565b34801561061157600080fd5b5061034f61296c565b34801561062657600080fd5b5061047a7f000000000000000000000000388d7bd34dd59f62bc93c5066ff6c468e68eaaa781565b34801561065a57600080fd5b50610699610669366004613c8f565b8051602081830181018051601182529282019190930120915280546001909101546001600160a01b039091169082565b604080516001600160a01b039093168352602083019190915201610391565b3480156106c457600080fd5b506103876106d3366004613aae565b601260209081526000928352604080842090915290825290205481565b3480156106fc57600080fd5b5061034f61070b366004613cca565b6129a2565b34801561071c57600080fd5b50610387600a81565b34801561073157600080fd5b50600c5461047a906001600160a01b031681565b34801561075157600080fd5b506103877f0000000000000000000000000000000000000000000000008ac7230489e8000081565b34801561078557600080fd5b5061038760075481565b34801561079b57600080fd5b5061034f612a7e565b3480156107b057600080fd5b5061034f6107bf366004613cca565b612ab4565b3480156107d057600080fd5b506103876103e881565b3480156107e657600080fd5b506001546001600160a01b031661047a565b34801561080457600080fd5b506103877f000000000000000000000000000000000000000000000000002386f26fc1000081565b34801561083857600080fd5b5061044d610847366004613c8f565b612b93565b34801561085857600080fd5b506104e3610867366004613c8f565b612d58565b34801561087857600080fd5b5061047a7f000000000000000000000000c02aaa39b223fe8d0a0e5c4f27ead9083c756cc281565b3480156108ac57600080fd5b5061034f6108bb366004613a2f565b612f9f565b3480156108cc57600080fd5b5061034f6108db366004613a2f565b61306a565b3480156108ec57600080fd5b50600b5461047a906001600160a01b031681565b34801561090c57600080fd5b5061034f61091b366004613aae565b613171565b34801561092c57600080fd5b5061034f61093b366004613a2f565b613208565b34801561094c57600080fd5b5061038764174876e80081565b34801561096557600080fd5b50600e5461047a906001600160a01b031681565b34801561098557600080fd5b5061034f610994366004613a2f565b6132d3565b3480156109a557600080fd5b5061038760095481565b3480156109bb57600080fd5b506109cf6109ca366004613c8f565b61338e565b6040805182516001600160a01b031681526020928301519281019290925201610391565b3480156109ff57600080fd5b5061034f6133ef565b348015610a1457600080fd5b5061034f610a23366004613a2f565b6135a5565b348015610a3457600080fd5b5061044d610a43366004613aae565b61363d565b348015610a5457600080fd5b5061038760035481565b348015610a6a57600080fd5b506104e3610a79366004613a6e565b600f60209081526000938452604080852082529284528284209052825290205460ff1681565b6001546001600160a01b03163314610ad25760405162461bcd60e51b8152600401610ac990613f48565b60405180910390fd5b600c546001600160a01b0316610afa5760405162461bcd60e51b8152600401610ac990613ea2565b600c60009054906101000a90046001600160a01b03166001600160a01b0316630dd6794f6040518163ffffffff1660e01b8152600401600060405180830381600087803b158015610b4a57600080fd5b505af1158015610b5e573d6000803e3d6000fd5b50505050565b600e546001600160a01b0316610b8c5760405162461bcd60e51b8152600401610ac990613ef4565b600e546001600160a01b03163314610c0c5760405162461bcd60e51b815260206004820152603d60248201527f4e465452656769737472793a204f6e6c7920746865204d61726b6574706c616360448201527f6520636f6e74726163742063616e206d616b6520746869732063616c6c0000006064820152608401610ac9565b6000610c1885856136f6565b6001600160a01b038082166000908152600f60209081526040808320938a1683529281528282208883529052205490915060ff16610cb75760405162461bcd60e51b815260206004820152603660248201527f4e465452656769737472793a204e4654206861736e2774206265656e20616c6c60448201527537bbb2b2103337b9103730b6b2903a3930b739b332b960511b6064820152608401610ac9565b6001600160a01b038516600090815260106020908152604080832087845290915281208054610ce590614066565b80601f0160208091040260200160405190810160405280929190818152602001828054610d1190614066565b8015610d5e5780601f10610d3357610100808354040283529160200191610d5e565b820191906000526020600020905b815481529060010190602001808311610d4157829003601f168201915b505050505090506000815111610dcf5760405162461bcd60e51b815260206004820152603060248201527f4e465452656769737472793a2043616e2774207472616e73666572206e616d6560448201526f08185cc81a5d081a5cdb89dd081cd95d60821b6064820152608401610ac9565b60408051602080820180845260008084526001600160a01b038b168152601083528481208a82529092529290209051610e08929061392b565b506001600160a01b038416600090815260106020908152604080832086845282529091208251610e3a9284019061392b565b506040518060400160405280856001600160a01b03168152602001848152506011610e6483612b93565b604051610e719190613d31565b9081526040519081900360209081018220835181546001600160a01b039182166001600160a01b03199091161782559390910151600190910155858216918816907feb477db04e3acb04a54b59dc5662711ce9929dd7b0393b68832f7c998862a57d90610ee5908990889087908990613f7d565b60405180910390a3505050505050565b60026000541415610f485760405162461bcd60e51b815260206004820152601f60248201527f5265656e7472616e637947756172643a207265656e7472616e742063616c6c006044820152606401610ac9565b60026000556001808054600160a01b900460ff1690811115610f7a57634e487b7160e01b600052602160045260246000fd5b14610fd55760405162461bcd60e51b815260206004820152602560248201527f4e465452656769737472793a204e6f7420726561647920666f72206e616d696e60448201526419c81e595d60da1b6064820152608401610ac9565b610fdf85856137ff565b610fe883612d58565b61103e5760405162461bcd60e51b815260206004820152602160248201527f4e465452656769737472793a204e6f7420612076616c6964206e6577206e616d6044820152606560f81b6064820152608401610ac9565b6001600160a01b038516600090815260106020908152604080832087845290915290819020905160029161107191613d4d565b602060405180830381855afa15801561108e573d6000803e3d6000fd5b5050506040513d601f19601f820116820180604052508101906110b19190613c77565b6002846040516110c19190613d31565b602060405180830381855afa1580156110de573d6000803e3d6000fd5b5050506040513d601f19601f820116820180604052508101906111019190613c77565b14156111685760405162461bcd60e51b815260206004820152603060248201527f4e465452656769737472793a204e6577206e616d652069732073616d6520617360448201526f207468652063757272656e74206f6e6560801b6064820152608401610ac9565b6111b7601161117685612b93565b6040516111839190613d31565b90815260408051918290036020908101832083830190925281546001600160a01b031683526001909101549082015261387a565b61120e5760405162461bcd60e51b815260206004820152602260248201527f4e465452656769737472793a204e616d6520616c726561647920726573657276604482015261195960f21b6064820152608401610ac9565b600282600281111561123057634e487b7160e01b600052602160045260246000fd5b14156112c157806001146112bc5760405162461bcd60e51b815260206004820152604760248201527f4e465452656769737472793a2063757272656e63795175616e74697479206d7560448201527f73742062652031207768656e206e616d696e672077697468204e616d696e67206064820152664372656469747360c81b608482015260a401610ac9565b611411565b60018260028111156112e357634e487b7160e01b600052602160045260246000fd5b141561137b5760035481146112bc5760405162461bcd60e51b815260206004820152605260248201527f4e465452656769737472793a2063757272656e63795175616e74697479206d7560448201527f737420626520657175616c20746f206e616d696e675072696365524e4d207768606482015271656e206e616d696e67207769746820524e4d60701b608482015260a401610ac9565b60025481146114115760405162461bcd60e51b815260206004820152605660248201527f4e465452656769737472793a2063757272656e63795175616e74697479206d7560448201527f737420626520657175616c20746f206e616d696e6750726963654574686572206064820152753bb432b7103730b6b4b733903bb4ba341022ba3432b960511b608482015260a401610ac9565b600a61141c84612b93565b6040516114299190613d31565b9081526040519081900360200190205460ff16156114e9576040516323b872dd60e01b8152336004820152306024820152600160448201527f000000000000000000000000388d7bd34dd59f62bc93c5066ff6c468e68eaaa76001600160a01b0316906323b872dd90606401602060405180830381600087803b1580156114af57600080fd5b505af11580156114c3573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906114e79190613c57565b505b600182600281111561150b57634e487b7160e01b600052602160045260246000fd5b148015611519575060055443105b1561157e5760405162461bcd60e51b815260206004820152602f60248201527f4e465452656769737472793a204e6f7420726561647920666f72206e616d696e60448201526e672070616964207769746820524e4d60881b6064820152608401610ac9565b600d546000906001600160a01b0316158015906115bc57506001600160a01b0386166000908152601260209081526040808320888452909152902054155b156116c857600d54604051631a0ec30360e31b81526001600160a01b038881166004830152600092839291169063d076181890602401604080518083038186803b15801561160957600080fd5b505afa15801561161d573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906116419190613ce2565b915091508143101580156116555750804311155b156116c557600d5460405163a562f95d60e01b81526001600160a01b038a81166004830152602482018a90529091169063a562f95d90604401600060405180830381600087803b1580156116a857600080fd5b505af11580156116bc573d6000803e3d6000fd5b50505050600192505b50505b80611c955760008360028111156116ef57634e487b7160e01b600052602160045260246000fd5b1415611a62573460025411156118d9573460025461170d9190614023565b6040516370a0823160e01b81523360048201527f000000000000000000000000c02aaa39b223fe8d0a0e5c4f27ead9083c756cc26001600160a01b0316906370a082319060240160206040518083038186803b15801561176c57600080fd5b505afa158015611780573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906117a49190613c77565b101561180d5760405162461bcd60e51b815260206004820152603260248201527f4e465452656769737472793a204e6f7420656e6f756768204554482073656e74604482015271206f72205745544820617661696c61626c6560701b6064820152608401610ac9565b7f000000000000000000000000c02aaa39b223fe8d0a0e5c4f27ead9083c756cc26001600160a01b03166323b872dd33303460025461184c9190614023565b6040516001600160e01b031960e086901b1681526001600160a01b0393841660048201529290911660248301526044820152606401602060405180830381600087803b15801561189b57600080fd5b505af11580156118af573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906118d39190613c57565b5061193e565b346002541461193e5760405162461bcd60e51b815260206004820152602b60248201527f4e465452656769737472793a20546f6f206d7563682045746865722073656e7460448201526a20666f72206e616d696e6760a81b6064820152608401610ac9565b7f000000000000000000000000c02aaa39b223fe8d0a0e5c4f27ead9083c756cc26001600160a01b031663d0e30db0346040518263ffffffff1660e01b81526004016000604051808303818588803b15801561199957600080fd5b505af11580156119ad573d6000803e3d6000fd5b50506004805460025460405163a9059cbb60e01b81526001600160a01b039283169381019390935260248301527f000000000000000000000000c02aaa39b223fe8d0a0e5c4f27ead9083c756cc216935063a9059cbb92506044019050602060405180830381600087803b158015611a2457600080fd5b505af1158015611a38573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611a5c9190613c57565b50611c95565b6002836002811115611a8457634e487b7160e01b600052602160045260246000fd5b1415611b1c57600c546001600160a01b0316611ab25760405162461bcd60e51b8152600401610ac990613ea2565b600c546040516318f32ab360e31b8152336004820152600160248201526001600160a01b039091169063c7995598906044015b600060405180830381600087803b158015611aff57600080fd5b505af1158015611b13573d6000803e3d6000fd5b50505050611c95565b6001836002811115611b3e57634e487b7160e01b600052602160045260246000fd5b1415611c3057600b546001600160a01b0316611b6c5760405162461bcd60e51b8152600401610ac990613e5b565b600b546003546040516323b872dd60e01b815233600482015230602482015260448101919091526001600160a01b03909116906323b872dd90606401602060405180830381600087803b158015611bc257600080fd5b505af1158015611bd6573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611bfa9190613c57565b50600b54600354604051630852cd8d60e31b81526001600160a01b03909216916342966c6891611ae59160040190815260200190565b60405162461bcd60e51b815260206004820152603460248201527f4e465452656769737472793a205468652063757272656e63792069736e277420604482015273737570706f7274656420666f72206e616d696e6760601b6064820152608401610ac9565b6001600160a01b038616600090815260106020908152604080832088845290915281208054611cc390614066565b90501115611d81576001600160a01b038616600090815260106020908152604080832088845290915290208054611d819190611cfe90614066565b80601f0160208091040260200160405190810160405280929190818152602001828054611d2a90614066565b8015611d775780601f10611d4c57610100808354040283529160200191611d77565b820191906000526020600020905b815481529060010190602001808311611d5a57829003601f168201915b5050505050613899565b6040518060400160405280876001600160a01b03168152602001868152506011611daa86612b93565b604051611db79190613d31565b9081526040805160209281900383019020835181546001600160a01b0319166001600160a01b03918216178255938301516001909101559188166000908152601082528281208882528252919091208551611e149287019061392b565b506001600160a01b0386166000908152601260209081526040808320888452909152902054611e64576001600160a01b038616600090815260126020908152604080832088845290915290204390555b84866001600160a01b03167fdaaef4e21298fe0051de164f9ecb62a3400672506c9dc877928aee534133fbeb86338787604051611ea49493929190613e15565b60405180910390a35050600160005550505050565b600e546001600160a01b0316611ee15760405162461bcd60e51b8152600401610ac990613ef4565b611eeb82826137ff565b336000818152600f602090815260408083206001600160a01b038716808552908352818420868552835292819020805460ff19166001179055518481529192917f3e0dec829a933a85a6f226ab0941c1c07f3f005e507450e2bc7be22246efed4991015b60405180910390a35050565b6001546001600160a01b03163314611f855760405162461bcd60e51b8152600401610ac990613f48565b60085460ff166120085760405162461bcd60e51b815260206004820152604260248201527f4e465452656769737472793a205570646174696e67207468652070726f746f6360448201527f6f6c2066656520726563697069656e7420686173206265656e2073687574206f606482015261333360f11b608482015260a401610ac9565b600480546001600160a01b0319166001600160a01b0383169081179091556040517f8cffb07faa2874440346743bdc0a86b06c3335cc47dc49b327d10e77b73ceb1090600090a250565b6001546001600160a01b0316331461207c5760405162461bcd60e51b8152600401610ac990613f48565b600c546001600160a01b03166120a45760405162461bcd60e51b8152600401610ac990613ea2565b600a8111156121255760405162461bcd60e51b815260206004820152604160248201527f4e465452656769737472793a2043616e27742061737369676e2074686174206e60448201527f756d626572206f66206372656469747320696e20612073696e676c652063616c6064820152601b60fa1b608482015260a401610ac9565b6103e8816007546121369190613fe6565b11156121d05760405162461bcd60e51b815260206004820152605e60248201527f4e465452656769737472793a2041737369676e696e672074686174206e756d6260448201527f6572206f66206372656469747320776f756c642074616b6520746f74616c206160648201527f737369676e65642063726564697473206f76657220746865206c696d69740000608482015260a401610ac9565b80600760008282546121e29190613fe6565b9091555050600c54604051632922b50760e01b81526001600160a01b0384811660048301526024820184905290911690632922b50790604401600060405180830381600087803b15801561223557600080fd5b505af1158015612249573d6000803e3d6000fd5b505050505050565b6001546001600160a01b0316331461227b5760405162461bcd60e51b8152600401610ac990613f48565b600d546001600160a01b03166122ec5760405162461bcd60e51b815260206004820152603060248201527f4e465452656769737472793a20486f6c64204661726d696e6720636f6e74726160448201526f18dd081a5cdb89dd081cd95d081e595d60821b6064820152608401610ac9565b600a600654106123645760405162461bcd60e51b815260206004820152603d60248201527f4e465452656769737472793a204e756d626572206f662063757261746564206360448201527f6f6c6c656374696f6e7320686173206265656e206d61786564206f75740000006064820152608401610ac9565b60068054906000612374836140a1565b9091555050600d54604051632af745dd60e01b81526001600160a01b03838116600483015290911690632af745dd906024015b600060405180830381600087803b1580156123c157600080fd5b505af11580156123d5573d6000803e3d6000fd5b5050505050565b60106020908152600092835260408084209091529082529020805461240090614066565b80601f016020809104026020016040519081016040528092919081815260200182805461242c90614066565b80156124795780601f1061244e57610100808354040283529160200191612479565b820191906000526020600020905b81548152906001019060200180831161245c57829003601f168201915b505050505081565b6001546001600160a01b031633146124ab5760405162461bcd60e51b8152600401610ac990613f48565b64174876e8006005541461251f5760405162461bcd60e51b815260206004820152603560248201527f4e465452656769737472793a20726e6d4e616d696e675374617274426c6f636b6044820152742063616e206f6e6c7920626520736574206f6e636560581b6064820152608401610ac9565b4381116125945760405162461bcd60e51b815260206004820152603860248201527f4e465452656769737472793a20524e4d206e616d696e6720737461727420626c60448201527f6f636b2063616e27742062652073657420746f207061737400000000000000006064820152608401610ac9565b6125a1436202ee00613fe6565b81106126205760405162461bcd60e51b815260206004820152604260248201527f4e465452656769737472793a20524e4d206e616d696e6720737461727420626c60448201527f6f636b2063616e27742062652073657420736f2066617220696e20616476616e606482015261636560f01b608482015260a401610ac9565b60058190556040518181527f439097389fa3099271ae82924d227c95c4b789ef05c14c8249511392775d2f07906020015b60405180910390a150565b6001546001600160a01b031633146126865760405162461bcd60e51b8152600401610ac990613f48565b600c546001600160a01b03161561270f5760405162461bcd60e51b815260206004820152604160248201527f4e465452656769737472793a206e616d696e67206372656469747320636f6e7460448201527f7261637420616464726573732063616e206f6e6c7920626520736574206f6e636064820152606560f81b608482015260a401610ac9565b600c80546001600160a01b0319166001600160a01b0392909216919091179055565b6001546001600160a01b0316331461275b5760405162461bcd60e51b8152600401610ac990613f48565b6103e8815160095461276d9190613fe6565b11156127ed5760405162461bcd60e51b815260206004820152604360248201527f4e465452656769737472793a205468697320776f756c64206d616b652073706560448201527f6369616c206e616d6573206c697374206c6f6e676572207468616e20616c6c6f6064820152621dd95960ea1b608482015260a401610ac9565b60005b815181101561294857600a61282b83838151811061281e57634e487b7160e01b600052603260045260246000fd5b6020026020010151612b93565b6040516128389190613d31565b9081526040519081900360200190205460ff16156128cc5760405162461bcd60e51b815260206004820152604560248201527f4e465452656769737472793a204174206c65617374206f6e65206f662074686560448201527f206e616d657320697320616c726561647920696e20746865207370656369616c606482015264081b1a5cdd60da1b608482015260a401610ac9565b6001600a6128f384848151811061281e57634e487b7160e01b600052603260045260246000fd5b6040516129009190613d31565b908152604051908190036020019020805491151560ff1990921691909117905560098054906000612930836140a1565b91905055508080612940906140a1565b9150506127f0565b506103e86009541415612969576001805460ff60a01b1916600160a01b1790555b50565b6001546001600160a01b031633146129965760405162461bcd60e51b8152600401610ac990613f48565b6129a060006138d9565b565b6001546001600160a01b031633146129cc5760405162461bcd60e51b8152600401610ac990613f48565b7f0000000000000000000000000000000000000000000000008ac7230489e80000811015612a4a5760405162461bcd60e51b815260206004820152602560248201527f4e465452656769737472793a20524e4d206e616d696e6720707269636520746f6044820152646f206c6f7760d81b6064820152608401610ac9565b60038190556040518181527e33c32d7ad6f0120d1a4eab9be1d62b3f8ff0c4b1a24fdfdc2eb3221dcc5e4a90602001612651565b6001546001600160a01b03163314612aa85760405162461bcd60e51b8152600401610ac990613f48565b6008805460ff19169055565b6001546001600160a01b03163314612ade5760405162461bcd60e51b8152600401610ac990613f48565b7f000000000000000000000000000000000000000000000000002386f26fc10000811015612b5e5760405162461bcd60e51b815260206004820152602760248201527f4e465452656769737472793a204554484552206e616d696e6720707269636520604482015266746f6f206c6f7760c81b6064820152608401610ac9565b60028190556040518181527f28b5c9776fb5d8d7b813bbcdfe31a02505b31efb0b803266bcb60ed493e800f190602001612651565b606060008290506000815167ffffffffffffffff811115612bc457634e487b7160e01b600052604160045260246000fd5b6040519080825280601f01601f191660200182016040528015612bee576020820181803683370190505b50905060005b8251811015612d50576041838281518110612c1f57634e487b7160e01b600052603260045260246000fd5b016020015160f81c10801590612c5d5750605a838281518110612c5257634e487b7160e01b600052603260045260246000fd5b016020015160f81c11155b15612cdb57828181518110612c8257634e487b7160e01b600052603260045260246000fd5b602001015160f81c60f81b60f81c6020612c9c9190613ffe565b60f81b828281518110612cbf57634e487b7160e01b600052603260045260246000fd5b60200101906001600160f81b031916908160001a905350612d3e565b828181518110612cfb57634e487b7160e01b600052603260045260246000fd5b602001015160f81c60f81b828281518110612d2657634e487b7160e01b600052603260045260246000fd5b60200101906001600160f81b031916908160001a9053505b80612d48816140a1565b915050612bf4565b509392505050565b600080829050600181511015612d715750600092915050565b601981511115612d845750600092915050565b80600081518110612da557634e487b7160e01b600052603260045260246000fd5b6020910101516001600160f81b031916600160fd1b1415612dc95750600092915050565b8060018251612dd89190614023565b81518110612df657634e487b7160e01b600052603260045260246000fd5b6020910101516001600160f81b031916600160fd1b1415612e1a5750600092915050565b600081600081518110612e3d57634e487b7160e01b600052603260045260246000fd5b01602001516001600160f81b031916905060005b8251811015612f94576000838281518110612e7c57634e487b7160e01b600052603260045260246000fd5b01602001516001600160f81b0319169050600160fd1b81148015612ead5750600160fd1b6001600160f81b03198416145b15612ebe5750600095945050505050565b600360fc1b6001600160f81b0319821610801590612eea5750603960f81b6001600160f81b0319821611155b158015612f205750604160f81b6001600160f81b0319821610801590612f1e5750602d60f91b6001600160f81b0319821611155b155b8015612f555750606160f81b6001600160f81b0319821610801590612f535750603d60f91b6001600160f81b0319821611155b155b8015612f6f5750600160fd1b6001600160f81b0319821614155b15612f805750600095945050505050565b915080612f8c816140a1565b915050612e51565b506001949350505050565b6001546001600160a01b03163314612fc95760405162461bcd60e51b8152600401610ac990613f48565b600e546001600160a01b0316156130485760405162461bcd60e51b815260206004820152603e60248201527f4e465452656769737472793a206d61726b6574706c61636520636f6e7472616360448201527f7420616464726573732063616e206f6e6c7920626520736574206f6e636500006064820152608401610ac9565b600e80546001600160a01b0319166001600160a01b0392909216919091179055565b6001546001600160a01b031633146130945760405162461bcd60e51b8152600401610ac990613f48565b600c546001600160a01b03166130bc5760405162461bcd60e51b8152600401610ac990613ea2565b60085460ff166131405760405162461bcd60e51b815260206004820152604360248201527f4e465452656769737472793a205570646174696e67207468652070726f746f6360448201527f6f6c206672656520726563697069656e7420686173206265656e20736875742060648201526237b33360e91b608482015260a401610ac9565b600c54604051623be8ff60e71b81526001600160a01b03838116600483015290911690631df47f80906024016123a7565b600e546001600160a01b03166131995760405162461bcd60e51b8152600401610ac990613ef4565b6131a382826137ff565b336000818152600f602090815260408083206001600160a01b038716808552908352818420868552835292819020805460ff19169055518481529192917f6f3e41c3eb642e6be48df2a585aa1e90d91e5984a4941179f65c49e445b2ddd09101611f4f565b6001546001600160a01b031633146132325760405162461bcd60e51b8152600401610ac990613f48565b600d546001600160a01b0316156132b15760405162461bcd60e51b815260206004820152603f60248201527f4e465452656769737472793a20686f6c64206661726d696e6720636f6e74726160448201527f637420616464726573732063616e206f6e6c7920626520736574206f6e6365006064820152608401610ac9565b600d80546001600160a01b0319166001600160a01b0392909216919091179055565b6001546001600160a01b031633146132fd5760405162461bcd60e51b8152600401610ac990613f48565b600b546001600160a01b03161561336c5760405162461bcd60e51b815260206004820152602d60248201527f4e465452656769737472793a20524e4d20616464726573732068617320616c7260448201526c1958591e481899595b881cd95d609a1b6064820152608401610ac9565b600b80546001600160a01b0319166001600160a01b0392909216919091179055565b604080518082019091526000808252602082015260116133ad83612b93565b6040516133ba9190613d31565b90815260408051918290036020908101832083830190925281546001600160a01b031683526001909101549082015292915050565b6001546001600160a01b031633146134195760405162461bcd60e51b8152600401610ac990613f48565b600b546001600160a01b03166134415760405162461bcd60e51b8152600401610ac990613e5b565b600b546040516370a0823160e01b81523060048201526000916001600160a01b0316906370a082319060240160206040518083038186803b15801561348557600080fd5b505afa158015613499573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906134bd9190613c77565b90508061351d5760405162461bcd60e51b815260206004820152602860248201527f4e465452656769737472793a205468657265206973206e6f20524e4d20746f20604482015267776974686472617760c01b6064820152608401610ac9565b600b5460405163a9059cbb60e01b8152336004820152602481018390526001600160a01b039091169063a9059cbb90604401602060405180830381600087803b15801561356957600080fd5b505af115801561357d573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906135a19190613c57565b5050565b6001546001600160a01b031633146135cf5760405162461bcd60e51b8152600401610ac990613f48565b6001600160a01b0381166136345760405162461bcd60e51b815260206004820152602660248201527f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160448201526564647265737360d01b6064820152608401610ac9565b612969816138d9565b6001600160a01b0382166000908152601060209081526040808320848452909152902080546060919061366f90614066565b80601f016020809104026020016040519081016040528092919081815260200182805461369b90614066565b80156136e85780601f106136bd576101008083540402835291602001916136e8565b820191906000526020600020905b8154815290600101906020018083116136cb57829003601f168201915b505050505090505b92915050565b60007f000000000000000000000000b47e3cd837ddf8e4c57f05d70ab865de6e193bbb6001600160a01b0316836001600160a01b031614156137d257604051630b02f02d60e31b8152600481018390527f000000000000000000000000b47e3cd837ddf8e4c57f05d70ab865de6e193bbb6001600160a01b0316906358178168906024015b60206040518083038186803b15801561379357600080fd5b505afa1580156137a7573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906137cb9190613a52565b90506136f0565b6040516331a9108f60e11b8152600481018390526001600160a01b03841690636352211e9060240161377b565b61380982826136f6565b6001600160a01b0316336001600160a01b0316146135a15760405162461bcd60e51b815260206004820152602860248201527f4e465452656769737472793a2043616c6c6572206973206e6f7420746865204e604482015267232a1037bbb732b960c11b6064820152608401610ac9565b80516000906001600160a01b03161580156136f0575050602001511590565b60116138a482612b93565b6040516138b19190613d31565b90815260405190819003602001902080546001600160a01b0319168155600060019091015550565b600180546001600160a01b038381166001600160a01b0319831681179093556040519116919082907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e090600090a35050565b82805461393790614066565b90600052602060002090601f016020900481019282613959576000855561399f565b82601f1061397257805160ff191683800117855561399f565b8280016001018555821561399f579182015b8281111561399f578251825591602001919060010190613984565b506139ab9291506139af565b5090565b5b808211156139ab57600081556001016139b0565b600082601f8301126139d4578081fd5b813567ffffffffffffffff8111156139ee576139ee6140e8565b613a01601f8201601f1916602001613fb5565b818152846020838601011115613a15578283fd5b816020850160208301379081016020019190915292915050565b600060208284031215613a40578081fd5b8135613a4b816140fe565b9392505050565b600060208284031215613a63578081fd5b8151613a4b816140fe565b600080600060608486031215613a82578182fd5b8335613a8d816140fe565b92506020840135613a9d816140fe565b929592945050506040919091013590565b60008060408385031215613ac0578182fd5b8235613acb816140fe565b946020939093013593505050565b60008060008060808587031215613aee578081fd5b8435613af9816140fe565b9350602085013592506040850135613b10816140fe565b9396929550929360600135925050565b600080600080600060a08688031215613b37578081fd5b8535613b42816140fe565b945060208601359350604086013567ffffffffffffffff811115613b64578182fd5b613b70888289016139c4565b935050606086013560038110613b84578182fd5b949793965091946080013592915050565b60006020808385031215613ba7578182fd5b823567ffffffffffffffff80821115613bbe578384fd5b818501915085601f830112613bd1578384fd5b813581811115613be357613be36140e8565b8060051b613bf2858201613fb5565b8281528581019085870183870188018b1015613c0c578889fd5b8893505b84841015613c4957803586811115613c2657898afd5b613c348c8a838b01016139c4565b84525060019390930192918701918701613c10565b509998505050505050505050565b600060208284031215613c68578081fd5b81518015158114613a4b578182fd5b600060208284031215613c88578081fd5b5051919050565b600060208284031215613ca0578081fd5b813567ffffffffffffffff811115613cb6578182fd5b613cc2848285016139c4565b949350505050565b600060208284031215613cdb578081fd5b5035919050565b60008060408385031215613cf4578182fd5b505080516020909101519092909150565b60008151808452613d1d81602086016020860161403a565b601f01601f19169290920160200192915050565b60008251613d4381846020870161403a565b9190910192915050565b600080835482600182811c915080831680613d6957607f831692505b6020808410821415613d8957634e487b7160e01b87526022600452602487fd5b818015613d9d5760018114613dae57613dda565b60ff19861689528489019650613dda565b60008a815260209020885b86811015613dd25781548b820152908501908301613db9565b505084890196505b509498975050505050505050565b6020810160028310613dfc57613dfc6140d2565b91905290565b602081526000613a4b6020830184613d05565b608081526000613e286080830187613d05565b6001600160a01b0386166020840152905060038410613e4957613e496140d2565b60408201939093526060015292915050565b60208082526027908201527f4e465452656769737472793a20524e4d20636f6e74726163742069736e2774206040820152661cd95d081e595d60ca1b606082015260800190565b60208082526032908201527f4e465452656769737472793a204e616d696e67204372656469747320636f6e746040820152711c9858dd081a5cdb89dd081cd95d081e595d60721b606082015260800190565b60208082526034908201527f4e465452656769737472793a204d61726b6574706c6163652061646472657373604082015273081a185cdb89dd081899595b881cd95d081e595d60621b606082015260800190565b6020808252818101527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572604082015260600190565b848152836020820152608060408201526000613f9c6080830185613d05565b905060018060a01b038316606083015295945050505050565b604051601f8201601f1916810167ffffffffffffffff81118282101715613fde57613fde6140e8565b604052919050565b60008219821115613ff957613ff96140bc565b500190565b600060ff821660ff84168060ff0382111561401b5761401b6140bc565b019392505050565b600082821015614035576140356140bc565b500390565b60005b8381101561405557818101518382015260200161403d565b83811115610b5e5750506000910152565b600181811c9082168061407a57607f821691505b6020821081141561409b57634e487b7160e01b600052602260045260246000fd5b50919050565b60006000198214156140b5576140b56140bc565b5060010190565b634e487b7160e01b600052601160045260246000fd5b634e487b7160e01b600052602160045260246000fd5b634e487b7160e01b600052604160045260246000fd5b6001600160a01b038116811461296957600080fdfea2646970667358221220205e8e62c259d0c34500e2cab18f9283c275d781e544c91ea96d2a8a0087b3ac64736f6c63430008040033

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

000000000000000000000000b47e3cd837ddf8e4c57f05d70ab865de6e193bbb000000000000000000000000388d7bd34dd59f62bc93c5066ff6c468e68eaaa7000000000000000000000000c02aaa39b223fe8d0a0e5c4f27ead9083c756cc200000000000000000000000004a040bbc188c0a893cccb913a6a93f643761c70000000000000000000000000000000000000000000000000002386f26fc100000000000000000000000000000000000000000000000000008ac7230489e80000

-----Decoded View---------------
Arg [0] : _punksAddress (address): 0xb47e3cd837dDF8e4c57F05d70Ab865de6e193BBB
Arg [1] : _goldenTicketAddress (address): 0x388d7bd34dd59F62bC93C5066ff6c468e68eaaA7
Arg [2] : _WETH (address): 0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2
Arg [3] : _protocolFeeRecipient (address): 0x04A040BBC188c0A893CCCB913a6A93F643761C70
Arg [4] : _minNamingPriceEther (uint256): 10000000000000000
Arg [5] : _minNamingPriceRNM (uint256): 10000000000000000000

-----Encoded View---------------
6 Constructor Arguments found :
Arg [0] : 000000000000000000000000b47e3cd837ddf8e4c57f05d70ab865de6e193bbb
Arg [1] : 000000000000000000000000388d7bd34dd59f62bc93c5066ff6c468e68eaaa7
Arg [2] : 000000000000000000000000c02aaa39b223fe8d0a0e5c4f27ead9083c756cc2
Arg [3] : 00000000000000000000000004a040bbc188c0a893cccb913a6a93f643761c70
Arg [4] : 000000000000000000000000000000000000000000000000002386f26fc10000
Arg [5] : 0000000000000000000000000000000000000000000000008ac7230489e80000


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  ]
[ 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.