ETH Price: $3,465.16 (-0.18%)
Gas: 6 Gwei

Quest-3 (⛰)
 

Overview

TokenID

471

Total Transfers

-

Market

Onchain Market Cap

$0.00

Circulating Supply Market Cap

-
Loading...
Loading
Loading...
Loading
Loading...
Loading

Click here to update the token information / general information
# Exchange Pair Price  24H Volume % Volume

Contract Source Code Verified (Exact Match)

Contract Name:
Quest3

Compiler Version
v0.8.12+commit.f00d7308

Optimization Enabled:
Yes with 200 runs

Other Settings:
default evmVersion
File 1 of 6 : Quest3.sol
// SPDX-License-Identifier: AGPL-3.0
// ©2022 Ponderware Ltd

pragma solidity ^0.8.12;

import "./openzeppelin/contracts/utils/introspection/IERC165.sol";
import "./openzeppelin/contracts/token/ERC721/IERC721.sol";
import "./openzeppelin/contracts/token/ERC721/IERC721Receiver.sol";
import "./openzeppelin/contracts/token/ERC721/extensions/IERC721Enumerable.sol";
import "./openzeppelin/contracts/token/ERC721/extensions/IERC721Metadata.sol";

interface IReverseResolver {
    function claim(address owner) external returns (bytes32);
}

interface IERC20 {
    function balanceOf(address account) external view returns (uint256);
    function transfer(address recipient, uint256 amount) external returns (bool);
}

interface IQuest3Data {
    function getDeath (uint256 seed, uint256 prevLevel, bytes[8] memory stats) external view returns (bytes memory death, string memory ending);
    function getFail (uint256 seed, uint256 level, bytes[8] memory stats) external view returns (bytes memory happening);
    function getAdvance (uint256 seed, uint256 level, bytes[8] memory stats) external view returns (bytes memory happening, bytes memory stat);
    function getMetadata (uint256 tokenId, uint256 level, uint8 journeyLength, bytes[15] memory storySegments, bytes[8] memory stats, uint16 heroStatus) external pure returns (string memory);
    function generateCompletionImage (uint tokenId, uint level, bytes memory lastWords, uint heroStatus) external pure returns (bytes memory);
    function generateProgressImage (uint tokenId, uint level) external pure returns (bytes memory);
}

/**
 * @title Quest3
 * @author Ponderware Ltd (a.k.a. Pondertech Digital Solutions)
 * @notice ERC-721 Quest Tokens (where will your journey lead?)
 * @dev ERC-721 Enumerable Token with fully-on-chain ERC721 Metadata
 */
