ETH Price: $3,430.89 (-1.28%)
Gas: 4 Gwei

Contract

0xeB0493d5317C968003B708F0e3dCC478ca6679B6
 

Overview

ETH Balance

0.2393048376102 ETH

Eth Value

$821.03 (@ $3,430.89/ETH)
Transaction Hash
Method
Block
From
To
Safe Transfer Fr...197221262024-04-24 2:00:5983 days ago1713924059IN
0xeB0493d5...8ca6679B6
0 ETH0.0008155710.7372217
Safe Transfer Fr...197221142024-04-24 1:58:2383 days ago1713923903IN
0xeB0493d5...8ca6679B6
0 ETH0.0008748710.08813502
Safe Transfer Fr...197221102024-04-24 1:57:3583 days ago1713923855IN
0xeB0493d5...8ca6679B6
0 ETH0.0011268910.85400902
Set Approval For...195389292024-03-29 10:00:47109 days ago1711706447IN
0xeB0493d5...8ca6679B6
0 ETH0.0009920821.43428705
Set Approval For...193553962024-03-03 14:59:23135 days ago1709477963IN
0xeB0493d5...8ca6679B6
0 ETH0.0029321663.46546251
Set Approval For...191171272024-01-30 5:06:47168 days ago1706591207IN
0xeB0493d5...8ca6679B6
0 ETH0.0005322311.52005297
Set Approval For...191097072024-01-29 4:09:59169 days ago1706501399IN
0xeB0493d5...8ca6679B6
0 ETH0.0004676210.1216316
Set Approval For...189920442024-01-12 16:35:59186 days ago1705077359IN
0xeB0493d5...8ca6679B6
0 ETH0.0009176237.64911724
Set Approval For...189240052024-01-03 2:57:47195 days ago1704250667IN
0xeB0493d5...8ca6679B6
0 ETH0.0007354815.89038346
Set Approval For...189235702024-01-03 1:29:59195 days ago1704245399IN
0xeB0493d5...8ca6679B6
0 ETH0.0008290417.91176946
Do Something187338922023-12-07 10:42:59222 days ago1701945779IN
0xeB0493d5...8ca6679B6
0 ETH0.0027968139.81113059
Do Something183599352023-10-16 2:25:23274 days ago1697423123IN
0xeB0493d5...8ca6679B6
0 ETH0.000520497.41787077
Do Something179985052023-08-26 11:20:35325 days ago1693048835IN
0xeB0493d5...8ca6679B6
0 ETH0.0008322611.86034452
Do Something175132292023-06-19 10:34:11393 days ago1687170851IN
0xeB0493d5...8ca6679B6
0 ETH0.0011227516
Do Something174857692023-06-15 14:06:59397 days ago1686838019IN
0xeB0493d5...8ca6679B6
0 ETH0.0026043930.16022951
Do Something173131492023-05-22 6:46:59421 days ago1684738019IN
0xeB0493d5...8ca6679B6
0 ETH0.002912233.83726263
Safe Transfer Fr...173129732023-05-22 6:11:47421 days ago1684735907IN
0xeB0493d5...8ca6679B6
0 ETH0.0024874927.35136908
Mint171396542023-04-27 19:41:23446 days ago1682624483IN
0xeB0493d5...8ca6679B6
0.09971034 ETH0.0184070133.74152478
Do Something170956162023-04-21 15:21:47452 days ago1682090507IN
0xeB0493d5...8ca6679B6
0 ETH0.0026070737.27051322
Set Approval For...170638252023-04-17 3:23:11456 days ago1681701791IN
0xeB0493d5...8ca6679B6
0 ETH0.0012409426.85965979
Do Something166337852023-02-15 11:15:59517 days ago1676459759IN
0xeB0493d5...8ca6679B6
0 ETH0.0016210123.07596682
Do Something165308152023-02-01 1:54:11531 days ago1675216451IN
0xeB0493d5...8ca6679B6
0 ETH0.0011869916.96604821
Set Approval For...164488132023-01-20 15:07:59543 days ago1674227279IN
0xeB0493d5...8ca6679B6
0 ETH0.0014266330.87879206
Set Approval For...163563082023-01-07 17:10:23556 days ago1673111423IN
0xeB0493d5...8ca6679B6
0 ETH0.0010935923.67038853
Set Approval For...163382752023-01-05 4:43:23558 days ago1672893803IN
0xeB0493d5...8ca6679B6
0 ETH0.0007314215.83137513
View all transactions

Latest 2 internal transactions

Advanced mode:
Parent Transaction Hash Block From To
151679802022-07-18 17:23:54729 days ago1658165034
0xeB0493d5...8ca6679B6
18.72560354 ETH
144972792022-04-01 0:52:08837 days ago1648774328
0xeB0493d5...8ca6679B6
0.79768279 ETH
Loading...
Loading

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


Block Transaction Difficulty Gas Used Reward
View All Blocks Produced

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

Validator Index Block Amount
View All Withdrawals

Transaction Hash Block Value Eth2 PubKey Valid
View All Deposits
Loading...
Loading
[ Download: CSV Export  ]
[ Download: CSV Export  ]

A contract address hosts a smart contract, which is a set of code stored on the blockchain that runs when predetermined conditions are met. Learn more about addresses in our Knowledge Base.