ETH Price: $3,359.86 (+0.36%)
Gas: 8.82 Gwei

Token

Degen$ Farm Creatures (CREAT)
 

Overview

Max Total Supply

963 CREAT

Holders

192

Market

Volume (24H)

N/A

Min Price (24H)

N/A

Max Price (24H)

N/A
Filtered by Token Holder
d1m0ndhvnd.eth
Balance
2 CREAT
0xad4489f64a8be791294116d3e99d2721c7f0a72a
Loading...
Loading
Loading...
Loading
Loading...
Loading

OVERVIEW

[Degen’$ Farm](https://www.degens.farm) is a gamified NFT collectible tightly connected with DeFi culture. It's an experiment with skill-based distribution. There are 2420 unique creatures to be discovered, each has its own character, style and sound. They are 100% blockchain creatures and produce $DUNG and collect $ETH for their owners. If you want to farm next level creatures, you need [LAND](https://opensea.io/collection/degens-farm-lands) and after you deploy it with your creature in our [farming](https://degens.farm/farming) cabinet you receive an [EGG](https://opensea.io/collection/degens-farm-eggs). You can use [TOOLS](https://opensea.io/collection/degens-farm-tools) and other [farming tricks](https://docs.degensfarm.com/farming) to improve your farming probability. Come back in one week and see what you've got! “The more one sows – the greater the harvest!” Chichi, Degen’$ Farm CEO

# Exchange Pair Price  24H Volume % Volume

Contract Source Code Verified (Exact Match)

Contract Name:
Creatures

Compiler Version
v0.7.4+commit.3f05b770

Optimization Enabled:
Yes with 200 runs

Other Settings:
default evmVersion, MIT license

Contract Source Code (Solidity Multiple files format)

File 3 of 26: CreatureERC721.sol
// SPDX-License-Identifier: MIT
// // Degen Farm. Collectible NFT game
pragma solidity ^0.7.4;
pragma experimental ABIEncoderV2;

import "./ERC721URIStorage.sol";

contract Creatures is ERC721URIStorage {

    enum AnimalType {
        Cow, Horse, Rabbit, Chicken, Pig, Cat, Dog, Goose, Goat, Sheep,
        Snake, Fish, Frog, Worm, Lama, Mouse, Camel, Donkey, Bee, Duck,
        GenesisEgg // 20
    }
    enum Rarity     {
        Normie, // 0
        Chad,   // 1
        Degen,  // 2
        Unique // 3
    }

    struct Animal {
        AnimalType atype; // uint8
        Rarity     rarity; // uint8
        uint32     index;
        uint64     birthday;
        string     name;
    }

    mapping (uint256 => Animal) public animals;

    mapping(address => bool) public trusted_markets;
    event TrustedMarket(address indexed _market, bool _state);

    constructor(string memory name_,
        string memory symbol_) ERC721(name_, symbol_)  {
    }

    function mint(
        address to,
        uint256 tokenId,
        uint8 _animalType,
        uint8 _rarity,
        uint32 index
        ) external onlyOwner {

        _mint(to, tokenId);
        animals[tokenId] = Animal(AnimalType(_animalType), Rarity(_rarity), index, uint64(block.timestamp), "");
    }

    function setName(uint256 tokenId, string calldata _name) external {
        require(ownerOf(tokenId) == msg.sender, 'Only owner can change name');
        require(bytes(animals[tokenId].name).length == 0, 'The name has already been given');

        animals[tokenId].name = _name;
    }

    function setTrustedMarket(address _market, bool _state) external onlyOwner {
        trusted_markets[_market] = _state;
        emit TrustedMarket(_market, _state);
    }

    function getTypeAndRarity(uint256 _tokenId) external view returns(uint8, uint8) {
        return (uint8(animals[_tokenId].atype), uint8(animals[_tokenId].rarity));
    }

    function getUsersTokens(address _owner) external view returns (uint256[] memory) {
        //We can return only uint256[] memory
         uint256 n = balanceOf(_owner);

        uint256[] memory result = new uint256[](n);
        for (uint16 i=0; i < n; i++) {
            result[i]=tokenOfOwnerByIndex(_owner, i);
        }
        return  result;
    }

    function baseURI() public view override returns (string memory) {
        return 'http://degens.farm/meta/creatures/';
    }

    /**
     * @dev Overriding standart function for gas safe traiding with trusted parts like DegenFarm
     * Requirements:
     *
     * - `from` and `to` cannot be the zero address.
     * - `caller` must be added to trustedMarkets.
     */
    function transferFrom(address from, address to, uint256 tokenId) public override {
        if (trusted_markets[msg.sender]) {
            _transfer(from, to, tokenId);
        } else {
            super.transferFrom(from, to, tokenId);
        }

    }
}

File 1 of 26: Address.sol
// SPDX-License-Identifier: MIT

pragma solidity >=0.6.2 <0.8.0;

/**
 * @dev Collection of functions related to the address type
 */
library Address {
    /**
     * @dev Returns true if `account` is a contract.
     *
     * [IMPORTANT]
     * ====
     * It is unsafe to assume that an address for which this function returns
     * false is an externally-owned account (EOA) and not a contract.
     *
     * Among others, `isContract` will return false for the following
     * types of addresses:
     *
     *  - an externally-owned account
     *  - a contract in construction
     *  - an address where a contract will be created
     *  - an address where a contract lived, but was destroyed
     * ====
     */
    function isContract(address account) internal view returns (bool) {
        // This method relies on extcodesize, which returns 0 for contracts in
        // construction, since the code is only stored at the end of the
        // constructor execution.

        uint256 size;
        // solhint-disable-next-line no-inline-assembly
        assembly { size := extcodesize(account) }
        return size > 0;
    }

    /**
     * @dev Replacement for Solidity's `transfer`: sends `amount` wei to
     * `recipient`, forwarding all available gas and reverting on errors.
     *
     * https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost
     * of certain opcodes, possibly making contracts go over the 2300 gas limit
     * imposed by `transfer`, making them unable to receive funds via
     * `transfer`. {sendValue} removes this limitation.
     *
     * https://diligence.consensys.net/posts/2019/09/stop-using-soliditys-transfer-now/[Learn more].
     *
     * IMPORTANT: because control is transferred to `recipient`, care must be
     * taken to not create reentrancy vulnerabilities. Consider using
     * {ReentrancyGuard} or the
     * https://solidity.readthedocs.io/en/v0.5.11/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern].
     */
    function sendValue(address payable recipient, uint256 amount) internal {
        require(address(this).balance >= amount, "Address: insufficient balance");

        // solhint-disable-next-line avoid-low-level-calls, avoid-call-value
        (bool success, ) = recipient.call{ value: amount }("");
        require(success, "Address: unable to send value, recipient may have reverted");
    }

    /**
     * @dev Performs a Solidity function call using a low level `call`. A
     * plain`call` is an unsafe replacement for a function call: use this
     * function instead.
     *
     * If `target` reverts with a revert reason, it is bubbled up by this
     * function (like regular Solidity function calls).
     *
     * Returns the raw returned data. To convert to the expected return value,
     * use https://solidity.readthedocs.io/en/latest/units-and-global-variables.html?highlight=abi.decode#abi-encoding-and-decoding-functions[`abi.decode`].
     *
     * Requirements:
     *
     * - `target` must be a contract.
     * - calling `target` with `data` must not revert.
     *
     * _Available since v3.1._
     */
    function functionCall(address target, bytes memory data) internal returns (bytes memory) {
      return functionCall(target, data, "Address: low-level call failed");
    }

    /**
     * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], but with
     * `errorMessage` as a fallback revert reason when `target` reverts.
     *
     * _Available since v3.1._
     */
    function functionCall(address target, bytes memory data, string memory errorMessage) internal returns (bytes memory) {
        return functionCallWithValue(target, data, 0, errorMessage);
    }

    /**
     * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],
     * but also transferring `value` wei to `target`.
     *
     * Requirements:
     *
     * - the calling contract must have an ETH balance of at least `value`.
     * - the called Solidity function must be `payable`.
     *
     * _Available since v3.1._
     */
    function functionCallWithValue(address target, bytes memory data, uint256 value) internal returns (bytes memory) {
        return functionCallWithValue(target, data, value, "Address: low-level call with value failed");
    }

    /**
     * @dev Same as {xref-Address-functionCallWithValue-address-bytes-uint256-}[`functionCallWithValue`], but
     * with `errorMessage` as a fallback revert reason when `target` reverts.
     *
     * _Available since v3.1._
     */
    function functionCallWithValue(address target, bytes memory data, uint256 value, string memory errorMessage) internal returns (bytes memory) {
        require(address(this).balance >= value, "Address: insufficient balance for call");
        require(isContract(target), "Address: call to non-contract");

        // solhint-disable-next-line avoid-low-level-calls
        (bool success, bytes memory returndata) = target.call{ value: value }(data);
        return _verifyCallResult(success, returndata, errorMessage);
    }

    /**
     * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],
     * but performing a static call.
     *
     * _Available since v3.3._
     */
    function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) {
        return functionStaticCall(target, data, "Address: low-level static call failed");
    }

    /**
     * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],
     * but performing a static call.
     *
     * _Available since v3.3._
     */
    function functionStaticCall(address target, bytes memory data, string memory errorMessage) internal view returns (bytes memory) {
        require(isContract(target), "Address: static call to non-contract");

        // solhint-disable-next-line avoid-low-level-calls
        (bool success, bytes memory returndata) = target.staticcall(data);
        return _verifyCallResult(success, returndata, errorMessage);
    }

    /**
     * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],
     * but performing a delegate call.
     *
     * _Available since v3.4._
     */
    function functionDelegateCall(address target, bytes memory data) internal returns (bytes memory) {
        return functionDelegateCall(target, data, "Address: low-level delegate call failed");
    }

    /**
     * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],
     * but performing a delegate call.
     *
     * _Available since v3.4._
     */
    function functionDelegateCall(address target, bytes memory data, string memory errorMessage) internal returns (bytes memory) {
        require(isContract(target), "Address: delegate call to non-contract");

        // solhint-disable-next-line avoid-low-level-calls
        (bool success, bytes memory returndata) = target.delegatecall(data);
        return _verifyCallResult(success, returndata, errorMessage);
    }

    function _verifyCallResult(bool success, bytes memory returndata, string memory errorMessage) private pure returns(bytes memory) {
        if (success) {
            return returndata;
        } else {
            // Look for revert reason and bubble it up if present
            if (returndata.length > 0) {
                // The easiest way to bubble the revert reason is using memory via assembly

                // solhint-disable-next-line no-inline-assembly
                assembly {
                    let returndata_size := mload(returndata)
                    revert(add(32, returndata), returndata_size)
                }
            } else {
                revert(errorMessage);
            }
        }
    }
}

File 2 of 26: Context.sol
// SPDX-License-Identifier: MIT

pragma solidity >=0.6.0 <0.8.0;

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

    function _msgData() internal view virtual returns (bytes memory) {
        this; // silence state mutability warning without generating bytecode - see https://github.com/ethereum/solidity/issues/2691
        return msg.data;
    }
}

File 4 of 26: DegensFarm.sol
// SPDX-License-Identifier: MIT
// Degen Farm. Collectible NFT game
pragma solidity ^0.7.4;
pragma experimental ABIEncoderV2;

import "./DegensFarmBase.sol";

contract DegenFarm is DegenFarmBase {

    uint8   constant public CREATURE_TYPE_COUNT= 20;  //how much creatures types may be used
    uint256 constant public FARMING_DURATION   = 168 hours; //in seconds
    //uint256 constant public NEXT_FARMING_DELAY = 1   weeks;
    uint256 constant public TOOL_UNSTAKE_DELAY = 1   weeks;
    uint256 constant public REVEAL_THRESHOLD   = 810e18;    //90% from MAX_BAGS
    uint16   constant public NORMIE_COUNT_IN_TYPE = 100;
    uint16   constant public CHAD_COUNT_IN_TYPE = 20;
    uint16   constant public MAX_LANDS = 2500;

    constructor (
        address _land,
        address _creatures,
        address _inventory,
        address _bagstoken,
        address _dungtoken,
        IEggs _eggs
    )
        DegenFarmBase(_land, _creatures, _inventory, _bagstoken, _dungtoken, _eggs)
    {
        require(CREATURE_TYPE_COUNT <= CREATURE_TYPE_COUNT_MAX, "CREATURE_TYPE_COUNT is greater than CREATURE_TYPE_COUNT_MAX");

        // Mainnet amulet addrresses
        amulets[0] = [0xD533a949740bb3306d119CC777fa900bA034cd52, 0x1F573D6Fb3F13d689FF844B4cE37794d79a7FF1C];
        amulets[1] = [0x1f9840a85d5aF5bf1D1762F925BDADdC4201F984, 0x111111111117dC0aa78b770fA6A738034120C302];
        amulets[2] = [0xE41d2489571d322189246DaFA5ebDe1F4699F498, 0xC011a73ee8576Fb46F5E1c5751cA3B9Fe0af2a6F,
            0xfA5047c9c78B8877af97BDcb85Db743fD7313d4a
        ];
        amulets[3] = [0x0000000000000000000000000000000000000000, 0x0000000000000000000000000000000000000000];
        amulets[4] = [0xc00e94Cb662C3520282E6f5717214004A7f26888, 0x6B3595068778DD592e39A122f4f5a5cF09C90fE2,
            0x9f8F72aA9304c8B593d555F12eF6589cC3A579A2
        ];
        amulets[5] = [0x0D8775F648430679A709E98d2b0Cb6250d2887EF, 0x584bC13c7D411c00c01A62e8019472dE68768430];
        amulets[6] = [0x3472A5A71965499acd81997a54BBA8D852C6E53d, 0x0F5D2fB29fb7d3CFeE444a200298f468908cC942];
        amulets[7] = [0x514910771AF9Ca656af840dff83E8264EcF986CA, 0xd7c49CEE7E9188cCa6AD8FF264C1DA2e69D4Cf3B];
        amulets[8] = [0x0bc529c00C6401aEF6D220BE8C6Ea1667F6Ad93e, 0x3155BA85D5F96b2d030a4966AF206230e46849cb];
        amulets[9] = [0xa1faa113cbE53436Df28FF0aEe54275c13B40975, 0x3F382DbD960E3a9bbCeaE22651E88158d2791550,
            0x7Fc66500c84A76Ad7e9c93437bFc5Ac33E2DDaE9
        ];
        // TODO: add amulets
        for (uint i = 10; i < CREATURE_TYPE_COUNT; i++) {
            amulets[i] = [0xa1faa113cbE53436Df28FF0aEe54275c13B40975];
        }
    }

    function getCreatureTypeCount() override internal view returns (uint16) {
        return CREATURE_TYPE_COUNT;
    }

    function getFarmingDuration() override internal view returns (uint) {
        return FARMING_DURATION;
    }

    function getNormieCountInType() override internal view returns (uint16) {
        return NORMIE_COUNT_IN_TYPE;
    }

    function getChadCountInType() override internal view returns (uint16) {
        return CHAD_COUNT_IN_TYPE;
    }

    function getMaxLands() override internal view returns (uint16) {
        return MAX_LANDS;
    }

    function getToolUnstakeDelay() override internal view returns (uint) {
        return TOOL_UNSTAKE_DELAY;
    }

}

File 5 of 26: DegensFarmBase.sol
// SPDX-License-Identifier: MIT
// Degen Farm. Collectible NFT game
pragma solidity ^0.7.4;
pragma experimental ABIEncoderV2;

import "./IERC20.sol";
import "./IERC1155.sol";
import "./ERC1155Receiver.sol";
import "./IERC721.sol";
import "./Ownable.sol";

interface IEggs is IERC721 {
    function mint(address to, uint256 tokenId) external;
    function burn(uint256 tokenId) external;
    function getUsersTokens(address _owner) external view returns (uint256[] memory);
}


interface ICreatures is IERC721 {
    function mint(
        address to, 
        uint256 tokenId, 
        uint8 _animalType,
        uint8 _rarity,
        uint32 index
        ) external;

    function getTypeAndRarity(uint256 _tokenId) external view returns(uint8, uint8);
}

interface ILand is IERC721 {
    function mint(
        address to, 
        uint256 tokenId
    ) external;
    function burn(uint256 tokenId) external;
}

interface IDung is IERC20 {
    function mint(
        address to, 
        uint256 amount 
    ) external;
}

interface IInventory is IERC1155 {
     function getToolBoost(uint8 _item) external view returns (uint16);
}

interface IAmuletPriceProvider {
     function getLastPrice(address _amulet) external view returns (uint256);
}

interface IOperatorManage {
    function addOperator(address _newOperator) external;    
    function removeOperator(address _oldOperator) external;
    function withdrawERC20(IERC20 _tokenContract, address _admin) external;
}