contract Quest3 is IERC721Enumerable, IERC721Metadata {

    string public name = "Quest-3";
    string public symbol = unicode"⛰";

    uint256 public maxSupply = 25600;
    uint256 public totalSupply = 0;

    address public contractOwner;

    address[25600] internal Owners; // Maps tokenIds to owning addresses.
    mapping (address => uint256[]) internal TokensByOwner; // Mapping from address to owned tokens.
    uint16[25600] internal OwnerTokenIndex; // Maps the a tokenId to its index in the `TokensByOwner[address]` array.


    mapping(uint256 => address) internal TokenApprovals; // Mapping from token ID to approved address.
    mapping(address => mapping(address => bool)) internal OperatorApprovals; // Mapping from owner to operator approvals.

    bool paused = true; // Pausing stops all user interactions.
    bool frozen = false; // Freezing stops minting and actions.

    uint256 public MintPriceWei = 0.01994206980085 ether;

    /**
     * @dev Contains the journey information for the token. Idx 0 is the journey length, Idx [1..14] contains the reveal seed at level of the token at that journey position, and Idx 15 is a flag to indicate if an action is in the `ActionQueue`.
     */
    mapping (uint256 => uint16[16]) TokenHistory;

    /**
     * @dev The number of items a token must reveal to increase their hero status.
     */
    uint256 public HeroThreshold = 10;
    /**
     * @dev If a token reveals more than HeroThreshold actions, the number of reveals is added to that token's hero status.
     */
    uint16[25600] public HeroStatus;

    /**
     * @dev Reference to the metadata assembly contract.
     */
    IQuest3Data Data;

    // Owner Functions

    constructor (address quest3DataContract) {
        contractOwner = msg.sender;
        Data = IQuest3Data(quest3DataContract);
        IReverseResolver(0x084b1c3C81545d370f3634392De611CaaBFf8148).claim(msg.sender);
    }

    /**
     * @dev Change the owner of the contract.
     */
    function transferOwnership (address newOwner) public onlyOwner {
        contractOwner = newOwner;
    }

    function pause () public onlyOwner {
        paused = true;
    }

    function unpause () public onlyOwner {
        paused = false;
    }

    function ownerWithdraw () public {
        payable(contractOwner).transfer(address(this).balance);
    }

    function clearPendingStatus (uint256 tokenId) public onlyOwner {
        TokenHistory[tokenId][IS_PENDING_INDEX] = 0;
    }

    function setHeroThreshold (uint256 threshold) public onlyOwner {
        HeroThreshold = threshold;
    }

    /**
     * @dev Set `maxSupply` to `totalSupply` to end minting.
     */
    function permanentlyCloseMint() public onlyOwner {
        maxSupply = totalSupply;
    }

    /**
     * @dev When frozen action (and mint) calls will throw.
     */
    function setFrozen (bool state) public onlyOwner {
        frozen = state;
    }

    // Modifiers

    modifier onlyOwner() {
        require(msg.sender == contractOwner, "Not Owner");
        _;
    }

    modifier whenNotPaused() {
        require(paused == false || msg.sender == contractOwner, "Paused");
        _;
    }

    // Action Queue

    /**
     * @dev Actions are placed into the FIFO `ActionQueue` ring and revealed on future blocks.
     */
    Action[256] public ActionQueue;
    uint constant public MAX_QUEUE = 256;

    /**
     * @dev Actions are queued. The `revealBlock` is the block at which this action becomes eligible for reveal.
     */
    struct Action {
        uint128 revealBlock;
        uint128 tokenId;
    }

    /**
     * @dev `count` is the current length of the queue. `index` is the offset to the first queue item.
     */
    struct QueueCursor {
        uint16 index;
        uint16 count;
    }

    QueueCursor public Cursor = QueueCursor(0,0);

    function getQueueLength () public view returns (uint256) {
        return Cursor.count;
    }

    /**
     * @dev Assembles the `ActionQueue` into an array of actions in order (deconstructs the "ring").
     */
    function getQueue () public view returns (Action[] memory) {
        uint count = Cursor.count;
        uint index = Cursor.index;
        Action[] memory queue = new Action[](count);
        for (uint i = 0; i < queue.length; i++) {
            queue[i] = ActionQueue[index];
            index++;
            if(index == MAX_QUEUE) index = 0;
        }
        return queue;
    }

    // Quest Actions / Progress Handling

    /**
     * @dev Indexes into `TokenHistory` arrays. The seed/level data is stored in indexes [1..14].
     */
    uint256 constant JOURNEY_LENGTH_INDEX = 0;
    uint256 constant IS_PENDING_INDEX = 15;

    /**
     * @dev Reveals the most recent pending action on a token. Packs the result into [seed (12 bits), level (4 bits)].
     */
    function updateTokenHistory (uint256 tokenId) internal {
        uint16[16] storage history = TokenHistory[tokenId];
        uint journeyLength = history[JOURNEY_LENGTH_INDEX];

        uint level = history[journeyLength] & 15;

        uint prevLevel = 0;

        if (journeyLength == 0) {
            level = 1; // starting level
        } else if (journeyLength == 1) {
            prevLevel = 1; // starting level is always 1
        } else {
            prevLevel = history[journeyLength - 1] & 15; // prevLevel is penultimate level in pendingHistory
        }

        uint nextSeed = uint256(keccak256(abi.encodePacked(tokenId, blockhash(block.number-1))));

        uint resolution = nextSeed & 255;
        uint deathThreshold = 5 + level * 9;
        uint failThreshold = 90 + level * 22;
        if (level == 1) { deathThreshold = 2; } // low chance to die on level 1
        if (prevLevel == level) { failThreshold = 0; } // must die or advance
        if (resolution < deathThreshold) {
            level = 0; // died
        } else if (resolution >= failThreshold) {
            level = level + 1; // advanced
        }

        history[JOURNEY_LENGTH_INDEX] = uint16(journeyLength + 1);
        history[journeyLength + 1] = uint16((nextSeed << 4) + level);
        history[IS_PENDING_INDEX] = 0;
    }

    /**
     * @dev Reveals up to `maxReveals` pending `Action`s in the Action Queue, then enqueues the supplied `tokenId` if eligible.
     */
    function handleAction (uint256 tokenId, uint256 maxReveals) private whenNotPaused {
        require(frozen == false, "Frozen");
        uint count = Cursor.count;
        uint index = Cursor.index;
        if (maxReveals < 3) {
            maxReveals = 3;
        }
        uint revealCount = 0;
        for (uint i = 0; i < maxReveals; i++) {
            if (count == 0) break;
            Action storage action = ActionQueue[index];
            if (block.number <= action.revealBlock) break;
            updateTokenHistory(action.tokenId);
            delete ActionQueue[index];
            count--;
            index++;
            revealCount++;
            if(index == MAX_QUEUE) index = 0;
        }
        if (revealCount >= HeroThreshold) {
            HeroStatus[tokenId] += uint16(revealCount);
        }

        uint16[16] storage history = TokenHistory[tokenId];

        uint tokenJourneyLength = history[JOURNEY_LENGTH_INDEX];
        uint tokenLevel = history[tokenJourneyLength] & 15;

        if (((tokenLevel > 0 && tokenLevel < 8) || tokenJourneyLength == 0)
            && count < MAX_QUEUE
            && history[IS_PENDING_INDEX] == 0)
        {
            uint tokenQueueIndex = count + index;
            count++;
            if (MAX_QUEUE <= tokenQueueIndex) {
                tokenQueueIndex -= MAX_QUEUE;
            }
            ActionQueue[tokenQueueIndex] = Action(uint128(block.number + 1), uint128(tokenId));
            history[IS_PENDING_INDEX] = 1;
        }
        Cursor.count = uint16(count);
        Cursor.index = uint16(index);
    }

    /**
     * @notice Like `doSomething` but set a max number of reveals to perform (must be >= HeroThreshold). If it reveals enough, the number of reveals will be added to the tokens HeroScore. Can be called even if your quest is complete.
     * @dev Cannot be called by a smart contract.
     */
    function doSomethingHeroic (uint256 tokenId, uint256 maxAssists) public {
        require(msg.sender == Owners[tokenId] && msg.sender == tx.origin, "Not Owner");
        require(maxAssists >= HeroThreshold, "A true hero must assist many others");
        handleAction(tokenId, maxAssists);
    }

    /**
     * @notice Places the token into the `ActionQueue` where it will be revealed by actions in future blocks. Reveals up to 3 pending actions.
     * @dev Cannot be called by a smart contract.
     */
    function doSomething (uint256 tokenId) public {
        require(msg.sender == Owners[tokenId] && msg.sender == tx.origin, "Not Owner");
        handleAction(tokenId, 3);
    }

    /**
     * @notice Like `doSomething` but allows multiple tokenIds to be put in the ActionQueue.
     * @dev Cannot be called by a smart contract.
     */
    function doSomething (uint256[] memory tokenIds) public {
        require(msg.sender == tx.origin);
        for (uint i = 0; i < tokenIds.length; i++) {
            uint256 tokenId = tokenIds[i];
            require(msg.sender == Owners[tokenId], "Not Owner");
            handleAction(tokenId, 3);
        }
    }

    // Minting

    /**
     * @dev Bookkeeping for minting. Note: minting does not guarantee entry into the `ActionQueue`.
     */
    function mintHelper (address recipient) private  {
        uint256 tokenId = totalSupply;
        TokensByOwner[recipient].push(tokenId);
        OwnerTokenIndex[tokenId] = uint16(TokensByOwner[recipient].length);
        Owners[tokenId] = recipient;
        totalSupply++;
        handleAction(tokenId, 3);
        emit Transfer(address(0), recipient, tokenId);
    }

    /**
     * @notice Mint tokens to the provided recipient address, quantity per call is limited to 10.
     */
    function mint (address recipient, uint256 quantity) public payable whenNotPaused {
        require (quantity <= 10, "Quantity Limit Exceeded");
        require (totalSupply + quantity <= maxSupply, "Max Supply Exceeded");
        uint256 cost = quantity * MintPriceWei;
        require(msg.value >= cost, "Insufficent Funds");
        for (uint i = 0; i < quantity; i++) {
            mintHelper(recipient);
        }
    }

    /**
     * @notice Mint tokens to msg.sender, quantity per call is limited to 10.
     */
    function mint (uint256 quantity) public payable {
        mint(msg.sender, quantity);
    }

    /**
     * @notice Mint tokens to an array of recipient addresses, array length must be <= 10.
     */
    function mint (address[] memory recipients) public payable whenNotPaused {
        uint quantity = recipients.length;
        require (quantity <= 10 || msg.sender == contractOwner, "Quantity Limit Exceeded");
        require (totalSupply + quantity <= maxSupply, "Max Supply Exceeded");
        uint256 cost = quantity * MintPriceWei;
        require(msg.value >= cost, "Insufficent Funds");
        for (uint i = 0; i < quantity; i++) {
            mintHelper(recipients[i]);
        }
    }


    // Quest Info

    /**
     * @notice Shows where the token is in the `Action Queue`.
     * @dev `pending` indicates the token is in the queue. `position` is the number of preceding Actions. `revealBlock` is the block at which the action becomes eligible for reveal.
     */
    function isPending (uint256 tokenId) public view returns (bool pending, uint position, uint revealBlock) {
        pending = TokenHistory[tokenId][IS_PENDING_INDEX] == 1;
        if (pending) {
            uint count = Cursor.count;
            uint index = Cursor.index;
            for (uint i = 0; i < count; i++) {
                Action storage action = ActionQueue[index];
                if (action.tokenId == tokenId) {
                    position = i;
                    revealBlock = action.revealBlock;
                    break;
                }
                index++;
                if(index == MAX_QUEUE) index = 0;
            }
        }
    }

    /**
     * @notice Fetches details used to generate token metadata. `level` => indicates numeric stage of the quest. `journeyLength` => number of revealed actions. `storySegments` => text corresponding to each reveled action. `stats` => attributes collected on the quest. `heroStatus` => number of tokens revealed through `doSomethingHeroic`.
     * @dev `level` will be in range [0(ngmi)..8(gmi)]. `storySegments` will have `journeyLength` entries unless `level` == 0 in which case it will have one additional element. `stats` indexes correspond to levels - 1.
     */
    function getDetails (uint256 tokenId) public view returns (uint256 level,
                                                               uint8 journeyLength,
                                                               bytes[15] memory storySegments,
                                                               bytes[8] memory stats,
                                                               uint16 heroStatus)
    {
        require(tokenId < totalSupply, "Doesn't Exist");
        uint16[16] storage tokenHistory = TokenHistory[tokenId];
        journeyLength = uint8(tokenHistory[JOURNEY_LENGTH_INDEX]);
        level = 1; // if quest has just begun, level will be 1
        uint prevLevel = 1;
        for (uint i = 1; i <= journeyLength; i++) {
            uint256 seed = uint256(keccak256(abi.encodePacked(tokenHistory[i], tokenId)));
            level = tokenHistory[i] & 15;
            if (level == 0) {
                (bytes memory storySegment, string memory ending) = Data.getDeath(seed, prevLevel, stats);
                stats[7] = storySegment;
                storySegments[i-1] = storySegment;
                storySegments[i] = bytes(ending);
            } else if (prevLevel == level) {
                storySegments[i-1] = Data.getFail(seed, level, stats);
            } else {
                (bytes memory storySegment, bytes memory stat) = Data.getAdvance(seed, level, stats);
                stats[level - 1] = stat;
                storySegments[i-1] = storySegment;
            }
            prevLevel = level;
        }

        heroStatus = HeroStatus[tokenId];

        if (tokenHistory[IS_PENDING_INDEX] == 1) {
            stats[0] = "Pending";
        } else if (level == 0) {
            stats[0] = "NGMI";
        } else if (level == 8) {
            stats[0] = "GMI";
        } else {
            stats[0] = "Questing";
        }
    }

    /**
     * @notice Fetches the current stage of the journey in numeric terms. 0 => NGMI. 8 => GMI.
     * @dev `level` is always in the range [0..8].
     */
    function getLevel (uint256 tokenId) public view returns (uint256 level) {
        require(tokenId < totalSupply, "Doesn't Exist");
        uint16[16] storage tokenHistory = TokenHistory[tokenId];
        uint16 journeyLength = tokenHistory[JOURNEY_LENGTH_INDEX];
        if (journeyLength == 0) {
            return 1;
        } else {
            return (tokenHistory[journeyLength] & 15);
        }
    }

    function getSym(int seed) internal pure returns (uint8) {
        if (seed & 1 == 0) return 0;
        if ((seed >> 1) & 1 == 0) {
            return 1;
        }
        return 2;
    }

    /**
     * @dev `cartouche` is an array of chevron positions and orientations. 0 => None, 1 => Right, 2 => Left. Data is only valid if `level` == 8.
     */
    function getMysteriousCartouche (uint256 tokenId) public view returns (uint8 level, uint8[6] memory cartouche) {
        (uint256 currentLevel,uint8 journeyLength,, bytes[8] memory stats,) = getDetails(tokenId);
        if (currentLevel == 8) {
            int seed = int(uint256(keccak256(abi.encodePacked(tokenId, stats[7]))) >> 141);
            cartouche[0] = getSym(seed);
            cartouche[1] = getSym(seed >> 2);
            cartouche[2] = getSym(seed >> 4);
            cartouche[3] = getSym(seed >> 6);
            cartouche[4] = getSym(seed >> 8);
            cartouche[5] = getSym(seed >> 10);
        }
        if (journeyLength > 0) {
            level = uint8(currentLevel);
        } else {
            level = 1;
        }
    }

    // ERC-721 Metadata

    /**
     * @notice Assembles and returns the Base64 encoded token URI containing the JSON token's metadata. Assembled entirely on-chain.
     */
    function tokenURI (uint256 tokenId) public view returns (string memory) {
        (uint256 level, uint8 journeyLength, bytes[15] memory storySegments, bytes[8] memory stats, uint16 heroStatus) = getDetails(tokenId);
        return Data.getMetadata(tokenId, level, journeyLength, storySegments, stats, heroStatus);
    }

    /**
     * @notice Assembles and returns the token's SVG image. Assembled entirely on-chain.
     */
    function tokenSVG (uint256 tokenId) public view returns (string memory svg) {
        (uint256 level, uint8 journeyLength,, bytes[8] memory stats, uint16 heroStatus) = getDetails(tokenId);
        if (journeyLength > 0 && (level == 0 || level == 8)) {
            svg = string(Data.generateCompletionImage(tokenId, level, stats[7], heroStatus));
        } else {
            svg = string(Data.generateProgressImage(tokenId, level));
        }
    }

    // ERC-721 Base

    function tokenExists(uint256 tokenId) public view returns (bool) {
        return (tokenId < totalSupply);
    }

    function ownerOf(uint256 tokenId) public view returns (address) {
        require(tokenExists(tokenId), "ERC721: Nonexistent token");
        return Owners[tokenId];
    }

    function balanceOf(address owner) public view returns (uint256) {
        require(owner != address(0), "ERC721: balance query for the zero address");
        return TokensByOwner[owner].length;
    }

    function supportsInterface(bytes4 interfaceId) public pure returns (bool) {
        return
            interfaceId == type(IERC165).interfaceId ||
            interfaceId == type(IERC721).interfaceId ||
            interfaceId == type(IERC721Metadata).interfaceId ||
            interfaceId == type(IERC721Enumerable).interfaceId;
    }

    function _approve(address to, uint256 tokenId) internal {
        TokenApprovals[tokenId] = to;
        emit Approval(ownerOf(tokenId), to, tokenId);
    }

    function approve(address to, uint256 tokenId) public  {
        address owner = ownerOf(tokenId);
        require(to != owner, "ERC721: approval to current owner");

        require(
                msg.sender == owner || isApprovedForAll(owner, msg.sender),
                "ERC721: approve caller is not owner nor approved for all"
                );
        _approve(to, tokenId);
    }

    function getApproved(uint256 tokenId) public view returns (address) {
        require(tokenId < totalSupply, "ERC721: approved query for nonexistent token");
        return TokenApprovals[tokenId];
    }

    function isApprovedForAll(address owner, address operator) public view  returns (bool) {
        return OperatorApprovals[owner][operator];
    }

    function setApprovalForAll(
                               address operator,
                               bool approved
                               ) external virtual {
        require(msg.sender != operator, "ERC721: approve to caller");
        OperatorApprovals[msg.sender][operator] = approved;
        emit ApprovalForAll(msg.sender, operator, approved);
    }

    function isContract(address account) internal view returns (bool) {
        uint256 size;
        assembly {
        size := extcodesize(account)
                }
        return size > 0;
    }

    function _checkOnERC721Received(
                                    address from,
                                    address to,
                                    uint256 tokenId,
                                    bytes memory _data
                                    ) private returns (bool) {
        if (isContract(to)) {
            try IERC721Receiver(to).onERC721Received(msg.sender, from, tokenId, _data) returns (bytes4 retval) {
                return retval == IERC721Receiver.onERC721Received.selector;
            } catch (bytes memory reason) {
                if (reason.length == 0) {
                    revert("ERC721: transfer to non ERC721Receiver implementer");
                } else {
                    assembly {
                        revert(add(32, reason), mload(reason))
                            }
                }
            }
        } else {
            return true;
        }
    }

    function _transfer(
                       address from,
                       address to,
                       uint256 tokenId
                       ) private whenNotPaused {
        require(ownerOf(tokenId) == from, "ERC721: transfer of token that is not own");
        require(to != address(0), "ERC721: transfer to the zero address");
        _approve(address(0), tokenId);

        uint16 valueIndex = OwnerTokenIndex[tokenId];
        uint256 toDeleteIndex = valueIndex - 1;
        uint256 lastIndex = TokensByOwner[from].length - 1;
        if (lastIndex != toDeleteIndex) {
            uint256 lastTokenId = TokensByOwner[from][lastIndex];
            TokensByOwner[from][toDeleteIndex] = lastTokenId;
            OwnerTokenIndex[lastTokenId] = valueIndex;
        }
        TokensByOwner[from].pop();

        TokensByOwner[to].push(tokenId);
        OwnerTokenIndex[tokenId] = uint16(TokensByOwner[to].length);

        Owners[tokenId] = to;
        emit Transfer(from, to, tokenId);
    }

    function _isApprovedOrOwner(address spender, uint256 tokenId) internal view returns (bool) {
        require(tokenId < totalSupply, "ERC721: operator query for nonexistent token");
        address owner = ownerOf(tokenId);
        return (spender == owner || getApproved(tokenId) == spender || isApprovedForAll(owner, spender));
    }

    function transferFrom(
                          address from,
                          address to,
                          uint256 tokenId
                          ) public {
        require(_isApprovedOrOwner(msg.sender, tokenId), "ERC721: transfer caller is not owner nor approved");

        _transfer(from, to, tokenId);
    }

    function safeTransferFrom(
                              address from,
                              address to,
                              uint256 tokenId
                              ) public {
        safeTransferFrom(from, to, tokenId, "");
    }

    function safeTransferFrom(
                              address from,
                              address to,
                              uint256 tokenId,
                              bytes memory _data
                              ) public {
        require(_isApprovedOrOwner(msg.sender, tokenId), "ERC721: transfer caller is not owner nor approved");
        _safeTransfer(from, to, tokenId, _data);
    }


    function _safeTransfer(
                           address from,
                           address to,
                           uint256 tokenId,
                           bytes memory _data
                           ) private {
        _transfer(from, to, tokenId);
        require(_checkOnERC721Received(from, to, tokenId, _data), "ERC721: transfer to non ERC721Receiver implementer");
    }

    // Enumerable

    function tokenByIndex(uint256 tokenId) public view returns (uint256) {
        require(tokenExists(tokenId), "Nonexistent Token");
        return tokenId;
    }

    function tokenOfOwnerByIndex(address owner, uint256 index) public view returns (uint256) {
        require(index < balanceOf(owner), "ERC721Enumerable: owner index out of bounds");
        return TokensByOwner[owner][index];
    }

    // Rescuers

    /**
    * @dev Rescue ERC20 assets sent directly to this contract.
    */
    function withdrawForeignERC20(address tokenContract) public onlyOwner {
        IERC20 token = IERC20(tokenContract);
        token.transfer(contractOwner, token.balanceOf(address(this)));
        }

    /**
     * @dev Rescue ERC721 assets sent directly to this contract.
     */
    function withdrawForeignERC721(address tokenContract, uint256 tokenId) public onlyOwner {
        IERC721(tokenContract).safeTransferFrom(address(this), contractOwner, tokenId);
    }
}