abstract contract DegenFarmBase is ERC1155Receiver, Ownable {
    enum AnimalType {
        Cow, Horse, Rabbit, Chicken, Pig, Cat, Dog, Goose, Goat, Sheep,
        Snake, Fish, Frog, Worm, Lama, Mouse, Camel, Donkey, Bee, Duck,
        GenesisEgg // 20
    }
    enum Rarity     {
        Normie, // 0
        Chad,   // 1
        Degen,  // 2
        Unique // 3
    }
    enum   Result     {Fail,   Dung,  Chad, Degen}
    
    //External conatrct addresses used with this farm.
    struct AddressRegistry {
        address land;
        address creatures;
        address inventory;
        address bagstoken;
        address dungtoken;
    }

    //Degens Farm Key numbers
    struct CreaturesCount {
        uint16 totalNormie;
        uint16 leftNormie;
        uint16 totalChad;
        uint16 leftChadToDiscover;
        uint16 totalDegen;
        uint16 leftDegenToDiscover;
        uint16 leftChadFarmAttempts;
        uint16 leftDegenFarmAttempts;
    }

    //Land count record
    struct LandCount {
        uint16 total;
        uint16 left;
    }
 
    // Record  represent one farming act
    struct FarmRecord {
        uint256   creatureId;
        uint256   landId;
        uint256   harvestTime;
        uint256[] amuletsPrice1;
        uint256[] amuletsPrice2;
        Result    harvest;
        uint256   harvestId; //new NFT tokenId
        bool[3]   commonAmuletInitialHold;
    }

    // Bonus for better harvest
    struct Bonus {
        uint16 amuletHold;
        uint16 amuletBullTrend;
        uint16 inventoryHold;
    }

    uint8   constant public CREATURE_TYPE_COUNT_MAX = 20;  //how much creatures types may be used

    //Creature probubility multiplier, scaled with 100. 3.00  - 300, 3.05 - 305 etc
    // so we need additional divide on 100 in formula
    uint32  constant public CREATURE_P_MULT = 230;
    uint16  public MAX_ALL_NORMIES    = getCreatureTypeCount() * getNormieCountInType(); //subj
    uint256 constant public NFT_ID_MULTIPLIER  = 10000;     //must be set more then all Normies count
    uint256 constant public FARM_DUNG_AMOUNT   = 250e32;      //per one harvest
    uint16  constant public BONUS_POINTS_AMULET_HOLD       = 10;
    uint16  constant public BONUS_POINTS_AMULET_BULL_TREND = 90;
    
    //Common Amulet addresses
    address[3] public COMMON_AMULETS = [
        0xa0246c9032bC3A600820415aE600c6388619A14D, 
        0x87d73E916D7057945c9BcD8cdd94e42A6F47f776,
        0x126c121f99e1E211dF2e5f8De2d96Fa36647c855
    ];

    bool    public REVEAL_ENABLED  = false;
    bool    public FARMING_ENABLED = false;
    address public priceProvider;
    IEggs    public eggs;
    
    address[][CREATURE_TYPE_COUNT_MAX] public amulets; //amulets for creatures
    AddressRegistry                    public farm;
    LandCount                          public landCount;

    //common token price snapshots
    mapping(uint256 => uint256[3]) public commonAmuletPrices; 

    mapping(address => uint256) public maxAmuletBalances;

    // mapping from user to his(her) staked tools
    // Index of uint256[6] represent tool NFT  itemID
    mapping(address => uint256[6]) public userStakedTools;


    uint16 public allNormiesesLeft;
    CreaturesCount[CREATURE_TYPE_COUNT_MAX] public creaturesBorn;
    FarmRecord[]       farming;

    event Reveal(uint256 indexed _tokenId, bool _isCreature, uint8 _animalType);
    event Harvest(
        uint256 indexed _eggId, 
        address farmer, 
        uint8   result ,
        uint16  baseChance, 
        uint16  amuletHold,
        uint16  amuletBullTrend,
        uint16  inventoryHold
    );
    
    constructor (
        address _land, 
        address _creatures,
        address _inventory,
        address _bagstoken,
        address _dungtoken,
        IEggs _eggs
    )
    {
        farm.land      = _land;
        farm.creatures = _creatures;
        farm.inventory = _inventory;
        farm.bagstoken = _bagstoken;
        farm.dungtoken = _dungtoken;
        
        // Index of creaturesBorn in this initial setting  
        // must NOT exceed CREATURE_TYPE_COUNT
        for (uint i = 0; i < getCreatureTypeCount(); i++) {
            creaturesBorn[i] = CreaturesCount(
                getNormieCountInType(), // totalNormie;
                getNormieCountInType(), // leftNormie;
                getChadCountInType(),   // totalChad;
                getChadCountInType(),   // leftChadToDiscover;
                1,                      // totalDegen;
                1,                      // leftDegenToDiscover;
                getNormieCountInType(), // leftChadFarmAttempts;
                getChadCountInType());  // leftDegenFarmAttempts;
        }

        landCount        = LandCount(getMaxLands(), getMaxLands());
        allNormiesesLeft = MAX_ALL_NORMIES;
        eggs = _eggs;
    }

    /**
     * @dev Changes inventory contract
    */
    function setInventory(address _inventory) external onlyOwner {
        farm.inventory = _inventory;
    }

    function reveal(uint count) external {
        require(_isRevelEnabled(), "Please wait for reveal enabled.");
        require(count > 0, "Count must be positive");
        require(count <= 8, "Count must less than 9"); // random limit
        require(
            IERC20(farm.bagstoken).allowance(msg.sender, address(this)) >= count*1,
            "Please approve your BAGS token to this contract."
        );
        require(
            IERC20(farm.bagstoken).transferFrom(msg.sender, address(this), count*1)
        );
        uint randomSeed = uint(keccak256(abi.encodePacked(block.timestamp, msg.sender)));
        // random seed for 8 reveals (8x32=256)
        for (uint i = 0; i < count; i++) {
            _reveal(randomSeed);
            randomSeed = randomSeed / 0x100000000; // shift right 32 bits
        }
    }

    event Log(string mess);
    /**
     * @dev Start farming process. New NFT - Egg will minted for user 
     * @param _creatureId - NFT tokenId, caller must be owner of this token
     * @param _landId -- NFT tokenId, caller must be owner of this token
     */
    function farmDeploy(uint256 _creatureId, uint256 _landId) external {
        require(FARMING_ENABLED == true, "Chief Farmer not enable yet");
        require(ICreatures(farm.creatures).ownerOf(_creatureId) == msg.sender, 
            "Need to be Creature Owner"
        );
        require(ILand(farm.land).ownerOf(_landId) == msg.sender,
            "Need to be Land Owner"
        );
        (uint8 crType, uint8 crRarity) = ICreatures(farm.creatures).getTypeAndRarity(_creatureId);
        require((DegenFarmBase.Rarity)(crRarity) == Rarity.Normie ||
            (DegenFarmBase.Rarity)(crRarity) == Rarity.Chad,
            "Can farm only Normie and Chad");
        //Check that farming available yet
        if (crRarity == 0) {
            require(creaturesBorn[crType].leftChadToDiscover > 0, "No more chads left");
        } else {
            require(creaturesBorn[crType].leftDegenToDiscover > 0, "No more Degen left");
        }
        //1. Lets make amulet price snapshot
        //1.1. First we need creat array with properly elements count
        uint256[] memory prices1  = new uint256[](amulets[crType].length);
        uint256[] memory prices2  = new uint256[](amulets[crType].length);
        prices1 = _getExistingAmuletsPrices(amulets[crType]);
        //2.Check and save Common Amulets price(if not exist yet)
        _saveCommonAmuletPrices(block.timestamp);
        //3. Save deploy record
        farming.push(
            FarmRecord({
                creatureId:    _creatureId,
                landId:        _landId,
                harvestTime:   block.timestamp + getFarmingDuration(),
                amuletsPrice1: prices1,
                amuletsPrice2: prices2,
                harvest:       Result.Fail,
                harvestId:     0, 
                commonAmuletInitialHold: _getCommonAmuletsHoldState(msg.sender) //save initial hold state
            })
        );

        // Let's  mint Egg.
        eggs.mint(
            msg.sender,         // farmer
            farming.length - 1  // tokenId
        );
        //STAKE LAND  and Creatures!!!!
        ILand(farm.land).transferFrom(msg.sender, address(this), _landId);
        ICreatures(farm.creatures).transferFrom(msg.sender, address(this), _creatureId);
    }

    /**
     * @dev Finish farming process. Egg NFT will be  burn 
     * @param _deployId - NFT tokenId, caller must be owner of this token
     */
    function harvest(uint256 _deployId) external {

        require(eggs.ownerOf(_deployId) == msg.sender, "This is NOT YOUR EGG");
        
        FarmRecord storage f = farming[_deployId];
        require(f.harvestTime <= block.timestamp, "To early for harvest");
        //Lets Calculate Dung/CHAD-DEGEN chance
        Result farmingResult;
        Bonus memory bonus;
        //1. BaseChance
        (uint8 crType, uint8 crRarity) = ICreatures(farm.creatures).getTypeAndRarity(
            f.creatureId
        );
        uint16 baseChance;
        if  (crRarity == 0) {
            //Try farm CHAD. So if there is no CHADs any more we must return assets
            if  (creaturesBorn[crType].leftChadToDiscover == 0) {
                _endFarming(_deployId, Result.Fail);
                return;
            }
            baseChance = creaturesBorn[crType].leftChadToDiscover * 100
                /(creaturesBorn[crType].leftChadFarmAttempts);
            //Decrease appropriate farm ATTEMPTS COUNT!!!
            creaturesBorn[crType].leftChadFarmAttempts -= 1;
        } else {

            //Try farm DEGEN. So if there is no DEGENSs any more we must return assets
            if  (creaturesBorn[crType].leftDegenToDiscover == 0) {
                _endFarming(_deployId, Result.Fail);
                return;
            }
            baseChance = creaturesBorn[crType].leftDegenToDiscover * 100
                /(creaturesBorn[crType].leftDegenFarmAttempts);
            //Decrease appropriate farm ATTEMPTS COUNT!!!
            creaturesBorn[crType].leftDegenFarmAttempts -= 1;
        }
        //////////////////////////////////////////////
        //   2. Bonus for amulet token ***HOLD***
        //   3. Bonus for amulets BULLs trend
        //////////////////////////////////////////////
        bonus.amuletHold      = 0;
        bonus.amuletBullTrend = 0;
        //Check common amulets
        _saveCommonAmuletPrices(block.timestamp);
        //Get current hold stae
        for (uint8 i = 0; i < COMMON_AMULETS.length; i ++){
            if (f.commonAmuletInitialHold[i] &&  _getCommonAmuletsHoldState(msg.sender)[i]) {
                //token was hold at deploy time and now - iT IS GOOD
                //Lets check max Balance, because 
                //bonus.amuletHold = userAmuletBalance/maxAmuletBalances*BONUS_POINTS_AMULET_HOLD
                _checkAndSaveMaxAmuletPrice(COMMON_AMULETS[i]);
                bonus.amuletHold = uint16(
                    IERC20(COMMON_AMULETS[i]).balanceOf(msg.sender) * 100 
                    / maxAmuletBalances[COMMON_AMULETS[i]] * BONUS_POINTS_AMULET_HOLD / 100 //100 used for scale
                );     
                //Lets check Bull TREND
                if  (_getCommonAmuletPrices(f.harvestTime - getFarmingDuration())[i]
                        <  _getCommonAmuletPrices(block.timestamp)[i]
                    ) 
                    {
                       bonus.amuletBullTrend = BONUS_POINTS_AMULET_BULL_TREND; 
                    }
                break;
            }
        }
        //Ok,  if there is NO common amulets lets check personal
        uint256[] memory prices2    = new uint256[](amulets[crType].length);
        prices2 = _getExistingAmuletsPrices(amulets[crType]);
        if  (bonus.amuletHold != BONUS_POINTS_AMULET_HOLD) {
            for (uint8 i=0; i < f.amuletsPrice1.length; i ++){
                if (f.amuletsPrice1[i] > 0 && prices2[i] > 0){
                    //Lets check max Balance, because 
                    //bonus.amuletHold = userAmuletBalance/maxAmuletBalances*BONUS_POINTS_AMULET_HOLD
                    _checkAndSaveMaxAmuletPrice(amulets[i][crType]);
                    bonus.amuletHold = uint16(
                        IERC20(amulets[i][crType]).balanceOf(msg.sender) * 100 //100 used for scale
                        / maxAmuletBalances[amulets[i][crType]] * BONUS_POINTS_AMULET_HOLD /100
                    );
                    //Lets check Bull TREND
                    if (f.amuletsPrice1[i] < prices2[i]) {
                       bonus.amuletBullTrend = BONUS_POINTS_AMULET_BULL_TREND; 
                    }
                    break;
                }
            }
        }
        //////////////////////////////////////////////


        ////////////////////////////////////////////// 
        //4. Bonus for inventory 
        //////////////////////////////////////////////
        bonus.inventoryHold = 0;
        if (userStakedTools[msg.sender].length > 0) { 
           for (uint8 i=0; i<userStakedTools[msg.sender].length; i++) {
               if  (userStakedTools[msg.sender][i] > 0){
                   bonus.inventoryHold = bonus.inventoryHold 
                   + IInventory(farm.inventory).getToolBoost(i);
               }
           }
        }  
        //////////////////////////////////////////////

        uint16 allBonus = bonus.amuletHold 
            + bonus.amuletBullTrend 
            + bonus.inventoryHold;
        uint8 chanceOfRarityUP = uint8(
            (baseChance + allBonus) * 100 / (100 + allBonus)
        );
        uint8[] memory choiceWeight = new uint8[](2); 
        choiceWeight[0] = chanceOfRarityUP; 
        choiceWeight[1] = 100 - chanceOfRarityUP;
        uint8 choice = uint8(_getWeightedChoice(choiceWeight));

        if (choice == 0) {
            f.harvestId = (crRarity + 1) * NFT_ID_MULTIPLIER + _deployId;
            // Mint new chad/degen

            uint32 index;
            //Decrease appropriate CREATRURE COUNT
            if (crRarity + 1 == uint8(Rarity.Chad)) {
                index = creaturesBorn[crType].totalChad - creaturesBorn[crType].leftChadToDiscover + 1;
                creaturesBorn[crType].leftChadToDiscover -= 1;
                farmingResult = Result.Chad;
            } else if (crRarity + 1 == uint8(Rarity.Degen)) {
                index = creaturesBorn[crType].totalDegen - creaturesBorn[crType].leftDegenToDiscover + 1;
                creaturesBorn[crType].leftDegenToDiscover -= 1;
                farmingResult = Result.Degen;
            }

            ICreatures(farm.creatures).mint(
                msg.sender, 
                (crRarity + 1) * NFT_ID_MULTIPLIER + _deployId, // new iD
                crType, //AnimalType
                crRarity + 1,
                index // index
            );
        } else {
        //Mint new dung
            IDung(farm.dungtoken).mint(msg.sender, FARM_DUNG_AMOUNT);
            farmingResult = Result.Dung;
        }
        
        //BURN Land
        ILand(farm.land).burn(f.landId);
        _endFarming(_deployId, farmingResult);
        emit Harvest(
            _deployId, 
            msg.sender, 
            uint8(farmingResult),
            baseChance,
            bonus.amuletHold,
            bonus.amuletBullTrend,
            bonus.inventoryHold 
        );
    }

    /**
     * @dev Stake one inventory item 
     * @param _itemId - NFT tokenId, caller must be owner of this token
     */
    function stakeOneTool(uint8 _itemId) external {
        _stakeOneTool(_itemId);
    }

    /**
     * @dev UnStake one inventory item 
     * @param _itemId - NFT tokenId
     */

    function unstakeOneTool(uint8 _itemId) external {
        _unstakeOneTool(_itemId);
    }

    /////////////////////////////////////////////////////
    ////    Admin functions                       ///////
    /////////////////////////////////////////////////////
    function setOneCommonAmulet(uint8 _index, address _token) external onlyOwner {
        COMMON_AMULETS[_index] = _token;
    }

    function setAmuletForOneCreature(uint8 _index, address[] memory _tokens) external onlyOwner {
        delete amulets[_index];
        amulets[_index] = _tokens;
    }

    function setPriceProvider(address _priceProvider) external onlyOwner {
        priceProvider = _priceProvider;
    }

    function enableReveal(bool _isEnabled) external onlyOwner {
        REVEAL_ENABLED = _isEnabled;
    }

    function enableFarming(bool _isEnabled) external onlyOwner {
        FARMING_ENABLED = _isEnabled;
    }

    ////////////////////////////////////////
    /// Proxy for NFT Operators mamnage   //
    ////////////////////////////////////////
    function  addOperator(address _contract, address newOperator) external onlyOwner {
        IOperatorManage(_contract).addOperator(newOperator);
    }

    function removeOperator(address _contract, address oldOperator) external onlyOwner {
        IOperatorManage(_contract).removeOperator(oldOperator);
    }
 
    function reclaimToken(address _contract, IERC20 anyTokens, address _admin) external onlyOwner {
        IOperatorManage(_contract).withdrawERC20(anyTokens, _admin);
    }
    ////////////////////////////////////////////////////////

    function getCreatureAmulets(uint8 _creatureType) external view returns (address[] memory) {
        return _getCreatureAmulets(_creatureType);
    }

    function _getCreatureAmulets(uint8 _creatureType) internal view returns (address[] memory) {
        return amulets[_creatureType];
    } 

    function getCreatureStat(uint8 _creatureType) 
        external 
        view 
        returns (
            uint16, 
            uint16, 
            uint16, 
            uint16, 
            uint16, 
            uint16,
            uint16,
            uint16 
        )
    {
        CreaturesCount storage stat = creaturesBorn[_creatureType];
        return (
            stat.totalNormie, 
            stat.leftNormie, 
            stat.totalChad, 
            stat.leftChadToDiscover, 
            stat.totalDegen, 
            stat.leftDegenToDiscover,
            stat.leftChadFarmAttempts,
            stat.leftDegenFarmAttempts
        );
    }

    function getWeightedChoice(uint8[] memory _weights) external view returns (uint8){
        return _getWeightedChoice(_weights);
    }

    function _getWeightedChoice(uint8[] memory _weights) internal view returns (uint8){
        uint randomSeed = uint(keccak256(abi.encodePacked(block.timestamp, msg.sender)));
        return _getWeightedChoice2(_weights, randomSeed);
    }

    function getFarmingById(uint256 _farmingId) external view returns (FarmRecord memory) {
        return farming[_farmingId];
    }

    function getCommonAmuletPrices(uint256 _timestamp) external view returns (uint256[3] memory) {
        return _getCommonAmuletPrices(_timestamp);
    }

    function getOneAmuletPrice(address _token) external view returns (uint256) {
        return _getOneAmuletPrice(_token);
    }

    
    ///////////////////////////////////////////////
    ///  Internals                          ///////                   
    ///////////////////////////////////////////////
    /**
     * @dev Save farming results in storage and mint
     * appropriate token (NFT, ERC20 or None)
    */
    function _endFarming(uint256 _deployId, Result  _res) internal {
        //TODO need refactor if EGGs will be
        FarmRecord storage f = farming[_deployId];
        f.harvest = _res;
        // unstake creature
        ICreatures(farm.creatures).transferFrom(address(this), msg.sender, f.creatureId);
        eggs.burn(_deployId); // Burn EGG

        if  (_res ==  Result.Fail) {
            //unstake land (if staked)
            if (ILand(farm.land).ownerOf(f.landId) == address(this)){
               ILand(farm.land).transferFrom(address(this), msg.sender, f.landId);
            }
            emit Harvest(
                _deployId, 
                msg.sender, 
                uint8(_res),
                0, //baseChance
                0, //bonus.amuletHold,
                0, //bonus.amuletBullTrend,
                0  //bonus.inventoryHold 
            );   
        }
    }

    function _stakeOneTool(uint8 _itemId) internal {
        require(IInventory(farm.inventory).balanceOf(msg.sender, _itemId) >= 1,
            "You must own this tool for stake!"
        );
        //Before stake  we need two checks.
        //1. Removed
        //2. Cant`t stake one tool more than one item
        require(userStakedTools[msg.sender][_itemId] == 0, "Tool is already staked");

        //stake
        IInventory(farm.inventory).safeTransferFrom(
            msg.sender, 
            address(this), 
            _itemId, 
            1, 
            bytes('0')
        );
        userStakedTools[msg.sender][_itemId] = block.timestamp;

    }

    function _unstakeOneTool(uint8 _itemId) internal {
        require(userStakedTools[msg.sender][_itemId] > 0, "This tool is not staked yet");
        require(block.timestamp - userStakedTools[msg.sender][_itemId] >= getToolUnstakeDelay(),
            "Cant unstake earlier than a week"
        );
        userStakedTools[msg.sender][_itemId] = 0;
        IInventory(farm.inventory).safeTransferFrom(
            address(this), 
            msg.sender, 
            _itemId, 
            1, 
            bytes('0')
        );

    }

    function _saveCommonAmuletPrices(uint256 _timestamp) internal {
        //Lets check if price NOT exist for this timestamp - lets save it
        if  (commonAmuletPrices[_timestamp][0] == 0) {
            for (uint8 i=0; i < COMMON_AMULETS.length; i++){
                commonAmuletPrices[_timestamp][i] = _getOneAmuletPrice(COMMON_AMULETS[i]);
            }
        }
    }

    function _checkAndSaveMaxAmuletPrice(address _amulet) internal {
        if  (IERC20(_amulet).balanceOf(msg.sender) 
                > maxAmuletBalances[_amulet]
            ) 
            {
              maxAmuletBalances[_amulet] 
              = IERC20(_amulet).balanceOf(msg.sender);
            }
    }

    function _getCommonAmuletPrices(uint256 _timestamp) internal view returns (uint256[3] memory) {
        //Lets check if price allready exist for this timestamp - just return it
        if  (commonAmuletPrices[_timestamp][0] != 0) {
            return commonAmuletPrices[_timestamp];
        }
        //If price is not exist lets get it from oracles
        uint256[3] memory res;
        for (uint8 i=0; i < COMMON_AMULETS.length; i++){
            res[i] = _getOneAmuletPrice(COMMON_AMULETS[i]);
        }
        return res;
    }

    function _getCommonAmuletsHoldState(address _farmer) internal view returns (bool[3] memory) {
        
        //If token balance =0 - set false
        bool[3] memory res;
        for (uint8 i=0; i < COMMON_AMULETS.length; i++){
            if  (IERC20(COMMON_AMULETS[i]).balanceOf(_farmer) > 0){
                res[i] = true;    
            } else {
            // Set to zero if token balance is 0   
                res[i] = false;
            }
        }
        return res;
    }

    function _getExistingAmuletsPrices(address[] memory _tokens) 
        internal 
        view 
        returns (uint256[] memory) 
    {
        uint256[] memory res = new uint256[](_tokens.length);
        for (uint8 i=0; i < _tokens.length; i++){
            if  (IERC20(_tokens[i]).balanceOf(msg.sender) > 0){
                res[i] = _getOneAmuletPrice(_tokens[i]);    
            } else {
            // Set to zero if token balance is 0   
                res[i] = 0;
            }    
        }
        return res;
    }

    function _getOneAmuletPrice(address _token) internal view returns (uint256) {
        return IAmuletPriceProvider(priceProvider).getLastPrice(_token);
    }

    function _isRevelEnabled() internal view returns (bool) {
        return REVEAL_ENABLED;
    }

    function _reveal(uint randomSeed) internal {
        require ((landCount.left + allNormiesesLeft) > 0, "Sorry, no more reveal!");
        //1. Lets choose Land OR Creature, %
        //So we have two possible results. 1 - Land, 0 - Creature.
        // sum of weights = 100, lets define weigth for Creature
        uint8[] memory choiceWeight = new uint8[](2); 
        choiceWeight[0] = uint8(
            uint32(allNormiesesLeft) * CREATURE_P_MULT         // * 100 removed due CREATURE_P_MULT 
            / (CREATURE_P_MULT * uint32(allNormiesesLeft) / 100 + uint32(landCount.left))
        ); 
        choiceWeight[1] = 100 - choiceWeight[0];
        uint8 choice = uint8(_getWeightedChoice2(choiceWeight, randomSeed));
        //Check that choice can be executed
        if (choice != 0 && landCount.left == 0) {
            //There are no more Lands. So we need change choice
            choice = 0;
        }

        if (choice == 0) { // create creature
            uint8[] memory choiceWeight0 = new uint8[](getCreatureTypeCount());
            //2. Ok, Creature will  be born. But what kind of?
            for (uint8 i = 0; i < getCreatureTypeCount(); i ++) {
                choiceWeight0[i] = uint8(creaturesBorn[i].leftNormie);
            }
            choice = uint8(_getWeightedChoice2(choiceWeight0, randomSeed / 0x10000)); // shift right 16 bits
            ICreatures(farm.creatures).mint(
                msg.sender, 
                MAX_ALL_NORMIES - allNormiesesLeft,
                choice, //AnimalType
                0,
                creaturesBorn[choice].totalNormie - creaturesBorn[choice].leftNormie + 1 // index
            );
            emit Reveal(MAX_ALL_NORMIES - allNormiesesLeft, true, choice);
            allNormiesesLeft -= 1;
            creaturesBorn[choice].leftNormie -= 1;
        } else { // create land
            ILand(farm.land).mint(
                msg.sender, 
                getMaxLands() - landCount.left
            );
            emit Reveal(getMaxLands() - landCount.left , false, 0);
            landCount.left -= 1; 
        }
    }

    function _getWeightedChoice2(uint8[] memory _weights, uint randomSeed) internal view returns (uint8){
        uint256 sum_of_weights;
        for (uint8 i = 0; i < _weights.length; i++) {
            sum_of_weights += _weights[i];
        }
        uint256 rnd = randomSeed % sum_of_weights;
        for (uint8 i = 0; i < _weights.length; i++) {
            if (rnd < _weights[i]) {
                return i;
            }
            rnd -= _weights[i];
        }
        return 0;
    }

    /**
        @dev Handles the receipt of a single ERC1155 token type. This function is
        called at the end of a `safeTransferFrom` after the balance has been updated.
        To accept the transfer, this must return
        `bytes4(keccak256("onERC1155Received(address,address,uint256,uint256,bytes)"))`
        (i.e. 0xf23a6e61, or its own function selector).
        @param operator The address which initiated the transfer (i.e. msg.sender)
        @param from The address which previously owned the token
        @param id The ID of the token being transferred
        @param value The amount of tokens being transferred
        @param data Additional data with no specified format
        @return `bytes4(keccak256("onERC1155Received(address,address,uint256,uint256,bytes)"))` if transfer is allowed
    */
    function onERC1155Received(
        address operator,
        address from,
        uint256 id,
        uint256 value,
        bytes calldata data
    )
        external
        override
        returns(bytes4)
    {
        return bytes4(keccak256("onERC1155Received(address,address,uint256,uint256,bytes)"));  
    }    

    /**
        @dev Handles the receipt of a multiple ERC1155 token types. This function
        is called at the end of a `safeBatchTransferFrom` after the balances have
        been updated. To accept the transfer(s), this must return
        `bytes4(keccak256("onERC1155BatchReceived(address,address,uint256[],uint256[],bytes)"))`
        (i.e. 0xbc197c81, or its own function selector).
        @param operator The address which initiated the batch transfer (i.e. msg.sender)
        @param from The address which previously owned the token
        @param ids An array containing ids of each token being transferred (order and length must match values array)
        @param values An array containing amounts of each token being transferred (order and length must match ids array)
        @param data Additional data with no specified format
        @return `bytes4(keccak256("onERC1155BatchReceived(address,address,uint256[],uint256[],bytes)"))` if transfer is allowed
    */
    function onERC1155BatchReceived(
        address operator,
        address from,
        uint256[] calldata ids,
        uint256[] calldata values,
        bytes calldata data
    )
        external
        override
        returns(bytes4)
    {
        return bytes4(keccak256("onERC1155BatchReceived(address,address,uint256,uint256,bytes)"));  
    }

    function getCreatureTypeCount() virtual internal view returns (uint16);

    function getFarmingDuration() virtual internal view returns (uint);

    function getToolUnstakeDelay() virtual internal view returns (uint);

    function getNormieCountInType() virtual internal view returns (uint16);

    function getChadCountInType() virtual internal view returns (uint16);

    function getMaxLands() virtual internal view returns (uint16);

    function getUsersTokens(address _owner) external view returns (uint256[] memory) {
        return eggs.getUsersTokens(_owner);
    }
}

File 6 of 26: DegensFarmLite.sol
// SPDX-License-Identifier: MIT
// Degen Farm. Collectible NFT game
pragma solidity ^0.7.4;
pragma experimental ABIEncoderV2;

import "./DegensFarmBase.sol";

contract DegenFarmLite is DegenFarmBase {

    uint8   constant public CREATURE_TYPE_COUNT= 2;  //how much creatures types may be used
    uint256 constant public FARMING_DURATION   = 168 seconds; //in seconds
    //uint256 constant public NEXT_FARMING_DELAY = 1   minutes;
    uint256 constant public TOOL_UNSTAKE_DELAY = 1   minutes;
    uint256 constant public REVEAL_THRESHOLD   = 0;    //90% from MAX_BAGS
    uint16   constant public NORMIE_COUNT_IN_TYPE = 20;
    uint16   constant public CHAD_COUNT_IN_TYPE = 5;
    uint16   constant public MAX_LANDS = 100;

    constructor (
        address _land,
        address _creatures,
        address _inventory,
        address _bagstoken,
        address _dungtoken,
        IEggs _eggs
    )
        DegenFarmBase(_land, _creatures, _inventory, _bagstoken, _dungtoken, _eggs)
    {
        require(CREATURE_TYPE_COUNT <= CREATURE_TYPE_COUNT_MAX, "CREATURE_TYPE_COUNT is greater than CREATURE_TYPE_COUNT_MAX");

        // Rinkeby amulet addrresses
        amulets[0] = [0xD533a949740bb3306d119CC777fa900bA034cd52, 0x1F573D6Fb3F13d689FF844B4cE37794d79a7FF1C];
        amulets[1] = [0x1f9840a85d5aF5bf1D1762F925BDADdC4201F984, 0x111111111117dC0aa78b770fA6A738034120C302];
    }

    function getCreatureTypeCount() override internal view returns (uint16) {
        return CREATURE_TYPE_COUNT;
    }

    function getFarmingDuration() override internal view returns (uint) {
        return FARMING_DURATION;
    }

    function getNormieCountInType() override internal view returns (uint16) {
        return NORMIE_COUNT_IN_TYPE;
    }

    function getChadCountInType() override internal view returns (uint16) {
        return CHAD_COUNT_IN_TYPE;
    }

    function getMaxLands() override internal view returns (uint16) {
        return MAX_LANDS;
    }

    function getToolUnstakeDelay() override internal view returns (uint) {
        return TOOL_UNSTAKE_DELAY;
    }

}

File 7 of 26: EggERC721.sol
// SPDX-License-Identifier: MIT
// Degen Farm. Collectible NFT game
pragma solidity ^0.7.4;
pragma experimental ABIEncoderV2;

import "./ERC721URIStorage.sol";

contract Eggs is ERC721URIStorage {

    mapping(address => bool) public trusted_markets;
    event TrustedMarket(address indexed _market, bool _state);

    constructor() ERC721("Degen$ Farm Eggs", "EGG")  {
    }

    function mint(
        address to, 
        uint256 tokenId
        ) external onlyOwner {
    	
        _mint(to, tokenId);
    }
    
    function setTrustedMarket(address _market, bool _state) external onlyOwner {
        trusted_markets[_market] = _state;
        emit TrustedMarket(_market, _state);
    }

    function getUsersTokens(address _owner) external view returns (uint256[] memory) {
        //We can return only uint256[] memory, but we cant use push 
        // with memory arrays. 
        //https://docs.soliditylang.org/en/v0.7.4/types.html#allocating-memory-arrays
        uint256 n = balanceOf(_owner); 

        uint256[] memory result = new uint256[](n);
        for (uint16 i=0; i < n; i++) {
            result[i]=tokenOfOwnerByIndex(_owner, i);
        }
        return result;
    }

    function baseURI() public view  override returns (string memory) {
        return 'http://degens.farm/meta/eggs/';
    }
    
    /**
     * @dev Overriding standart function for gas safe traiding with trusted parts like DegenFarm
     * Requirements:
     *
     * - `from` and `to` cannot be the zero address.
     * - `caller` must be added to trustedMarkets.
     */
    function transferFrom(address from, address to, uint256 tokenId) public override {
        if  (trusted_markets[msg.sender]) {    
            _transfer(from, to, tokenId);
        } else {
            super.transferFrom(from, to, tokenId);
        }
    }

    function burn(uint256 tokenId) external onlyOwner {
        _burn(tokenId);
    }
}

File 8 of 26: EnumerableMap.sol
// SPDX-License-Identifier: MIT

pragma solidity >=0.6.0 <0.8.0;

/**
 * @dev Library for managing an enumerable variant of Solidity's
 * https://solidity.readthedocs.io/en/latest/types.html#mapping-types[`mapping`]
 * type.
 *
 * Maps have the following properties:
 *
 * - Entries are added, removed, and checked for existence in constant time
 * (O(1)).
 * - Entries are enumerated in O(n). No guarantees are made on the ordering.
 *
 * ```
 * contract Example {
 *     // Add the library methods
 *     using EnumerableMap for EnumerableMap.UintToAddressMap;
 *
 *     // Declare a set state variable
 *     EnumerableMap.UintToAddressMap private myMap;
 * }
 * ```
 *
 * As of v3.0.0, only maps of type `uint256 -> address` (`UintToAddressMap`) are
 * supported.
 */
library EnumerableMap {
    // To implement this library for multiple types with as little code
    // repetition as possible, we write it in terms of a generic Map type with
    // bytes32 keys and values.
    // The Map implementation uses private functions, and user-facing
    // implementations (such as Uint256ToAddressMap) are just wrappers around
    // the underlying Map.
    // This means that we can only create new EnumerableMaps for types that fit
    // in bytes32.

    struct MapEntry {
        bytes32 _key;
        bytes32 _value;
    }

    struct Map {
        // Storage of map keys and values
        MapEntry[] _entries;

        // Position of the entry defined by a key in the `entries` array, plus 1
        // because index 0 means a key is not in the map.
        mapping (bytes32 => uint256) _indexes;
    }

    /**
     * @dev Adds a key-value pair to a map, or updates the value for an existing
     * key. O(1).
     *
     * Returns true if the key was added to the map, that is if it was not
     * already present.
     */
    function _set(Map storage map, bytes32 key, bytes32 value) private returns (bool) {
        // We read and store the key's index to prevent multiple reads from the same storage slot
        uint256 keyIndex = map._indexes[key];

        if (keyIndex == 0) { // Equivalent to !contains(map, key)
            map._entries.push(MapEntry({ _key: key, _value: value }));
            // The entry is stored at length-1, but we add 1 to all indexes
            // and use 0 as a sentinel value
            map._indexes[key] = map._entries.length;
            return true;
        } else {
            map._entries[keyIndex - 1]._value = value;
            return false;
        }
    }

    /**
     * @dev Removes a key-value pair from a map. O(1).
     *
     * Returns true if the key was removed from the map, that is if it was present.
     */
    function _remove(Map storage map, bytes32 key) private returns (bool) {
        // We read and store the key's index to prevent multiple reads from the same storage slot
        uint256 keyIndex = map._indexes[key];

        if (keyIndex != 0) { // Equivalent to contains(map, key)
            // To delete a key-value pair from the _entries array in O(1), we swap the entry to delete with the last one
            // in the array, and then remove the last entry (sometimes called as 'swap and pop').
            // This modifies the order of the array, as noted in {at}.

            uint256 toDeleteIndex = keyIndex - 1;
            uint256 lastIndex = map._entries.length - 1;

            // When the entry to delete is the last one, the swap operation is unnecessary. However, since this occurs
            // so rarely, we still do the swap anyway to avoid the gas cost of adding an 'if' statement.

            MapEntry storage lastEntry = map._entries[lastIndex];

            // Move the last entry to the index where the entry to delete is
            map._entries[toDeleteIndex] = lastEntry;
            // Update the index for the moved entry
            map._indexes[lastEntry._key] = toDeleteIndex + 1; // All indexes are 1-based

            // Delete the slot where the moved entry was stored
            map._entries.pop();

            // Delete the index for the deleted slot
            delete map._indexes[key];

            return true;
        } else {
            return false;
        }
    }

    /**
     * @dev Returns true if the key is in the map. O(1).
     */
    function _contains(Map storage map, bytes32 key) private view returns (bool) {
        return map._indexes[key] != 0;
    }

    /**
     * @dev Returns the number of key-value pairs in the map. O(1).
     */
    function _length(Map storage map) private view returns (uint256) {
        return map._entries.length;
    }

   /**
    * @dev Returns the key-value pair stored at position `index` in the map. O(1).
    *
    * Note that there are no guarantees on the ordering of entries inside the
    * array, and it may change when more entries are added or removed.
    *
    * Requirements:
    *
    * - `index` must be strictly less than {length}.
    */
    function _at(Map storage map, uint256 index) private view returns (bytes32, bytes32) {
        require(map._entries.length > index, "EnumerableMap: index out of bounds");

        MapEntry storage entry = map._entries[index];
        return (entry._key, entry._value);
    }

    /**
     * @dev Tries to returns the value associated with `key`.  O(1).
     * Does not revert if `key` is not in the map.
     */
    function _tryGet(Map storage map, bytes32 key) private view returns (bool, bytes32) {
        uint256 keyIndex = map._indexes[key];
        if (keyIndex == 0) return (false, 0); // Equivalent to contains(map, key)
        return (true, map._entries[keyIndex - 1]._value); // All indexes are 1-based
    }

    /**
     * @dev Returns the value associated with `key`.  O(1).
     *
     * Requirements:
     *
     * - `key` must be in the map.
     */
    function _get(Map storage map, bytes32 key) private view returns (bytes32) {
        uint256 keyIndex = map._indexes[key];
        require(keyIndex != 0, "EnumerableMap: nonexistent key"); // Equivalent to contains(map, key)
        return map._entries[keyIndex - 1]._value; // All indexes are 1-based
    }

    /**
     * @dev Same as {_get}, with a custom error message when `key` is not in the map.
     *
     * CAUTION: This function is deprecated because it requires allocating memory for the error
     * message unnecessarily. For custom revert reasons use {_tryGet}.
     */
    function _get(Map storage map, bytes32 key, string memory errorMessage) private view returns (bytes32) {
        uint256 keyIndex = map._indexes[key];
        require(keyIndex != 0, errorMessage); // Equivalent to contains(map, key)
        return map._entries[keyIndex - 1]._value; // All indexes are 1-based
    }

    // UintToAddressMap

    struct UintToAddressMap {
        Map _inner;
    }

    /**
     * @dev Adds a key-value pair to a map, or updates the value for an existing
     * key. O(1).
     *
     * Returns true if the key was added to the map, that is if it was not
     * already present.
     */
    function set(UintToAddressMap storage map, uint256 key, address value) internal returns (bool) {
        return _set(map._inner, bytes32(key), bytes32(uint256(uint160(value))));
    }

    /**
     * @dev Removes a value from a set. O(1).
     *
     * Returns true if the key was removed from the map, that is if it was present.
     */
    function remove(UintToAddressMap storage map, uint256 key) internal returns (bool) {
        return _remove(map._inner, bytes32(key));
    }

    /**
     * @dev Returns true if the key is in the map. O(1).
     */
    function contains(UintToAddressMap storage map, uint256 key) internal view returns (bool) {
        return _contains(map._inner, bytes32(key));
    }

    /**
     * @dev Returns the number of elements in the map. O(1).
     */
    function length(UintToAddressMap storage map) internal view returns (uint256) {
        return _length(map._inner);
    }

   /**
    * @dev Returns the element stored at position `index` in the set. O(1).
    * Note that there are no guarantees on the ordering of values inside the
    * array, and it may change when more values are added or removed.
    *
    * Requirements:
    *
    * - `index` must be strictly less than {length}.
    */
    function at(UintToAddressMap storage map, uint256 index) internal view returns (uint256, address) {
        (bytes32 key, bytes32 value) = _at(map._inner, index);
        return (uint256(key), address(uint160(uint256(value))));
    }

    /**
     * @dev Tries to returns the value associated with `key`.  O(1).
     * Does not revert if `key` is not in the map.
     *
     * _Available since v3.4._
     */
    function tryGet(UintToAddressMap storage map, uint256 key) internal view returns (bool, address) {
        (bool success, bytes32 value) = _tryGet(map._inner, bytes32(key));
        return (success, address(uint160(uint256(value))));
    }

    /**
     * @dev Returns the value associated with `key`.  O(1).
     *
     * Requirements:
     *
     * - `key` must be in the map.
     */
    function get(UintToAddressMap storage map, uint256 key) internal view returns (address) {
        return address(uint160(uint256(_get(map._inner, bytes32(key)))));
    }

    /**
     * @dev Same as {get}, with a custom error message when `key` is not in the map.
     *
     * CAUTION: This function is deprecated because it requires allocating memory for the error
     * message unnecessarily. For custom revert reasons use {tryGet}.
     */
    function get(UintToAddressMap storage map, uint256 key, string memory errorMessage) internal view returns (address) {
        return address(uint160(uint256(_get(map._inner, bytes32(key), errorMessage))));
    }
}

File 9 of 26: EnumerableSet.sol
// SPDX-License-Identifier: MIT

pragma solidity >=0.6.0 <0.8.0;

/**
 * @dev Library for managing
 * https://en.wikipedia.org/wiki/Set_(abstract_data_type)[sets] of primitive
 * types.
 *
 * Sets have the following properties:
 *
 * - Elements are added, removed, and checked for existence in constant time
 * (O(1)).
 * - Elements are enumerated in O(n). No guarantees are made on the ordering.
 *
 * ```
 * contract Example {
 *     // Add the library methods
 *     using EnumerableSet for EnumerableSet.AddressSet;
 *
 *     // Declare a set state variable
 *     EnumerableSet.AddressSet private mySet;
 * }
 * ```
 *
 * As of v3.3.0, sets of type `bytes32` (`Bytes32Set`), `address` (`AddressSet`)
 * and `uint256` (`UintSet`) are supported.
 */
library EnumerableSet {
    // To implement this library for multiple types with as little code
    // repetition as possible, we write it in terms of a generic Set type with
    // bytes32 values.
    // The Set implementation uses private functions, and user-facing
    // implementations (such as AddressSet) are just wrappers around the
    // underlying Set.
    // This means that we can only create new EnumerableSets for types that fit
    // in bytes32.

    struct Set {
        // Storage of set values
        bytes32[] _values;

        // Position of the value in the `values` array, plus 1 because index 0
        // means a value is not in the set.
        mapping (bytes32 => uint256) _indexes;
    }

    /**
     * @dev Add a value to a set. O(1).
     *
     * Returns true if the value was added to the set, that is if it was not
     * already present.
     */
    function _add(Set storage set, bytes32 value) private returns (bool) {
        if (!_contains(set, value)) {
            set._values.push(value);
            // The value is stored at length-1, but we add 1 to all indexes
            // and use 0 as a sentinel value
            set._indexes[value] = set._values.length;
            return true;
        } else {
            return false;
        }
    }

    /**
     * @dev Removes a value from a set. O(1).
     *
     * Returns true if the value was removed from the set, that is if it was
     * present.
     */
    function _remove(Set storage set, bytes32 value) private returns (bool) {
        // We read and store the value's index to prevent multiple reads from the same storage slot
        uint256 valueIndex = set._indexes[value];

        if (valueIndex != 0) { // Equivalent to contains(set, value)
            // To delete an element from the _values array in O(1), we swap the element to delete with the last one in
            // the array, and then remove the last element (sometimes called as 'swap and pop').
            // This modifies the order of the array, as noted in {at}.

            uint256 toDeleteIndex = valueIndex - 1;
            uint256 lastIndex = set._values.length - 1;

            // When the value to delete is the last one, the swap operation is unnecessary. However, since this occurs
            // so rarely, we still do the swap anyway to avoid the gas cost of adding an 'if' statement.

            bytes32 lastvalue = set._values[lastIndex];

            // Move the last value to the index where the value to delete is
            set._values[toDeleteIndex] = lastvalue;
            // Update the index for the moved value
            set._indexes[lastvalue] = toDeleteIndex + 1; // All indexes are 1-based

            // Delete the slot where the moved value was stored
            set._values.pop();

            // Delete the index for the deleted slot
            delete set._indexes[value];

            return true;
        } else {
            return false;
        }
    }

    /**
     * @dev Returns true if the value is in the set. O(1).
     */
    function _contains(Set storage set, bytes32 value) private view returns (bool) {
        return set._indexes[value] != 0;
    }

    /**
     * @dev Returns the number of values on the set. O(1).
     */
    function _length(Set storage set) private view returns (uint256) {
        return set._values.length;
    }

   /**
    * @dev Returns the value stored at position `index` in the set. O(1).
    *
    * Note that there are no guarantees on the ordering of values inside the
    * array, and it may change when more values are added or removed.
    *
    * Requirements:
    *
    * - `index` must be strictly less than {length}.
    */
    function _at(Set storage set, uint256 index) private view returns (bytes32) {
        require(set._values.length > index, "EnumerableSet: index out of bounds");
        return set._values[index];
    }

    // Bytes32Set

    struct Bytes32Set {
        Set _inner;
    }

    /**
     * @dev Add a value to a set. O(1).
     *
     * Returns true if the value was added to the set, that is if it was not
     * already present.
     */
    function add(Bytes32Set storage set, bytes32 value) internal returns (bool) {
        return _add(set._inner, value);
    }

    /**
     * @dev Removes a value from a set. O(1).
     *
     * Returns true if the value was removed from the set, that is if it was
     * present.
     */
    function remove(Bytes32Set storage set, bytes32 value) internal returns (bool) {
        return _remove(set._inner, value);
    }

    /**
     * @dev Returns true if the value is in the set. O(1).
     */
    function contains(Bytes32Set storage set, bytes32 value) internal view returns (bool) {
        return _contains(set._inner, value);
    }

    /**
     * @dev Returns the number of values in the set. O(1).
     */
    function length(Bytes32Set storage set) internal view returns (uint256) {
        return _length(set._inner);
    }

   /**
    * @dev Returns the value stored at position `index` in the set. O(1).
    *
    * Note that there are no guarantees on the ordering of values inside the
    * array, and it may change when more values are added or removed.
    *
    * Requirements:
    *
    * - `index` must be strictly less than {length}.
    */
    function at(Bytes32Set storage set, uint256 index) internal view returns (bytes32) {
        return _at(set._inner, index);
    }

    // AddressSet

    struct AddressSet {
        Set _inner;
    }

    /**
     * @dev Add a value to a set. O(1).
     *
     * Returns true if the value was added to the set, that is if it was not
     * already present.
     */
    function add(AddressSet storage set, address value) internal returns (bool) {
        return _add(set._inner, bytes32(uint256(uint160(value))));
    }

    /**
     * @dev Removes a value from a set. O(1).
     *
     * Returns true if the value was removed from the set, that is if it was
     * present.
     */
    function remove(AddressSet storage set, address value) internal returns (bool) {
        return _remove(set._inner, bytes32(uint256(uint160(value))));
    }

    /**
     * @dev Returns true if the value is in the set. O(1).
     */
    function contains(AddressSet storage set, address value) internal view returns (bool) {
        return _contains(set._inner, bytes32(uint256(uint160(value))));
    }

    /**
     * @dev Returns the number of values in the set. O(1).
     */
    function length(AddressSet storage set) internal view returns (uint256) {
        return _length(set._inner);
    }

   /**
    * @dev Returns the value stored at position `index` in the set. O(1).
    *
    * Note that there are no guarantees on the ordering of values inside the
    * array, and it may change when more values are added or removed.
    *
    * Requirements:
    *
    * - `index` must be strictly less than {length}.
    */
    function at(AddressSet storage set, uint256 index) internal view returns (address) {
        return address(uint160(uint256(_at(set._inner, index))));
    }


    // UintSet

    struct UintSet {
        Set _inner;
    }

    /**
     * @dev Add a value to a set. O(1).
     *
     * Returns true if the value was added to the set, that is if it was not
     * already present.
     */
    function add(UintSet storage set, uint256 value) internal returns (bool) {
        return _add(set._inner, bytes32(value));
    }

    /**
     * @dev Removes a value from a set. O(1).
     *
     * Returns true if the value was removed from the set, that is if it was
     * present.
     */
    function remove(UintSet storage set, uint256 value) internal returns (bool) {
        return _remove(set._inner, bytes32(value));
    }

    /**
     * @dev Returns true if the value is in the set. O(1).
     */
    function contains(UintSet storage set, uint256 value) internal view returns (bool) {
        return _contains(set._inner, bytes32(value));
    }

    /**
     * @dev Returns the number of values on the set. O(1).
     */
    function length(UintSet storage set) internal view returns (uint256) {
        return _length(set._inner);
    }

   /**
    * @dev Returns the value stored at position `index` in the set. O(1).
    *
    * Note that there are no guarantees on the ordering of values inside the
    * array, and it may change when more values are added or removed.
    *
    * Requirements:
    *
    * - `index` must be strictly less than {length}.
    */
    function at(UintSet storage set, uint256 index) internal view returns (uint256) {
        return uint256(_at(set._inner, index));
    }
}

File 10 of 26: ERC1155Receiver.sol
// SPDX-License-Identifier: MIT

pragma solidity >=0.6.0 <0.8.0;

import "./IERC1155Receiver.sol";
import "./ERC165.sol";

/**
 * @dev _Available since v3.1._
 */
abstract contract ERC1155Receiver is ERC165, IERC1155Receiver {
    constructor() internal {
        _registerInterface(
            ERC1155Receiver(address(0)).onERC1155Received.selector ^
            ERC1155Receiver(address(0)).onERC1155BatchReceived.selector
        );
    }
}

File 11 of 26: ERC165.sol
// SPDX-License-Identifier: MIT

pragma solidity >=0.6.0 <0.8.0;

import "./IERC165.sol";

/**
 * @dev Implementation of the {IERC165} interface.
 *
 * Contracts may inherit from this and call {_registerInterface} to declare
 * their support of an interface.
 */
abstract contract ERC165 is IERC165 {
    /*
     * bytes4(keccak256('supportsInterface(bytes4)')) == 0x01ffc9a7
     */
    bytes4 private constant _INTERFACE_ID_ERC165 = 0x01ffc9a7;

    /**
     * @dev Mapping of interface ids to whether or not it's supported.
     */
    mapping(bytes4 => bool) private _supportedInterfaces;

    constructor () internal {
        // Derived contracts need only register support for their own interfaces,
        // we register support for ERC165 itself here
        _registerInterface(_INTERFACE_ID_ERC165);
    }

    /**
     * @dev See {IERC165-supportsInterface}.
     *
     * Time complexity O(1), guaranteed to always use less than 30 000 gas.
     */
    function supportsInterface(bytes4 interfaceId) public view virtual override returns (bool) {
        return _supportedInterfaces[interfaceId];
    }

    /**
     * @dev Registers the contract as an implementer of the interface defined by
     * `interfaceId`. Support of the actual ERC165 interface is automatic and
     * registering its interface id is not required.
     *
     * See {IERC165-supportsInterface}.
     *
     * Requirements:
     *
     * - `interfaceId` cannot be the ERC165 invalid interface (`0xffffffff`).
     */
    function _registerInterface(bytes4 interfaceId) internal virtual {
        require(interfaceId != 0xffffffff, "ERC165: invalid interface id");
        _supportedInterfaces[interfaceId] = true;
    }
}

File 12 of 26: ERC721.sol
// SPDX-License-Identifier: MIT

pragma solidity >=0.6.0 <0.8.0;

import "./Context.sol";
import "./IERC721.sol";
import "./IERC721Metadata.sol";
import "./IERC721Enumerable.sol";
import "./IERC721Receiver.sol";
import "./ERC165.sol";
import "./SafeMath.sol";
import "./Address.sol";
import "./EnumerableSet.sol";
import "./EnumerableMap.sol";
import "./Strings.sol";

/**
 * @title ERC721 Non-Fungible Token Standard basic implementation
 * @dev see https://eips.ethereum.org/EIPS/eip-721
 */
contract ERC721 is Context, ERC165, IERC721, IERC721Metadata, IERC721Enumerable {
    using SafeMath for uint256;
    using Address for address;
    using EnumerableSet for EnumerableSet.UintSet;
    using EnumerableMap for EnumerableMap.UintToAddressMap;
    using Strings for uint256;

    // Equals to `bytes4(keccak256("onERC721Received(address,address,uint256,bytes)"))`
    // which can be also obtained as `IERC721Receiver(0).onERC721Received.selector`
    bytes4 private constant _ERC721_RECEIVED = 0x150b7a02;

    // Mapping from holder address to their (enumerable) set of owned tokens
    mapping (address => EnumerableSet.UintSet) private _holderTokens;

    // Enumerable mapping from token ids to their owners
    EnumerableMap.UintToAddressMap private _tokenOwners;

    // Mapping from token ID to approved address
    mapping (uint256 => address) private _tokenApprovals;

    // Mapping from owner to operator approvals
    mapping (address => mapping (address => bool)) private _operatorApprovals;

    // Token name
    string private _name;

    // Token symbol
    string private _symbol;

    // Optional mapping for token URIs
    mapping (uint256 => string) private _tokenURIs;

    // Base URI
    string private _baseURI;

    /*
     *     bytes4(keccak256('balanceOf(address)')) == 0x70a08231
     *     bytes4(keccak256('ownerOf(uint256)')) == 0x6352211e
     *     bytes4(keccak256('approve(address,uint256)')) == 0x095ea7b3
     *     bytes4(keccak256('getApproved(uint256)')) == 0x081812fc
     *     bytes4(keccak256('setApprovalForAll(address,bool)')) == 0xa22cb465
     *     bytes4(keccak256('isApprovedForAll(address,address)')) == 0xe985e9c5
     *     bytes4(keccak256('transferFrom(address,address,uint256)')) == 0x23b872dd
     *     bytes4(keccak256('safeTransferFrom(address,address,uint256)')) == 0x42842e0e
     *     bytes4(keccak256('safeTransferFrom(address,address,uint256,bytes)')) == 0xb88d4fde
     *
     *     => 0x70a08231 ^ 0x6352211e ^ 0x095ea7b3 ^ 0x081812fc ^
     *        0xa22cb465 ^ 0xe985e9c5 ^ 0x23b872dd ^ 0x42842e0e ^ 0xb88d4fde == 0x80ac58cd
     */
    bytes4 private constant _INTERFACE_ID_ERC721 = 0x80ac58cd;

    /*
     *     bytes4(keccak256('name()')) == 0x06fdde03
     *     bytes4(keccak256('symbol()')) == 0x95d89b41
     *     bytes4(keccak256('tokenURI(uint256)')) == 0xc87b56dd
     *
     *     => 0x06fdde03 ^ 0x95d89b41 ^ 0xc87b56dd == 0x5b5e139f
     */
    bytes4 private constant _INTERFACE_ID_ERC721_METADATA = 0x5b5e139f;

    /*
     *     bytes4(keccak256('totalSupply()')) == 0x18160ddd
     *     bytes4(keccak256('tokenOfOwnerByIndex(address,uint256)')) == 0x2f745c59
     *     bytes4(keccak256('tokenByIndex(uint256)')) == 0x4f6ccce7
     *
     *     => 0x18160ddd ^ 0x2f745c59 ^ 0x4f6ccce7 == 0x780e9d63
     */
    bytes4 private constant _INTERFACE_ID_ERC721_ENUMERABLE = 0x780e9d63;

    /**
     * @dev Initializes the contract by setting a `name` and a `symbol` to the token collection.
     */
    constructor (string memory name_, string memory symbol_) public {
        _name = name_;
        _symbol = symbol_;

        // register the supported interfaces to conform to ERC721 via ERC165
        _registerInterface(_INTERFACE_ID_ERC721);
        _registerInterface(_INTERFACE_ID_ERC721_METADATA);
        _registerInterface(_INTERFACE_ID_ERC721_ENUMERABLE);
    }

    /**
     * @dev See {IERC721-balanceOf}.
     */
    function balanceOf(address owner) public view virtual override returns (uint256) {
        require(owner != address(0), "ERC721: balance query for the zero address");
        return _holderTokens[owner].length();
    }

    /**
     * @dev See {IERC721-ownerOf}.
     */
    function ownerOf(uint256 tokenId) public view virtual override returns (address) {
        return _tokenOwners.get(tokenId, "ERC721: owner query for nonexistent token");
    }

    /**
     * @dev See {IERC721Metadata-name}.
     */
    function name() public view virtual override returns (string memory) {
        return _name;
    }

    /**
     * @dev See {IERC721Metadata-symbol}.
     */
    function symbol() public view virtual override returns (string memory) {
        return _symbol;
    }

    /**
     * @dev See {IERC721Metadata-tokenURI}.
     */
    function tokenURI(uint256 tokenId) public view virtual override returns (string memory) {
        require(_exists(tokenId), "ERC721Metadata: URI query for nonexistent token");

        string memory _tokenURI = _tokenURIs[tokenId];
        string memory base = baseURI();

        // If there is no base URI, return the token URI.
        if (bytes(base).length == 0) {
            return _tokenURI;
        }
        // If both are set, concatenate the baseURI and tokenURI (via abi.encodePacked).
        if (bytes(_tokenURI).length > 0) {
            return string(abi.encodePacked(base, _tokenURI));
        }
        // If there is a baseURI but no tokenURI, concatenate the tokenID to the baseURI.
        return string(abi.encodePacked(base, tokenId.toString()));
    }

    /**
    * @dev Returns the base URI set via {_setBaseURI}. This will be
    * automatically added as a prefix in {tokenURI} to each token's URI, or
    * to the token ID if no specific URI is set for that token ID.
    */
    function baseURI() public view virtual returns (string memory) {
        return _baseURI;
    }

    /**
     * @dev See {IERC721Enumerable-tokenOfOwnerByIndex}.
     */
    function tokenOfOwnerByIndex(address owner, uint256 index) public view virtual override returns (uint256) {
        return _holderTokens[owner].at(index);
    }

    /**
     * @dev See {IERC721Enumerable-totalSupply}.
     */
    function totalSupply() public view virtual override returns (uint256) {
        // _tokenOwners are indexed by tokenIds, so .length() returns the number of tokenIds
        return _tokenOwners.length();
    }

    /**
     * @dev See {IERC721Enumerable-tokenByIndex}.
     */
    function tokenByIndex(uint256 index) public view virtual override returns (uint256) {
        (uint256 tokenId, ) = _tokenOwners.at(index);
        return tokenId;
    }

    /**
     * @dev See {IERC721-approve}.
     */
    function approve(address to, uint256 tokenId) public virtual override {
        address owner = ERC721.ownerOf(tokenId);
        require(to != owner, "ERC721: approval to current owner");

        require(_msgSender() == owner || ERC721.isApprovedForAll(owner, _msgSender()),
            "ERC721: approve caller is not owner nor approved for all"
        );

        _approve(to, tokenId);
    }

    /**
     * @dev See {IERC721-getApproved}.
     */
    function getApproved(uint256 tokenId) public view virtual override returns (address) {
        require(_exists(tokenId), "ERC721: approved query for nonexistent token");

        return _tokenApprovals[tokenId];
    }

    /**
     * @dev See {IERC721-setApprovalForAll}.
     */
    function setApprovalForAll(address operator, bool approved) public virtual override {
        require(operator != _msgSender(), "ERC721: approve to caller");

        _operatorApprovals[_msgSender()][operator] = approved;
        emit ApprovalForAll(_msgSender(), operator, approved);
    }

    /**
     * @dev See {IERC721-isApprovedForAll}.
     */
    function isApprovedForAll(address owner, address operator) public view virtual override returns (bool) {
        return _operatorApprovals[owner][operator];
    }

    /**
     * @dev See {IERC721-transferFrom}.
     */
    function transferFrom(address from, address to, uint256 tokenId) public virtual override {
        //solhint-disable-next-line max-line-length
        require(_isApprovedOrOwner(_msgSender(), tokenId), "ERC721: transfer caller is not owner nor approved");

        _transfer(from, to, tokenId);
    }

    /**
     * @dev See {IERC721-safeTransferFrom}.
     */
    function safeTransferFrom(address from, address to, uint256 tokenId) public virtual override {
        safeTransferFrom(from, to, tokenId, "");
    }

    /**
     * @dev See {IERC721-safeTransferFrom}.
     */
    function safeTransferFrom(address from, address to, uint256 tokenId, bytes memory _data) public virtual override {
        require(_isApprovedOrOwner(_msgSender(), tokenId), "ERC721: transfer caller is not owner nor approved");
        _safeTransfer(from, to, tokenId, _data);
    }

    /**
     * @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.
     *
     * `_data` is additional data, it has no specified format and it is sent in call to `to`.
     *
     * This internal function is equivalent to {safeTransferFrom}, and can be used to e.g.
     * implement alternative mechanisms to perform token transfer, such as signature-based.
     *
     * Requirements:
     *
     * - `from` cannot be the zero address.
     * - `to` cannot be the zero address.
     * - `tokenId` token must exist and be owned by `from`.
     * - If `to` refers to a smart contract, it must implement {IERC721Receiver-onERC721Received}, which is called upon a safe transfer.
     *
     * Emits a {Transfer} event.
     */
    function _safeTransfer(address from, address to, uint256 tokenId, bytes memory _data) internal virtual {
        _transfer(from, to, tokenId);
        require(_checkOnERC721Received(from, to, tokenId, _data), "ERC721: transfer to non ERC721Receiver implementer");
    }

    /**
     * @dev Returns whether `tokenId` exists.
     *
     * Tokens can be managed by their owner or approved accounts via {approve} or {setApprovalForAll}.
     *
     * Tokens start existing when they are minted (`_mint`),
     * and stop existing when they are burned (`_burn`).
     */
    function _exists(uint256 tokenId) internal view virtual returns (bool) {
        return _tokenOwners.contains(tokenId);
    }

    /**
     * @dev Returns whether `spender` is allowed to manage `tokenId`.
     *
     * Requirements:
     *
     * - `tokenId` must exist.
     */
    function _isApprovedOrOwner(address spender, uint256 tokenId) internal view virtual returns (bool) {
        require(_exists(tokenId), "ERC721: operator query for nonexistent token");
        address owner = ERC721.ownerOf(tokenId);
        return (spender == owner || getApproved(tokenId) == spender || ERC721.isApprovedForAll(owner, spender));
    }

    /**
     * @dev Safely mints `tokenId` and transfers it to `to`.
     *
     * Requirements:
     d*
     * - `tokenId` must not exist.
     * - If `to` refers to a smart contract, it must implement {IERC721Receiver-onERC721Received}, which is called upon a safe transfer.
     *
     * Emits a {Transfer} event.
     */
    function _safeMint(address to, uint256 tokenId) internal virtual {
        _safeMint(to, tokenId, "");
    }

    /**
     * @dev Same as {xref-ERC721-_safeMint-address-uint256-}[`_safeMint`], with an additional `data` parameter which is
     * forwarded in {IERC721Receiver-onERC721Received} to contract recipients.
     */
    function _safeMint(address to, uint256 tokenId, bytes memory _data) internal virtual {
        _mint(to, tokenId);
        require(_checkOnERC721Received(address(0), to, tokenId, _data), "ERC721: transfer to non ERC721Receiver implementer");
    }

    /**
     * @dev Mints `tokenId` and transfers it to `to`.
     *
     * WARNING: Usage of this method is discouraged, use {_safeMint} whenever possible
     *
     * Requirements:
     *
     * - `tokenId` must not exist.
     * - `to` cannot be the zero address.
     *
     * Emits a {Transfer} event.
     */
    function _mint(address to, uint256 tokenId) internal virtual {
        require(to != address(0), "ERC721: mint to the zero address");
        require(!_exists(tokenId), "ERC721: token already minted");

        _beforeTokenTransfer(address(0), to, tokenId);

        _holderTokens[to].add(tokenId);

        _tokenOwners.set(tokenId, to);

        emit Transfer(address(0), to, tokenId);
    }

    /**
     * @dev Destroys `tokenId`.
     * The approval is cleared when the token is burned.
     *
     * Requirements:
     *
     * - `tokenId` must exist.
     *
     * Emits a {Transfer} event.
     */
    function _burn(uint256 tokenId) internal virtual {
        address owner = ERC721.ownerOf(tokenId); // internal owner

        _beforeTokenTransfer(owner, address(0), tokenId);

        // Clear approvals
        _approve(address(0), tokenId);

        // Clear metadata (if any)
        if (bytes(_tokenURIs[tokenId]).length != 0) {
            delete _tokenURIs[tokenId];
        }

        _holderTokens[owner].remove(tokenId);

        _tokenOwners.remove(tokenId);

        emit Transfer(owner, address(0), tokenId);
    }

    /**
     * @dev Transfers `tokenId` from `from` to `to`.
     *  As opposed to {transferFrom}, this imposes no restrictions on msg.sender.
     *
     * Requirements:
     *
     * - `to` cannot be the zero address.
     * - `tokenId` token must be owned by `from`.
     *
     * Emits a {Transfer} event.
     */
    function _transfer(address from, address to, uint256 tokenId) internal virtual {
        require(ERC721.ownerOf(tokenId) == from, "ERC721: transfer of token that is not own"); // internal owner
        require(to != address(0), "ERC721: transfer to the zero address");

        _beforeTokenTransfer(from, to, tokenId);

        // Clear approvals from the previous owner
        _approve(address(0), tokenId);

        _holderTokens[from].remove(tokenId);
        _holderTokens[to].add(tokenId);

        _tokenOwners.set(tokenId, to);

        emit Transfer(from, to, tokenId);
    }

    /**
     * @dev Sets `_tokenURI` as the tokenURI of `tokenId`.
     *
     * Requirements:
     *
     * - `tokenId` must exist.
     */
    function _setTokenURI(uint256 tokenId, string memory _tokenURI) internal virtual {
        require(_exists(tokenId), "ERC721Metadata: URI set of nonexistent token");
        _tokenURIs[tokenId] = _tokenURI;
    }

    /**
     * @dev Internal function to set the base URI for all token IDs. It is
     * automatically added as a prefix to the value returned in {tokenURI},
     * or to the token ID if {tokenURI} is empty.
     */
    function _setBaseURI(string memory baseURI_) internal virtual {
        _baseURI = baseURI_;
    }

    /**
     * @dev Internal function to invoke {IERC721Receiver-onERC721Received} on a target address.
     * The call is not executed if the target address is not a contract.
     *
     * @param from address representing the previous owner of the given token ID
     * @param to target address that will receive the tokens
     * @param tokenId uint256 ID of the token to be transferred
     * @param _data bytes optional data to send along with the call
     * @return bool whether the call correctly returned the expected magic value
     */
    function _checkOnERC721Received(address from, address to, uint256 tokenId, bytes memory _data)
        private returns (bool)
    {
        if (!to.isContract()) {
            return true;
        }
        bytes memory returndata = to.functionCall(abi.encodeWithSelector(
            IERC721Receiver(to).onERC721Received.selector,
            _msgSender(),
            from,
            tokenId,
            _data
        ), "ERC721: transfer to non ERC721Receiver implementer");
        bytes4 retval = abi.decode(returndata, (bytes4));
        return (retval == _ERC721_RECEIVED);
    }

    function _approve(address to, uint256 tokenId) private {
        _tokenApprovals[tokenId] = to;
        emit Approval(ERC721.ownerOf(tokenId), to, tokenId); // internal owner
    }

    /**
     * @dev Hook that is called before any token transfer. This includes minting
     * and burning.
     *
     * Calling conditions:
     *
     * - When `from` and `to` are both non-zero, ``from``'s `tokenId` will be
     * transferred to `to`.
     * - When `from` is zero, `tokenId` will be minted for `to`.
     * - When `to` is zero, ``from``'s `tokenId` will be burned.
     * - `from` cannot be the zero address.
     * - `to` cannot be the zero address.
     *
     * To learn more about hooks, head to xref:ROOT:extending-contracts.adoc#using-hooks[Using Hooks].
     */
    function _beforeTokenTransfer(address from, address to, uint256 tokenId) internal virtual { }
}