File 2 of 6 : IERC165.sol
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts v4.4.1 (utils/introspection/IERC165.sol)

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 3 of 6 : IERC721.sol
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts v4.4.1 (token/ERC721/IERC721.sol)

pragma solidity ^0.8.0;

import "../../utils/introspection/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 4 of 6 : IERC721Receiver.sol
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts v4.4.1 (token/ERC721/IERC721Receiver.sol)

pragma solidity ^0.8.0;

/**
 * @title ERC721 token receiver interface
 * @dev Interface for any contract that wants to support safeTransfers
 * from ERC721 asset contracts.
 */
interface IERC721Receiver {
    /**
     * @dev Whenever an {IERC721} `tokenId` token is transferred to this contract via {IERC721-safeTransferFrom}
     * by `operator` from `from`, this function is called.
     *
     * It must return its Solidity selector to confirm the token transfer.
     * If any other value is returned or the interface is not implemented by the recipient, the transfer will be reverted.
     *
     * The selector can be obtained in Solidity with `IERC721.onERC721Received.selector`.
     */
    function onERC721Received(
        address operator,
        address from,
        uint256 tokenId,
        bytes calldata data
    ) external returns (bytes4);
}

File 5 of 6 : IERC721Enumerable.sol
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v4.5.0) (token/ERC721/extensions/IERC721Enumerable.sol)

pragma solidity ^0.8.0;

import "../IERC721.sol";

/**
 * @title ERC-721 Non-Fungible Token Standard, optional enumeration extension
 * @dev See https://eips.ethereum.org/EIPS/eip-721
 */
interface IERC721Enumerable is IERC721 {
    /**
     * @dev Returns the total amount of tokens stored by the contract.
     */
    function totalSupply() external view returns (uint256);

    /**
     * @dev Returns a token ID owned by `owner` at a given `index` of its token list.
     * Use along with {balanceOf} to enumerate all of ``owner``'s tokens.
     */
    function tokenOfOwnerByIndex(address owner, uint256 index) external view returns (uint256);

    /**
     * @dev Returns a token ID at a given `index` of all the tokens stored by the contract.
     * Use along with {totalSupply} to enumerate all tokens.
     */
    function tokenByIndex(uint256 index) external view returns (uint256);
}

File 6 of 6 : IERC721Metadata.sol
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts v4.4.1 (token/ERC721/extensions/IERC721Metadata.sol)

pragma solidity ^0.8.0;

import "../IERC721.sol";

/**
 * @title ERC-721 Non-Fungible Token Standard, optional metadata extension
 * @dev See https://eips.ethereum.org/EIPS/eip-721
 */
interface IERC721Metadata is IERC721 {
    /**
     * @dev Returns the token collection name.
     */
    function name() external view returns (string memory);

    /**
     * @dev Returns the token collection symbol.
     */
    function symbol() external view returns (string memory);

    /**
     * @dev Returns the Uniform Resource Identifier (URI) for `tokenId` token.
     */
    function tokenURI(uint256 tokenId) external view returns (string memory);
}

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

Contract Security Audit

Contract ABI

[{"inputs":[{"internalType":"address","name":"quest3DataContract","type":"address"}],"stateMutability":"nonpayable","type":"constructor"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"owner","type":"address"},{"indexed":true,"internalType":"address","name":"approved","type":"address"},{"indexed":true,"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"Approval","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"owner","type":"address"},{"indexed":true,"internalType":"address","name":"operator","type":"address"},{"indexed":false,"internalType":"bool","name":"approved","type":"bool"}],"name":"ApprovalForAll","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"from","type":"address"},{"indexed":true,"internalType":"address","name":"to","type":"address"},{"indexed":true,"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"Transfer","type":"event"},{"inputs":[{"internalType":"uint256","name":"","type":"uint256"}],"name":"ActionQueue","outputs":[{"internalType":"uint128","name":"revealBlock","type":"uint128"},{"internalType":"uint128","name":"tokenId","type":"uint128"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"Cursor","outputs":[{"internalType":"uint16","name":"index","type":"uint16"},{"internalType":"uint16","name":"count","type":"uint16"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"","type":"uint256"}],"name":"HeroStatus","outputs":[{"internalType":"uint16","name":"","type":"uint16"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"HeroThreshold","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"MAX_QUEUE","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"MintPriceWei","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"approve","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"owner","type":"address"}],"name":"balanceOf","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"clearPendingStatus","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"contractOwner","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256[]","name":"tokenIds","type":"uint256[]"}],"name":"doSomething","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"doSomething","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"},{"internalType":"uint256","name":"maxAssists","type":"uint256"}],"name":"doSomethingHeroic","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"getApproved","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"getDetails","outputs":[{"internalType":"uint256","name":"level","type":"uint256"},{"internalType":"uint8","name":"journeyLength","type":"uint8"},{"internalType":"bytes[15]","name":"storySegments","type":"bytes[15]"},{"internalType":"bytes[8]","name":"stats","type":"bytes[8]"},{"internalType":"uint16","name":"heroStatus","type":"uint16"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"getLevel","outputs":[{"internalType":"uint256","name":"level","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"getMysteriousCartouche","outputs":[{"internalType":"uint8","name":"level","type":"uint8"},{"internalType":"uint8[6]","name":"cartouche","type":"uint8[6]"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getQueue","outputs":[{"components":[{"internalType":"uint128","name":"revealBlock","type":"uint128"},{"internalType":"uint128","name":"tokenId","type":"uint128"}],"internalType":"struct Quest3.Action[]","name":"","type":"tuple[]"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getQueueLength","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"owner","type":"address"},{"internalType":"address","name":"operator","type":"address"}],"name":"isApprovedForAll","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"isPending","outputs":[{"internalType":"bool","name":"pending","type":"bool"},{"internalType":"uint256","name":"position","type":"uint256"},{"internalType":"uint256","name":"revealBlock","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"maxSupply","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"recipient","type":"address"},{"internalType":"uint256","name":"quantity","type":"uint256"}],"name":"mint","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"uint256","name":"quantity","type":"uint256"}],"name":"mint","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"address[]","name":"recipients","type":"address[]"}],"name":"mint","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[],"name":"name","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"ownerOf","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"ownerWithdraw","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"pause","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"permanentlyCloseMint","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"from","type":"address"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"safeTransferFrom","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"from","type":"address"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"tokenId","type":"uint256"},{"internalType":"bytes","name":"_data","type":"bytes"}],"name":"safeTransferFrom","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"operator","type":"address"},{"internalType":"bool","name":"approved","type":"bool"}],"name":"setApprovalForAll","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bool","name":"state","type":"bool"}],"name":"setFrozen","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"threshold","type":"uint256"}],"name":"setHeroThreshold","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes4","name":"interfaceId","type":"bytes4"}],"name":"supportsInterface","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"pure","type":"function"},{"inputs":[],"name":"symbol","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"tokenByIndex","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"tokenExists","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"owner","type":"address"},{"internalType":"uint256","name":"index","type":"uint256"}],"name":"tokenOfOwnerByIndex","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"tokenSVG","outputs":[{"internalType":"string","name":"svg","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"tokenURI","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"totalSupply","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"from","type":"address"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"transferFrom","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"newOwner","type":"address"}],"name":"transferOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"unpause","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"tokenContract","type":"address"}],"name":"withdrawForeignERC20","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"tokenContract","type":"address"},{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"withdrawForeignERC721","outputs":[],"stateMutability":"nonpayable","type":"function"}]