File 13 of 26: ERC721URIStorage.sol
// SPDX-License-Identifier: MIT
pragma solidity ^0.7.4;
pragma experimental ABIEncoderV2;

import "./ERC721.sol";
import "./Operators.sol";

/**
 * @dev this contract used just for override some
 * OpneZeppelin tokenURI() behavior
 * so we need redeclare _tokenURIs becouse in OpenZeppelin
 * ERC721 it has private visibility
 */
abstract contract ERC721URIStorage is ERC721, Operators {
    using Strings for uint256;

    // Optional mapping for token URIs
    mapping (uint256 => string) private _tokenURIs;

    /**
     * @dev See {IERC721Metadata-tokenURI}.
     */
    function tokenURI(uint256 tokenId) public view virtual override returns (string memory) {
        require(_exists(tokenId), "ERC721URIStorage: URI query for nonexistent token");

        string memory _tokenURI = _tokenURIs[tokenId];
        string memory base = baseURI();

        // If there is no base URI, return the token URI.
        if (bytes(base).length == 0) {
            return _tokenURI;
        }
        // If both are set, concatenate the baseURI and tokenURI (via abi.encodePacked).
        if (bytes(_tokenURI).length > 0) {
            //return string(abi.encodePacked(base, _tokenURI));
            //Due customer requirements
            return _tokenURI;
        }

        return super.tokenURI(tokenId);
    }

    /**
     * @dev Sets `_tokenURI` as the tokenURI of `tokenId`.
     *
     * Requirements:
     *
     * - `tokenId` must exist.
     */
    function _setTokenURI(uint256 tokenId, string memory _tokenURI) internal virtual override {
        require(_exists(tokenId), "ERC721URIStorage: URI set of nonexistent token");
        _tokenURIs[tokenId] = _tokenURI;
    }

    /**
     * @dev Destroys `tokenId`.
     * The approval is cleared when the token is burned.
     *
     * Requirements:
     *
     * - `tokenId` must exist.
     *
     * Emits a {Transfer} event.
     */
    function _burn(uint256 tokenId) internal virtual override {
        super._burn(tokenId);

        if (bytes(_tokenURIs[tokenId]).length != 0) {
            delete _tokenURIs[tokenId];
        }
    }

    function setURI(uint256 tokenId, string calldata _tokenURI) external onlyOperator {
        _setTokenURI(tokenId, _tokenURI);
    }

    function setURIBatch(uint256[] calldata tokenId, string[] calldata _tokenURI) external onlyOperator {
        require(tokenId.length == _tokenURI.length, "tokenId length is not equal to _tokenURI length");
        for (uint i = 0; i < tokenId.length; i++) {
            _setTokenURI(tokenId[i], _tokenURI[i]);
        }
    }

    address public signerAddress;

    function setSigner(address _newSigner) external onlyOwner {
        signerAddress = _newSigner;
    }

    function hashArguments(uint256 tokenId, string calldata _tokenURI)
        public pure returns (bytes32 msgHash)
    {
        msgHash = keccak256(abi.encode(tokenId, _tokenURI));
    }

    function getSigner(uint256 tokenId, string calldata _tokenURI, uint8 _v, bytes32 _r, bytes32 _s)
        public
        pure
        returns (address)
    {
        bytes32 msgHash = hashArguments(tokenId, _tokenURI);
        return ecrecover(msgHash, _v, _r, _s);
    }

    function isValidSignature(uint256 tokenId, string calldata _tokenURI, uint8 _v, bytes32 _r, bytes32 _s)
        public
        view
        returns (bool)
    {
        return getSigner(tokenId, _tokenURI, _v, _r, _s) == signerAddress;
    }

    /**
       * @dev Sets token URI using signature
       * This method can be called by anyone, who has signature,
       * that was created by signer role
       */
    function setURISigned(uint256 tokenId, string calldata _tokenURI, uint8 _v, bytes32 _r, bytes32 _s) external {
        require(isValidSignature(tokenId, _tokenURI, _v, _r, _s), "Invalid signature");
        _setTokenURI(tokenId, _tokenURI);
    }

}

File 14 of 26: IERC1155.sol
// SPDX-License-Identifier: MIT

pragma solidity >=0.6.2 <0.8.0;

import "./IERC165.sol";

/**
 * @dev Required interface of an ERC1155 compliant contract, as defined in the
 * https://eips.ethereum.org/EIPS/eip-1155[EIP].
 *
 * _Available since v3.1._
 */
interface IERC1155 is IERC165 {
    /**
     * @dev Emitted when `value` tokens of token type `id` are transferred from `from` to `to` by `operator`.
     */
    event TransferSingle(address indexed operator, address indexed from, address indexed to, uint256 id, uint256 value);

    /**
     * @dev Equivalent to multiple {TransferSingle} events, where `operator`, `from` and `to` are the same for all
     * transfers.
     */
    event TransferBatch(address indexed operator, address indexed from, address indexed to, uint256[] ids, uint256[] values);

    /**
     * @dev Emitted when `account` grants or revokes permission to `operator` to transfer their tokens, according to
     * `approved`.
     */
    event ApprovalForAll(address indexed account, address indexed operator, bool approved);

    /**
     * @dev Emitted when the URI for token type `id` changes to `value`, if it is a non-programmatic URI.
     *
     * If an {URI} event was emitted for `id`, the standard
     * https://eips.ethereum.org/EIPS/eip-1155#metadata-extensions[guarantees] that `value` will equal the value
     * returned by {IERC1155MetadataURI-uri}.
     */
    event URI(string value, uint256 indexed id);

    /**
     * @dev Returns the amount of tokens of token type `id` owned by `account`.
     *
     * Requirements:
     *
     * - `account` cannot be the zero address.
     */
    function balanceOf(address account, uint256 id) external view returns (uint256);

    /**
     * @dev xref:ROOT:erc1155.adoc#batch-operations[Batched] version of {balanceOf}.
     *
     * Requirements:
     *
     * - `accounts` and `ids` must have the same length.
     */
    function balanceOfBatch(address[] calldata accounts, uint256[] calldata ids) external view returns (uint256[] memory);

    /**
     * @dev Grants or revokes permission to `operator` to transfer the caller's tokens, according to `approved`,
     *
     * Emits an {ApprovalForAll} event.
     *
     * Requirements:
     *
     * - `operator` cannot be the caller.
     */
    function setApprovalForAll(address operator, bool approved) external;

    /**
     * @dev Returns true if `operator` is approved to transfer ``account``'s tokens.
     *
     * See {setApprovalForAll}.
     */
    function isApprovedForAll(address account, address operator) external view returns (bool);

    /**
     * @dev Transfers `amount` tokens of token type `id` from `from` to `to`.
     *
     * Emits a {TransferSingle} event.
     *
     * Requirements:
     *
     * - `to` cannot be the zero address.
     * - If the caller is not `from`, it must be have been approved to spend ``from``'s tokens via {setApprovalForAll}.
     * - `from` must have a balance of tokens of type `id` of at least `amount`.
     * - If `to` refers to a smart contract, it must implement {IERC1155Receiver-onERC1155Received} and return the
     * acceptance magic value.
     */
    function safeTransferFrom(address from, address to, uint256 id, uint256 amount, bytes calldata data) external;

    /**
     * @dev xref:ROOT:erc1155.adoc#batch-operations[Batched] version of {safeTransferFrom}.
     *
     * Emits a {TransferBatch} event.
     *
     * Requirements:
     *
     * - `ids` and `amounts` must have the same length.
     * - If `to` refers to a smart contract, it must implement {IERC1155Receiver-onERC1155BatchReceived} and return the
     * acceptance magic value.
     */
    function safeBatchTransferFrom(address from, address to, uint256[] calldata ids, uint256[] calldata amounts, bytes calldata data) external;
}

File 15 of 26: IERC1155Receiver.sol
// SPDX-License-Identifier: MIT

pragma solidity >=0.6.0 <0.8.0;

import "./IERC165.sol";

/**
 * _Available since v3.1._
 */
interface IERC1155Receiver is IERC165 {

    /**
        @dev Handles the receipt of a single ERC1155 token type. This function is
        called at the end of a `safeTransferFrom` after the balance has been updated.
        To accept the transfer, this must return
        `bytes4(keccak256("onERC1155Received(address,address,uint256,uint256,bytes)"))`
        (i.e. 0xf23a6e61, or its own function selector).
        @param operator The address which initiated the transfer (i.e. msg.sender)
        @param from The address which previously owned the token
        @param id The ID of the token being transferred
        @param value The amount of tokens being transferred
        @param data Additional data with no specified format
        @return `bytes4(keccak256("onERC1155Received(address,address,uint256,uint256,bytes)"))` if transfer is allowed
    */
    function onERC1155Received(
        address operator,
        address from,
        uint256 id,
        uint256 value,
        bytes calldata data
    )
        external
        returns(bytes4);

    /**
        @dev Handles the receipt of a multiple ERC1155 token types. This function
        is called at the end of a `safeBatchTransferFrom` after the balances have
        been updated. To accept the transfer(s), this must return
        `bytes4(keccak256("onERC1155BatchReceived(address,address,uint256[],uint256[],bytes)"))`
        (i.e. 0xbc197c81, or its own function selector).
        @param operator The address which initiated the batch transfer (i.e. msg.sender)
        @param from The address which previously owned the token
        @param ids An array containing ids of each token being transferred (order and length must match values array)
        @param values An array containing amounts of each token being transferred (order and length must match ids array)
        @param data Additional data with no specified format
        @return `bytes4(keccak256("onERC1155BatchReceived(address,address,uint256[],uint256[],bytes)"))` if transfer is allowed
    */
    function onERC1155BatchReceived(
        address operator,
        address from,
        uint256[] calldata ids,
        uint256[] calldata values,
        bytes calldata data
    )
        external
        returns(bytes4);
}

File 16 of 26: IERC165.sol
// SPDX-License-Identifier: MIT

pragma solidity >=0.6.0 <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 17 of 26: IERC20.sol
// SPDX-License-Identifier: MIT

pragma solidity >=0.6.0 <0.8.0;

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

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

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

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

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

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

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

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

File 18 of 26: IERC721.sol
// SPDX-License-Identifier: MIT

pragma solidity >=0.6.2 <0.8.0;

import "./IERC165.sol";

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

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

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

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

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

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

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

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

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

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

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

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

File 19 of 26: IERC721Enumerable.sol
// SPDX-License-Identifier: MIT

pragma solidity >=0.6.2 <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 tokenId);

    /**
     * @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 20 of 26: IERC721Metadata.sol
// SPDX-License-Identifier: MIT

pragma solidity >=0.6.2 <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);
}

File 21 of 26: IERC721Receiver.sol
// SPDX-License-Identifier: MIT

pragma solidity >=0.6.0 <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 22 of 26: LandERC721.sol
// SPDX-License-Identifier: MIT
// Degen Farm: El Dorado. Collectible NFT game
pragma solidity ^0.7.4;
pragma experimental ABIEncoderV2;

import "./ERC721URIStorage.sol";

contract Land is ERC721URIStorage {

    uint constant public MAP_HEIGHT = 50;
    uint constant public LAND_TYPE_COUNT = 5;
    enum LandType  { None, Clay, Chalky, Sandy, Loamy, Peaty }

    struct LandPiece {
        LandType atype; // uint8
        int32    x;
        int32    y;
    }

    mapping (uint256 => LandPiece) public lands;

    mapping(address => bool) public trusted_markets;
    event TrustedMarket(address indexed _market, bool _state);

    constructor(string memory name_,
        string memory symbol_) ERC721(name_, symbol_)  {
    }

    function mint(address to, uint256 tokenId) external onlyOwner {
        int32 x = (int32)(tokenId / MAP_HEIGHT);
        int32 y = (int32)(tokenId % MAP_HEIGHT);
        LandPiece memory land = LandPiece(_createLandType(x, y), x, y);
        lands[tokenId] = land;
        _mint(to, tokenId);
    }

    function _createLandType(int32 x, int32 y) internal returns (LandType) {
        uint256 rnd = uint(keccak256(abi.encodePacked(block.timestamp, msg.sender, totalSupply()))) % LAND_TYPE_COUNT;
        return (LandType)(rnd + 1);
    }

    function burn(uint256 tokenId) external {
        _burn(tokenId);
    }

    function setTrustedMarket(address _market, bool _state) external onlyOwner {
        trusted_markets[_market] = _state;
        emit TrustedMarket(_market, _state);
    }

    function getUsersTokens(address _owner) external view returns (uint256[] memory) {
        //https://docs.soliditylang.org/en/v0.7.4/types.html#allocating-memory-arrays
        //So first we need calc size of array to be returned
        uint256 n = balanceOf(_owner);

        uint256[] memory result = new uint256[](n);
        for (uint16 i=0; i < n; i++) {
            result[i]=tokenOfOwnerByIndex(_owner, i);
        }
        return result;
    }

    function baseURI() public view  override returns (string memory) {
        return 'http://degens.farm/meta/lands/';
    }

    /**
     * @dev Overriding standart function for gas safe traiding with trusted parts like DegenFarm
     * Requirements:
     *
     * - `from` and `to` cannot be the zero address.
     * - `caller` must be added to trustedMarkets.
     */
    function transferFrom(address from, address to, uint256 tokenId) public override {
        if  (trusted_markets[msg.sender]) {
            _transfer(from, to, tokenId);
        } else {
            super.transferFrom(from, to, tokenId);
        }

    }

}

File 23 of 26: Operators.sol
// SPDX-License-Identifier: MIT
// Degen Farm. Collectible NFT game
pragma solidity ^0.7.4;

import "./IERC20.sol";
import "./Ownable.sol";

contract Operators is Ownable
{
    mapping (address=>bool) operatorAddress;

    modifier onlyOperator() {
        require(isOperator(msg.sender), "Access denied");
        _;
    }

    function isOwner(address _addr) public view returns (bool) {
        return owner() == _addr;
    }

    function isOperator(address _addr) public view returns (bool) {
        return operatorAddress[_addr] || isOwner(_addr);
    }

    function addOperator(address _newOperator) external onlyOwner {
        require(_newOperator != address(0), "New operator is empty");

        operatorAddress[_newOperator] = true;
    }

    function removeOperator(address _oldOperator) external onlyOwner {
        delete(operatorAddress[_oldOperator]);
    }

    /**
     * @dev Owner can claim any tokens that transferred
     * to this contract address
     */
    function withdrawERC20(IERC20 _tokenContract, address _admin) external onlyOwner
    {
        uint256 balance = _tokenContract.balanceOf(address(this));
        _tokenContract.transfer(_admin, balance);
    }
}

File 24 of 26: Ownable.sol
// SPDX-License-Identifier: MIT

pragma solidity >=0.6.0 <0.8.0;

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

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

    /**
     * @dev Initializes the contract setting the deployer as the initial owner.
     */
    constructor () internal {
        address msgSender = _msgSender();
        _owner = msgSender;
        emit OwnershipTransferred(address(0), msgSender);
    }

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

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

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

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

File 25 of 26: SafeMath.sol
// SPDX-License-Identifier: MIT

pragma solidity >=0.6.0 <0.8.0;

/**
 * @dev Wrappers over Solidity's arithmetic operations with added overflow
 * checks.
 *
 * Arithmetic operations in Solidity wrap on overflow. This can easily result
 * in bugs, because programmers usually assume that an overflow raises an
 * error, which is the standard behavior in high level programming languages.
 * `SafeMath` restores this intuition by reverting the transaction when an
 * operation overflows.
 *
 * Using this library instead of the unchecked operations eliminates an entire
 * class of bugs, so it's recommended to use it always.
 */
library SafeMath {
    /**
     * @dev Returns the addition of two unsigned integers, with an overflow flag.
     *
     * _Available since v3.4._
     */
    function tryAdd(uint256 a, uint256 b) internal pure returns (bool, uint256) {
        uint256 c = a + b;
        if (c < a) return (false, 0);
        return (true, c);
    }

    /**
     * @dev Returns the substraction of two unsigned integers, with an overflow flag.
     *
     * _Available since v3.4._
     */
    function trySub(uint256 a, uint256 b) internal pure returns (bool, uint256) {
        if (b > a) return (false, 0);
        return (true, a - b);
    }

    /**
     * @dev Returns the multiplication of two unsigned integers, with an overflow flag.
     *
     * _Available since v3.4._
     */
    function tryMul(uint256 a, uint256 b) internal pure returns (bool, uint256) {
        // Gas optimization: this is cheaper than requiring 'a' not being zero, but the
        // benefit is lost if 'b' is also tested.
        // See: https://github.com/OpenZeppelin/openzeppelin-contracts/pull/522
        if (a == 0) return (true, 0);
        uint256 c = a * b;
        if (c / a != b) return (false, 0);
        return (true, c);
    }

    /**
     * @dev Returns the division of two unsigned integers, with a division by zero flag.
     *
     * _Available since v3.4._
     */
    function tryDiv(uint256 a, uint256 b) internal pure returns (bool, uint256) {
        if (b == 0) return (false, 0);
        return (true, a / b);
    }

    /**
     * @dev Returns the remainder of dividing two unsigned integers, with a division by zero flag.
     *
     * _Available since v3.4._
     */
    function tryMod(uint256 a, uint256 b) internal pure returns (bool, uint256) {
        if (b == 0) return (false, 0);
        return (true, a % b);
    }

    /**
     * @dev Returns the addition of two unsigned integers, reverting on
     * overflow.
     *
     * Counterpart to Solidity's `+` operator.
     *
     * Requirements:
     *
     * - Addition cannot overflow.
     */
    function add(uint256 a, uint256 b) internal pure returns (uint256) {
        uint256 c = a + b;
        require(c >= a, "SafeMath: addition overflow");
        return c;
    }

    /**
     * @dev Returns the subtraction of two unsigned integers, reverting on
     * overflow (when the result is negative).
     *
     * Counterpart to Solidity's `-` operator.
     *
     * Requirements:
     *
     * - Subtraction cannot overflow.
     */
    function sub(uint256 a, uint256 b) internal pure returns (uint256) {
        require(b <= a, "SafeMath: subtraction overflow");
        return a - b;
    }

    /**
     * @dev Returns the multiplication of two unsigned integers, reverting on
     * overflow.
     *
     * Counterpart to Solidity's `*` operator.
     *
     * Requirements:
     *
     * - Multiplication cannot overflow.
     */
    function mul(uint256 a, uint256 b) internal pure returns (uint256) {
        if (a == 0) return 0;
        uint256 c = a * b;
        require(c / a == b, "SafeMath: multiplication overflow");
        return c;
    }

    /**
     * @dev Returns the integer division of two unsigned integers, reverting on
     * division by zero. The result is rounded towards zero.
     *
     * Counterpart to Solidity's `/` operator. Note: this function uses a
     * `revert` opcode (which leaves remaining gas untouched) while Solidity
     * uses an invalid opcode to revert (consuming all remaining gas).
     *
     * Requirements:
     *
     * - The divisor cannot be zero.
     */
    function div(uint256 a, uint256 b) internal pure returns (uint256) {
        require(b > 0, "SafeMath: division by zero");
        return a / b;
    }

    /**
     * @dev Returns the remainder of dividing two unsigned integers. (unsigned integer modulo),
     * reverting when dividing by zero.
     *
     * Counterpart to Solidity's `%` operator. This function uses a `revert`
     * opcode (which leaves remaining gas untouched) while Solidity uses an
     * invalid opcode to revert (consuming all remaining gas).
     *
     * Requirements:
     *
     * - The divisor cannot be zero.
     */
    function mod(uint256 a, uint256 b) internal pure returns (uint256) {
        require(b > 0, "SafeMath: modulo by zero");
        return a % b;
    }

    /**
     * @dev Returns the subtraction of two unsigned integers, reverting with custom message on
     * overflow (when the result is negative).
     *
     * CAUTION: This function is deprecated because it requires allocating memory for the error
     * message unnecessarily. For custom revert reasons use {trySub}.
     *
     * Counterpart to Solidity's `-` operator.
     *
     * Requirements:
     *
     * - Subtraction cannot overflow.
     */
    function sub(uint256 a, uint256 b, string memory errorMessage) internal pure returns (uint256) {
        require(b <= a, errorMessage);
        return a - b;
    }

    /**
     * @dev Returns the integer division of two unsigned integers, reverting with custom message on
     * division by zero. The result is rounded towards zero.
     *
     * CAUTION: This function is deprecated because it requires allocating memory for the error
     * message unnecessarily. For custom revert reasons use {tryDiv}.
     *
     * Counterpart to Solidity's `/` operator. Note: this function uses a
     * `revert` opcode (which leaves remaining gas untouched) while Solidity
     * uses an invalid opcode to revert (consuming all remaining gas).
     *
     * Requirements:
     *
     * - The divisor cannot be zero.
     */
    function div(uint256 a, uint256 b, string memory errorMessage) internal pure returns (uint256) {
        require(b > 0, errorMessage);
        return a / b;
    }

    /**
     * @dev Returns the remainder of dividing two unsigned integers. (unsigned integer modulo),
     * reverting with custom message when dividing by zero.
     *
     * CAUTION: This function is deprecated because it requires allocating memory for the error
     * message unnecessarily. For custom revert reasons use {tryMod}.
     *
     * Counterpart to Solidity's `%` operator. This function uses a `revert`
     * opcode (which leaves remaining gas untouched) while Solidity uses an
     * invalid opcode to revert (consuming all remaining gas).
     *
     * Requirements:
     *
     * - The divisor cannot be zero.
     */
    function mod(uint256 a, uint256 b, string memory errorMessage) internal pure returns (uint256) {
        require(b > 0, errorMessage);
        return a % b;
    }
}

File 26 of 26: Strings.sol
// SPDX-License-Identifier: MIT

pragma solidity >=0.6.0 <0.8.0;

/**
 * @dev String operations.
 */
library Strings {
    /**
     * @dev Converts a `uint256` to its ASCII `string` representation.
     */
    function toString(uint256 value) internal pure returns (string memory) {
        // Inspired by OraclizeAPI's implementation - MIT licence
        // https://github.com/oraclize/ethereum-api/blob/b42146b063c7d6ee1358846c198246239e9360e8/oraclizeAPI_0.4.25.sol

        if (value == 0) {
            return "0";
        }
        uint256 temp = value;
        uint256 digits;
        while (temp != 0) {
            digits++;
            temp /= 10;
        }
        bytes memory buffer = new bytes(digits);
        uint256 index = digits - 1;
        temp = value;
        while (temp != 0) {
            buffer[index--] = bytes1(uint8(48 + temp % 10));
            temp /= 10;
        }
        return string(buffer);
    }
}

Contract Security Audit

Contract ABI

[{"inputs":[{"internalType":"string","name":"name_","type":"string"},{"internalType":"string","name":"symbol_","type":"string"}],"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":"previousOwner","type":"address"},{"indexed":true,"internalType":"address","name":"newOwner","type":"address"}],"name":"OwnershipTransferred","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"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"_market","type":"address"},{"indexed":false,"internalType":"bool","name":"_state","type":"bool"}],"name":"TrustedMarket","type":"event"},{"inputs":[{"internalType":"address","name":"_newOperator","type":"address"}],"name":"addOperator","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"","type":"uint256"}],"name":"animals","outputs":[{"internalType":"enum Creatures.AnimalType","name":"atype","type":"uint8"},{"internalType":"enum Creatures.Rarity","name":"rarity","type":"uint8"},{"internalType":"uint32","name":"index","type":"uint32"},{"internalType":"uint64","name":"birthday","type":"uint64"},{"internalType":"string","name":"name","type":"string"}],"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":[],"name":"baseURI","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","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"},{"internalType":"string","name":"_tokenURI","type":"string"},{"internalType":"uint8","name":"_v","type":"uint8"},{"internalType":"bytes32","name":"_r","type":"bytes32"},{"internalType":"bytes32","name":"_s","type":"bytes32"}],"name":"getSigner","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"pure","type":"function"},{"inputs":[{"internalType":"uint256","name":"_tokenId","type":"uint256"}],"name":"getTypeAndRarity","outputs":[{"internalType":"uint8","name":"","type":"uint8"},{"internalType":"uint8","name":"","type":"uint8"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_owner","type":"address"}],"name":"getUsersTokens","outputs":[{"internalType":"uint256[]","name":"","type":"uint256[]"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"},{"internalType":"string","name":"_tokenURI","type":"string"}],"name":"hashArguments","outputs":[{"internalType":"bytes32","name":"msgHash","type":"bytes32"}],"stateMutability":"pure","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":"address","name":"_addr","type":"address"}],"name":"isOperator","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_addr","type":"address"}],"name":"isOwner","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"},{"internalType":"string","name":"_tokenURI","type":"string"},{"internalType":"uint8","name":"_v","type":"uint8"},{"internalType":"bytes32","name":"_r","type":"bytes32"},{"internalType":"bytes32","name":"_s","type":"bytes32"}],"name":"isValidSignature","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"tokenId","type":"uint256"},{"internalType":"uint8","name":"_animalType","type":"uint8"},{"internalType":"uint8","name":"_rarity","type":"uint8"},{"internalType":"uint32","name":"index","type":"uint32"}],"name":"mint","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"name","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"owner","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"ownerOf","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_oldOperator","type":"address"}],"name":"removeOperator","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"renounceOwnership","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":"uint256","name":"tokenId","type":"uint256"},{"internalType":"string","name":"_name","type":"string"}],"name":"setName","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_newSigner","type":"address"}],"name":"setSigner","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_market","type":"address"},{"internalType":"bool","name":"_state","type":"bool"}],"name":"setTrustedMarket","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"},{"internalType":"string","name":"_tokenURI","type":"string"}],"name":"setURI","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256[]","name":"tokenId","type":"uint256[]"},{"internalType":"string[]","name":"_tokenURI","type":"string[]"}],"name":"setURIBatch","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"},{"internalType":"string","name":"_tokenURI","type":"string"},{"internalType":"uint8","name":"_v","type":"uint8"},{"internalType":"bytes32","name":"_r","type":"bytes32"},{"internalType":"bytes32","name":"_s","type":"bytes32"}],"name":"setURISigned","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"signerAddress","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes4","name":"interfaceId","type":"bytes4"}],"name":"supportsInterface","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"symbol","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"index","type":"uint256"}],"name":"tokenByIndex","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"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":"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":[{"internalType":"address","name":"","type":"address"}],"name":"trusted_markets","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"contract IERC20","name":"_tokenContract","type":"address"},{"internalType":"address","name":"_admin","type":"address"}],"name":"withdrawERC20","outputs":[],"stateMutability":"nonpayable","type":"function"}]

60806040523480156200001157600080fd5b5060405162003602380380620036028339810160408190526200003491620002e7565b8181620000486301ffc9a760e01b6200010f565b81516200005d90600690602085019062000198565b5080516200007390600790602084019062000198565b50620000866380ac58cd60e01b6200010f565b62000098635b5e139f60e01b6200010f565b620000aa63780e9d6360e01b6200010f565b5060009050620000b962000194565b600a80546001600160a01b0319166001600160a01b038316908117909155604051919250906000907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0908290a35050506200034e565b6001600160e01b031980821614156200016f576040805162461bcd60e51b815260206004820152601c60248201527f4552433136353a20696e76616c696420696e7465726661636520696400000000604482015290519081900360640190fd5b6001600160e01b0319166000908152602081905260409020805460ff19166001179055565b3390565b828054600181600116156101000203166002900490600052602060002090601f016020900481019282620001d057600085556200021b565b82601f10620001eb57805160ff19168380011785556200021b565b828001600101855582156200021b579182015b828111156200021b578251825591602001919060010190620001fe565b50620002299291506200022d565b5090565b5b808211156200022957600081556001016200022e565b600082601f83011262000255578081fd5b81516001600160401b03808211156200026a57fe5b6040516020601f8401601f19168201810183811183821017156200028a57fe5b80604052508194508382528681858801011115620002a757600080fd5b600092505b83831015620002cb5785830181015182840182015291820191620002ac565b83831115620002dd5760008185840101525b5050505092915050565b60008060408385031215620002fa578182fd5b82516001600160401b038082111562000311578384fd5b6200031f8683870162000244565b9350602085015191508082111562000335578283fd5b50620003448582860162000244565b9150509250929050565b6132a4806200035e6000396000f3fe608060405234801561001057600080fd5b50600436106102485760003560e01c806385aa84b61161013b578063a22cb465116100b8578063e8c9a3b31161007c578063e8c9a3b314610504578063e985e9c514610517578063eb46a4661461052a578063f2fde38b1461053d578063fe55932a1461055057610248565b8063a22cb465146104a5578063ac8a584a146104b8578063b88d4fde146104cb578063c87b56dd146104de578063d7a377a1146104f157610248565b806395d89b41116100ff57806395d89b4114610432578063963513ca1461043a5780639870d7fe1461044d578063998dd3ca146104605780639ed4f2561461048457610248565b806385aa84b6146103de578063862440e2146103f157806389dd289f146104045780638da5cb5b146104175780639456fbcc1461041f57610248565b80634f6ccce7116101c95780636c0360eb1161018d5780636c0360eb146103955780636c19e7831461039d5780636d70f7ae146103b057806370a08231146103c3578063715018a6146103d657610248565b80634f6ccce714610334578063509044be14610347578063540d259e146103675780635b7633d01461037a5780636352211e1461038257610248565b806318160ddd1161021057806318160ddd146102d357806323b872dd146102e85780632f54bf6e146102fb5780632f745c591461030e57806342842e0e1461032157610248565b806301b98ea01461024d57806301ffc9a71461026257806306fdde031461028b578063081812fc146102a0578063095ea7b3146102c0575b600080fd5b61026061025b366004612b0c565b610563565b005b610275610270366004612b74565b61065d565b6040516102829190612d1f565b60405180910390f35b610293610680565b6040516102829190612d9f565b6102b36102ae366004612bae565b610716565b6040516102829190612cc7565b6102606102ce366004612a76565b610778565b6102db61084e565b6040516102829190612d2a565b6102606102f6366004612942565b61085f565b6102756103093660046128ee565b610892565b6102db61031c366004612a76565b6108b6565b61026061032f366004612942565b6108e1565b6102db610342366004612bae565b6108fc565b61035a6103553660046128ee565b610912565b6040516102829190612cdb565b610260610375366004612c0f565b6109a6565b6102b3610a18565b6102b3610390366004612bae565b610a27565b610293610a4f565b6102606103ab3660046128ee565b610a6f565b6102756103be3660046128ee565b610af3565b6102db6103d13660046128ee565b610b1e565b610260610b86565b6102b36103ec366004612c0f565b610c32565b6102606103ff366004612bc6565b610c9e565b6102db610412366004612bc6565b610d28565b6102b3610d5e565b61026061042d366004612b9c565b610d6d565b610293610eca565b610275610448366004612c0f565b610f2b565b61026061045b3660046128ee565b610f5d565b61047361046e366004612bae565b611036565b604051610282959493929190612d51565b610497610492366004612bae565b611109565b604051610282929190612f6f565b6102606104b3366004612a45565b611153565b6102606104c63660046128ee565b611258565b6102606104d9366004612982565b6112db565b6102936104ec366004612bae565b611339565b6102606104ff366004612a45565b61143a565b610260610512366004612aa1565b6114fc565b61027561052536600461290a565b6116a2565b6102756105383660046128ee565b6116d0565b61026061054b3660046128ee565b6116e5565b61026061055e366004612bc6565b6117e8565b61056c33610af3565b6105ad576040805162461bcd60e51b815260206004820152600d60248201526c1058d8d95cdcc819195b9a5959609a1b604482015290519081900360640190fd5b8281146105d55760405162461bcd60e51b81526004016105cc90612db2565b60405180910390fd5b60005b838110156106565761064e8585838181106105ef57fe5b9050602002013584848481811061060257fe5b90506020028101906106149190612f83565b8080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525061187592505050565b6001016105d8565b5050505050565b6001600160e01b0319811660009081526020819052604090205460ff165b919050565b60068054604080516020601f600260001961010060018816150201909516949094049384018190048102820181019092528281526060939092909183018282801561070c5780601f106106e15761010080835404028352916020019161070c565b820191906000526020600020905b8154815290600101906020018083116106ef57829003601f168201915b5050505050905090565b6000610721826118b9565b61075c5760405162461bcd60e51b815260040180806020018281038252602c815260200180613179602c913960400191505060405180910390fd5b506000908152600460205260409020546001600160a01b031690565b600061078382610a27565b9050806001600160a01b0316836001600160a01b031614156107d65760405162461bcd60e51b815260040180806020018281038252602181526020018061321d6021913960400191505060405180910390fd5b806001600160a01b03166107e86118c6565b6001600160a01b031614806108045750610804816105256118c6565b61083f5760405162461bcd60e51b81526004018080602001828103825260388152602001806130cc6038913960400191505060405180910390fd5b61084983836118ca565b505050565b600061085a6002611938565b905090565b336000908152600f602052604090205460ff161561088757610882838383611943565b610849565b610849838383611a8f565b6000816001600160a01b03166108a6610d5e565b6001600160a01b03161492915050565b6001600160a01b03821660009081526001602052604081206108d89083611ae6565b90505b92915050565b610849838383604051806020016040528060008152506112db565b60008061090a600284611af2565b509392505050565b6060600061091f83610b1e565b90506060816001600160401b038111801561093957600080fd5b50604051908082528060200260200182016040528015610963578160200160208202803683370190505b50905060005b828161ffff16101561090a57610983858261ffff166108b6565b828261ffff168151811061099357fe5b6020908102919091010152600101610969565b6109b4868686868686610f2b565b6109d05760405162461bcd60e51b81526004016105cc90612e01565b610a108686868080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525061187592505050565b505050505050565b600d546001600160a01b031681565b60006108db8260405180606001604052806029815260200161312e6029913960029190611b10565b606060405180606001604052806022815260200161300260229139905090565b610a776118c6565b6001600160a01b0316610a88610d5e565b6001600160a01b031614610ad1576040805162461bcd60e51b815260206004820181905260248201526000805160206131a5833981519152604482015290519081900360640190fd5b600d80546001600160a01b0319166001600160a01b0392909216919091179055565b6001600160a01b0381166000908152600b602052604081205460ff16806108db57506108db82610892565b60006001600160a01b038216610b655760405162461bcd60e51b815260040180806020018281038252602a815260200180613104602a913960400191505060405180910390fd5b6001600160a01b03821660009081526001602052604090206108db90611938565b610b8e6118c6565b6001600160a01b0316610b9f610d5e565b6001600160a01b031614610be8576040805162461bcd60e51b815260206004820181905260248201526000805160206131a5833981519152604482015290519081900360640190fd5b600a546040516000916001600160a01b0316907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0908390a3600a80546001600160a01b0319169055565b600080610c40888888610d28565b905060018186868660405160008152602001604052604051610c659493929190612d33565b6020604051602081039080840390855afa158015610c87573d6000803e3d6000fd5b5050604051601f1901519998505050505050505050565b610ca733610af3565b610ce8576040805162461bcd60e51b815260206004820152600d60248201526c1058d8d95cdcc819195b9a5959609a1b604482015290519081900360640190fd5b6108498383838080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525061187592505050565b6000838383604051602001610d3f93929190612f39565b6040516020818303038152906040528051906020012090509392505050565b600a546001600160a01b031690565b610d756118c6565b6001600160a01b0316610d86610d5e565b6001600160a01b031614610dcf576040805162461bcd60e51b815260206004820181905260248201526000805160206131a5833981519152604482015290519081900360640190fd5b6000826001600160a01b03166370a08231306040518263ffffffff1660e01b815260040180826001600160a01b0316815260200191505060206040518083038186803b158015610e1e57600080fd5b505afa158015610e32573d6000803e3d6000fd5b505050506040513d6020811015610e4857600080fd5b50516040805163a9059cbb60e01b81526001600160a01b0385811660048301526024820184905291519293509085169163a9059cbb916044808201926020929091908290030181600087803b158015610ea057600080fd5b505af1158015610eb4573d6000803e3d6000fd5b505050506040513d602081101561065657600080fd5b60078054604080516020601f600260001961010060018816150201909516949094049384018190048102820181019092528281526060939092909183018282801561070c5780601f106106e15761010080835404028352916020019161070c565b600d546000906001600160a01b0316610f48888888888888610c32565b6001600160a01b031614979650505050505050565b610f656118c6565b6001600160a01b0316610f76610d5e565b6001600160a01b031614610fbf576040805162461bcd60e51b815260206004820181905260248201526000805160206131a5833981519152604482015290519081900360640190fd5b6001600160a01b038116611012576040805162461bcd60e51b81526020600482015260156024820152744e6577206f70657261746f7220697320656d70747960581b604482015290519081900360640190fd5b6001600160a01b03166000908152600b60205260409020805460ff19166001179055565b600e60209081526000918252604091829020805460018083018054865160026101009483161585026000190190921691909104601f810187900487028201870190975286815260ff80851697938504169562010000850463ffffffff169566010000000000009095046001600160401b03169493919291908301828280156110ff5780601f106110d4576101008083540402835291602001916110ff565b820191906000526020600020905b8154815290600101906020018083116110e257829003601f168201915b5050505050905085565b6000818152600e6020526040812054819060ff16601481111561112857fe5b6000848152600e6020526040902054610100900460ff16600381111561114a57fe5b91509150915091565b61115b6118c6565b6001600160a01b0316826001600160a01b031614156111c1576040805162461bcd60e51b815260206004820152601960248201527f4552433732313a20617070726f766520746f2063616c6c657200000000000000604482015290519081900360640190fd5b80600560006111ce6118c6565b6001600160a01b03908116825260208083019390935260409182016000908120918716808252919093529120805460ff1916921515929092179091556112126118c6565b6001600160a01b03167f17307eab39ab6107e8899845ad3d59bd9653f200f220920489ca2b5937696c318360405180821515815260200191505060405180910390a35050565b6112606118c6565b6001600160a01b0316611271610d5e565b6001600160a01b0316146112ba576040805162461bcd60e51b815260206004820181905260248201526000805160206131a5833981519152604482015290519081900360640190fd5b6001600160a01b03166000908152600b60205260409020805460ff19169055565b6112ec6112e66118c6565b83611b27565b6113275760405162461bcd60e51b815260040180806020018281038252603181526020018061323e6031913960400191505060405180910390fd5b61133384848484611bc3565b50505050565b6060611344826118b9565b6113605760405162461bcd60e51b81526004016105cc90612e7a565b6000828152600c602090815260409182902080548351601f60026000196101006001861615020190931692909204918201849004840281018401909452808452606093928301828280156113f55780601f106113ca576101008083540402835291602001916113f5565b820191906000526020600020905b8154815290600101906020018083116113d857829003601f168201915b505050505090506060611406610a4f565b905080516000141561141a5750905061067b565b8151156114295750905061067b565b61143284611c15565b949350505050565b6114426118c6565b6001600160a01b0316611453610d5e565b6001600160a01b03161461149c576040805162461bcd60e51b815260206004820181905260248201526000805160206131a5833981519152604482015290519081900360640190fd5b6001600160a01b0382166000818152600f602052604090819020805460ff1916841515179055517f735768a8abddcbaa527672c7b507c39cdfee45818f675893d3ccf2326523c09e906114f0908490612d1f565b60405180910390a25050565b6115046118c6565b6001600160a01b0316611515610d5e565b6001600160a01b03161461155e576040805162461bcd60e51b815260206004820181905260248201526000805160206131a5833981519152604482015290519081900360640190fd5b6115688585611e98565b6040518060a001604052808460ff16601481111561158257fe5b601481111561158d57fe5b81526020018360ff1660038111156115a157fe5b60038111156115ac57fe5b815263ffffffff83166020808301919091526001600160401b034216604080840191909152805180830182526000808252606090940152878352600e909152902081518154829060ff1916600183601481111561160557fe5b021790555060208201518154829061ff00191661010083600381111561162757fe5b02179055506040820151815460608401516001600160401b03166601000000000000026dffffffffffffffff0000000000001963ffffffff909316620100000265ffffffff000019909216919091179190911617815560808201518051611698916001840191602090910190612740565b5050505050505050565b6001600160a01b03918216600090815260056020908152604080832093909416825291909152205460ff1690565b600f6020526000908152604090205460ff1681565b6116ed6118c6565b6001600160a01b03166116fe610d5e565b6001600160a01b031614611747576040805162461bcd60e51b815260206004820181905260248201526000805160206131a5833981519152604482015290519081900360640190fd5b6001600160a01b03811661178c5760405162461bcd60e51b81526004018080602001828103825260268152602001806130566026913960400191505060405180910390fd5b600a546040516001600160a01b038084169216907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e090600090a3600a80546001600160a01b0319166001600160a01b0392909216919091179055565b336117f284610a27565b6001600160a01b0316146118185760405162461bcd60e51b81526004016105cc90612ecb565b6000838152600e6020526040902060019081015460029181161561010002600019011604156118595760405162461bcd60e51b81526004016105cc90612f02565b6000838152600e602052604090206113339060010183836127cc565b61187e826118b9565b61189a5760405162461bcd60e51b81526004016105cc90612e2c565b6000828152600c60209081526040909120825161084992840190612740565b60006108db600283611fc6565b3390565b600081815260046020526040902080546001600160a01b0319166001600160a01b03841690811790915581906118ff82610a27565b6001600160a01b03167f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b92560405160405180910390a45050565b60006108db82611fd2565b826001600160a01b031661195682610a27565b6001600160a01b03161461199b5760405162461bcd60e51b81526004018080602001828103825260298152602001806131c56029913960400191505060405180910390fd5b6001600160a01b0382166119e05760405162461bcd60e51b815260040180806020018281038252602481526020018061307c6024913960400191505060405180910390fd5b6119eb838383610849565b6119f66000826118ca565b6001600160a01b0383166000908152600160205260409020611a189082611fd6565b506001600160a01b0382166000908152600160205260409020611a3b9082611fe2565b50611a4860028284611fee565b5080826001600160a01b0316846001600160a01b03167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef60405160405180910390a4505050565b611aa0611a9a6118c6565b82611b27565b611adb5760405162461bcd60e51b815260040180806020018281038252603181526020018061323e6031913960400191505060405180910390fd5b610849838383611943565b60006108d88383612004565b6000808080611b018686612068565b909450925050505b9250929050565b6000611b1d8484846120e3565b90505b9392505050565b6000611b32826118b9565b611b6d5760405162461bcd60e51b815260040180806020018281038252602c8152602001806130a0602c913960400191505060405180910390fd5b6000611b7883610a27565b9050806001600160a01b0316846001600160a01b03161480611bb35750836001600160a01b0316611ba884610716565b6001600160a01b0316145b80611432575061143281856116a2565b611bce848484611943565b611bda848484846121ad565b6113335760405162461bcd60e51b81526004018080602001828103825260328152602001806130246032913960400191505060405180910390fd5b6060611c20826118b9565b611c5b5760405162461bcd60e51b815260040180806020018281038252602f8152602001806131ee602f913960400191505060405180910390fd5b60008281526008602090815260409182902080548351601f6002600019610100600186161502019093169290920491820184900484028101840190945280845260609392830182828015611cf05780601f10611cc557610100808354040283529160200191611cf0565b820191906000526020600020905b815481529060010190602001808311611cd357829003601f168201915b505050505090506060611d01610a4f565b9050805160001415611d155750905061067b565b815115611dd65780826040516020018083805190602001908083835b60208310611d505780518252601f199092019160209182019101611d31565b51815160209384036101000a600019018019909216911617905285519190930192850191508083835b60208310611d985780518252601f199092019160209182019101611d79565b6001836020036101000a038019825116818451168082178552505050505050905001925050506040516020818303038152906040529250505061067b565b80611de085612315565b6040516020018083805190602001908083835b60208310611e125780518252601f199092019160209182019101611df3565b51815160209384036101000a600019018019909216911617905285519190930192850191508083835b60208310611e5a5780518252601f199092019160209182019101611e3b565b6001836020036101000a0380198251168184511680821785525050505050509050019250505060405160208183030381529060405292505050919050565b6001600160a01b038216611ef3576040805162461bcd60e51b815260206004820181905260248201527f4552433732313a206d696e7420746f20746865207a65726f2061646472657373604482015290519081900360640190fd5b611efc816118b9565b15611f4e576040805162461bcd60e51b815260206004820152601c60248201527f4552433732313a20746f6b656e20616c7265616479206d696e74656400000000604482015290519081900360640190fd5b611f5a60008383610849565b6001600160a01b0382166000908152600160205260409020611f7c9082611fe2565b50611f8960028284611fee565b5060405181906001600160a01b038416906000907fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef908290a45050565b60006108d883836123ef565b5490565b60006108d88383612407565b60006108d883836124cd565b6000611b1d84846001600160a01b038516612517565b815460009082106120465760405162461bcd60e51b8152600401808060200182810382526022815260200180612fe06022913960400191505060405180910390fd5b82600001828154811061205557fe5b9060005260206000200154905092915050565b8154600090819083106120ac5760405162461bcd60e51b81526004018080602001828103825260228152602001806131576022913960400191505060405180910390fd5b60008460000184815481106120bd57fe5b906000526020600020906002020190508060000154816001015492509250509250929050565b6000828152600184016020526040812054828161217e5760405162461bcd60e51b81526004018080602001828103825283818151815260200191508051906020019080838360005b8381101561214357818101518382015260200161212b565b50505050905090810190601f1680156121705780820380516001836020036101000a031916815260200191505b509250505060405180910390fd5b5084600001600182038154811061219157fe5b9060005260206000209060020201600101549150509392505050565b60006121c1846001600160a01b03166125ae565b6121cd57506001611432565b60606122db630a85bd0160e11b6121e26118c6565b88878760405160240180856001600160a01b03168152602001846001600160a01b0316815260200183815260200180602001828103825283818151815260200191508051906020019080838360005b83811015612249578181015183820152602001612231565b50505050905090810190601f1680156122765780820380516001836020036101000a031916815260200191505b5095505050505050604051602081830303815290604052906001600160e01b0319166020820180516001600160e01b038381831617835250505050604051806060016040528060328152602001613024603291396001600160a01b03881691906125b4565b905060008180602001905160208110156122f457600080fd5b50516001600160e01b031916630a85bd0160e11b1492505050949350505050565b60608161233a57506040805180820190915260018152600360fc1b602082015261067b565b8160005b811561235257600101600a8204915061233e565b6060816001600160401b038111801561236a57600080fd5b506040519080825280601f01601f191660200182016040528015612395576020820181803683370190505b50859350905060001982015b83156123e657600a840660300160f81b828280600190039350815181106123c457fe5b60200101906001600160f81b031916908160001a905350600a840493506123a1565b50949350505050565b60009081526001919091016020526040902054151590565b600081815260018301602052604081205480156124c3578354600019808301919081019060009087908390811061243a57fe5b906000526020600020015490508087600001848154811061245757fe5b60009182526020808320909101929092558281526001898101909252604090209084019055865487908061248757fe5b600190038181906000526020600020016000905590558660010160008781526020019081526020016000206000905560019450505050506108db565b60009150506108db565b60006124d983836123ef565b61250f575081546001818101845560008481526020808220909301849055845484825282860190935260409020919091556108db565b5060006108db565b60008281526001840160205260408120548061257c575050604080518082018252838152602080820184815286546001818101895560008981528481209551600290930290950191825591519082015586548684528188019092529290912055611b20565b8285600001600183038154811061258f57fe5b9060005260206000209060020201600101819055506000915050611b20565b3b151590565b6060611b1d8484600085856125c8856125ae565b612619576040805162461bcd60e51b815260206004820152601d60248201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e7472616374000000604482015290519081900360640190fd5b60006060866001600160a01b031685876040518082805190602001908083835b602083106126585780518252601f199092019160209182019101612639565b6001836020036101000a03801982511681845116808217855250505050505090500191505060006040518083038185875af1925050503d80600081146126ba576040519150601f19603f3d011682016040523d82523d6000602084013e6126bf565b606091505b50915091506126cf8282866126da565b979650505050505050565b606083156126e9575081611b20565b8251156126f95782518084602001fd5b60405162461bcd60e51b815260206004820181815284516024840152845185939192839260440191908501908083836000831561214357818101518382015260200161212b565b828054600181600116156101000203166002900490600052602060002090601f01602090048101928261277657600085556127bc565b82601f1061278f57805160ff19168380011785556127bc565b828001600101855582156127bc579182015b828111156127bc5782518255916020019190600101906127a1565b506127c8929150612848565b5090565b828054600181600116156101000203166002900490600052602060002090601f01602090048101928261280257600085556127bc565b82601f1061281b5782800160ff198235161785556127bc565b828001600101855582156127bc579182015b828111156127bc57823582559160200191906001019061282d565b5b808211156127c85760008155600101612849565b60008083601f84011261286e578182fd5b5081356001600160401b03811115612884578182fd5b6020830191508360208083028501011115611b0957600080fd5b60008083601f8401126128af578182fd5b5081356001600160401b038111156128c5578182fd5b602083019150836020828501011115611b0957600080fd5b803560ff8116811461067b57600080fd5b6000602082840312156128ff578081fd5b8135611b2081612fc7565b6000806040838503121561291c578081fd5b823561292781612fc7565b9150602083013561293781612fc7565b809150509250929050565b600080600060608486031215612956578081fd5b833561296181612fc7565b9250602084013561297181612fc7565b929592945050506040919091013590565b60008060008060808587031215612997578081fd5b84356129a281612fc7565b93506020858101356129b381612fc7565b93506040860135925060608601356001600160401b03808211156129d5578384fd5b818801915088601f8301126129e8578384fd5b8135818111156129f457fe5b604051601f8201601f1916810185018381118282101715612a1157fe5b60405281815283820185018b1015612a27578586fd5b81858501868301379081019093019390935250939692955090935050565b60008060408385031215612a57578182fd5b8235612a6281612fc7565b915060208301358015158114612937578182fd5b60008060408385031215612a88578182fd5b8235612a9381612fc7565b946020939093013593505050565b600080600080600060a08688031215612ab8578081fd5b8535612ac381612fc7565b945060208601359350612ad8604087016128dd565b9250612ae6606087016128dd565b9150608086013563ffffffff81168114612afe578182fd5b809150509295509295909350565b60008060008060408587031215612b21578384fd5b84356001600160401b0380821115612b37578586fd5b612b438883890161285d565b90965094506020870135915080821115612b5b578384fd5b50612b688782880161285d565b95989497509550505050565b600060208284031215612b85578081fd5b81356001600160e01b031981168114611b20578182fd5b6000806040838503121561291c578182fd5b600060208284031215612bbf578081fd5b5035919050565b600080600060408486031215612bda578081fd5b8335925060208401356001600160401b03811115612bf6578182fd5b612c028682870161289e565b9497909650939450505050565b60008060008060008060a08789031215612c27578384fd5b8635955060208701356001600160401b03811115612c43578485fd5b612c4f89828a0161289e565b9096509450612c629050604088016128dd565b925060608701359150608087013590509295509295509295565b60008151808452815b81811015612ca157602081850181015186830182015201612c85565b81811115612cb25782602083870101525b50601f01601f19169290920160200192915050565b6001600160a01b0391909116815260200190565b6020808252825182820181905260009190848201906040850190845b81811015612d1357835183529284019291840191600101612cf7565b50909695505050505050565b901515815260200190565b90815260200190565b93845260ff9290921660208401526040830152606082015260800190565b600060158710612d5d57fe5b86825260048610612d6a57fe5b85602083015263ffffffff851660408301526001600160401b038416606083015260a060808301526126cf60a0830184612c7c565b6000602082526108d86020830184612c7c565b6020808252602f908201527f746f6b656e4964206c656e677468206973206e6f7420657175616c20746f205f60408201526e0e8ded6cadcaaa49240d8cadccee8d608b1b606082015260800190565b602080825260119082015270496e76616c6964207369676e617475726560781b604082015260600190565b6020808252602e908201527f45524337323155524953746f726167653a2055524920736574206f66206e6f6e60408201526d32bc34b9ba32b73a103a37b5b2b760911b606082015260800190565b60208082526031908201527f45524337323155524953746f726167653a2055524920717565727920666f72206040820152703737b732bc34b9ba32b73a103a37b5b2b760791b606082015260800190565b6020808252601a908201527f4f6e6c79206f776e65722063616e206368616e6765206e616d65000000000000604082015260600190565b6020808252601f908201527f546865206e616d652068617320616c7265616479206265656e20676976656e00604082015260600190565b60008482526040602083015282604083015282846060840137818301606090810191909152601f909201601f1916010192915050565b60ff92831681529116602082015260400190565b6000808335601e19843603018112612f99578283fd5b8301803591506001600160401b03821115612fb2578283fd5b602001915036819003821315611b0957600080fd5b6001600160a01b0381168114612fdc57600080fd5b5056fe456e756d657261626c655365743a20696e646578206f7574206f6620626f756e6473687474703a2f2f646567656e732e6661726d2f6d6574612f6372656174757265732f4552433732313a207472616e7366657220746f206e6f6e20455243373231526563656976657220696d706c656d656e7465724f776e61626c653a206e6577206f776e657220697320746865207a65726f20616464726573734552433732313a207472616e7366657220746f20746865207a65726f20616464726573734552433732313a206f70657261746f7220717565727920666f72206e6f6e6578697374656e7420746f6b656e4552433732313a20617070726f76652063616c6c6572206973206e6f74206f776e6572206e6f7220617070726f76656420666f7220616c6c4552433732313a2062616c616e636520717565727920666f7220746865207a65726f20616464726573734552433732313a206f776e657220717565727920666f72206e6f6e6578697374656e7420746f6b656e456e756d657261626c654d61703a20696e646578206f7574206f6620626f756e64734552433732313a20617070726f76656420717565727920666f72206e6f6e6578697374656e7420746f6b656e4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e65724552433732313a207472616e73666572206f6620746f6b656e2074686174206973206e6f74206f776e4552433732314d657461646174613a2055524920717565727920666f72206e6f6e6578697374656e7420746f6b656e4552433732313a20617070726f76616c20746f2063757272656e74206f776e65724552433732313a207472616e736665722063616c6c6572206973206e6f74206f776e6572206e6f7220617070726f766564a2646970667358221220308c7d0f38216f626771d86f2b5b3091893bd5f12659a801a1f13db0060ec78f64736f6c63430007040033000000000000000000000000000000000000000000000000000000000000004000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000015446567656e24204661726d20437265617475726573000000000000000000000000000000000000000000000000000000000000000000000000000000000000054352454154000000000000000000000000000000000000000000000000000000