60c0604052600760808190526651756573742d3360c81b60a09081526200002a91600091906200017e565b50604080518082019091526003808252620e29bb60ec1b602090920191825262000057916001916200017e565b5061640060025560006003819055616a48805461ffff191660011790556646d934f290d250616a4955600a616a4b55604080518082019091528181526020015261718d805463ffffffff19169055348015620000b257600080fd5b5060405162003ae538038062003ae5833981016040819052620000d59162000224565b60048054336001600160a01b03199182168117835561708c80549092166001600160a01b03851617909155604051630f41a04d60e11b81529182015273084b1c3c81545d370f3634392de611caabff814890631e83409a906024016020604051808303816000875af115801562000150573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019062000176919062000256565b5050620002ad565b8280546200018c9062000270565b90600052602060002090601f016020900481019282620001b05760008555620001fb565b82601f10620001cb57805160ff1916838001178555620001fb565b82800160010185558215620001fb579182015b82811115620001fb578251825591602001919060010190620001de565b50620002099291506200020d565b5090565b5b808211156200020957600081556001016200020e565b6000602082840312156200023757600080fd5b81516001600160a01b03811681146200024f57600080fd5b9392505050565b6000602082840312156200026957600080fd5b5051919050565b600181811c908216806200028557607f821691505b60208210811415620002a757634e487b7160e01b600052602260045260246000fd5b50919050565b61382880620002bd6000396000f3fe6080604052600436106102925760003560e01c80638456cb591161015a578063b93a89f7116100c1578063ce606ee01161007a578063ce606ee01461080f578063d5abeb011461082f578063e985e9c514610845578063ee8ed88b14610865578063ef4cdb4b1461087c578063f2fde38b146108bc57600080fd5b8063b93a89f71461071b578063bd075b841461074c578063bd0e61a51461075f578063c7e50eec14610792578063c87b56dd146107b2578063ca8836d2146107d257600080fd5b8063a2581b4211610113578063a2581b4214610658578063a6b206bf14610686578063a9ac1621146106a6578063ac23cdfd146106c6578063b88d4fde146106db578063b8f77005146106fb57600080fd5b80638456cb59146105bb57806386481d40146105d057806395d89b41146105f05780639bac5f7a14610605578063a0712d6814610625578063a22cb4651461063857600080fd5b80633f4ba83a116101fe5780634f6ccce7116101b75780634f6ccce71461050457806351289894146105245780635c4719951461053b5780636352211e1461055b57806370a082311461057b5780637e932d321461059b57600080fd5b80633f4ba83a146104505780633f7b5e401461046557806340c10f191461047b57806342842e0e1461048e5780634311de8f146104ae57806348d6cf4a146104c357600080fd5b80630ce06b68116102505780630ce06b681461038c57806318160ddd146103ac578063238b089e146103d057806323b872dd146103f05780632f745c5914610410578063383775b21461043057600080fd5b8062923f9e1461029757806301fce27e146102ce57806301ffc9a7146102f057806306fdde0314610310578063081812fc14610332578063095ea7b31461036a575b600080fd5b3480156102a357600080fd5b506102b96102b2366004612db9565b6003541190565b60405190151581526020015b60405180910390f35b3480156102da57600080fd5b506102e36108dc565b6040516102c59190612dd2565b3480156102fc57600080fd5b506102b961030b366004612e44565b6109f2565b34801561031c57600080fd5b50610325610a5f565b6040516102c59190612ec0565b34801561033e57600080fd5b5061035261034d366004612db9565b610aed565b6040516001600160a01b0390911681526020016102c5565b34801561037657600080fd5b5061038a610385366004612eef565b610b77565b005b34801561039857600080fd5b5061038a6103a7366004612eef565b610c8d565b3480156103b857600080fd5b506103c260035481565b6040519081526020016102c5565b3480156103dc57600080fd5b5061038a6103eb366004612db9565b610d29565b3480156103fc57600080fd5b5061038a61040b366004612f19565b610d71565b34801561041c57600080fd5b506103c261042b366004612eef565b610da2565b34801561043c57600080fd5b5061038a61044b366004612fc0565b610e4d565b34801561045c57600080fd5b5061038a610ee2565b34801561047157600080fd5b506103c261010081565b61038a610489366004612eef565b610f19565b34801561049a57600080fd5b5061038a6104a9366004612f19565b611075565b3480156104ba57600080fd5b5061038a611090565b3480156104cf57600080fd5b5061718d546104e99061ffff808216916201000090041682565b6040805161ffff9384168152929091166020830152016102c5565b34801561051057600080fd5b506103c261051f366004612db9565b6110cc565b34801561053057600080fd5b506103c2616a495481565b34801561054757600080fd5b5061038a61055636600461304b565b61111d565b34801561056757600080fd5b50610352610576366004612db9565b611232565b34801561058757600080fd5b506103c261059636600461304b565b6112b0565b3480156105a757600080fd5b5061038a6105b6366004613074565b611338565b3480156105c757600080fd5b5061038a61137d565b3480156105dc57600080fd5b506103c26105eb366004612db9565b6113b7565b3480156105fc57600080fd5b50610325611453565b34801561061157600080fd5b50610325610620366004612db9565b611460565b61038a610633366004612db9565b6115a5565b34801561064457600080fd5b5061038a610653366004613091565b6115af565b34801561066457600080fd5b50610678610673366004612db9565b611675565b6040516102c59291906130c8565b34801561069257600080fd5b5061038a6106a1366004612db9565b61176e565b3480156106b257600080fd5b5061038a6106c1366004612db9565b6117c1565b3480156106d257600080fd5b5061038a6117f1565b3480156106e757600080fd5b5061038a6106f6366004613130565b611823565b34801561070757600080fd5b5061718d5462010000900461ffff166103c2565b34801561072757600080fd5b5061073b610736366004612db9565b611855565b6040516102c5959493929190613257565b61038a61075a3660046132a2565b611cb2565b34801561076b57600080fd5b5061077f61077a366004612db9565b611e38565b60405161ffff90911681526020016102c5565b34801561079e57600080fd5b5061038a6107ad36600461332f565b611e68565b3480156107be57600080fd5b506103256107cd366004612db9565b611f19565b3480156107de57600080fd5b506107f26107ed366004612db9565b611fc2565b6040805193151584526020840192909252908201526060016102c5565b34801561081b57600080fd5b50600454610352906001600160a01b031681565b34801561083b57600080fd5b506103c260025481565b34801561085157600080fd5b506102b9610860366004613351565b612087565b34801561087157600080fd5b506103c2616a4b5481565b34801561088857600080fd5b5061089c610897366004612db9565b6120b6565b604080516001600160801b039384168152929091166020830152016102c5565b3480156108c857600080fd5b5061038a6108d736600461304b565b6120e3565b61718d5460609061ffff6201000082048116911660008267ffffffffffffffff81111561090b5761090b612f55565b60405190808252806020026020018201604052801561095057816020015b60408051808201909152600080825260208201528152602001906001900390816109295790505b50905060005b81518110156109ea5761708d83610100811061097457610974613384565b604080518082019091529101546001600160801b038082168352600160801b90910416602082015282518390839081106109b0576109b0613384565b602002602001018190525082806109c6906133b0565b9350506101008314156109d857600092505b806109e2816133b0565b915050610956565b509392505050565b60006001600160e01b031982166301ffc9a760e01b1480610a2357506001600160e01b031982166380ac58cd60e01b145b80610a3e57506001600160e01b03198216635b5e139f60e01b145b80610a5957506001600160e01b0319821663780e9d6360e01b145b92915050565b60008054610a6c906133cb565b80601f0160208091040260200160405190810160405280929190818152602001828054610a98906133cb565b8015610ae55780601f10610aba57610100808354040283529160200191610ae5565b820191906000526020600020905b815481529060010190602001808311610ac857829003601f168201915b505050505081565b60006003548210610b5a5760405162461bcd60e51b815260206004820152602c60248201527f4552433732313a20617070726f76656420717565727920666f72206e6f6e657860448201526b34b9ba32b73a103a37b5b2b760a11b60648201526084015b60405180910390fd5b506000908152616a4660205260409020546001600160a01b031690565b6000610b8282611232565b9050806001600160a01b0316836001600160a01b03161415610bf05760405162461bcd60e51b815260206004820152602160248201527f4552433732313a20617070726f76616c20746f2063757272656e74206f776e656044820152603960f91b6064820152608401610b51565b336001600160a01b0382161480610c0c5750610c0c8133612087565b610c7e5760405162461bcd60e51b815260206004820152603860248201527f4552433732313a20617070726f76652063616c6c6572206973206e6f74206f7760448201527f6e6572206e6f7220617070726f76656420666f7220616c6c00000000000000006064820152608401610b51565b610c88838361212f565b505050565b6004546001600160a01b03163314610cb75760405162461bcd60e51b8152600401610b5190613406565b60048054604051632142170760e11b815230928101929092526001600160a01b039081166024830152604482018390528316906342842e0e90606401600060405180830381600087803b158015610d0d57600080fd5b505af1158015610d21573d6000803e3d6000fd5b505050505050565b6004546001600160a01b03163314610d535760405162461bcd60e51b8152600401610b5190613406565b6000908152616a4a6020526040902080546001600160f01b03169055565b610d7b338261219e565b610d975760405162461bcd60e51b8152600401610b5190613429565b610c88838383612264565b6000610dad836112b0565b8210610e0f5760405162461bcd60e51b815260206004820152602b60248201527f455243373231456e756d657261626c653a206f776e657220696e646578206f7560448201526a74206f6620626f756e647360a81b6064820152608401610b51565b6001600160a01b038316600090815261640560205260409020805483908110610e3a57610e3a613384565b9060005260206000200154905092915050565b333214610e5957600080fd5b60005b8151811015610ede576000828281518110610e7957610e79613384565b602002602001015190506005816164008110610e9757610e97613384565b01546001600160a01b03163314610ec05760405162461bcd60e51b8152600401610b5190613406565b610ecb8160036125cf565b5080610ed6816133b0565b915050610e5c565b5050565b6004546001600160a01b03163314610f0c5760405162461bcd60e51b8152600401610b5190613406565b616a48805460ff19169055565b616a485460ff161580610f3657506004546001600160a01b031633145b610f525760405162461bcd60e51b8152600401610b519061347a565b600a811115610f9d5760405162461bcd60e51b8152602060048201526017602482015276145d585b9d1a5d1e48131a5b5a5d08115e18d959591959604a1b6044820152606401610b51565b60025481600354610fae919061349a565b1115610ff25760405162461bcd60e51b815260206004820152601360248201527213585e0814dd5c1c1b1e48115e18d959591959606a1b6044820152606401610b51565b6000616a49548261100391906134b2565b9050803410156110495760405162461bcd60e51b8152602060048201526011602482015270496e737566666963656e742046756e647360781b6044820152606401610b51565b60005b8281101561106f5761105d846128fd565b80611067816133b0565b91505061104c565b50505050565b610c8883838360405180602001604052806000815250611823565b6004546040516001600160a01b03909116904780156108fc02916000818181858888f193505050501580156110c9573d6000803e3d6000fd5b50565b60006110d9826003541190565b6111195760405162461bcd60e51b81526020600482015260116024820152702737b732bc34b9ba32b73a102a37b5b2b760791b6044820152606401610b51565b5090565b6004546001600160a01b031633146111475760405162461bcd60e51b8152600401610b5190613406565b600480546040516370a0823160e01b8152309281019290925282916001600160a01b038084169263a9059cbb9291169083906370a0823190602401602060405180830381865afa15801561119f573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906111c391906134d1565b6040516001600160e01b031960e085901b1681526001600160a01b03909216600483015260248201526044016020604051808303816000875af115801561120e573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610c8891906134ea565b600061123f826003541190565b61128b5760405162461bcd60e51b815260206004820152601960248201527f4552433732313a204e6f6e6578697374656e7420746f6b656e000000000000006044820152606401610b51565b600582616400811061129f5761129f613384565b01546001600160a01b031692915050565b60006001600160a01b03821661131b5760405162461bcd60e51b815260206004820152602a60248201527f4552433732313a2062616c616e636520717565727920666f7220746865207a65604482015269726f206164647265737360b01b6064820152608401610b51565b506001600160a01b03166000908152616405602052604090205490565b6004546001600160a01b031633146113625760405162461bcd60e51b8152600401610b5190613406565b616a4880549115156101000261ff0019909216919091179055565b6004546001600160a01b031633146113a75760405162461bcd60e51b8152600401610b5190613406565b616a48805460ff19166001179055565b600060035482106113fa5760405162461bcd60e51b815260206004820152600d60248201526c111bd95cdb89dd08115e1a5cdd609a1b6044820152606401610b51565b6000828152616a4a60205260409020805461ffff168061141e575060019392505050565b818161ffff166010811061143457611434613384565b60108104909101546002600f928316026101000a900416949350505050565b60018054610a6c906133cb565b606060008060008061147186611855565b94509450509350935060008360ff1611801561149557508315806114955750836008145b156115205761708c5460e0830151604051630b711cb560e31b81526001600160a01b0390921691635b88e5a8916114d4918a9189918790600401613507565b600060405180830381865afa1580156114f1573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f191682016040526115199190810190613580565b945061159c565b61708c546040516358d8bcf360e11b815260048101889052602481018690526001600160a01b039091169063b1b179e690604401600060405180830381865afa158015611571573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f191682016040526115999190810190613580565b94505b50505050919050565b6110c93382610f19565b336001600160a01b03831614156116085760405162461bcd60e51b815260206004820152601960248201527f4552433732313a20617070726f766520746f2063616c6c6572000000000000006044820152606401610b51565b336000818152616a47602090815260408083206001600160a01b03871680855290835292819020805460ff191686151590811790915590519081529192917f17307eab39ab6107e8899845ad3d59bd9653f200f220920489ca2b5937696c31910160405180910390a35050565b600061167f612d58565b600080600061168d86611855565b509350509250925082600814156117505760e0810151604051600091608d916116ba918a916020016135b5565b6040516020818303038152906040528051906020012060001c901c90506116e0816129fd565b60ff1685526116f2600282901d6129fd565b60ff166020860152611707600482901d6129fd565b60ff16604086015261171c600682901d6129fd565b60ff166060860152611731600882901d6129fd565b60ff166080860152611746600a82901d6129fd565b60ff1660a0860152505b60ff82161561176157829450611766565b600194505b505050915091565b600581616400811061178257611782613384565b01546001600160a01b03163314801561179a57503332145b6117b65760405162461bcd60e51b8152600401610b5190613406565b6110c98160036125cf565b6004546001600160a01b031633146117eb5760405162461bcd60e51b8152600401610b5190613406565b616a4b55565b6004546001600160a01b0316331461181b5760405162461bcd60e51b8152600401610b5190613406565b600354600255565b61182d338361219e565b6118495760405162461bcd60e51b8152600401610b5190613429565b61106f84848484612a29565b600080611860612d76565b611868612d9e565b600060035486106118ab5760405162461bcd60e51b815260206004820152600d60248201526c111bd95cdb89dd08115e1a5cdd609a1b6044820152606401610b51565b6000868152616a4a6020526040902080546001965061ffff16945085805b8660ff168111611bbe5760008382601081106118e7576118e7613384565b601081049190910154604051600f9092166002026101000a900460f01b6001600160f01b0319166020820152602281018b90526042016040516020818303038152906040528051906020012060001c905083826010811061194a5761194a613384565b60108104909101546002600f928316026101000a900416985088611a355761708c54604051638f27b05f60e01b815260009182916001600160a01b0390911690638f27b05f906119a290869089908d906004016135db565b600060405180830381865afa1580156119bf573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f191682016040526119e79190810190613603565b60e08a0182905290925090508189611a00600187613667565b600f8110611a1057611a10613384565b6020020152808985600f8110611a2857611a28613384565b602002015250611ba89050565b88831415611add5761708c54604051630f4db48d60e11b81526001600160a01b0390911690631e9b691a90611a729084908d908b906004016135db565b600060405180830381865afa158015611a8f573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f19168201604052611ab79190810190613580565b87611ac3600185613667565b600f8110611ad357611ad3613384565b6020020152611ba8565b61708c54604051630bb2ee5160e01b815260009182916001600160a01b0390911690630bb2ee5190611b179086908f908d906004016135db565b600060405180830381865afa158015611b34573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f19168201604052611b5c9190810190613603565b90925090508088611b6e60018e613667565b60088110611b7e57611b7e613384565b60200201528189611b90600187613667565b600f8110611ba057611ba0613384565b602002015250505b5087915080611bb6816133b0565b9150506118c9565b50616a4c886164008110611bd457611bd4613384565b6010810491909101548354600f9092166002026101000a900461ffff90811694506001600160f01b909204161415611c325760408051808201909152600781526650656e64696e6760c81b60208201528460005b6020020152611ca7565b86611c5a576040805180820190915260048152634e474d4960e01b6020820152846000611c28565b8660081415611c8557604080518082019091526003815262474d4960e81b6020820152846000611c28565b6040805180820190915260088152675175657374696e6760c01b602082015284525b505091939590929450565b616a485460ff161580611ccf57506004546001600160a01b031633145b611ceb5760405162461bcd60e51b8152600401610b519061347a565b8051600a81111580611d0757506004546001600160a01b031633145b611d4d5760405162461bcd60e51b8152602060048201526017602482015276145d585b9d1a5d1e48131a5b5a5d08115e18d959591959604a1b6044820152606401610b51565b60025481600354611d5e919061349a565b1115611da25760405162461bcd60e51b815260206004820152601360248201527213585e0814dd5c1c1b1e48115e18d959591959606a1b6044820152606401610b51565b6000616a495482611db391906134b2565b905080341015611df95760405162461bcd60e51b8152602060048201526011602482015270496e737566666963656e742046756e647360781b6044820152606401610b51565b60005b8281101561106f57611e26848281518110611e1957611e19613384565b60200260200101516128fd565b80611e30816133b0565b915050611dfc565b616a4c816164008110611e4a57600080fd5b60109182820401919006600202915054906101000a900461ffff1681565b6005826164008110611e7c57611e7c613384565b01546001600160a01b031633148015611e9457503332145b611eb05760405162461bcd60e51b8152600401610b5190613406565b616a4b54811015611f0f5760405162461bcd60e51b815260206004820152602360248201527f412074727565206865726f206d75737420617373697374206d616e79206f746860448201526265727360e81b6064820152608401610b51565b610ede82826125cf565b60606000806000806000611f2c87611855565b61708c54604051635e7cd47560e01b8152959a50939850919650945092506001600160a01b031690635e7cd47590611f72908a908990899089908990899060040161367e565b600060405180830381865afa158015611f8f573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f19168201604052611fb79190810190613580565b979650505050505050565b6000818152616a4a6020526040812054600160f01b900461ffff16600114908082156120805761718d5461ffff6201000082048116911660005b8281101561207c57600061708d83610100811061201b5761201b613384565b018054909150600160801b90046001600160801b031688141561204d57549094506001600160801b031692508361207c565b82612057816133b0565b93505061010083141561206957600092505b5080612074816133b0565b915050611ffc565b5050505b9193909250565b6001600160a01b039182166000908152616a476020908152604080832093909416825291909152205460ff1690565b61708d8161010081106120c857600080fd5b01546001600160801b038082169250600160801b9091041682565b6004546001600160a01b0316331461210d5760405162461bcd60e51b8152600401610b5190613406565b600480546001600160a01b0319166001600160a01b0392909216919091179055565b6000818152616a466020526040902080546001600160a01b0319166001600160a01b038416908117909155819061216582611232565b6001600160a01b03167f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b92560405160405180910390a45050565b600060035482106122065760405162461bcd60e51b815260206004820152602c60248201527f4552433732313a206f70657261746f7220717565727920666f72206e6f6e657860448201526b34b9ba32b73a103a37b5b2b760a11b6064820152608401610b51565b600061221183611232565b9050806001600160a01b0316846001600160a01b0316148061224c5750836001600160a01b031661224184610aed565b6001600160a01b0316145b8061225c575061225c8185612087565b949350505050565b616a485460ff16158061228157506004546001600160a01b031633145b61229d5760405162461bcd60e51b8152600401610b519061347a565b826001600160a01b03166122b082611232565b6001600160a01b0316146123185760405162461bcd60e51b815260206004820152602960248201527f4552433732313a207472616e73666572206f6620746f6b656e2074686174206960448201526839903737ba1037bbb760b91b6064820152608401610b51565b6001600160a01b03821661237a5760405162461bcd60e51b8152602060048201526024808201527f4552433732313a207472616e7366657220746f20746865207a65726f206164646044820152637265737360e01b6064820152608401610b51565b61238560008261212f565b600061640682616400811061239c5761239c613384565b601091828204019190066002029054906101000a900461ffff16905060006001826123c791906136d0565b6001600160a01b0386166000908152616405602052604081205461ffff929092169250906123f790600190613667565b90508181146124b9576001600160a01b03861660009081526164056020526040812080548390811061242b5761242b613384565b90600052602060002001549050806164056000896001600160a01b03166001600160a01b03168152602001908152602001600020848154811061247057612470613384565b6000918252602090912001558361640682616400811061249257612492613384565b601091828204019190066002026101000a81548161ffff021916908361ffff160217905550505b6001600160a01b0386166000908152616405602052604090208054806124e1576124e16136f3565b6000828152602080822083016000199081018390559092019092556001600160a01b03871680835261640582526040832080546001810182558185529284209092018790559091525461640685616400811061253f5761253f613384565b601091828204019190066002026101000a81548161ffff021916908361ffff16021790555084600585616400811061257957612579613384565b0180546001600160a01b0319166001600160a01b03928316179055604051859187811691908916907fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef90600090a4505050505050565b616a485460ff1615806125ec57506004546001600160a01b031633145b6126085760405162461bcd60e51b8152600401610b519061347a565b616a4854610100900460ff161561264a5760405162461bcd60e51b8152602060048201526006602482015265233937bd32b760d11b6044820152606401610b51565b61718d5461ffff62010000820481169116600383101561266957600392505b6000805b84811015612731578361267f57612731565b600061708d84610100811061269657612696613384565b0180549091506001600160801b031643116126b15750612731565b80546126cc90600160801b90046001600160801b0316612a5c565b61708d8461010081106126e1576126e1613384565b6000910155846126f081613709565b95505083806126fe906133b0565b945050828061270c906133b0565b93505061010084141561271e57600093505b5080612729816133b0565b91505061266d565b50616a4b5481106127945780616a4c86616400811061275257612752613384565b601091828204019190066002028282829054906101000a900461ffff166127799190613720565b92506101000a81548161ffff021916908361ffff1602179055505b6000858152616a4a602052604081208054909161ffff909116908282601081106127c0576127c0613384565b60108104909101546002600f928316026101000a900416905080158015906127e85750600881105b806127f1575081155b80156127fe575061010086105b801561281457508254600160f01b900461ffff16155b156128cd576000612825868861349a565b905086612831816133b0565b975050806101001161284c5761284961010082613667565b90505b6040518060400160405280436001612864919061349a565b6001600160801b031681526020018a6001600160801b031681525061708d82610100811061289457612894613384565b82516020909301516001600160801b03908116600160801b02931692909217910155508254600160f01b6001600160f01b039091161783555b505061718d805463ffffffff19166201000061ffff9687160261ffff191617939094169290921790925550505050565b6003546001600160a01b038216600081815261640560209081526040822080546001810182558184529183209091018490559190525461640682616400811061294857612948613384565b601091828204019190066002026101000a81548161ffff021916908361ffff16021790555081600582616400811061298257612982613384565b0180546001600160a01b0319166001600160a01b0392909216919091179055600380549060006129b1836133b0565b91905055506129c18160036125cf565b60405181906001600160a01b038416906000907fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef908290a45050565b600060018216612a0f57506000919050565b600182811d16612a2157506001919050565b506002919050565b612a34848484612264565b612a4084848484612c63565b61106f5760405162461bcd60e51b8152600401610b5190613746565b6000818152616a4a602052604081208054909161ffff90911690828260108110612a8857612a88613384565b60108104909101546002600f928316026101000a9004169050600082612ab15760019150612af8565b8260011415612ac257506001612af8565b83612ace600185613667565b60108110612ade57612ade613384565b60108104909101546002600f928316026101000a90041690505b600085612b06600143613667565b40604051602001612b21929190918252602082015260400190565b60408051601f198184030181529190528051602090910120905060ff81166000612b4c8560096134b2565b612b5790600561349a565b90506000612b668660166134b2565b612b7190605a61349a565b90508560011415612b8157600291505b85851415612b8d575060005b81831015612b9e5760009550612bb3565b808310612bb357612bb086600161349a565b95505b612bbe87600161349a565b885461ffff191661ffff91909116178855612bdd86600486901b61349a565b88612be989600161349a565b60108110612bf957612bf9613384565b601091828204019190066002026101000a81548161ffff021916908361ffff160217905550600088600f60108110612c3357612c33613384565b601091828204019190066002026101000a81548161ffff021916908361ffff160217905550505050505050505050565b6000833b15612d4d57604051630a85bd0160e11b81526001600160a01b0385169063150b7a0290612c9e903390899088908890600401613798565b6020604051808303816000875af1925050508015612cd9575060408051601f3d908101601f19168201909252612cd6918101906137d5565b60015b612d33573d808015612d07576040519150601f19603f3d011682016040523d82523d6000602084013e612d0c565b606091505b508051612d2b5760405162461bcd60e51b8152600401610b5190613746565b805181602001fd5b6001600160e01b031916630a85bd0160e11b14905061225c565b506001949350505050565b6040518060c001604052806006906020820280368337509192915050565b604051806101e00160405280600f905b6060815260200190600190039081612d865790505090565b60408051610100810190915260608152600760208201612d86565b600060208284031215612dcb57600080fd5b5035919050565b602080825282518282018190526000919060409081850190868401855b82811015612e2157815180516001600160801b0390811686529087015116868501529284019290850190600101612def565b5091979650505050505050565b6001600160e01b0319811681146110c957600080fd5b600060208284031215612e5657600080fd5b8135612e6181612e2e565b9392505050565b60005b83811015612e83578181015183820152602001612e6b565b8381111561106f5750506000910152565b60008151808452612eac816020860160208601612e68565b601f01601f19169290920160200192915050565b602081526000612e616020830184612e94565b80356001600160a01b0381168114612eea57600080fd5b919050565b60008060408385031215612f0257600080fd5b612f0b83612ed3565b946020939093013593505050565b600080600060608486031215612f2e57600080fd5b612f3784612ed3565b9250612f4560208501612ed3565b9150604084013590509250925092565b634e487b7160e01b600052604160045260246000fd5b604051601f8201601f1916810167ffffffffffffffff81118282101715612f9457612f94612f55565b604052919050565b600067ffffffffffffffff821115612fb657612fb6612f55565b5060051b60200190565b60006020808385031215612fd357600080fd5b823567ffffffffffffffff811115612fea57600080fd5b8301601f81018513612ffb57600080fd5b803561300e61300982612f9c565b612f6b565b81815260059190911b8201830190838101908783111561302d57600080fd5b928401925b82841015611fb757833582529284019290840190613032565b60006020828403121561305d57600080fd5b612e6182612ed3565b80151581146110c957600080fd5b60006020828403121561308657600080fd5b8135612e6181613066565b600080604083850312156130a457600080fd5b6130ad83612ed3565b915060208301356130bd81613066565b809150509250929050565b60ff838116825260e082019060208084018560005b60068110156130fc5781518516835291830191908301906001016130dd565b50505050509392505050565b600067ffffffffffffffff82111561312257613122612f55565b50601f01601f191660200190565b6000806000806080858703121561314657600080fd5b61314f85612ed3565b935061315d60208601612ed3565b925060408501359150606085013567ffffffffffffffff81111561318057600080fd5b8501601f8101871361319157600080fd5b803561319f61300982613108565b8181528860208385010111156131b457600080fd5b8160208401602083013760006020838301015280935050505092959194509250565b6000826101e081018360005b600f8110156132115783830387526131fb838351612e94565b60209788019790935091909101906001016131e2565b509095945050505050565b60008261010081018360005b6008811015613211578383038752613241838351612e94565b6020978801979093509190910190600101613228565b85815260ff8516602082015260a06040820152600061327960a08301866131d6565b828103606084015261328b818661321c565b91505061ffff831660808301529695505050505050565b600060208083850312156132b557600080fd5b823567ffffffffffffffff8111156132cc57600080fd5b8301601f810185136132dd57600080fd5b80356132eb61300982612f9c565b81815260059190911b8201830190838101908783111561330a57600080fd5b928401925b82841015611fb75761332084612ed3565b8252928401929084019061330f565b6000806040838503121561334257600080fd5b50508035926020909101359150565b6000806040838503121561336457600080fd5b61336d83612ed3565b915061337b60208401612ed3565b90509250929050565b634e487b7160e01b600052603260045260246000fd5b634e487b7160e01b600052601160045260246000fd5b60006000198214156133c4576133c461339a565b5060010190565b600181811c908216806133df57607f821691505b6020821081141561340057634e487b7160e01b600052602260045260246000fd5b50919050565b6020808252600990820152682737ba1027bbb732b960b91b604082015260600190565b60208082526031908201527f4552433732313a207472616e736665722063616c6c6572206973206e6f74206f6040820152701ddb995c881b9bdc88185c1c1c9bdd9959607a1b606082015260800190565b60208082526006908201526514185d5cd95960d21b604082015260600190565b600082198211156134ad576134ad61339a565b500190565b60008160001904831182151516156134cc576134cc61339a565b500290565b6000602082840312156134e357600080fd5b5051919050565b6000602082840312156134fc57600080fd5b8151612e6181613066565b8481528360208201526080604082015260006135266080830185612e94565b905061ffff8316606083015295945050505050565b600082601f83011261354c57600080fd5b815161355a61300982613108565b81815284602083860101111561356f57600080fd5b61225c826020830160208701612e68565b60006020828403121561359257600080fd5b815167ffffffffffffffff8111156135a957600080fd5b61225c8482850161353b565b828152600082516135cd816020850160208701612e68565b919091016020019392505050565b8381528260208201526060604082015260006135fa606083018461321c565b95945050505050565b6000806040838503121561361657600080fd5b825167ffffffffffffffff8082111561362e57600080fd5b61363a8683870161353b565b9350602085015191508082111561365057600080fd5b5061365d8582860161353b565b9150509250929050565b6000828210156136795761367961339a565b500390565b86815285602082015260ff8516604082015260c0606082015260006136a660c08301866131d6565b82810360808401526136b8818661321c565b91505061ffff831660a0830152979650505050505050565b600061ffff838116908316818110156136eb576136eb61339a565b039392505050565b634e487b7160e01b600052603160045260246000fd5b6000816137185761371861339a565b506000190190565b600061ffff80831681851680830382111561373d5761373d61339a565b01949350505050565b60208082526032908201527f4552433732313a207472616e7366657220746f206e6f6e20455243373231526560408201527131b2b4bb32b91034b6b83632b6b2b73a32b960711b606082015260800190565b6001600160a01b03858116825284166020820152604081018390526080606082018190526000906137cb90830184612e94565b9695505050505050565b6000602082840312156137e757600080fd5b8151612e6181612e2e56fea264697066735822122035966c1ca62a2b6362d48637348298e71a4db64fb9dbf7b48abd20048664347f64736f6c634300080c0033000000000000000000000000fea93334f43db574b905be00dce122210641215d