Deployed Bytecode

0x608060405234801561001057600080fd5b50600436106102485760003560e01c806385aa84b61161013b578063a22cb465116100b8578063e8c9a3b31161007c578063e8c9a3b314610504578063e985e9c514610517578063eb46a4661461052a578063f2fde38b1461053d578063fe55932a1461055057610248565b8063a22cb465146104a5578063ac8a584a146104b8578063b88d4fde146104cb578063c87b56dd146104de578063d7a377a1146104f157610248565b806395d89b41116100ff57806395d89b4114610432578063963513ca1461043a5780639870d7fe1461044d578063998dd3ca146104605780639ed4f2561461048457610248565b806385aa84b6146103de578063862440e2146103f157806389dd289f146104045780638da5cb5b146104175780639456fbcc1461041f57610248565b80634f6ccce7116101c95780636c0360eb1161018d5780636c0360eb146103955780636c19e7831461039d5780636d70f7ae146103b057806370a08231146103c3578063715018a6146103d657610248565b80634f6ccce714610334578063509044be14610347578063540d259e146103675780635b7633d01461037a5780636352211e1461038257610248565b806318160ddd1161021057806318160ddd146102d357806323b872dd146102e85780632f54bf6e146102fb5780632f745c591461030e57806342842e0e1461032157610248565b806301b98ea01461024d57806301ffc9a71461026257806306fdde031461028b578063081812fc146102a0578063095ea7b3146102c0575b600080fd5b61026061025b366004612b0c565b610563565b005b610275610270366004612b74565b61065d565b6040516102829190612d1f565b60405180910390f35b610293610680565b6040516102829190612d9f565b6102b36102ae366004612bae565b610716565b6040516102829190612cc7565b6102606102ce366004612a76565b610778565b6102db61084e565b6040516102829190612d2a565b6102606102f6366004612942565b61085f565b6102756103093660046128ee565b610892565b6102db61031c366004612a76565b6108b6565b61026061032f366004612942565b6108e1565b6102db610342366004612bae565b6108fc565b61035a6103553660046128ee565b610912565b6040516102829190612cdb565b610260610375366004612c0f565b6109a6565b6102b3610a18565b6102b3610390366004612bae565b610a27565b610293610a4f565b6102606103ab3660046128ee565b610a6f565b6102756103be3660046128ee565b610af3565b6102db6103d13660046128ee565b610b1e565b610260610b86565b6102b36103ec366004612c0f565b610c32565b6102606103ff366004612bc6565b610c9e565b6102db610412366004612bc6565b610d28565b6102b3610d5e565b61026061042d366004612b9c565b610d6d565b610293610eca565b610275610448366004612c0f565b610f2b565b61026061045b3660046128ee565b610f5d565b61047361046e366004612bae565b611036565b604051610282959493929190612d51565b610497610492366004612bae565b611109565b604051610282929190612f6f565b6102606104b3366004612a45565b611153565b6102606104c63660046128ee565b611258565b6102606104d9366004612982565b6112db565b6102936104ec366004612bae565b611339565b6102606104ff366004612a45565b61143a565b610260610512366004612aa1565b6114fc565b61027561052536600461290a565b6116a2565b6102756105383660046128ee565b6116d0565b61026061054b3660046128ee565b6116e5565b61026061055e366004612bc6565b6117e8565b61056c33610af3565b6105ad576040805162461bcd60e51b815260206004820152600d60248201526c1058d8d95cdcc819195b9a5959609a1b604482015290519081900360640190fd5b8281146105d55760405162461bcd60e51b81526004016105cc90612db2565b60405180910390fd5b60005b838110156106565761064e8585838181106105ef57fe5b9050602002013584848481811061060257fe5b90506020028101906106149190612f83565b8080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525061187592505050565b6001016105d8565b5050505050565b6001600160e01b0319811660009081526020819052604090205460ff165b919050565b60068054604080516020601f600260001961010060018816150201909516949094049384018190048102820181019092528281526060939092909183018282801561070c5780601f106106e15761010080835404028352916020019161070c565b820191906000526020600020905b8154815290600101906020018083116106ef57829003601f168201915b5050505050905090565b6000610721826118b9565b61075c5760405162461bcd60e51b815260040180806020018281038252602c815260200180613179602c913960400191505060405180910390fd5b506000908152600460205260409020546001600160a01b031690565b600061078382610a27565b9050806001600160a01b0316836001600160a01b031614156107d65760405162461bcd60e51b815260040180806020018281038252602181526020018061321d6021913960400191505060405180910390fd5b806001600160a01b03166107e86118c6565b6001600160a01b031614806108045750610804816105256118c6565b61083f5760405162461bcd60e51b81526004018080602001828103825260388152602001806130cc6038913960400191505060405180910390fd5b61084983836118ca565b505050565b600061085a6002611938565b905090565b336000908152600f602052604090205460ff161561088757610882838383611943565b610849565b610849838383611a8f565b6000816001600160a01b03166108a6610d5e565b6001600160a01b03161492915050565b6001600160a01b03821660009081526001602052604081206108d89083611ae6565b90505b92915050565b610849838383604051806020016040528060008152506112db565b60008061090a600284611af2565b509392505050565b6060600061091f83610b1e565b90506060816001600160401b038111801561093957600080fd5b50604051908082528060200260200182016040528015610963578160200160208202803683370190505b50905060005b828161ffff16101561090a57610983858261ffff166108b6565b828261ffff168151811061099357fe5b6020908102919091010152600101610969565b6109b4868686868686610f2b565b6109d05760405162461bcd60e51b81526004016105cc90612e01565b610a108686868080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525061187592505050565b505050505050565b600d546001600160a01b031681565b60006108db8260405180606001604052806029815260200161312e6029913960029190611b10565b606060405180606001604052806022815260200161300260229139905090565b610a776118c6565b6001600160a01b0316610a88610d5e565b6001600160a01b031614610ad1576040805162461bcd60e51b815260206004820181905260248201526000805160206131a5833981519152604482015290519081900360640190fd5b600d80546001600160a01b0319166001600160a01b0392909216919091179055565b6001600160a01b0381166000908152600b602052604081205460ff16806108db57506108db82610892565b60006001600160a01b038216610b655760405162461bcd60e51b815260040180806020018281038252602a815260200180613104602a913960400191505060405180910390fd5b6001600160a01b03821660009081526001602052604090206108db90611938565b610b8e6118c6565b6001600160a01b0316610b9f610d5e565b6001600160a01b031614610be8576040805162461bcd60e51b815260206004820181905260248201526000805160206131a5833981519152604482015290519081900360640190fd5b600a546040516000916001600160a01b0316907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0908390a3600a80546001600160a01b0319169055565b600080610c40888888610d28565b905060018186868660405160008152602001604052604051610c659493929190612d33565b6020604051602081039080840390855afa158015610c87573d6000803e3d6000fd5b5050604051601f1901519998505050505050505050565b610ca733610af3565b610ce8576040805162461bcd60e51b815260206004820152600d60248201526c1058d8d95cdcc819195b9a5959609a1b604482015290519081900360640190fd5b6108498383838080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525061187592505050565b6000838383604051602001610d3f93929190612f39565b6040516020818303038152906040528051906020012090509392505050565b600a546001600160a01b031690565b610d756118c6565b6001600160a01b0316610d86610d5e565b6001600160a01b031614610dcf576040805162461bcd60e51b815260206004820181905260248201526000805160206131a5833981519152604482015290519081900360640190fd5b6000826001600160a01b03166370a08231306040518263ffffffff1660e01b815260040180826001600160a01b0316815260200191505060206040518083038186803b158015610e1e57600080fd5b505afa158015610e32573d6000803e3d6000fd5b505050506040513d6020811015610e4857600080fd5b50516040805163a9059cbb60e01b81526001600160a01b0385811660048301526024820184905291519293509085169163a9059cbb916044808201926020929091908290030181600087803b158015610ea057600080fd5b505af1158015610eb4573d6000803e3d6000fd5b505050506040513d602081101561065657600080fd5b60078054604080516020601f600260001961010060018816150201909516949094049384018190048102820181019092528281526060939092909183018282801561070c5780601f106106e15761010080835404028352916020019161070c565b600d546000906001600160a01b0316610f48888888888888610c32565b6001600160a01b031614979650505050505050565b610f656118c6565b6001600160a01b0316610f76610d5e565b6001600160a01b031614610fbf576040805162461bcd60e51b815260206004820181905260248201526000805160206131a5833981519152604482015290519081900360640190fd5b6001600160a01b038116611012576040805162461bcd60e51b81526020600482015260156024820152744e6577206f70657261746f7220697320656d70747960581b604482015290519081900360640190fd5b6001600160a01b03166000908152600b60205260409020805460ff19166001179055565b600e60209081526000918252604091829020805460018083018054865160026101009483161585026000190190921691909104601f810187900487028201870190975286815260ff80851697938504169562010000850463ffffffff169566010000000000009095046001600160401b03169493919291908301828280156110ff5780601f106110d4576101008083540402835291602001916110ff565b820191906000526020600020905b8154815290600101906020018083116110e257829003601f168201915b5050505050905085565b6000818152600e6020526040812054819060ff16601481111561112857fe5b6000848152600e6020526040902054610100900460ff16600381111561114a57fe5b91509150915091565b61115b6118c6565b6001600160a01b0316826001600160a01b031614156111c1576040805162461bcd60e51b815260206004820152601960248201527f4552433732313a20617070726f766520746f2063616c6c657200000000000000604482015290519081900360640190fd5b80600560006111ce6118c6565b6001600160a01b03908116825260208083019390935260409182016000908120918716808252919093529120805460ff1916921515929092179091556112126118c6565b6001600160a01b03167f17307eab39ab6107e8899845ad3d59bd9653f200f220920489ca2b5937696c318360405180821515815260200191505060405180910390a35050565b6112606118c6565b6001600160a01b0316611271610d5e565b6001600160a01b0316146112ba576040805162461bcd60e51b815260206004820181905260248201526000805160206131a5833981519152604482015290519081900360640190fd5b6001600160a01b03166000908152600b60205260409020805460ff19169055565b6112ec6112e66118c6565b83611b27565b6113275760405162461bcd60e51b815260040180806020018281038252603181526020018061323e6031913960400191505060405180910390fd5b61133384848484611bc3565b50505050565b6060611344826118b9565b6113605760405162461bcd60e51b81526004016105cc90612e7a565b6000828152600c602090815260409182902080548351601f60026000196101006001861615020190931692909204918201849004840281018401909452808452606093928301828280156113f55780601f106113ca576101008083540402835291602001916113f5565b820191906000526020600020905b8154815290600101906020018083116113d857829003601f168201915b505050505090506060611406610a4f565b905080516000141561141a5750905061067b565b8151156114295750905061067b565b61143284611c15565b949350505050565b6114426118c6565b6001600160a01b0316611453610d5e565b6001600160a01b03161461149c576040805162461bcd60e51b815260206004820181905260248201526000805160206131a5833981519152604482015290519081900360640190fd5b6001600160a01b0382166000818152600f602052604090819020805460ff1916841515179055517f735768a8abddcbaa527672c7b507c39cdfee45818f675893d3ccf2326523c09e906114f0908490612d1f565b60405180910390a25050565b6115046118c6565b6001600160a01b0316611515610d5e565b6001600160a01b03161461155e576040805162461bcd60e51b815260206004820181905260248201526000805160206131a5833981519152604482015290519081900360640190fd5b6115688585611e98565b6040518060a001604052808460ff16601481111561158257fe5b601481111561158d57fe5b81526020018360ff1660038111156115a157fe5b60038111156115ac57fe5b815263ffffffff83166020808301919091526001600160401b034216604080840191909152805180830182526000808252606090940152878352600e909152902081518154829060ff1916600183601481111561160557fe5b021790555060208201518154829061ff00191661010083600381111561162757fe5b02179055506040820151815460608401516001600160401b03166601000000000000026dffffffffffffffff0000000000001963ffffffff909316620100000265ffffffff000019909216919091179190911617815560808201518051611698916001840191602090910190612740565b5050505050505050565b6001600160a01b03918216600090815260056020908152604080832093909416825291909152205460ff1690565b600f6020526000908152604090205460ff1681565b6116ed6118c6565b6001600160a01b03166116fe610d5e565b6001600160a01b031614611747576040805162461bcd60e51b815260206004820181905260248201526000805160206131a5833981519152604482015290519081900360640190fd5b6001600160a01b03811661178c5760405162461bcd60e51b81526004018080602001828103825260268152602001806130566026913960400191505060405180910390fd5b600a546040516001600160a01b038084169216907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e090600090a3600a80546001600160a01b0319166001600160a01b0392909216919091179055565b336117f284610a27565b6001600160a01b0316146118185760405162461bcd60e51b81526004016105cc90612ecb565b6000838152600e6020526040902060019081015460029181161561010002600019011604156118595760405162461bcd60e51b81526004016105cc90612f02565b6000838152600e602052604090206113339060010183836127cc565b61187e826118b9565b61189a5760405162461bcd60e51b81526004016105cc90612e2c565b6000828152600c60209081526040909120825161084992840190612740565b60006108db600283611fc6565b3390565b600081815260046020526040902080546001600160a01b0319166001600160a01b03841690811790915581906118ff82610a27565b6001600160a01b03167f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b92560405160405180910390a45050565b60006108db82611fd2565b826001600160a01b031661195682610a27565b6001600160a01b03161461199b5760405162461bcd60e51b81526004018080602001828103825260298152602001806131c56029913960400191505060405180910390fd5b6001600160a01b0382166119e05760405162461bcd60e51b815260040180806020018281038252602481526020018061307c6024913960400191505060405180910390fd5b6119eb838383610849565b6119f66000826118ca565b6001600160a01b0383166000908152600160205260409020611a189082611fd6565b506001600160a01b0382166000908152600160205260409020611a3b9082611fe2565b50611a4860028284611fee565b5080826001600160a01b0316846001600160a01b03167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef60405160405180910390a4505050565b611aa0611a9a6118c6565b82611b27565b611adb5760405162461bcd60e51b815260040180806020018281038252603181526020018061323e6031913960400191505060405180910390fd5b610849838383611943565b60006108d88383612004565b6000808080611b018686612068565b909450925050505b9250929050565b6000611b1d8484846120e3565b90505b9392505050565b6000611b32826118b9565b611b6d5760405162461bcd60e51b815260040180806020018281038252602c8152602001806130a0602c913960400191505060405180910390fd5b6000611b7883610a27565b9050806001600160a01b0316846001600160a01b03161480611bb35750836001600160a01b0316611ba884610716565b6001600160a01b0316145b80611432575061143281856116a2565b611bce848484611943565b611bda848484846121ad565b6113335760405162461bcd60e51b81526004018080602001828103825260328152602001806130246032913960400191505060405180910390fd5b6060611c20826118b9565b611c5b5760405162461bcd60e51b815260040180806020018281038252602f8152602001806131ee602f913960400191505060405180910390fd5b60008281526008602090815260409182902080548351601f6002600019610100600186161502019093169290920491820184900484028101840190945280845260609392830182828015611cf05780601f10611cc557610100808354040283529160200191611cf0565b820191906000526020600020905b815481529060010190602001808311611cd357829003601f168201915b505050505090506060611d01610a4f565b9050805160001415611d155750905061067b565b815115611dd65780826040516020018083805190602001908083835b60208310611d505780518252601f199092019160209182019101611d31565b51815160209384036101000a600019018019909216911617905285519190930192850191508083835b60208310611d985780518252601f199092019160209182019101611d79565b6001836020036101000a038019825116818451168082178552505050505050905001925050506040516020818303038152906040529250505061067b565b80611de085612315565b6040516020018083805190602001908083835b60208310611e125780518252601f199092019160209182019101611df3565b51815160209384036101000a600019018019909216911617905285519190930192850191508083835b60208310611e5a5780518252601f199092019160209182019101611e3b565b6001836020036101000a0380198251168184511680821785525050505050509050019250505060405160208183030381529060405292505050919050565b6001600160a01b038216611ef3576040805162461bcd60e51b815260206004820181905260248201527f4552433732313a206d696e7420746f20746865207a65726f2061646472657373604482015290519081900360640190fd5b611efc816118b9565b15611f4e576040805162461bcd60e51b815260206004820152601c60248201527f4552433732313a20746f6b656e20616c7265616479206d696e74656400000000604482015290519081900360640190fd5b611f5a60008383610849565b6001600160a01b0382166000908152600160205260409020611f7c9082611fe2565b50611f8960028284611fee565b5060405181906001600160a01b038416906000907fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef908290a45050565b60006108d883836123ef565b5490565b60006108d88383612407565b60006108d883836124cd565b6000611b1d84846001600160a01b038516612517565b815460009082106120465760405162461bcd60e51b8152600401808060200182810382526022815260200180612fe06022913960400191505060405180910390fd5b82600001828154811061205557fe5b9060005260206000200154905092915050565b8154600090819083106120ac5760405162461bcd60e51b81526004018080602001828103825260228152602001806131576022913960400191505060405180910390fd5b60008460000184815481106120bd57fe5b906000526020600020906002020190508060000154816001015492509250509250929050565b6000828152600184016020526040812054828161217e5760405162461bcd60e51b81526004018080602001828103825283818151815260200191508051906020019080838360005b8381101561214357818101518382015260200161212b565b50505050905090810190601f1680156121705780820380516001836020036101000a031916815260200191505b509250505060405180910390fd5b5084600001600182038154811061219157fe5b9060005260206000209060020201600101549150509392505050565b60006121c1846001600160a01b03166125ae565b6121cd57506001611432565b60606122db630a85bd0160e11b6121e26118c6565b88878760405160240180856001600160a01b03168152602001846001600160a01b0316815260200183815260200180602001828103825283818151815260200191508051906020019080838360005b83811015612249578181015183820152602001612231565b50505050905090810190601f1680156122765780820380516001836020036101000a031916815260200191505b5095505050505050604051602081830303815290604052906001600160e01b0319166020820180516001600160e01b038381831617835250505050604051806060016040528060328152602001613024603291396001600160a01b03881691906125b4565b905060008180602001905160208110156122f457600080fd5b50516001600160e01b031916630a85bd0160e11b1492505050949350505050565b60608161233a57506040805180820190915260018152600360fc1b602082015261067b565b8160005b811561235257600101600a8204915061233e565b6060816001600160401b038111801561236a57600080fd5b506040519080825280601f01601f191660200182016040528015612395576020820181803683370190505b50859350905060001982015b83156123e657600a840660300160f81b828280600190039350815181106123c457fe5b60200101906001600160f81b031916908160001a905350600a840493506123a1565b50949350505050565b60009081526001919091016020526040902054151590565b600081815260018301602052604081205480156124c3578354600019808301919081019060009087908390811061243a57fe5b906000526020600020015490508087600001848154811061245757fe5b60009182526020808320909101929092558281526001898101909252604090209084019055865487908061248757fe5b600190038181906000526020600020016000905590558660010160008781526020019081526020016000206000905560019450505050506108db565b60009150506108db565b60006124d983836123ef565b61250f575081546001818101845560008481526020808220909301849055845484825282860190935260409020919091556108db565b5060006108db565b60008281526001840160205260408120548061257c575050604080518082018252838152602080820184815286546001818101895560008981528481209551600290930290950191825591519082015586548684528188019092529290912055611b20565b8285600001600183038154811061258f57fe5b9060005260206000209060020201600101819055506000915050611b20565b3b151590565b6060611b1d8484600085856125c8856125ae565b612619576040805162461bcd60e51b815260206004820152601d60248201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e7472616374000000604482015290519081900360640190fd5b60006060866001600160a01b031685876040518082805190602001908083835b602083106126585780518252601f199092019160209182019101612639565b6001836020036101000a03801982511681845116808217855250505050505090500191505060006040518083038185875af1925050503d80600081146126ba576040519150601f19603f3d011682016040523d82523d6000602084013e6126bf565b606091505b50915091506126cf8282866126da565b979650505050505050565b606083156126e9575081611b20565b8251156126f95782518084602001fd5b60405162461bcd60e51b815260206004820181815284516024840152845185939192839260440191908501908083836000831561214357818101518382015260200161212b565b828054600181600116156101000203166002900490600052602060002090601f01602090048101928261277657600085556127bc565b82601f1061278f57805160ff19168380011785556127bc565b828001600101855582156127bc579182015b828111156127bc5782518255916020019190600101906127a1565b506127c8929150612848565b5090565b828054600181600116156101000203166002900490600052602060002090601f01602090048101928261280257600085556127bc565b82601f1061281b5782800160ff198235161785556127bc565b828001600101855582156127bc579182015b828111156127bc57823582559160200191906001019061282d565b5b808211156127c85760008155600101612849565b60008083601f84011261286e578182fd5b5081356001600160401b03811115612884578182fd5b6020830191508360208083028501011115611b0957600080fd5b60008083601f8401126128af578182fd5b5081356001600160401b038111156128c5578182fd5b602083019150836020828501011115611b0957600080fd5b803560ff8116811461067b57600080fd5b6000602082840312156128ff578081fd5b8135611b2081612fc7565b6000806040838503121561291c578081fd5b823561292781612fc7565b9150602083013561293781612fc7565b809150509250929050565b600080600060608486031215612956578081fd5b833561296181612fc7565b9250602084013561297181612fc7565b929592945050506040919091013590565b60008060008060808587031215612997578081fd5b84356129a281612fc7565b93506020858101356129b381612fc7565b93506040860135925060608601356001600160401b03808211156129d5578384fd5b818801915088601f8301126129e8578384fd5b8135818111156129f457fe5b604051601f8201601f1916810185018381118282101715612a1157fe5b60405281815283820185018b1015612a27578586fd5b81858501868301379081019093019390935250939692955090935050565b60008060408385031215612a57578182fd5b8235612a6281612fc7565b915060208301358015158114612937578182fd5b60008060408385031215612a88578182fd5b8235612a9381612fc7565b946020939093013593505050565b600080600080600060a08688031215612ab8578081fd5b8535612ac381612fc7565b945060208601359350612ad8604087016128dd565b9250612ae6606087016128dd565b9150608086013563ffffffff81168114612afe578182fd5b809150509295509295909350565b60008060008060408587031215612b21578384fd5b84356001600160401b0380821115612b37578586fd5b612b438883890161285d565b90965094506020870135915080821115612b5b578384fd5b50612b688782880161285d565b95989497509550505050565b600060208284031215612b85578081fd5b81356001600160e01b031981168114611b20578182fd5b6000806040838503121561291c578182fd5b600060208284031215612bbf578081fd5b5035919050565b600080600060408486031215612bda578081fd5b8335925060208401356001600160401b03811115612bf6578182fd5b612c028682870161289e565b9497909650939450505050565b60008060008060008060a08789031215612c27578384fd5b8635955060208701356001600160401b03811115612c43578485fd5b612c4f89828a0161289e565b9096509450612c629050604088016128dd565b925060608701359150608087013590509295509295509295565b60008151808452815b81811015612ca157602081850181015186830182015201612c85565b81811115612cb25782602083870101525b50601f01601f19169290920160200192915050565b6001600160a01b0391909116815260200190565b6020808252825182820181905260009190848201906040850190845b81811015612d1357835183529284019291840191600101612cf7565b50909695505050505050565b901515815260200190565b90815260200190565b93845260ff9290921660208401526040830152606082015260800190565b600060158710612d5d57fe5b86825260048610612d6a57fe5b85602083015263ffffffff851660408301526001600160401b038416606083015260a060808301526126cf60a0830184612c7c565b6000602082526108d86020830184612c7c565b6020808252602f908201527f746f6b656e4964206c656e677468206973206e6f7420657175616c20746f205f60408201526e0e8ded6cadcaaa49240d8cadccee8d608b1b606082015260800190565b602080825260119082015270496e76616c6964207369676e617475726560781b604082015260600190565b6020808252602e908201527f45524337323155524953746f726167653a2055524920736574206f66206e6f6e60408201526d32bc34b9ba32b73a103a37b5b2b760911b606082015260800190565b60208082526031908201527f45524337323155524953746f726167653a2055524920717565727920666f72206040820152703737b732bc34b9ba32b73a103a37b5b2b760791b606082015260800190565b6020808252601a908201527f4f6e6c79206f776e65722063616e206368616e6765206e616d65000000000000604082015260600190565b6020808252601f908201527f546865206e616d652068617320616c7265616479206265656e20676976656e00604082015260600190565b60008482526040602083015282604083015282846060840137818301606090810191909152601f909201601f1916010192915050565b60ff92831681529116602082015260400190565b6000808335601e19843603018112612f99578283fd5b8301803591506001600160401b03821115612fb2578283fd5b602001915036819003821315611b0957600080fd5b6001600160a01b0381168114612fdc57600080fd5b5056fe456e756d657261626c655365743a20696e646578206f7574206f6620626f756e6473687474703a2f2f646567656e732e6661726d2f6d6574612f6372656174757265732f4552433732313a207472616e7366657220746f206e6f6e20455243373231526563656976657220696d706c656d656e7465724f776e61626c653a206e6577206f776e657220697320746865207a65726f20616464726573734552433732313a207472616e7366657220746f20746865207a65726f20616464726573734552433732313a206f70657261746f7220717565727920666f72206e6f6e6578697374656e7420746f6b656e4552433732313a20617070726f76652063616c6c6572206973206e6f74206f776e6572206e6f7220617070726f76656420666f7220616c6c4552433732313a2062616c616e636520717565727920666f7220746865207a65726f20616464726573734552433732313a206f776e657220717565727920666f72206e6f6e6578697374656e7420746f6b656e456e756d657261626c654d61703a20696e646578206f7574206f6620626f756e64734552433732313a20617070726f76656420717565727920666f72206e6f6e6578697374656e7420746f6b656e4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e65724552433732313a207472616e73666572206f6620746f6b656e2074686174206973206e6f74206f776e4552433732314d657461646174613a2055524920717565727920666f72206e6f6e6578697374656e7420746f6b656e4552433732313a20617070726f76616c20746f2063757272656e74206f776e65724552433732313a207472616e736665722063616c6c6572206973206e6f74206f776e6572206e6f7220617070726f766564a2646970667358221220308c7d0f38216f626771d86f2b5b3091893bd5f12659a801a1f13db0060ec78f64736f6c63430007040033

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

000000000000000000000000000000000000000000000000000000000000004000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000015446567656e24204661726d20437265617475726573000000000000000000000000000000000000000000000000000000000000000000000000000000000000054352454154000000000000000000000000000000000000000000000000000000

-----Decoded View---------------
Arg [0] : name_ (string): Degen$ Farm Creatures
Arg [1] : symbol_ (string): CREAT

-----Encoded View---------------
6 Constructor Arguments found :
Arg [0] : 0000000000000000000000000000000000000000000000000000000000000040
Arg [1] : 0000000000000000000000000000000000000000000000000000000000000080
Arg [2] : 0000000000000000000000000000000000000000000000000000000000000015
Arg [3] : 446567656e24204661726d204372656174757265730000000000000000000000
Arg [4] : 0000000000000000000000000000000000000000000000000000000000000005
Arg [5] : 4352454154000000000000000000000000000000000000000000000000000000


Deployed Bytecode Sourcemap

171:2836:2:-:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;2316:330:9;;;;;;:::i;:::-;;:::i;:::-;;999:150:7;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;4560:100:8;;;:::i;:::-;;;;;;;:::i;7346:221::-;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;6876:404::-;;;;;;:::i;:::-;;:::i;6354:211::-;;;:::i;:::-;;;;;;;:::i;2745:259:2:-;;;;;;:::i;:::-;;:::i;345:101:22:-;;;;;;:::i;:::-;;:::i;6116:162:8:-;;;;;;:::i;:::-;;:::i;8612:151::-;;;;;;:::i;:::-;;:::i;6642:172::-;;;;;;:::i;:::-;;:::i;1988:363:2:-;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;3713:249:9:-;;;;;;:::i;:::-;;:::i;2654:28::-;;;:::i;4316:177:8:-;;;;;;:::i;:::-;;:::i;2359:126:2:-;;;:::i;2691:103:9:-;;;;;;:::i;:::-;;:::i;454:128:22:-;;;;;;:::i;:::-;;:::i;4033:221:8:-;;;;;;:::i;:::-;;:::i;1763:148:23:-;;;:::i;2999:277:9:-;;;;;;:::i;:::-;;:::i;2175:133::-;;;;;;:::i;:::-;;:::i;2802:189::-;;;;;;:::i;:::-;;:::i;1112:87:23:-;;;:::i;1025:213:22:-;;;;;;:::i;:::-;;:::i;4729:104:8:-;;;:::i;3284:247:9:-;;;;;;:::i;:::-;;:::i;590:190:22:-;;;;;;:::i;:::-;;:::i;726:42:2:-;;;;;;:::i;:::-;;:::i;:::-;;;;;;;;;;;:::i;1809:171::-;;;;;;:::i;:::-;;:::i;:::-;;;;;;;;:::i;7639:295:8:-;;;;;;:::i;:::-;;:::i;788:121:22:-;;;;;;:::i;:::-;;:::i;8834:285:8:-;;;;;;:::i;:::-;;:::i;598:752:9:-;;;;;;:::i;:::-;;:::i;1628:173:2:-;;;;;;:::i;:::-;;:::i;1002:319::-;;;;;;:::i;:::-;;:::i;8005:164:8:-;;;;;;:::i;:::-;;:::i;777:47:2:-;;;;;;:::i;:::-;;:::i;2066:244:23:-;;;;;;:::i;:::-;;:::i;1329:291:2:-;;;;;;:::i;:::-;;:::i;2316:330:9:-;277:22:22;288:10;277;:22::i;:::-;269:48;;;;;-1:-1:-1;;;269:48:22;;;;;;;;;;;;-1:-1:-1;;;269:48:22;;;;;;;;;;;;;;;2435:34:9;;::::1;2427:94;;;;-1:-1:-1::0;;;2427:94:9::1;;;;;;;:::i;:::-;;;;;;;;;2537:6;2532:107;2549:18:::0;;::::1;2532:107;;;2589:38;2602:7;;2610:1;2602:10;;;;;;;;;;;;;2614:9;;2624:1;2614:12;;;;;;;;;;;;;;;;;;:::i;:::-;2589:38;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;::::0;::::1;::::0;;;;-1:-1:-1;2589:12:9::1;::::0;-1:-1:-1;;;2589:38:9:i:1;:::-;2569:3;;2532:107;;;;2316:330:::0;;;;:::o;999:150:7:-;-1:-1:-1;;;;;;1108:33:7;;1084:4;1108:33;;;;;;;;;;;;;999:150;;;;:::o;4560:100:8:-;4647:5;4640:12;;;;;;;;-1:-1:-1;;4640:12:8;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;4614:13;;4640:12;;4647:5;;4640:12;;4647:5;4640:12;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;4560:100;:::o;7346:221::-;7422:7;7450:16;7458:7;7450;:16::i;:::-;7442:73;;;;-1:-1:-1;;;7442:73:8;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;7535:24:8;;;;:15;:24;;;;;;-1:-1:-1;;;;;7535:24:8;;7346:221::o;6876:404::-;6957:13;6973:23;6988:7;6973:14;:23::i;:::-;6957:39;;7021:5;-1:-1:-1;;;;;7015:11:8;:2;-1:-1:-1;;;;;7015:11:8;;;7007:57;;;;-1:-1:-1;;;7007:57:8;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;7101:5;-1:-1:-1;;;;;7085:21:8;:12;:10;:12::i;:::-;-1:-1:-1;;;;;7085:21:8;;:69;;;;7110:44;7134:5;7141:12;:10;:12::i;7110:44::-;7077:161;;;;-1:-1:-1;;;7077:161:8;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;7251:21;7260:2;7264:7;7251:8;:21::i;:::-;6876:404;;;:::o;6354:211::-;6415:7;6536:21;:12;:19;:21::i;:::-;6529:28;;6354:211;:::o;2745:259:2:-;2857:10;2841:27;;;;:15;:27;;;;;;;;2837:158;;;2885:28;2895:4;2901:2;2905:7;2885:9;:28::i;:::-;2837:158;;;2946:37;2965:4;2971:2;2975:7;2946:18;:37::i;345:101:22:-;398:4;433:5;-1:-1:-1;;;;;422:16:22;:7;:5;:7::i;:::-;-1:-1:-1;;;;;422:16:22;;;345:101;-1:-1:-1;;345:101:22:o;6116:162:8:-;-1:-1:-1;;;;;6240:20:8;;6213:7;6240:20;;;:13;:20;;;;;:30;;6264:5;6240:23;:30::i;:::-;6233:37;;6116:162;;;;;:::o;8612:151::-;8716:39;8733:4;8739:2;8743:7;8716:39;;;;;;;;;;;;:16;:39::i;6642:172::-;6717:7;;6759:22;:12;6775:5;6759:15;:22::i;:::-;-1:-1:-1;6737:44:8;6642:172;-1:-1:-1;;;6642:172:8:o;1988:363:2:-;2051:16;2128:9;2140:17;2150:6;2140:9;:17::i;:::-;2128:29;;2170:23;2210:1;-1:-1:-1;;;;;2196:16:2;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;2196:16:2;;2170:42;;2228:8;2223:96;2244:1;2240;:5;;;2223:96;;;2277:30;2297:6;2305:1;2277:30;;:19;:30::i;:::-;2267:6;2274:1;2267:9;;;;;;;;;;;;;;;;;;;:40;2247:3;;2223:96;;3713:249:9;3841:48;3858:7;3867:9;;3878:2;3882;3886;3841:16;:48::i;:::-;3833:78;;;;-1:-1:-1;;;3833:78:9;;;;;;;:::i;:::-;3922:32;3935:7;3944:9;;3922:32;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;3922:12:9;;-1:-1:-1;;;3922:32:9:i;:::-;3713:249;;;;;;:::o;2654:28::-;;;-1:-1:-1;;;;;2654:28:9;;:::o;4316:177:8:-;4388:7;4415:70;4432:7;4415:70;;;;;;;;;;;;;;;;;:12;;:70;:16;:70::i;2359:126:2:-;2408:13;2434:43;;;;;;;;;;;;;;;;;;;2359:126;:::o;2691:103:9:-;1343:12:23;:10;:12::i;:::-;-1:-1:-1;;;;;1332:23:23;:7;:5;:7::i;:::-;-1:-1:-1;;;;;1332:23:23;;1324:68;;;;;-1:-1:-1;;;1324:68:23;;;;;;;;;;;;;-1:-1:-1;;;;;;;;;;;1324:68:23;;;;;;;;;;;;;;;2760:13:9::1;:26:::0;;-1:-1:-1;;;;;;2760:26:9::1;-1:-1:-1::0;;;;;2760:26:9;;;::::1;::::0;;;::::1;::::0;;2691:103::o;454:128:22:-;-1:-1:-1;;;;;534:22:22;;510:4;534:22;;;:15;:22;;;;;;;;;:40;;;560:14;568:5;560:7;:14::i;4033:221:8:-;4105:7;-1:-1:-1;;;;;4133:19:8;;4125:74;;;;-1:-1:-1;;;4125:74:8;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;;;4217:20:8;;;;;;:13;:20;;;;;:29;;:27;:29::i;1763:148:23:-;1343:12;:10;:12::i;:::-;-1:-1:-1;;;;;1332:23:23;:7;:5;:7::i;:::-;-1:-1:-1;;;;;1332:23:23;;1324:68;;;;;-1:-1:-1;;;1324:68:23;;;;;;;;;;;;;-1:-1:-1;;;;;;;;;;;1324:68:23;;;;;;;;;;;;;;;1854:6:::1;::::0;1833:40:::1;::::0;1870:1:::1;::::0;-1:-1:-1;;;;;1854:6:23::1;::::0;1833:40:::1;::::0;1870:1;;1833:40:::1;1884:6;:19:::0;;-1:-1:-1;;;;;;1884:19:23::1;::::0;;1763:148::o;2999:277:9:-;3144:7;3169:15;3187:33;3201:7;3210:9;;3187:13;:33::i;:::-;3169:51;;3238:30;3248:7;3257:2;3261;3265;3238:30;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;3238:30:9;;-1:-1:-1;;3238:30:9;;;2999:277;-1:-1:-1;;;;;;;;;2999:277:9:o;2175:133::-;277:22:22;288:10;277;:22::i;:::-;269:48;;;;;-1:-1:-1;;;269:48:22;;;;;;;;;;;;-1:-1:-1;;;269:48:22;;;;;;;;;;;;;;;2268:32:9::1;2281:7;2290:9;;2268:32;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;::::0;::::1;::::0;;;;-1:-1:-1;2268:12:9::1;::::0;-1:-1:-1;;;2268:32:9:i:1;2802:189::-:0;2899:15;2963:7;2972:9;;2952:30;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;2942:41;;;;;;2932:51;;2802:189;;;;;:::o;1112:87:23:-;1185:6;;-1:-1:-1;;;;;1185:6:23;1112:87;:::o;1025:213:22:-;1343:12:23;:10;:12::i;:::-;-1:-1:-1;;;;;1332:23:23;:7;:5;:7::i;:::-;-1:-1:-1;;;;;1332:23:23;;1324:68;;;;;-1:-1:-1;;;1324:68:23;;;;;;;;;;;;;-1:-1:-1;;;;;;;;;;;1324:68:23;;;;;;;;;;;;;;;1122:15:22::1;1140:14;-1:-1:-1::0;;;;;1140:24:22::1;;1173:4;1140:39;;;;;;;;;;;;;-1:-1:-1::0;;;;;1140:39:22::1;;;;;;;;;;;;;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;;;;;;;;::::0;::::1;;-1:-1:-1::0;1140:39:22;1190:40:::1;::::0;;-1:-1:-1;;;1190:40:22;;-1:-1:-1;;;;;1190:40:22;;::::1;;::::0;::::1;::::0;;;;;;;;;1140:39;;-1:-1:-1;1190:23:22;;::::1;::::0;::::1;::::0;:40;;;;;1140:39:::1;::::0;1190:40;;;;;;;;-1:-1:-1;1190:23:22;:40;::::1;;::::0;::::1;;;;::::0;::::1;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;;;;;;;;::::0;::::1;4729:104:8::0;4818:7;4811:14;;;;;;;;-1:-1:-1;;4811:14:8;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;4785:13;;4811:14;;4818:7;;4811:14;;4818:7;4811:14;;;;;;;;;;;;;;;;;;;;;;;;3284:247:9;3510:13;;3436:4;;-1:-1:-1;;;;;3510:13:9;3465:41;3475:7;3484:9;;3495:2;3499;3503;3465:9;:41::i;:::-;-1:-1:-1;;;;;3465:58:9;;;3284:247;-1:-1:-1;;;;;;;3284:247:9:o;590:190:22:-;1343:12:23;:10;:12::i;:::-;-1:-1:-1;;;;;1332:23:23;:7;:5;:7::i;:::-;-1:-1:-1;;;;;1332:23:23;;1324:68;;;;;-1:-1:-1;;;1324:68:23;;;;;;;;;;;;;-1:-1:-1;;;;;;;;;;;1324:68:23;;;;;;;;;;;;;;;-1:-1:-1;;;;;671:26:22;::::1;663:60;;;::::0;;-1:-1:-1;;;663:60:22;;::::1;;::::0;::::1;::::0;::::1;::::0;;;;-1:-1:-1;;;663:60:22;;;;;;;;;;;;;::::1;;-1:-1:-1::0;;;;;736:29:22::1;;::::0;;;:15:::1;:29;::::0;;;;:36;;-1:-1:-1;;736:36:22::1;768:4;736:36;::::0;;590:190::o;726:42:2:-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;726:42:2;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;;;726:42:2;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::o;1809:171::-;1875:5;1914:17;;;:7;:17;;;;;:23;1875:5;;1914:23;;1908:30;;;;;;;;1946:17;;;;:7;:17;;;;;:24;;;;;;1940:31;;;;;;;;1900:72;;;;1809:171;;;:::o;7639:295:8:-;7754:12;:10;:12::i;:::-;-1:-1:-1;;;;;7742:24:8;:8;-1:-1:-1;;;;;7742:24:8;;;7734:62;;;;;-1:-1:-1;;;7734:62:8;;;;;;;;;;;;;;;;;;;;;;;;;;;;7854:8;7809:18;:32;7828:12;:10;:12::i;:::-;-1:-1:-1;;;;;7809:32:8;;;;;;;;;;;;;;;;;-1:-1:-1;7809:32:8;;;:42;;;;;;;;;;;;:53;;-1:-1:-1;;7809:53:8;;;;;;;;;;;7893:12;:10;:12::i;:::-;-1:-1:-1;;;;;7878:48:8;;7917:8;7878:48;;;;;;;;;;;;;;;;;;;;7639:295;;:::o;788:121:22:-;1343:12:23;:10;:12::i;:::-;-1:-1:-1;;;;;1332:23:23;:7;:5;:7::i;:::-;-1:-1:-1;;;;;1332:23:23;;1324:68;;;;;-1:-1:-1;;;1324:68:23;;;;;;;;;;;;;-1:-1:-1;;;;;;;;;;;1324:68:23;;;;;;;;;;;;;;;-1:-1:-1;;;;;871:29:22::1;;::::0;;;:15:::1;:29;::::0;;;;864:37;;-1:-1:-1;;864:37:22::1;::::0;;788:121::o;8834:285:8:-;8966:41;8985:12;:10;:12::i;:::-;8999:7;8966:18;:41::i;:::-;8958:103;;;;-1:-1:-1;;;8958:103:8;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;9072:39;9086:4;9092:2;9096:7;9105:5;9072:13;:39::i;:::-;8834:285;;;;:::o;598:752:9:-;671:13;705:16;713:7;705;:16::i;:::-;697:78;;;;-1:-1:-1;;;697:78:9;;;;;;;:::i;:::-;814:19;;;;:10;:19;;;;;;;;;788:45;;;;;;-1:-1:-1;;788:45:9;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:23;;:45;;;814:19;788:45;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;844:18;865:9;:7;:9::i;:::-;844:30;;956:4;950:18;972:1;950:23;946:72;;;-1:-1:-1;997:9:9;-1:-1:-1;990:16:9;;946:72;1122:23;;:27;1118:182;;-1:-1:-1;1279:9:9;-1:-1:-1;1272:16:9;;1118:182;1319:23;1334:7;1319:14;:23::i;:::-;1312:30;598:752;-1:-1:-1;;;;598:752:9:o;1628:173:2:-;1343:12:23;:10;:12::i;:::-;-1:-1:-1;;;;;1332:23:23;:7;:5;:7::i;:::-;-1:-1:-1;;;;;1332:23:23;;1324:68;;;;;-1:-1:-1;;;1324:68:23;;;;;;;;;;;;;-1:-1:-1;;;;;;;;;;;1324:68:23;;;;;;;;;;;;;;;-1:-1:-1;;;;;1714:24:2;::::1;;::::0;;;:15:::1;:24;::::0;;;;;;:33;;-1:-1:-1;;1714:33:2::1;::::0;::::1;;;::::0;;1763:30;::::1;::::0;::::1;::::0;1714:33;;1763:30:::1;:::i;:::-;;;;;;;;1628:173:::0;;:::o;1002:319::-;1343:12:23;:10;:12::i;:::-;-1:-1:-1;;;;;1332:23:23;:7;:5;:7::i;:::-;-1:-1:-1;;;;;1332:23:23;;1324:68;;;;;-1:-1:-1;;;1324:68:23;;;;;;;;;;;;;-1:-1:-1;;;;;;;;;;;1324:68:23;;;;;;;;;;;;;;;1181:18:2::1;1187:2;1191:7;1181:5;:18::i;:::-;1229:84;;;;;;;;1247:11;1236:23;;;;;;;;;;1229:84;;;;;;;;;;;;1268:7;1261:15;;;;;;;;;;1229:84;;;;;;;;::::0;;::::1;::::0;::::1;;::::0;;::::1;::::0;;;;-1:-1:-1;;;;;1292:15:2::1;1229:84;::::0;;;;;;;;;;;;::::1;::::0;;-1:-1:-1;1229:84:2;;;;;;;;1210:16;;;:7:::1;:16:::0;;;;;:103;;;;:16;;-1:-1:-1;;1210:103:2::1;::::0;;::::1;::::0;::::1;;;;;;;;::::0;;-1:-1:-1;1210:103:2::1;::::0;::::1;::::0;;;;;-1:-1:-1;;1210:103:2::1;;::::0;::::1;::::0;::::1;;;;;;;;::::0;;-1:-1:-1;1210:103:2::1;::::0;::::1;::::0;;;::::1;::::0;::::1;::::0;-1:-1:-1;;;;;1210:103:2::1;::::0;::::1;-1:-1:-1::0;;1210:103:2::1;::::0;;::::1;::::0;::::1;-1:-1:-1::0;;1210:103:2;;::::1;::::0;;;::::1;::::0;;;::::1;;::::0;;::::1;::::0;::::1;::::0;;;::::1;::::0;-1:-1:-1;1210:103:2;::::1;::::0;::::1;::::0;;::::1;::::0;::::1;:::i;:::-;-1:-1:-1::0;;;;;;;;1002:319:2:o;8005:164:8:-;-1:-1:-1;;;;;8126:25:8;;;8102:4;8126:25;;;:18;:25;;;;;;;;:35;;;;;;;;;;;;;;;8005:164::o;777:47:2:-;;;;;;;;;;;;;;;:::o;2066:244:23:-;1343:12;:10;:12::i;:::-;-1:-1:-1;;;;;1332:23:23;:7;:5;:7::i;:::-;-1:-1:-1;;;;;1332:23:23;;1324:68;;;;;-1:-1:-1;;;1324:68:23;;;;;;;;;;;;;-1:-1:-1;;;;;;;;;;;1324:68:23;;;;;;;;;;;;;;;-1:-1:-1;;;;;2155:22:23;::::1;2147:73;;;;-1:-1:-1::0;;;2147:73:23::1;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;2257:6;::::0;2236:38:::1;::::0;-1:-1:-1;;;;;2236:38:23;;::::1;::::0;2257:6:::1;::::0;2236:38:::1;::::0;2257:6:::1;::::0;2236:38:::1;2285:6;:17:::0;;-1:-1:-1;;;;;;2285:17:23::1;-1:-1:-1::0;;;;;2285:17:23;;;::::1;::::0;;;::::1;::::0;;2066:244::o;1329:291:2:-;1434:10;1414:16;1422:7;1414;:16::i;:::-;-1:-1:-1;;;;;1414:30:2;;1406:69;;;;-1:-1:-1;;;1406:69:2;;;;;;;:::i;:::-;1500:16;;;;:7;:16;;;;;:21;;;;1494:35;;;;;;;;-1:-1:-1;;1494:35:2;;;:40;1486:84;;;;-1:-1:-1;;;1486:84:2;;;;;;;:::i;:::-;1583:16;;;;:7;:16;;;;;:29;;:21;;1607:5;;1583:29;:::i;1506:226:9:-;1615:16;1623:7;1615;:16::i;:::-;1607:75;;;;-1:-1:-1;;;1607:75:9;;;;;;;:::i;:::-;1693:19;;;;:10;:19;;;;;;;;:31;;;;;;;;:::i;10586:127:8:-;10651:4;10675:30;:12;10697:7;10675:21;:30::i;613:106:1:-;701:10;613:106;:::o;16493:183:8:-;16559:24;;;;:15;:24;;;;;:29;;-1:-1:-1;;;;;;16559:29:8;-1:-1:-1;;;;;16559:29:8;;;;;;;;:24;;16613:23;16559:24;16613:14;:23::i;:::-;-1:-1:-1;;;;;16604:46:8;;;;;;;;;;;16493:183;;:::o;8036:123:11:-;8105:7;8132:19;8140:3;8132:7;:19::i;14016:599:8:-;14141:4;-1:-1:-1;;;;;14114:31:8;:23;14129:7;14114:14;:23::i;:::-;-1:-1:-1;;;;;14114:31:8;;14106:85;;;;-1:-1:-1;;;14106:85:8;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;;;14228:16:8;;14220:65;;;;-1:-1:-1;;;14220:65:8;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;14298:39;14319:4;14325:2;14329:7;14298:20;:39::i;:::-;14402:29;14419:1;14423:7;14402:8;:29::i;:::-;-1:-1:-1;;;;;14444:19:8;;;;;;:13;:19;;;;;:35;;14471:7;14444:26;:35::i;:::-;-1:-1:-1;;;;;;14490:17:8;;;;;;:13;:17;;;;;:30;;14512:7;14490:21;:30::i;:::-;-1:-1:-1;14533:29:8;:12;14550:7;14559:2;14533:16;:29::i;:::-;;14599:7;14595:2;-1:-1:-1;;;;;14580:27:8;14589:4;-1:-1:-1;;;;;14580:27:8;;;;;;;;;;;14016:599;;;:::o;8236:305::-;8397:41;8416:12;:10;:12::i;:::-;8430:7;8397:18;:41::i;:::-;8389:103;;;;-1:-1:-1;;;8389:103:8;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;8505:28;8515:4;8521:2;8525:7;8505:9;:28::i;9543:137:12:-;9614:7;9649:22;9653:3;9665:5;9649:3;:22::i;8498:236:11:-;8578:7;;;;8638:22;8642:3;8654:5;8638:3;:22::i;:::-;8607:53;;-1:-1:-1;8607:53:11;-1:-1:-1;;;8498:236:11;;;;;;:::o;9784:213::-;9891:7;9942:44;9947:3;9967;9973:12;9942:4;:44::i;:::-;9934:53;-1:-1:-1;9784:213:11;;;;;;:::o;10880:355:8:-;10973:4;10998:16;11006:7;10998;:16::i;:::-;10990:73;;;;-1:-1:-1;;;10990:73:8;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;11074:13;11090:23;11105:7;11090:14;:23::i;:::-;11074:39;;11143:5;-1:-1:-1;;;;;11132:16:8;:7;-1:-1:-1;;;;;11132:16:8;;:51;;;;11176:7;-1:-1:-1;;;;;11152:31:8;:20;11164:7;11152:11;:20::i;:::-;-1:-1:-1;;;;;11152:31:8;;11132:51;:94;;;;11187:39;11211:5;11218:7;11187:23;:39::i;10001:272::-;10115:28;10125:4;10131:2;10135:7;10115:9;:28::i;:::-;10162:48;10185:4;10191:2;10195:7;10204:5;10162:22;:48::i;:::-;10154:111;;;;-1:-1:-1;;;10154:111:8;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;4904:792;4977:13;5011:16;5019:7;5011;:16::i;:::-;5003:76;;;;-1:-1:-1;;;5003:76:8;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;5118:19;;;;:10;:19;;;;;;;;;5092:45;;;;;;-1:-1:-1;;5092:45:8;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:23;;:45;;;5118:19;5092:45;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;5148:18;5169:9;:7;:9::i;:::-;5148:30;;5260:4;5254:18;5276:1;5254:23;5250:72;;;-1:-1:-1;5301:9:8;-1:-1:-1;5294:16:8;;5250:72;5426:23;;:27;5422:108;;5501:4;5507:9;5484:33;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;5484:33:8;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;5484:33:8;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;5484:33:8;;;;;;;;;;;;;-1:-1:-1;;5484:33:8;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;5470:48;;;;;;5422:108;5662:4;5668:18;:7;:16;:18::i;:::-;5645:42;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;5645:42:8;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;5645:42:8;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;5645:42:8;;;;;;;;;;;;;-1:-1:-1;;5645:42:8;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;5631:57;;;;4904:792;;;:::o;12501:404::-;-1:-1:-1;;;;;12581:16:8;;12573:61;;;;;-1:-1:-1;;;12573:61:8;;;;;;;;;;;;;;;;;;;;;;;;;;;;;12654:16;12662:7;12654;:16::i;:::-;12653:17;12645:58;;;;;-1:-1:-1;;;12645:58:8;;;;;;;;;;;;;;;;;;;;;;;;;;;;12716:45;12745:1;12749:2;12753:7;12716:20;:45::i;:::-;-1:-1:-1;;;;;12774:17:8;;;;;;:13;:17;;;;;:30;;12796:7;12774:21;:30::i;:::-;-1:-1:-1;12817:29:8;:12;12834:7;12843:2;12817:16;:29::i;:::-;-1:-1:-1;12864:33:8;;12889:7;;-1:-1:-1;;;;;12864:33:8;;;12881:1;;12864:33;;12881:1;;12864:33;12501:404;;:::o;7797:151:11:-;7881:4;7905:35;7915:3;7935;7905:9;:35::i;4615:110::-;4698:19;;4615:110::o;8630:137:12:-;8700:4;8724:35;8732:3;8752:5;8724:7;:35::i;8323:131::-;8390:4;8414:32;8419:3;8439:5;8414:4;:32::i;7220:185:11:-;7309:4;7333:64;7338:3;7358;-1:-1:-1;;;;;7372:23:11;;7333:4;:64::i;4581:204:12:-;4676:18;;4648:7;;4676:26;-1:-1:-1;4668:73:12;;;;-1:-1:-1;;;4668:73:12;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;4759:3;:11;;4771:5;4759:18;;;;;;;;;;;;;;;;4752:25;;4581:204;;;;:::o;5080:279:11:-;5184:19;;5147:7;;;;5184:27;-1:-1:-1;5176:74:11;;;;-1:-1:-1;;;5176:74:11;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;5263:22;5288:3;:12;;5301:5;5288:19;;;;;;;;;;;;;;;;;;5263:44;;5326:5;:10;;;5338:5;:12;;;5318:33;;;;;5080:279;;;;;:::o;6577:319::-;6671:7;6710:17;;;:12;;;:17;;;;;;6761:12;6746:13;6738:36;;;;-1:-1:-1;;;6738:36:11;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;6828:3;:12;;6852:1;6841:8;:12;6828:26;;;;;;;;;;;;;;;;;;:33;;;6821:40;;;6577:319;;;;;:::o;15881:604:8:-;16002:4;16029:15;:2;-1:-1:-1;;;;;16029:13:8;;:15::i;:::-;16024:60;;-1:-1:-1;16068:4:8;16061:11;;16024:60;16094:23;16120:252;-1:-1:-1;;;16233:12:8;:10;:12::i;:::-;16260:4;16279:7;16301:5;16136:181;;;;;;-1:-1:-1;;;;;16136:181:8;;;;;;-1:-1:-1;;;;;16136:181:8;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;;;16136:181:8;;;;;;;-1:-1:-1;;;;;16136:181:8;;;;;;;;;;;16120:252;;;;;;;;;;;;;;;;;-1:-1:-1;;;;;16120:15:8;;;:252;:15;:252::i;:::-;16094:278;;16383:13;16410:10;16399:32;;;;;;;;;;;;;;;-1:-1:-1;16399:32:8;-1:-1:-1;;;;;;16450:26:8;-1:-1:-1;;;16450:26:8;;-1:-1:-1;;;15881:604:8;;;;;;:::o;221:746:25:-;277:13;498:10;494:53;;-1:-1:-1;525:10:25;;;;;;;;;;;;-1:-1:-1;;;525:10:25;;;;;;494:53;572:5;557:12;613:78;620:9;;613:78;;646:8;;677:2;669:10;;;;613:78;;;701:19;733:6;-1:-1:-1;;;;;723:17:25;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;723:17:25;-1:-1:-1;795:5:25;;-1:-1:-1;701:39:25;-1:-1:-1;;;767:10:25;;811:117;818:9;;811:117;;887:2;880:4;:9;875:2;:14;862:29;;844:6;851:7;;;;;;;844:15;;;;;;;;;;;:47;-1:-1:-1;;;;;844:47:25;;;;;;;;-1:-1:-1;914:2:25;906:10;;;;811:117;;;-1:-1:-1;952:6:25;221:746;-1:-1:-1;;;;221:746:25:o;4395:125:11:-;4466:4;4490:17;;;:12;;;;;:17;;;;;;:22;;;4395:125::o;2283:1544:12:-;2349:4;2488:19;;;:12;;;:19;;;;;;2524:15;;2520:1300;;2959:18;;-1:-1:-1;;2910:14:12;;;;2959:22;;;;2886:21;;2959:3;;:22;;3246;;;;;;;;;;;;;;3226:42;;3392:9;3363:3;:11;;3375:13;3363:26;;;;;;;;;;;;;;;;;;;:38;;;;3469:23;;;3511:1;3469:12;;;:23;;;;;;3495:17;;;3469:43;;3621:17;;3469:3;;3621:17;;;;;;;;;;;;;;;;;;;;;;3716:3;:12;;:19;3729:5;3716:19;;;;;;;;;;;3709:26;;;3759:4;3752:11;;;;;;;;2520:1300;3803:5;3796:12;;;;;1693:414;1756:4;1778:21;1788:3;1793:5;1778:9;:21::i;:::-;1773:327;;-1:-1:-1;1816:23:12;;;;;;;;:11;:23;;;;;;;;;;;;;1999:18;;1977:19;;;:12;;;:19;;;;;;:40;;;;2032:11;;1773:327;-1:-1:-1;2083:5:12;2076:12;;1895:692:11;1971:4;2106:17;;;:12;;;:17;;;;;;2140:13;2136:444;;-1:-1:-1;;2225:38:11;;;;;;;;;;;;;;;;;;2207:57;;;;;;;;:12;:57;;;;;;;;;;;;;;;;;;;;;;;;2422:19;;2402:17;;;:12;;;:17;;;;;;;:39;2456:11;;2136:444;2536:5;2500:3;:12;;2524:1;2513:8;:12;2500:26;;;;;;;;;;;;;;;;;;:33;;:41;;;;2563:5;2556:12;;;;;751:422:0;1118:20;1157:8;;;751:422::o;3669:195::-;3772:12;3804:52;3826:6;3834:4;3840:1;3843:12;3772;4973:18;4984:6;4973:10;:18::i;:::-;4965:60;;;;;-1:-1:-1;;;4965:60:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;5099:12;5113:23;5140:6;-1:-1:-1;;;;;5140:11:0;5160:5;5168:4;5140:33;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;5140:33:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;5098:75;;;;5191:52;5209:7;5218:10;5230:12;5191:17;:52::i;:::-;5184:59;4721:530;-1:-1:-1;;;;;;;4721:530:0:o;7261:742::-;7376:12;7405:7;7401:595;;;-1:-1:-1;7436:10:0;7429:17;;7401:595;7550:17;;:21;7546:439;;7813:10;7807:17;7874:15;7861:10;7857:2;7853:19;7846:44;7761:148;7949:20;;-1:-1:-1;;;7949:20:0;;;;;;;;;;;;;;;;;7956:12;;7949:20;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;:::o;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;14:412:26;;;155:3;148:4;140:6;136:17;132:27;122:2;;180:8;170;163:26;122:2;-1:-1:-1;210:20:26;;-1:-1:-1;;;;;242:30:26;;239:2;;;292:8;282;275:26;239:2;336:4;328:6;324:17;312:29;;399:3;392:4;384;376:6;372:17;364:6;360:30;356:41;353:50;350:2;;;416:1;413;406:12;431:378;;;549:3;542:4;534:6;530:17;526:27;516:2;;574:8;564;557:26;516:2;-1:-1:-1;604:20:26;;-1:-1:-1;;;;;636:30:26;;633:2;;;686:8;676;669:26;633:2;730:4;722:6;718:17;706:29;;782:3;775:4;766:6;758;754:19;750:30;747:39;744:2;;;799:1;796;789:12;814:158;882:20;;942:4;931:16;;921:27;;911:2;;962:1;959;952:12;977:259;;1089:2;1077:9;1068:7;1064:23;1060:32;1057:2;;;1110:6;1102;1095:22;1057:2;1154:9;1141:23;1173:33;1200:5;1173:33;:::i;1241:402::-;;;1370:2;1358:9;1349:7;1345:23;1341:32;1338:2;;;1391:6;1383;1376:22;1338:2;1435:9;1422:23;1454:33;1481:5;1454:33;:::i;:::-;1506:5;-1:-1:-1;1563:2:26;1548:18;;1535:32;1576:35;1535:32;1576:35;:::i;:::-;1630:7;1620:17;;;1328:315;;;;;:::o;1648:470::-;;;;1794:2;1782:9;1773:7;1769:23;1765:32;1762:2;;;1815:6;1807;1800:22;1762:2;1859:9;1846:23;1878:33;1905:5;1878:33;:::i;:::-;1930:5;-1:-1:-1;1987:2:26;1972:18;;1959:32;2000:35;1959:32;2000:35;:::i;:::-;1752:366;;2054:7;;-1:-1:-1;;;2108:2:26;2093:18;;;;2080:32;;1752:366::o;2123:1316::-;;;;;2295:3;2283:9;2274:7;2270:23;2266:33;2263:2;;;2317:6;2309;2302:22;2263:2;2361:9;2348:23;2380:33;2407:5;2380:33;:::i;:::-;2432:5;-1:-1:-1;2456:2:26;2495:18;;;2482:32;2523:35;2482:32;2523:35;:::i;:::-;2577:7;-1:-1:-1;2631:2:26;2616:18;;2603:32;;-1:-1:-1;2686:2:26;2671:18;;2658:32;-1:-1:-1;;;;;2739:14:26;;;2736:2;;;2771:6;2763;2756:22;2736:2;2814:6;2803:9;2799:22;2789:32;;2859:7;2852:4;2848:2;2844:13;2840:27;2830:2;;2886:6;2878;2871:22;2830:2;2931;2918:16;2957:2;2949:6;2946:14;2943:2;;;2963:9;2943:2;3003;2997:9;3076:2;3053:17;;-1:-1:-1;;3049:31:26;3037:44;;3033:53;;3101:18;;;3121:22;;;3098:46;3095:2;;;3147:9;3095:2;3174;3167:22;3198;;;3239:15;;;3235:24;;3232:37;-1:-1:-1;3229:2:26;;;3287:6;3279;3272:22;3229:2;3348:6;3343:2;3339;3335:11;3330:2;3322:6;3318:15;3305:50;3375:19;;;3371:28;;;3364:44;;;;-1:-1:-1;2253:1186:26;;;;-1:-1:-1;2253:1186:26;;-1:-1:-1;;2253:1186:26:o;3444:438::-;;;3570:2;3558:9;3549:7;3545:23;3541:32;3538:2;;;3591:6;3583;3576:22;3538:2;3635:9;3622:23;3654:33;3681:5;3654:33;:::i;:::-;3706:5;-1:-1:-1;3763:2:26;3748:18;;3735:32;3805:15;;3798:23;3786:36;;3776:2;;3841:6;3833;3826:22;3887:327;;;4016:2;4004:9;3995:7;3991:23;3987:32;3984:2;;;4037:6;4029;4022:22;3984:2;4081:9;4068:23;4100:33;4127:5;4100:33;:::i;:::-;4152:5;4204:2;4189:18;;;;4176:32;;-1:-1:-1;;;3974:240:26:o;4219:655::-;;;;;;4394:3;4382:9;4373:7;4369:23;4365:33;4362:2;;;4416:6;4408;4401:22;4362:2;4460:9;4447:23;4479:33;4506:5;4479:33;:::i;:::-;4531:5;-1:-1:-1;4583:2:26;4568:18;;4555:32;;-1:-1:-1;4606:38:26;4640:2;4625:18;;4606:38;:::i;:::-;4596:48;;4663:38;4697:2;4686:9;4682:18;4663:38;:::i;:::-;4653:48;;4753:3;4742:9;4738:19;4725:33;4802:10;4793:7;4789:24;4780:7;4777:37;4767:2;;4833:6;4825;4818:22;4767:2;4861:7;4851:17;;;4352:522;;;;;;;;:::o;4879:843::-;;;;;5090:2;5078:9;5069:7;5065:23;5061:32;5058:2;;;5111:6;5103;5096:22;5058:2;5156:9;5143:23;-1:-1:-1;;;;;5226:2:26;5218:6;5215:14;5212:2;;;5247:6;5239;5232:22;5212:2;5291:84;5367:7;5358:6;5347:9;5343:22;5291:84;:::i;:::-;5394:8;;-1:-1:-1;5265:110:26;-1:-1:-1;5482:2:26;5467:18;;5454:32;;-1:-1:-1;5498:16:26;;;5495:2;;;5532:6;5524;5517:22;5495:2;;5576:86;5654:7;5643:8;5632:9;5628:24;5576:86;:::i;:::-;5048:674;;;;-1:-1:-1;5681:8:26;-1:-1:-1;;;;5048:674:26:o;5727:306::-;;5838:2;5826:9;5817:7;5813:23;5809:32;5806:2;;;5859:6;5851;5844:22;5806:2;5890:23;;-1:-1:-1;;;;;;5942:32:26;;5932:43;;5922:2;;5994:6;5986;5979:22;6038:417;;;6182:2;6170:9;6161:7;6157:23;6153:32;6150:2;;;6203:6;6195;6188:22;6460:190;;6572:2;6560:9;6551:7;6547:23;6543:32;6540:2;;;6593:6;6585;6578:22;6540:2;-1:-1:-1;6621:23:26;;6530:120;-1:-1:-1;6530:120:26:o;6655:501::-;;;;6804:2;6792:9;6783:7;6779:23;6775:32;6772:2;;;6825:6;6817;6810:22;6772:2;6866:9;6853:23;6843:33;;6927:2;6916:9;6912:18;6899:32;-1:-1:-1;;;;;6946:6:26;6943:30;6940:2;;;6991:6;6983;6976:22;6940:2;7035:61;7088:7;7079:6;7068:9;7064:22;7035:61;:::i;:::-;6762:394;;7115:8;;-1:-1:-1;7009:87:26;;-1:-1:-1;;;;6762:394:26:o;7161:711::-;;;;;;;7359:3;7347:9;7338:7;7334:23;7330:33;7327:2;;;7381:6;7373;7366:22;7327:2;7422:9;7409:23;7399:33;;7483:2;7472:9;7468:18;7455:32;-1:-1:-1;;;;;7502:6:26;7499:30;7496:2;;;7547:6;7539;7532:22;7496:2;7591:61;7644:7;7635:6;7624:9;7620:22;7591:61;:::i;:::-;7671:8;;-1:-1:-1;7565:87:26;-1:-1:-1;7725:38:26;;-1:-1:-1;7759:2:26;7744:18;;7725:38;:::i;:::-;7715:48;;7810:2;7799:9;7795:18;7782:32;7772:42;;7861:3;7850:9;7846:19;7833:33;7823:43;;7317:555;;;;;;;;:::o;7877:478::-;;7959:5;7953:12;7986:6;7981:3;7974:19;8011:3;8023:162;8037:6;8034:1;8031:13;8023:162;;;8099:4;8155:13;;;8151:22;;8145:29;8127:11;;;8123:20;;8116:59;8052:12;8023:162;;;8203:6;8200:1;8197:13;8194:2;;;8269:3;8262:4;8253:6;8248:3;8244:16;8240:27;8233:40;8194:2;-1:-1:-1;8337:2:26;8316:15;-1:-1:-1;;8312:29:26;8303:39;;;;8344:4;8299:50;;7929:426;-1:-1:-1;;7929:426:26:o;8360:203::-;-1:-1:-1;;;;;8524:32:26;;;;8506:51;;8494:2;8479:18;;8461:102::o;8568:635::-;8739:2;8791:21;;;8861:13;;8764:18;;;8883:22;;;8568:635;;8739:2;8962:15;;;;8936:2;8921:18;;;8568:635;9008:169;9022:6;9019:1;9016:13;9008:169;;;9083:13;;9071:26;;9152:15;;;;9117:12;;;;9044:1;9037:9;9008:169;;;-1:-1:-1;9194:3:26;;8719:484;-1:-1:-1;;;;;;8719:484:26:o;9208:187::-;9373:14;;9366:22;9348:41;;9336:2;9321:18;;9303:92::o;9400:177::-;9546:25;;;9534:2;9519:18;;9501:76::o;9582:398::-;9809:25;;;9882:4;9870:17;;;;9865:2;9850:18;;9843:45;9919:2;9904:18;;9897:34;9962:2;9947:18;;9940:34;9796:3;9781:19;;9763:217::o;9985:662::-;;10265:2;10257:6;10254:14;10244:2;;10272:9;10244:2;10310:6;10299:9;10292:25;10347:1;10339:6;10336:13;10326:2;;10353:9;10326:2;10400:6;10395:2;10384:9;10380:18;10373:34;10455:10;10447:6;10443:23;10438:2;10427:9;10423:18;10416:51;-1:-1:-1;;;;;10507:6:26;10503:31;10498:2;10487:9;10483:18;10476:59;10572:3;10566;10555:9;10551:19;10544:32;10593:48;10636:3;10625:9;10621:19;10613:6;10593:48;:::i;10652:222::-;;10801:2;10790:9;10783:21;10821:47;10864:2;10853:9;10849:18;10841:6;10821:47;:::i;10879:411::-;11081:2;11063:21;;;11120:2;11100:18;;;11093:30;11159:34;11154:2;11139:18;;11132:62;-1:-1:-1;;;11225:2:26;11210:18;;11203:45;11280:3;11265:19;;11053:237::o;11295:341::-;11497:2;11479:21;;;11536:2;11516:18;;;11509:30;-1:-1:-1;;;11570:2:26;11555:18;;11548:47;11627:2;11612:18;;11469:167::o;11641:410::-;11843:2;11825:21;;;11882:2;11862:18;;;11855:30;11921:34;11916:2;11901:18;;11894:62;-1:-1:-1;;;11987:2:26;11972:18;;11965:44;12041:3;12026:19;;11815:236::o;12056:413::-;12258:2;12240:21;;;12297:2;12277:18;;;12270:30;12336:34;12331:2;12316:18;;12309:62;-1:-1:-1;;;12402:2:26;12387:18;;12380:47;12459:3;12444:19;;12230:239::o;12474:350::-;12676:2;12658:21;;;12715:2;12695:18;;;12688:30;12754:28;12749:2;12734:18;;12727:56;12815:2;12800:18;;12648:176::o;12829:355::-;13031:2;13013:21;;;13070:2;13050:18;;;13043:30;13109:33;13104:2;13089:18;;13082:61;13175:2;13160:18;;13003:181::o;13371:464::-;;13558:6;13547:9;13540:25;13601:2;13596;13585:9;13581:18;13574:30;13640:6;13635:2;13624:9;13620:18;13613:34;13697:6;13689;13684:2;13673:9;13669:18;13656:48;13724:22;;;13748:2;13720:31;;;13713:45;;;;13819:2;13798:15;;;-1:-1:-1;;13794:29:26;13779:45;13775:54;;13530:305;-1:-1:-1;;13530:305:26:o;13840:262::-;14036:4;14024:17;;;14006:36;;14078:17;;14073:2;14058:18;;14051:45;13994:2;13979:18;;13961:141::o;14107:534::-;;;14251:11;14238:25;14345:2;14341:7;14330:8;14314:14;14310:29;14306:43;14286:18;14282:68;14272:2;;14367:4;14361;14354:18;14272:2;14397:33;;14449:20;;;-1:-1:-1;;;;;;14481:30:26;;14478:2;;;14527:4;14521;14514:18;14478:2;14563:4;14551:17;;-1:-1:-1;14594:14:26;14590:27;;;14580:38;;14577:2;;;14631:1;14628;14621:12;14646:133;-1:-1:-1;;;;;14723:31:26;;14713:42;;14703:2;;14769:1;14766;14759:12;14703:2;14693:86;:::o

Swarm Source

ipfs://308c7d0f38216f626771d86f2b5b3091893bd5f12659a801a1f13db0060ec78f
Loading...
Loading
Loading...
Loading
[ Download: CSV Export  ]
[ Download: CSV Export  ]

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