Deployed Bytecode

0x6080604052600436106102925760003560e01c80638456cb591161015a578063b93a89f7116100c1578063ce606ee01161007a578063ce606ee01461080f578063d5abeb011461082f578063e985e9c514610845578063ee8ed88b14610865578063ef4cdb4b1461087c578063f2fde38b146108bc57600080fd5b8063b93a89f71461071b578063bd075b841461074c578063bd0e61a51461075f578063c7e50eec14610792578063c87b56dd146107b2578063ca8836d2146107d257600080fd5b8063a2581b4211610113578063a2581b4214610658578063a6b206bf14610686578063a9ac1621146106a6578063ac23cdfd146106c6578063b88d4fde146106db578063b8f77005146106fb57600080fd5b80638456cb59146105bb57806386481d40146105d057806395d89b41146105f05780639bac5f7a14610605578063a0712d6814610625578063a22cb4651461063857600080fd5b80633f4ba83a116101fe5780634f6ccce7116101b75780634f6ccce71461050457806351289894146105245780635c4719951461053b5780636352211e1461055b57806370a082311461057b5780637e932d321461059b57600080fd5b80633f4ba83a146104505780633f7b5e401461046557806340c10f191461047b57806342842e0e1461048e5780634311de8f146104ae57806348d6cf4a146104c357600080fd5b80630ce06b68116102505780630ce06b681461038c57806318160ddd146103ac578063238b089e146103d057806323b872dd146103f05780632f745c5914610410578063383775b21461043057600080fd5b8062923f9e1461029757806301fce27e146102ce57806301ffc9a7146102f057806306fdde0314610310578063081812fc14610332578063095ea7b31461036a575b600080fd5b3480156102a357600080fd5b506102b96102b2366004612db9565b6003541190565b60405190151581526020015b60405180910390f35b3480156102da57600080fd5b506102e36108dc565b6040516102c59190612dd2565b3480156102fc57600080fd5b506102b961030b366004612e44565b6109f2565b34801561031c57600080fd5b50610325610a5f565b6040516102c59190612ec0565b34801561033e57600080fd5b5061035261034d366004612db9565b610aed565b6040516001600160a01b0390911681526020016102c5565b34801561037657600080fd5b5061038a610385366004612eef565b610b77565b005b34801561039857600080fd5b5061038a6103a7366004612eef565b610c8d565b3480156103b857600080fd5b506103c260035481565b6040519081526020016102c5565b3480156103dc57600080fd5b5061038a6103eb366004612db9565b610d29565b3480156103fc57600080fd5b5061038a61040b366004612f19565b610d71565b34801561041c57600080fd5b506103c261042b366004612eef565b610da2565b34801561043c57600080fd5b5061038a61044b366004612fc0565b610e4d565b34801561045c57600080fd5b5061038a610ee2565b34801561047157600080fd5b506103c261010081565b61038a610489366004612eef565b610f19565b34801561049a57600080fd5b5061038a6104a9366004612f19565b611075565b3480156104ba57600080fd5b5061038a611090565b3480156104cf57600080fd5b5061718d546104e99061ffff808216916201000090041682565b6040805161ffff9384168152929091166020830152016102c5565b34801561051057600080fd5b506103c261051f366004612db9565b6110cc565b34801561053057600080fd5b506103c2616a495481565b34801561054757600080fd5b5061038a61055636600461304b565b61111d565b34801561056757600080fd5b50610352610576366004612db9565b611232565b34801561058757600080fd5b506103c261059636600461304b565b6112b0565b3480156105a757600080fd5b5061038a6105b6366004613074565b611338565b3480156105c757600080fd5b5061038a61137d565b3480156105dc57600080fd5b506103c26105eb366004612db9565b6113b7565b3480156105fc57600080fd5b50610325611453565b34801561061157600080fd5b50610325610620366004612db9565b611460565b61038a610633366004612db9565b6115a5565b34801561064457600080fd5b5061038a610653366004613091565b6115af565b34801561066457600080fd5b50610678610673366004612db9565b611675565b6040516102c59291906130c8565b34801561069257600080fd5b5061038a6106a1366004612db9565b61176e565b3480156106b257600080fd5b5061038a6106c1366004612db9565b6117c1565b3480156106d257600080fd5b5061038a6117f1565b3480156106e757600080fd5b5061038a6106f6366004613130565b611823565b34801561070757600080fd5b5061718d5462010000900461ffff166103c2565b34801561072757600080fd5b5061073b610736366004612db9565b611855565b6040516102c5959493929190613257565b61038a61075a3660046132a2565b611cb2565b34801561076b57600080fd5b5061077f61077a366004612db9565b611e38565b60405161ffff90911681526020016102c5565b34801561079e57600080fd5b5061038a6107ad36600461332f565b611e68565b3480156107be57600080fd5b506103256107cd366004612db9565b611f19565b3480156107de57600080fd5b506107f26107ed366004612db9565b611fc2565b6040805193151584526020840192909252908201526060016102c5565b34801561081b57600080fd5b50600454610352906001600160a01b031681565b34801561083b57600080fd5b506103c260025481565b34801561085157600080fd5b506102b9610860366004613351565b612087565b34801561087157600080fd5b506103c2616a4b5481565b34801561088857600080fd5b5061089c610897366004612db9565b6120b6565b604080516001600160801b039384168152929091166020830152016102c5565b3480156108c857600080fd5b5061038a6108d736600461304b565b6120e3565b61718d5460609061ffff6201000082048116911660008267ffffffffffffffff81111561090b5761090b612f55565b60405190808252806020026020018201604052801561095057816020015b60408051808201909152600080825260208201528152602001906001900390816109295790505b50905060005b81518110156109ea5761708d83610100811061097457610974613384565b604080518082019091529101546001600160801b038082168352600160801b90910416602082015282518390839081106109b0576109b0613384565b602002602001018190525082806109c6906133b0565b9350506101008314156109d857600092505b806109e2816133b0565b915050610956565b509392505050565b60006001600160e01b031982166301ffc9a760e01b1480610a2357506001600160e01b031982166380ac58cd60e01b145b80610a3e57506001600160e01b03198216635b5e139f60e01b145b80610a5957506001600160e01b0319821663780e9d6360e01b145b92915050565b60008054610a6c906133cb565b80601f0160208091040260200160405190810160405280929190818152602001828054610a98906133cb565b8015610ae55780601f10610aba57610100808354040283529160200191610ae5565b820191906000526020600020905b815481529060010190602001808311610ac857829003601f168201915b505050505081565b60006003548210610b5a5760405162461bcd60e51b815260206004820152602c60248201527f4552433732313a20617070726f76656420717565727920666f72206e6f6e657860448201526b34b9ba32b73a103a37b5b2b760a11b60648201526084015b60405180910390fd5b506000908152616a4660205260409020546001600160a01b031690565b6000610b8282611232565b9050806001600160a01b0316836001600160a01b03161415610bf05760405162461bcd60e51b815260206004820152602160248201527f4552433732313a20617070726f76616c20746f2063757272656e74206f776e656044820152603960f91b6064820152608401610b51565b336001600160a01b0382161480610c0c5750610c0c8133612087565b610c7e5760405162461bcd60e51b815260206004820152603860248201527f4552433732313a20617070726f76652063616c6c6572206973206e6f74206f7760448201527f6e6572206e6f7220617070726f76656420666f7220616c6c00000000000000006064820152608401610b51565b610c88838361212f565b505050565b6004546001600160a01b03163314610cb75760405162461bcd60e51b8152600401610b5190613406565b60048054604051632142170760e11b815230928101929092526001600160a01b039081166024830152604482018390528316906342842e0e90606401600060405180830381600087803b158015610d0d57600080fd5b505af1158015610d21573d6000803e3d6000fd5b505050505050565b6004546001600160a01b03163314610d535760405162461bcd60e51b8152600401610b5190613406565b6000908152616a4a6020526040902080546001600160f01b03169055565b610d7b338261219e565b610d975760405162461bcd60e51b8152600401610b5190613429565b610c88838383612264565b6000610dad836112b0565b8210610e0f5760405162461bcd60e51b815260206004820152602b60248201527f455243373231456e756d657261626c653a206f776e657220696e646578206f7560448201526a74206f6620626f756e647360a81b6064820152608401610b51565b6001600160a01b038316600090815261640560205260409020805483908110610e3a57610e3a613384565b9060005260206000200154905092915050565b333214610e5957600080fd5b60005b8151811015610ede576000828281518110610e7957610e79613384565b602002602001015190506005816164008110610e9757610e97613384565b01546001600160a01b03163314610ec05760405162461bcd60e51b8152600401610b5190613406565b610ecb8160036125cf565b5080610ed6816133b0565b915050610e5c565b5050565b6004546001600160a01b03163314610f0c5760405162461bcd60e51b8152600401610b5190613406565b616a48805460ff19169055565b616a485460ff161580610f3657506004546001600160a01b031633145b610f525760405162461bcd60e51b8152600401610b519061347a565b600a811115610f9d5760405162461bcd60e51b8152602060048201526017602482015276145d585b9d1a5d1e48131a5b5a5d08115e18d959591959604a1b6044820152606401610b51565b60025481600354610fae919061349a565b1115610ff25760405162461bcd60e51b815260206004820152601360248201527213585e0814dd5c1c1b1e48115e18d959591959606a1b6044820152606401610b51565b6000616a49548261100391906134b2565b9050803410156110495760405162461bcd60e51b8152602060048201526011602482015270496e737566666963656e742046756e647360781b6044820152606401610b51565b60005b8281101561106f5761105d846128fd565b80611067816133b0565b91505061104c565b50505050565b610c8883838360405180602001604052806000815250611823565b6004546040516001600160a01b03909116904780156108fc02916000818181858888f193505050501580156110c9573d6000803e3d6000fd5b50565b60006110d9826003541190565b6111195760405162461bcd60e51b81526020600482015260116024820152702737b732bc34b9ba32b73a102a37b5b2b760791b6044820152606401610b51565b5090565b6004546001600160a01b031633146111475760405162461bcd60e51b8152600401610b5190613406565b600480546040516370a0823160e01b8152309281019290925282916001600160a01b038084169263a9059cbb9291169083906370a0823190602401602060405180830381865afa15801561119f573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906111c391906134d1565b6040516001600160e01b031960e085901b1681526001600160a01b03909216600483015260248201526044016020604051808303816000875af115801561120e573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610c8891906134ea565b600061123f826003541190565b61128b5760405162461bcd60e51b815260206004820152601960248201527f4552433732313a204e6f6e6578697374656e7420746f6b656e000000000000006044820152606401610b51565b600582616400811061129f5761129f613384565b01546001600160a01b031692915050565b60006001600160a01b03821661131b5760405162461bcd60e51b815260206004820152602a60248201527f4552433732313a2062616c616e636520717565727920666f7220746865207a65604482015269726f206164647265737360b01b6064820152608401610b51565b506001600160a01b03166000908152616405602052604090205490565b6004546001600160a01b031633146113625760405162461bcd60e51b8152600401610b5190613406565b616a4880549115156101000261ff0019909216919091179055565b6004546001600160a01b031633146113a75760405162461bcd60e51b8152600401610b5190613406565b616a48805460ff19166001179055565b600060035482106113fa5760405162461bcd60e51b815260206004820152600d60248201526c111bd95cdb89dd08115e1a5cdd609a1b6044820152606401610b51565b6000828152616a4a60205260409020805461ffff168061141e575060019392505050565b818161ffff166010811061143457611434613384565b60108104909101546002600f928316026101000a900416949350505050565b60018054610a6c906133cb565b606060008060008061147186611855565b94509450509350935060008360ff1611801561149557508315806114955750836008145b156115205761708c5460e0830151604051630b711cb560e31b81526001600160a01b0390921691635b88e5a8916114d4918a9189918790600401613507565b600060405180830381865afa1580156114f1573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f191682016040526115199190810190613580565b945061159c565b61708c546040516358d8bcf360e11b815260048101889052602481018690526001600160a01b039091169063b1b179e690604401600060405180830381865afa158015611571573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f191682016040526115999190810190613580565b94505b50505050919050565b6110c93382610f19565b336001600160a01b03831614156116085760405162461bcd60e51b815260206004820152601960248201527f4552433732313a20617070726f766520746f2063616c6c6572000000000000006044820152606401610b51565b336000818152616a47602090815260408083206001600160a01b03871680855290835292819020805460ff191686151590811790915590519081529192917f17307eab39ab6107e8899845ad3d59bd9653f200f220920489ca2b5937696c31910160405180910390a35050565b600061167f612d58565b600080600061168d86611855565b509350509250925082600814156117505760e0810151604051600091608d916116ba918a916020016135b5565b6040516020818303038152906040528051906020012060001c901c90506116e0816129fd565b60ff1685526116f2600282901d6129fd565b60ff166020860152611707600482901d6129fd565b60ff16604086015261171c600682901d6129fd565b60ff166060860152611731600882901d6129fd565b60ff166080860152611746600a82901d6129fd565b60ff1660a0860152505b60ff82161561176157829450611766565b600194505b505050915091565b600581616400811061178257611782613384565b01546001600160a01b03163314801561179a57503332145b6117b65760405162461bcd60e51b8152600401610b5190613406565b6110c98160036125cf565b6004546001600160a01b031633146117eb5760405162461bcd60e51b8152600401610b5190613406565b616a4b55565b6004546001600160a01b0316331461181b5760405162461bcd60e51b8152600401610b5190613406565b600354600255565b61182d338361219e565b6118495760405162461bcd60e51b8152600401610b5190613429565b61106f84848484612a29565b600080611860612d76565b611868612d9e565b600060035486106118ab5760405162461bcd60e51b815260206004820152600d60248201526c111bd95cdb89dd08115e1a5cdd609a1b6044820152606401610b51565b6000868152616a4a6020526040902080546001965061ffff16945085805b8660ff168111611bbe5760008382601081106118e7576118e7613384565b601081049190910154604051600f9092166002026101000a900460f01b6001600160f01b0319166020820152602281018b90526042016040516020818303038152906040528051906020012060001c905083826010811061194a5761194a613384565b60108104909101546002600f928316026101000a900416985088611a355761708c54604051638f27b05f60e01b815260009182916001600160a01b0390911690638f27b05f906119a290869089908d906004016135db565b600060405180830381865afa1580156119bf573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f191682016040526119e79190810190613603565b60e08a0182905290925090508189611a00600187613667565b600f8110611a1057611a10613384565b6020020152808985600f8110611a2857611a28613384565b602002015250611ba89050565b88831415611add5761708c54604051630f4db48d60e11b81526001600160a01b0390911690631e9b691a90611a729084908d908b906004016135db565b600060405180830381865afa158015611a8f573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f19168201604052611ab79190810190613580565b87611ac3600185613667565b600f8110611ad357611ad3613384565b6020020152611ba8565b61708c54604051630bb2ee5160e01b815260009182916001600160a01b0390911690630bb2ee5190611b179086908f908d906004016135db565b600060405180830381865afa158015611b34573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f19168201604052611b5c9190810190613603565b90925090508088611b6e60018e613667565b60088110611b7e57611b7e613384565b60200201528189611b90600187613667565b600f8110611ba057611ba0613384565b602002015250505b5087915080611bb6816133b0565b9150506118c9565b50616a4c886164008110611bd457611bd4613384565b6010810491909101548354600f9092166002026101000a900461ffff90811694506001600160f01b909204161415611c325760408051808201909152600781526650656e64696e6760c81b60208201528460005b6020020152611ca7565b86611c5a576040805180820190915260048152634e474d4960e01b6020820152846000611c28565b8660081415611c8557604080518082019091526003815262474d4960e81b6020820152846000611c28565b6040805180820190915260088152675175657374696e6760c01b602082015284525b505091939590929450565b616a485460ff161580611ccf57506004546001600160a01b031633145b611ceb5760405162461bcd60e51b8152600401610b519061347a565b8051600a81111580611d0757506004546001600160a01b031633145b611d4d5760405162461bcd60e51b8152602060048201526017602482015276145d585b9d1a5d1e48131a5b5a5d08115e18d959591959604a1b6044820152606401610b51565b60025481600354611d5e919061349a565b1115611da25760405162461bcd60e51b815260206004820152601360248201527213585e0814dd5c1c1b1e48115e18d959591959606a1b6044820152606401610b51565b6000616a495482611db391906134b2565b905080341015611df95760405162461bcd60e51b8152602060048201526011602482015270496e737566666963656e742046756e647360781b6044820152606401610b51565b60005b8281101561106f57611e26848281518110611e1957611e19613384565b60200260200101516128fd565b80611e30816133b0565b915050611dfc565b616a4c816164008110611e4a57600080fd5b60109182820401919006600202915054906101000a900461ffff1681565b6005826164008110611e7c57611e7c613384565b01546001600160a01b031633148015611e9457503332145b611eb05760405162461bcd60e51b8152600401610b5190613406565b616a4b54811015611f0f5760405162461bcd60e51b815260206004820152602360248201527f412074727565206865726f206d75737420617373697374206d616e79206f746860448201526265727360e81b6064820152608401610b51565b610ede82826125cf565b60606000806000806000611f2c87611855565b61708c54604051635e7cd47560e01b8152959a50939850919650945092506001600160a01b031690635e7cd47590611f72908a908990899089908990899060040161367e565b600060405180830381865afa158015611f8f573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f19168201604052611fb79190810190613580565b979650505050505050565b6000818152616a4a6020526040812054600160f01b900461ffff16600114908082156120805761718d5461ffff6201000082048116911660005b8281101561207c57600061708d83610100811061201b5761201b613384565b018054909150600160801b90046001600160801b031688141561204d57549094506001600160801b031692508361207c565b82612057816133b0565b93505061010083141561206957600092505b5080612074816133b0565b915050611ffc565b5050505b9193909250565b6001600160a01b039182166000908152616a476020908152604080832093909416825291909152205460ff1690565b61708d8161010081106120c857600080fd5b01546001600160801b038082169250600160801b9091041682565b6004546001600160a01b0316331461210d5760405162461bcd60e51b8152600401610b5190613406565b600480546001600160a01b0319166001600160a01b0392909216919091179055565b6000818152616a466020526040902080546001600160a01b0319166001600160a01b038416908117909155819061216582611232565b6001600160a01b03167f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b92560405160405180910390a45050565b600060035482106122065760405162461bcd60e51b815260206004820152602c60248201527f4552433732313a206f70657261746f7220717565727920666f72206e6f6e657860448201526b34b9ba32b73a103a37b5b2b760a11b6064820152608401610b51565b600061221183611232565b9050806001600160a01b0316846001600160a01b0316148061224c5750836001600160a01b031661224184610aed565b6001600160a01b0316145b8061225c575061225c8185612087565b949350505050565b616a485460ff16158061228157506004546001600160a01b031633145b61229d5760405162461bcd60e51b8152600401610b519061347a565b826001600160a01b03166122b082611232565b6001600160a01b0316146123185760405162461bcd60e51b815260206004820152602960248201527f4552433732313a207472616e73666572206f6620746f6b656e2074686174206960448201526839903737ba1037bbb760b91b6064820152608401610b51565b6001600160a01b03821661237a5760405162461bcd60e51b8152602060048201526024808201527f4552433732313a207472616e7366657220746f20746865207a65726f206164646044820152637265737360e01b6064820152608401610b51565b61238560008261212f565b600061640682616400811061239c5761239c613384565b601091828204019190066002029054906101000a900461ffff16905060006001826123c791906136d0565b6001600160a01b0386166000908152616405602052604081205461ffff929092169250906123f790600190613667565b90508181146124b9576001600160a01b03861660009081526164056020526040812080548390811061242b5761242b613384565b90600052602060002001549050806164056000896001600160a01b03166001600160a01b03168152602001908152602001600020848154811061247057612470613384565b6000918252602090912001558361640682616400811061249257612492613384565b601091828204019190066002026101000a81548161ffff021916908361ffff160217905550505b6001600160a01b0386166000908152616405602052604090208054806124e1576124e16136f3565b6000828152602080822083016000199081018390559092019092556001600160a01b03871680835261640582526040832080546001810182558185529284209092018790559091525461640685616400811061253f5761253f613384565b601091828204019190066002026101000a81548161ffff021916908361ffff16021790555084600585616400811061257957612579613384565b0180546001600160a01b0319166001600160a01b03928316179055604051859187811691908916907fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef90600090a4505050505050565b616a485460ff1615806125ec57506004546001600160a01b031633145b6126085760405162461bcd60e51b8152600401610b519061347a565b616a4854610100900460ff161561264a5760405162461bcd60e51b8152602060048201526006602482015265233937bd32b760d11b6044820152606401610b51565b61718d5461ffff62010000820481169116600383101561266957600392505b6000805b84811015612731578361267f57612731565b600061708d84610100811061269657612696613384565b0180549091506001600160801b031643116126b15750612731565b80546126cc90600160801b90046001600160801b0316612a5c565b61708d8461010081106126e1576126e1613384565b6000910155846126f081613709565b95505083806126fe906133b0565b945050828061270c906133b0565b93505061010084141561271e57600093505b5080612729816133b0565b91505061266d565b50616a4b5481106127945780616a4c86616400811061275257612752613384565b601091828204019190066002028282829054906101000a900461ffff166127799190613720565b92506101000a81548161ffff021916908361ffff1602179055505b6000858152616a4a602052604081208054909161ffff909116908282601081106127c0576127c0613384565b60108104909101546002600f928316026101000a900416905080158015906127e85750600881105b806127f1575081155b80156127fe575061010086105b801561281457508254600160f01b900461ffff16155b156128cd576000612825868861349a565b905086612831816133b0565b975050806101001161284c5761284961010082613667565b90505b6040518060400160405280436001612864919061349a565b6001600160801b031681526020018a6001600160801b031681525061708d82610100811061289457612894613384565b82516020909301516001600160801b03908116600160801b02931692909217910155508254600160f01b6001600160f01b039091161783555b505061718d805463ffffffff19166201000061ffff9687160261ffff191617939094169290921790925550505050565b6003546001600160a01b038216600081815261640560209081526040822080546001810182558184529183209091018490559190525461640682616400811061294857612948613384565b601091828204019190066002026101000a81548161ffff021916908361ffff16021790555081600582616400811061298257612982613384565b0180546001600160a01b0319166001600160a01b0392909216919091179055600380549060006129b1836133b0565b91905055506129c18160036125cf565b60405181906001600160a01b038416906000907fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef908290a45050565b600060018216612a0f57506000919050565b600182811d16612a2157506001919050565b506002919050565b612a34848484612264565b612a4084848484612c63565b61106f5760405162461bcd60e51b8152600401610b5190613746565b6000818152616a4a602052604081208054909161ffff90911690828260108110612a8857612a88613384565b60108104909101546002600f928316026101000a9004169050600082612ab15760019150612af8565b8260011415612ac257506001612af8565b83612ace600185613667565b60108110612ade57612ade613384565b60108104909101546002600f928316026101000a90041690505b600085612b06600143613667565b40604051602001612b21929190918252602082015260400190565b60408051601f198184030181529190528051602090910120905060ff81166000612b4c8560096134b2565b612b5790600561349a565b90506000612b668660166134b2565b612b7190605a61349a565b90508560011415612b8157600291505b85851415612b8d575060005b81831015612b9e5760009550612bb3565b808310612bb357612bb086600161349a565b95505b612bbe87600161349a565b885461ffff191661ffff91909116178855612bdd86600486901b61349a565b88612be989600161349a565b60108110612bf957612bf9613384565b601091828204019190066002026101000a81548161ffff021916908361ffff160217905550600088600f60108110612c3357612c33613384565b601091828204019190066002026101000a81548161ffff021916908361ffff160217905550505050505050505050565b6000833b15612d4d57604051630a85bd0160e11b81526001600160a01b0385169063150b7a0290612c9e903390899088908890600401613798565b6020604051808303816000875af1925050508015612cd9575060408051601f3d908101601f19168201909252612cd6918101906137d5565b60015b612d33573d808015612d07576040519150601f19603f3d011682016040523d82523d6000602084013e612d0c565b606091505b508051612d2b5760405162461bcd60e51b8152600401610b5190613746565b805181602001fd5b6001600160e01b031916630a85bd0160e11b14905061225c565b506001949350505050565b6040518060c001604052806006906020820280368337509192915050565b604051806101e00160405280600f905b6060815260200190600190039081612d865790505090565b60408051610100810190915260608152600760208201612d86565b600060208284031215612dcb57600080fd5b5035919050565b602080825282518282018190526000919060409081850190868401855b82811015612e2157815180516001600160801b0390811686529087015116868501529284019290850190600101612def565b5091979650505050505050565b6001600160e01b0319811681146110c957600080fd5b600060208284031215612e5657600080fd5b8135612e6181612e2e565b9392505050565b60005b83811015612e83578181015183820152602001612e6b565b8381111561106f5750506000910152565b60008151808452612eac816020860160208601612e68565b601f01601f19169290920160200192915050565b602081526000612e616020830184612e94565b80356001600160a01b0381168114612eea57600080fd5b919050565b60008060408385031215612f0257600080fd5b612f0b83612ed3565b946020939093013593505050565b600080600060608486031215612f2e57600080fd5b612f3784612ed3565b9250612f4560208501612ed3565b9150604084013590509250925092565b634e487b7160e01b600052604160045260246000fd5b604051601f8201601f1916810167ffffffffffffffff81118282101715612f9457612f94612f55565b604052919050565b600067ffffffffffffffff821115612fb657612fb6612f55565b5060051b60200190565b60006020808385031215612fd357600080fd5b823567ffffffffffffffff811115612fea57600080fd5b8301601f81018513612ffb57600080fd5b803561300e61300982612f9c565b612f6b565b81815260059190911b8201830190838101908783111561302d57600080fd5b928401925b82841015611fb757833582529284019290840190613032565b60006020828403121561305d57600080fd5b612e6182612ed3565b80151581146110c957600080fd5b60006020828403121561308657600080fd5b8135612e6181613066565b600080604083850312156130a457600080fd5b6130ad83612ed3565b915060208301356130bd81613066565b809150509250929050565b60ff838116825260e082019060208084018560005b60068110156130fc5781518516835291830191908301906001016130dd565b50505050509392505050565b600067ffffffffffffffff82111561312257613122612f55565b50601f01601f191660200190565b6000806000806080858703121561314657600080fd5b61314f85612ed3565b935061315d60208601612ed3565b925060408501359150606085013567ffffffffffffffff81111561318057600080fd5b8501601f8101871361319157600080fd5b803561319f61300982613108565b8181528860208385010111156131b457600080fd5b8160208401602083013760006020838301015280935050505092959194509250565b6000826101e081018360005b600f8110156132115783830387526131fb838351612e94565b60209788019790935091909101906001016131e2565b509095945050505050565b60008261010081018360005b6008811015613211578383038752613241838351612e94565b6020978801979093509190910190600101613228565b85815260ff8516602082015260a06040820152600061327960a08301866131d6565b828103606084015261328b818661321c565b91505061ffff831660808301529695505050505050565b600060208083850312156132b557600080fd5b823567ffffffffffffffff8111156132cc57600080fd5b8301601f810185136132dd57600080fd5b80356132eb61300982612f9c565b81815260059190911b8201830190838101908783111561330a57600080fd5b928401925b82841015611fb75761332084612ed3565b8252928401929084019061330f565b6000806040838503121561334257600080fd5b50508035926020909101359150565b6000806040838503121561336457600080fd5b61336d83612ed3565b915061337b60208401612ed3565b90509250929050565b634e487b7160e01b600052603260045260246000fd5b634e487b7160e01b600052601160045260246000fd5b60006000198214156133c4576133c461339a565b5060010190565b600181811c908216806133df57607f821691505b6020821081141561340057634e487b7160e01b600052602260045260246000fd5b50919050565b6020808252600990820152682737ba1027bbb732b960b91b604082015260600190565b60208082526031908201527f4552433732313a207472616e736665722063616c6c6572206973206e6f74206f6040820152701ddb995c881b9bdc88185c1c1c9bdd9959607a1b606082015260800190565b60208082526006908201526514185d5cd95960d21b604082015260600190565b600082198211156134ad576134ad61339a565b500190565b60008160001904831182151516156134cc576134cc61339a565b500290565b6000602082840312156134e357600080fd5b5051919050565b6000602082840312156134fc57600080fd5b8151612e6181613066565b8481528360208201526080604082015260006135266080830185612e94565b905061ffff8316606083015295945050505050565b600082601f83011261354c57600080fd5b815161355a61300982613108565b81815284602083860101111561356f57600080fd5b61225c826020830160208701612e68565b60006020828403121561359257600080fd5b815167ffffffffffffffff8111156135a957600080fd5b61225c8482850161353b565b828152600082516135cd816020850160208701612e68565b919091016020019392505050565b8381528260208201526060604082015260006135fa606083018461321c565b95945050505050565b6000806040838503121561361657600080fd5b825167ffffffffffffffff8082111561362e57600080fd5b61363a8683870161353b565b9350602085015191508082111561365057600080fd5b5061365d8582860161353b565b9150509250929050565b6000828210156136795761367961339a565b500390565b86815285602082015260ff8516604082015260c0606082015260006136a660c08301866131d6565b82810360808401526136b8818661321c565b91505061ffff831660a0830152979650505050505050565b600061ffff838116908316818110156136eb576136eb61339a565b039392505050565b634e487b7160e01b600052603160045260246000fd5b6000816137185761371861339a565b506000190190565b600061ffff80831681851680830382111561373d5761373d61339a565b01949350505050565b60208082526032908201527f4552433732313a207472616e7366657220746f206e6f6e20455243373231526560408201527131b2b4bb32b91034b6b83632b6b2b73a32b960711b606082015260800190565b6001600160a01b03858116825284166020820152604081018390526080606082018190526000906137cb90830184612e94565b9695505050505050565b6000602082840312156137e757600080fd5b8151612e6181612e2e56fea264697066735822122035966c1ca62a2b6362d48637348298e71a4db64fb9dbf7b48abd20048664347f64736f6c634300080c0033

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

000000000000000000000000fea93334f43db574b905be00dce122210641215d

-----Decoded View---------------
Arg [0] : quest3DataContract (address): 0xfEa93334F43DB574b905BE00dcE122210641215d

-----Encoded View---------------
1 Constructor Arguments found :
Arg [0] : 000000000000000000000000fea93334f43db574b905be00dce122210641215d


Loading...
Loading
Loading...
Loading
[ Download: CSV Export  ]

A token is a representation of an on-chain or off-chain asset. The token page shows information such as price, total supply, holders, transfers and social links. Learn more about this page in our Knowledge Base.