ETH Price: $3,874.75 (-1.94%)

Token

Gods Unchained Cards (CARD)
 

Overview

Max Total Supply

6,972,003 CARD

Holders

15,571

Total Transfers

-

Market

Volume (24H)

N/A

Min Price (24H)

N/A

Max Price (24H)

N/A
Loading...
Loading
Loading...
Loading
Loading...
Loading

OVERVIEW

A TCG on the Ethereum blockchain that uses NFT's to bring real ownership to in-game assets.

# Exchange Pair Price  24H Volume % Volume

Contract Source Code Verified (Exact Match)

Contract Name:
BatchWrapper

Compiler Version
v0.5.11+commit.c082d0b4

Optimization Enabled:
Yes with 200 runs

Other Settings:
default evmVersion

Contract Source Code (Solidity)

/**
 *Submitted for verification at Etherscan.io on 2019-11-16
*/

pragma solidity 0.5.11;

/**
 * @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, 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) {
        return sub(a, b, "SafeMath: subtraction overflow");
    }

    /**
     * @dev Returns the subtraction of two unsigned integers, reverting with custom message on
     * overflow (when the result is negative).
     *
     * Counterpart to Solidity's `-` operator.
     *
     * Requirements:
     * - Subtraction cannot overflow.
     *
     * _Available since v2.4.0._
     */
    function sub(uint256 a, uint256 b, string memory errorMessage) internal pure returns (uint256) {
        require(b <= a, errorMessage);
        uint256 c = a - b;

        return c;
    }

    /**
     * @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) {
        // 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 0;
        }

        uint256 c = a * b;
        require(c / a == b, "SafeMath: multiplication overflow");

        return c;
    }

    /**
     * @dev Returns the integer division of two unsigned integers. Reverts 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) {
        return div(a, b, "SafeMath: division by zero");
    }

    /**
     * @dev Returns the integer division of two unsigned integers. Reverts with custom message 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.
     *
     * _Available since v2.4.0._
     */
    function div(uint256 a, uint256 b, string memory errorMessage) internal pure returns (uint256) {
        // Solidity only automatically asserts when dividing by 0
        require(b > 0, errorMessage);
        uint256 c = a / b;
        // assert(a == b * c + a % b); // There is no case in which this doesn't hold

        return c;
    }

    /**
     * @dev Returns the remainder of dividing two unsigned integers. (unsigned integer modulo),
     * Reverts 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) {
        return mod(a, b, "SafeMath: modulo by zero");
    }

    /**
     * @dev Returns the remainder of dividing two unsigned integers. (unsigned integer modulo),
     * Reverts with custom message 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.
     *
     * _Available since v2.4.0._
     */
    function mod(uint256 a, uint256 b, string memory errorMessage) internal pure returns (uint256) {
        require(b != 0, errorMessage);
        return a % b;
    }
}


contract InscribableToken {

    mapping(bytes32 => bytes32) public properties;

    event ClassPropertySet(
        bytes32 indexed key,
        bytes32 value
    );

    event TokenPropertySet(
        uint indexed id,
        bytes32 indexed key,
        bytes32 value
    );

    function _setProperty(
        uint _id,
        bytes32 _key,
        bytes32 _value
    )
        internal
    {
        properties[getTokenKey(_id, _key)] = _value;
        emit TokenPropertySet(_id, _key, _value);
    }

    function getProperty(
        uint _id,
        bytes32 _key
    )
        public
        view
        returns (bytes32 _value)
    {
        return properties[getTokenKey(_id, _key)];
    }

    function _setClassProperty(
        bytes32 _key,
        bytes32 _value
    )
        internal
    {
        emit ClassPropertySet(_key, _value);
        properties[getClassKey(_key)] = _value;
    }

    function getTokenKey(
        uint _tokenId,
        bytes32 _key
    )
        public
        pure
        returns (bytes32)
    {
        // one prefix to prevent collisions
        return keccak256(abi.encodePacked(uint(1), _tokenId, _key));
    }

    function getClassKey(bytes32 _key)
        public
        pure
        returns (bytes32)
    {
        // zero prefix to prevent collisions
        return keccak256(abi.encodePacked(uint(0), _key));
    }

    function getClassProperty(bytes32 _key)
        public
        view
        returns (bytes32)
    {
        return properties[getClassKey(_key)];
    }

}



library String {

    /**
     * @dev Converts a `uint256` to a `string`.
     * via OraclizeAPI - MIT licence
     * https://github.com/oraclize/ethereum-api/blob/b42146b063c7d6ee1358846c198246239e9360e8/oraclizeAPI_0.4.25.sol
     */
    function fromUint(uint256 value) internal pure returns (string memory) {
        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--] = byte(uint8(48 + temp % 10));
            temp /= 10;
        }
        return string(buffer);
    }

    bytes constant alphabet = "0123456789abcdef";

    function fromAddress(address _addr) internal pure returns(string memory) {
        bytes32 value = bytes32(uint256(_addr));
        bytes memory str = new bytes(42);
        str[0] = '0';
        str[1] = 'x';
        for (uint i = 0; i < 20; i++) {
            str[2+i*2] = alphabet[uint(uint8(value[i + 12] >> 4))];
            str[3+i*2] = alphabet[uint(uint8(value[i + 12] & 0x0F))];
        }
        return string(str);
    }

}

// solium-disable security/no-inline-assembly


library StorageWrite {

    using SafeMath for uint256;

    function _getStorageArraySlot(uint _dest, uint _index) internal view returns (uint result) {
        uint slot = _getArraySlot(_dest, _index);
        assembly { result := sload(slot) }
    }

    function _getArraySlot(uint _dest, uint _index) internal pure returns (uint slot) {
        assembly {
            let free := mload(0x40)
            mstore(free, _dest)
            slot := add(keccak256(free, 32), _index)
        }
    }

    function _setArraySlot(uint _dest, uint _index, uint _value) internal {
        uint slot = _getArraySlot(_dest, _index);
        assembly { sstore(slot, _value) }
    }

    function _loadSlots(
        uint _slot,
        uint _offset,
        uint _perSlot,
        uint _length
    )
        internal
        view
        returns (uint[] memory slots)
    {
        uint slotCount = _slotCount(_offset, _perSlot, _length);
        slots = new uint[](slotCount);
        // top and tail the slots
        uint firstPos = _pos(_offset, _perSlot); // _offset.div(_perSlot);
        slots[0] = _getStorageArraySlot(_slot, firstPos);
        if (slotCount > 1) {
            uint lastPos = _pos(_offset.add(_length), _perSlot); // .div(_perSlot);
            slots[slotCount-1] = _getStorageArraySlot(_slot, lastPos);
        }
    }

    function _pos(uint items, uint perPage) internal pure returns (uint) {
        return items / perPage;
    }

    function _slotCount(uint _offset, uint _perSlot, uint _length) internal pure returns (uint) {
        uint start = _offset / _perSlot;
        uint end = (_offset + _length) / _perSlot;
        return (end - start) + 1;
    }

    function _saveSlots(uint _slot, uint _offset, uint _size, uint[] memory _slots) internal {
        uint offset = _offset.div((256/_size));
        for (uint i = 0; i < _slots.length; i++) {
            _setArraySlot(_slot, offset + i, _slots[i]);
        }
    }

    function _write(uint[] memory _slots, uint _offset, uint _size, uint _index, uint _value) internal pure {
        uint perSlot = 256 / _size;
        uint initialOffset = _offset % perSlot;
        uint slotPosition = (initialOffset + _index) / perSlot;
        uint withinSlot = ((_index + _offset) % perSlot) * _size;
        // evil bit shifting magic
        for (uint q = 0; q < _size; q += 8) {
            _slots[slotPosition] |= ((_value >> q) & 0xFF) << (withinSlot + q);
        }
    }

    function repeatUint16(uint _slot, uint _offset, uint _length, uint16 _item) internal {
        uint[] memory slots = _loadSlots(_slot, _offset, 16, _length);
        for (uint i = 0; i < _length; i++) {
            _write(slots, _offset, 16, i, _item);
        }
        _saveSlots(_slot, _offset, 16, slots);
    }

    function uint16s(uint _slot, uint _offset, uint16[] memory _items) internal {
        uint[] memory slots = _loadSlots(_slot, _offset, 16, _items.length);
        for (uint i = 0; i < _items.length; i++) {
            _write(slots, _offset, 16, i, _items[i]);
        }
        _saveSlots(_slot, _offset, 16, slots);
    }

    function uint8s(uint _slot, uint _offset, uint8[] memory _items) internal {
        uint[] memory slots = _loadSlots(_slot, _offset, 32, _items.length);
        for (uint i = 0; i < _items.length; i++) {
            _write(slots, _offset, 8, i, _items[i]);
        }
        _saveSlots(_slot, _offset, 8, slots);
    }

}

contract ImmutableToken {

    string public constant baseURI = "https://api.immutable.com/asset/";

    function tokenURI(uint256 tokenId) external view returns (string memory) {
        return string(abi.encodePacked(
            baseURI,
            String.fromAddress(address(this)),
            "/",
            String.fromUint(tokenId)
        ));
    }

}

/*
 * @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.
 */
contract Context {
    // Empty internal constructor, to prevent people from mistakenly deploying
    // an instance of this contract, which should be used via inheritance.
    constructor () internal { }
    // solhint-disable-previous-line no-empty-blocks

    function _msgSender() internal view returns (address payable) {
        return msg.sender;
    }

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


/**
 * @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);
}


/**
 * @dev Implementation of the {IERC165} interface.
 *
 * Contracts may inherit from this and call {_registerInterface} to declare
 * their support of an interface.
 */
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) external view 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 {
        require(interfaceId != 0xffffffff, "ERC165: invalid interface id");
        _supportedInterfaces[interfaceId] = true;
    }
}


/**
 * @title ERC721 token receiver interface
 * @dev Interface for any contract that wants to support safeTransfers
 * from ERC721 asset contracts.
 */
contract IERC721Receiver {
    /**
     * @notice Handle the receipt of an NFT
     * @dev The ERC721 smart contract calls this function on the recipient
     * after a {IERC721-safeTransferFrom}. This function MUST return the function selector,
     * otherwise the caller will revert the transaction. The selector to be
     * returned can be obtained as `this.onERC721Received.selector`. This
     * function MAY throw to revert and reject the transfer.
     * Note: the ERC721 contract address is always the message sender.
     * @param operator The address which called `safeTransferFrom` function
     * @param from The address which previously owned the token
     * @param tokenId The NFT identifier which is being transferred
     * @param data Additional data with no specified format
     * @return bytes4 `bytes4(keccak256("onERC721Received(address,address,uint256,bytes)"))`
     */
    function onERC721Received(address operator, address from, uint256 tokenId, bytes memory data)
    public returns (bytes4);
}


/**
 * @dev Collection of functions related to the address type
 */
library Address {
    /**
     * @dev Returns true if `account` is a contract.
     *
     * This test is non-exhaustive, and there may be false-negatives: during the
     * execution of a contract's constructor, its address will be reported as
     * not containing 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.
     */
    function isContract(address account) internal view returns (bool) {
        // This method relies in extcodesize, which returns 0 for contracts in
        // construction, since the code is only stored at the end of the
        // constructor execution.

        // According to EIP-1052, 0x0 is the value returned for not-yet created accounts
        // and 0xc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470 is returned
        // for accounts without code, i.e. `keccak256('')`
        bytes32 codehash;
        bytes32 accountHash = 0xc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470;
        // solhint-disable-next-line no-inline-assembly
        assembly { codehash := extcodehash(account) }
        return (codehash != 0x0 && codehash != accountHash);
    }

    /**
     * @dev Converts an `address` into `address payable`. Note that this is
     * simply a type cast: the actual underlying value is not changed.
     *
     * _Available since v2.4.0._
     */
    function toPayable(address account) internal pure returns (address payable) {
        return address(uint160(account));
    }

    /**
     * @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].
     *
     * _Available since v2.4.0._
     */
    function sendValue(address payable recipient, uint256 amount) internal {
        require(address(this).balance >= amount, "Address: insufficient balance");

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


/**
 * @title Counters
 * @author Matt Condon (@shrugs)
 * @dev Provides counters that can only be incremented or decremented by one. This can be used e.g. to track the number
 * of elements in a mapping, issuing ERC721 ids, or counting request ids.
 *
 * Include with `using Counters for Counters.Counter;`
 * Since it is not possible to overflow a 256 bit integer with increments of one, `increment` can skip the {SafeMath}
 * overflow check, thereby saving gas. This does assume however correct usage, in that the underlying `_value` is never
 * directly accessed.
 */
library Counters {
    using SafeMath for uint256;

    struct Counter {
        // This variable should never be directly accessed by users of the library: interactions must be restricted to
        // the library's function. As of Solidity v0.5.2, this cannot be enforced, though there is a proposal to add
        // this feature: see https://github.com/ethereum/solidity/issues/4637
        uint256 _value; // default: 0
    }

    function current(Counter storage counter) internal view returns (uint256) {
        return counter._value;
    }

    function increment(Counter storage counter) internal {
        counter._value += 1;
    }

    function decrement(Counter storage counter) internal {
        counter._value = counter._value.sub(1);
    }
}

/**
 * @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.
 *
 * 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.
 */
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 {
        _owner = _msgSender();
        emit OwnershipTransferred(address(0), _owner);
    }

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

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

    /**
     * @dev Returns true if the caller is the current owner.
     */
    function isOwner() public view returns (bool) {
        return _msgSender() == _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 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 onlyOwner {
        _transferOwnership(newOwner);
    }

    /**
     * @dev Transfers ownership of the contract to a new account (`newOwner`).
     */
    function _transferOwnership(address newOwner) internal {
        require(newOwner != address(0), "Ownable: new owner is the zero address");
        emit OwnershipTransferred(_owner, newOwner);
        _owner = newOwner;
    }
}


/**
 * @dev Required interface of an ERC721 compliant contract.
 */
contract IERC721 is IERC165 {
    event Transfer(address indexed from, address indexed to, uint256 indexed tokenId);
    event Approval(address indexed owner, address indexed approved, uint256 indexed tokenId);
    event ApprovalForAll(address indexed owner, address indexed operator, bool approved);

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

    /**
     * @dev Returns the owner of the NFT specified by `tokenId`.
     */
    function ownerOf(uint256 tokenId) public view returns (address owner);

    /**
     * @dev Transfers a specific NFT (`tokenId`) from one account (`from`) to
     * another (`to`).
     *
     *
     *
     * Requirements:
     * - `from`, `to` cannot be zero.
     * - `tokenId` must be owned by `from`.
     * - If the caller is not `from`, it must be have been allowed to move this
     * NFT by either {approve} or {setApprovalForAll}.
     */
    function safeTransferFrom(address from, address to, uint256 tokenId) public;
    /**
     * @dev Transfers a specific NFT (`tokenId`) from one account (`from`) to
     * another (`to`).
     *
     * Requirements:
     * - If the caller is not `from`, it must be approved to move this NFT by
     * either {approve} or {setApprovalForAll}.
     */
    function transferFrom(address from, address to, uint256 tokenId) public;
    function approve(address to, uint256 tokenId) public;
    function getApproved(uint256 tokenId) public view returns (address operator);

    function setApprovalForAll(address operator, bool _approved) public;
    function isApprovedForAll(address owner, address operator) public view returns (bool);


    function safeTransferFrom(address from, address to, uint256 tokenId, bytes memory data) public;
}








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

    // 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 token ID to owner
    mapping (uint256 => address) private _tokenOwner;

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

    // Mapping from owner to number of owned token
    mapping (address => Counters.Counter) private _ownedTokensCount;

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

    /*
     *     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 ^ 0xe985e9c ^ 0x23b872dd ^ 0x42842e0e ^ 0xb88d4fde == 0x80ac58cd
     */
    bytes4 private constant _INTERFACE_ID_ERC721 = 0x80ac58cd;

    constructor () public {
        // register the supported interfaces to conform to ERC721 via ERC165
        _registerInterface(_INTERFACE_ID_ERC721);
    }

    /**
     * @dev Gets the balance of the specified address.
     * @param owner address to query the balance of
     * @return uint256 representing the amount owned by the passed address
     */
    function balanceOf(address owner) public view returns (uint256) {
        require(owner != address(0), "ERC721: balance query for the zero address");

        return _ownedTokensCount[owner].current();
    }

    /**
     * @dev Gets the owner of the specified token ID.
     * @param tokenId uint256 ID of the token to query the owner of
     * @return address currently marked as the owner of the given token ID
     */
    function ownerOf(uint256 tokenId) public view returns (address) {
        address owner = _tokenOwner[tokenId];
        require(owner != address(0), "ERC721: owner query for nonexistent token");

        return owner;
    }

    /**
     * @dev Approves another address to transfer the given token ID
     * The zero address indicates there is no approved address.
     * There can only be one approved address per token at a given time.
     * Can only be called by the token owner or an approved operator.
     * @param to address to be approved for the given token ID
     * @param tokenId uint256 ID of the token to be approved
     */
    function approve(address to, uint256 tokenId) public {
        address owner = ownerOf(tokenId);
        require(to != owner, "ERC721: approval to current owner");

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

        _tokenApprovals[tokenId] = to;
        emit Approval(owner, to, tokenId);
    }

    /**
     * @dev Gets the approved address for a token ID, or zero if no address set
     * Reverts if the token ID does not exist.
     * @param tokenId uint256 ID of the token to query the approval of
     * @return address currently approved for the given token ID
     */
    function getApproved(uint256 tokenId) public view returns (address) {
        require(_exists(tokenId), "ERC721: approved query for nonexistent token");

        return _tokenApprovals[tokenId];
    }

    /**
     * @dev Sets or unsets the approval of a given operator
     * An operator is allowed to transfer all tokens of the sender on their behalf.
     * @param to operator address to set the approval
     * @param approved representing the status of the approval to be set
     */
    function setApprovalForAll(address to, bool approved) public {
        require(to != _msgSender(), "ERC721: approve to caller");

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

    /**
     * @dev Tells whether an operator is approved by a given owner.
     * @param owner owner address which you want to query the approval of
     * @param operator operator address which you want to query the approval of
     * @return bool whether the given operator is approved by the given owner
     */
    function isApprovedForAll(address owner, address operator) public view returns (bool) {
        return _operatorApprovals[owner][operator];
    }

    /**
     * @dev Transfers the ownership of a given token ID to another address.
     * Usage of this method is discouraged, use {safeTransferFrom} whenever possible.
     * Requires the msg.sender to be the owner, approved, or operator.
     * @param from current owner of the token
     * @param to address to receive the ownership of the given token ID
     * @param tokenId uint256 ID of the token to be transferred
     */
    function transferFrom(address from, address to, uint256 tokenId) public {
        //solhint-disable-next-line max-line-length
        require(_isApprovedOrOwner(_msgSender(), tokenId), "ERC721: transfer caller is not owner nor approved");

        _transferFrom(from, to, tokenId);
    }

    /**
     * @dev Safely transfers the ownership of a given token ID to another address
     * If the target address is a contract, it must implement {IERC721Receiver-onERC721Received},
     * which is called upon a safe transfer, and return the magic value
     * `bytes4(keccak256("onERC721Received(address,address,uint256,bytes)"))`; otherwise,
     * the transfer is reverted.
     * Requires the msg.sender to be the owner, approved, or operator
     * @param from current owner of the token
     * @param to address to receive the ownership of the given token ID
     * @param tokenId uint256 ID of the token to be transferred
     */
    function safeTransferFrom(address from, address to, uint256 tokenId) public {
        safeTransferFrom(from, to, tokenId, "");
    }

    /**
     * @dev Safely transfers the ownership of a given token ID to another address
     * If the target address is a contract, it must implement {IERC721Receiver-onERC721Received},
     * which is called upon a safe transfer, and return the magic value
     * `bytes4(keccak256("onERC721Received(address,address,uint256,bytes)"))`; otherwise,
     * the transfer is reverted.
     * Requires the _msgSender() to be the owner, approved, or operator
     * @param from current owner of the token
     * @param to address to receive the ownership of the given token ID
     * @param tokenId uint256 ID of the token to be transferred
     * @param _data bytes data to send along with a safe transfer check
     */
    function safeTransferFrom(address from, address to, uint256 tokenId, bytes memory _data) public {
        require(_isApprovedOrOwner(_msgSender(), tokenId), "ERC721: transfer caller is not owner nor approved");
        _safeTransferFrom(from, to, tokenId, _data);
    }

    /**
     * @dev Safely transfers the ownership of a given token ID to another address
     * If the target address is a contract, it must implement `onERC721Received`,
     * which is called upon a safe transfer, and return the magic value
     * `bytes4(keccak256("onERC721Received(address,address,uint256,bytes)"))`; otherwise,
     * the transfer is reverted.
     * Requires the msg.sender to be the owner, approved, or operator
     * @param from current owner of the token
     * @param to address to receive the ownership of the given token ID
     * @param tokenId uint256 ID of the token to be transferred
     * @param _data bytes data to send along with a safe transfer check
     */
    function _safeTransferFrom(address from, address to, uint256 tokenId, bytes memory _data) internal {
        _transferFrom(from, to, tokenId);
        require(_checkOnERC721Received(from, to, tokenId, _data), "ERC721: transfer to non ERC721Receiver implementer");
    }

    /**
     * @dev Returns whether the specified token exists.
     * @param tokenId uint256 ID of the token to query the existence of
     * @return bool whether the token exists
     */
    function _exists(uint256 tokenId) internal view returns (bool) {
        address owner = _tokenOwner[tokenId];
        return owner != address(0);
    }

    /**
     * @dev Returns whether the given spender can transfer a given token ID.
     * @param spender address of the spender to query
     * @param tokenId uint256 ID of the token to be transferred
     * @return bool whether the msg.sender is approved for the given token ID,
     * is an operator of the owner, or is the owner of the token
     */
    function _isApprovedOrOwner(address spender, uint256 tokenId) internal view returns (bool) {
        require(_exists(tokenId), "ERC721: operator query for nonexistent token");
        address owner = ownerOf(tokenId);
        return (spender == owner || getApproved(tokenId) == spender || isApprovedForAll(owner, spender));
    }

    /**
     * @dev Internal function to safely mint a new token.
     * Reverts if the given token ID already exists.
     * If the target address is a contract, it must implement `onERC721Received`,
     * which is called upon a safe transfer, and return the magic value
     * `bytes4(keccak256("onERC721Received(address,address,uint256,bytes)"))`; otherwise,
     * the transfer is reverted.
     * @param to The address that will own the minted token
     * @param tokenId uint256 ID of the token to be minted
     */
    function _safeMint(address to, uint256 tokenId) internal {
        _safeMint(to, tokenId, "");
    }

    /**
     * @dev Internal function to safely mint a new token.
     * Reverts if the given token ID already exists.
     * If the target address is a contract, it must implement `onERC721Received`,
     * which is called upon a safe transfer, and return the magic value
     * `bytes4(keccak256("onERC721Received(address,address,uint256,bytes)"))`; otherwise,
     * the transfer is reverted.
     * @param to The address that will own the minted token
     * @param tokenId uint256 ID of the token to be minted
     * @param _data bytes data to send along with a safe transfer check
     */
    function _safeMint(address to, uint256 tokenId, bytes memory _data) internal {
        _mint(to, tokenId);
        require(_checkOnERC721Received(address(0), to, tokenId, _data), "ERC721: transfer to non ERC721Receiver implementer");
    }

    /**
     * @dev Internal function to mint a new token.
     * Reverts if the given token ID already exists.
     * @param to The address that will own the minted token
     * @param tokenId uint256 ID of the token to be minted
     */
    function _mint(address to, uint256 tokenId) internal {
        require(to != address(0), "ERC721: mint to the zero address");
        require(!_exists(tokenId), "ERC721: token already minted");

        _tokenOwner[tokenId] = to;
        _ownedTokensCount[to].increment();

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

    /**
     * @dev Internal function to burn a specific token.
     * Reverts if the token does not exist.
     * Deprecated, use {_burn} instead.
     * @param owner owner of the token to burn
     * @param tokenId uint256 ID of the token being burned
     */
    function _burn(address owner, uint256 tokenId) internal {
        require(ownerOf(tokenId) == owner, "ERC721: burn of token that is not own");

        _clearApproval(tokenId);

        _ownedTokensCount[owner].decrement();
        _tokenOwner[tokenId] = address(0);

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

    /**
     * @dev Internal function to burn a specific token.
     * Reverts if the token does not exist.
     * @param tokenId uint256 ID of the token being burned
     */
    function _burn(uint256 tokenId) internal {
        _burn(ownerOf(tokenId), tokenId);
    }

    /**
     * @dev Internal function to transfer ownership of a given token ID to another address.
     * As opposed to {transferFrom}, this imposes no restrictions on msg.sender.
     * @param from current owner of the token
     * @param to address to receive the ownership of the given token ID
     * @param tokenId uint256 ID of the token to be transferred
     */
    function _transferFrom(address from, address to, uint256 tokenId) internal {
        require(ownerOf(tokenId) == from, "ERC721: transfer of token that is not own");
        require(to != address(0), "ERC721: transfer to the zero address");

        _clearApproval(tokenId);

        _ownedTokensCount[from].decrement();
        _ownedTokensCount[to].increment();

        _tokenOwner[tokenId] = to;

        emit Transfer(from, to, tokenId);
    }

    /**
     * @dev Internal function to invoke {IERC721Receiver-onERC721Received} on a target address.
     * The call is not executed if the target address is not a contract.
     *
     * This function is deprecated.
     * @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)
        internal returns (bool)
    {
        if (!to.isContract()) {
            return true;
        }

        bytes4 retval = IERC721Receiver(to).onERC721Received(_msgSender(), from, tokenId, _data);
        return (retval == _ERC721_RECEIVED);
    }

    /**
     * @dev Private function to clear current approval of a given token ID.
     * @param tokenId uint256 ID of the token to be transferred
     */
    function _clearApproval(uint256 tokenId) private {
        if (_tokenApprovals[tokenId] != address(0)) {
            _tokenApprovals[tokenId] = address(0);
        }
    }
}


/**
 * @title ERC-721 Non-Fungible Token Standard, optional metadata extension
 * @dev See https://eips.ethereum.org/EIPS/eip-721
 */
contract IERC721Metadata is IERC721 {
    function name() external view returns (string memory);
    function symbol() external view returns (string memory);
    function tokenURI(uint256 tokenId) external view returns (string memory);
}


contract MultiTransfer is IERC721 {

    function transferBatch(
        address from,
        address to,
        uint256 start,
        uint256 end
    )
        public
    {
        for (uint i = start; i < end; i++) {
            transferFrom(from, to, i);
        }
    }

    function transferAllFrom(
        address from,
        address to,
        uint256[] memory tokenIDs
    )
        public
    {
        for (uint i = 0; i < tokenIDs.length; i++) {
            transferFrom(from, to, tokenIDs[i]);
        }
    }

    function safeTransferBatch(
        address from,
        address to,
        uint256 start,
        uint256 end
    )
        public
    {
        for (uint i = start; i < end; i++) {
            safeTransferFrom(from, to, i);
        }
    }

    function safeTransferAllFrom(
        address from,
        address to,
        uint256[] memory tokenIDs
    )
        public
    {
        for (uint i = 0; i < tokenIDs.length; i++) {
            safeTransferFrom(from, to, tokenIDs[i]);
        }
    }

}

contract ICards is IERC721 {

    struct Batch {
        uint48 userID;
        uint16 size;
    }

    function batches(uint index) public view returns (uint48 userID, uint16 size);

    function userIDToAddress(uint48 id) public view returns (address);

    function getDetails(
        uint tokenId
    )
        public
        view
        returns (
        uint16 proto,
        uint8 quality
    );

    function setQuality(
        uint tokenId,
        uint8 quality
    ) public;

    function mintCards(
        address to,
        uint16[] memory _protos,
        uint8[] memory _qualities
    )
        public
        returns (uint);

    function mintCard(
        address to,
        uint16 _proto,
        uint8 _quality
    )
        public
        returns (uint);

    function burn(uint tokenId) public;

    function batchSize()
        public
        view
        returns (uint);
}




contract ERC721Metadata is Context, ERC165, ERC721, IERC721Metadata {
    // Token name
    string private _name;

    // Token symbol
    string private _symbol;

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

    /*
     *     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;

    /**
     * @dev Constructor function
     */
    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_METADATA);
    }

    /**
     * @dev Gets the token name.
     * @return string representing the token name
     */
    function name() external view returns (string memory) {
        return _name;
    }

    /**
     * @dev Gets the token symbol.
     * @return string representing the token symbol
     */
    function symbol() external view returns (string memory) {
        return _symbol;
    }

    /**
     * @dev Returns an URI for a given token ID.
     * Throws if the token ID does not exist. May return an empty string.
     * @param tokenId uint256 ID of the token to query
     */
    function tokenURI(uint256 tokenId) external view returns (string memory) {
        require(_exists(tokenId), "ERC721Metadata: URI query for nonexistent token");
        return _tokenURIs[tokenId];
    }

    /**
     * @dev Internal function to set the token URI for a given token.
     * Reverts if the token ID does not exist.
     * @param tokenId uint256 ID of the token to set its URI
     * @param uri string URI to assign
     */
    function _setTokenURI(uint256 tokenId, string memory uri) internal {
        require(_exists(tokenId), "ERC721Metadata: URI set of nonexistent token");
        _tokenURIs[tokenId] = uri;
    }

    /**
     * @dev Internal function to burn a specific token.
     * Reverts if the token does not exist.
     * Deprecated, use _burn(uint256) instead.
     * @param owner owner of the token to burn
     * @param tokenId uint256 ID of the token being burned by the msg.sender
     */
    function _burn(address owner, uint256 tokenId) internal {
        super._burn(owner, tokenId);

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



contract BatchToken is ERC721Metadata {

    using SafeMath for uint256;

    struct Batch {
        uint48 userID;
        uint16 size;
    }

    mapping(uint48 => address) public userIDToAddress;
    mapping(address => uint48) public addressToUserID;

    uint256 public batchSize;
    uint256 public nextBatch;
    uint256 public tokenCount;

    uint48[] internal ownerIDs;
    uint48[] internal approvedIDs;

    mapping(uint => Batch) public batches;

    uint48 internal userCount = 1;

    mapping(address => uint) internal _balances;

    uint256 internal constant MAX_LENGTH = uint(2**256 - 1);

    constructor(
        uint256 _batchSize,
        string memory name,
        string memory symbol
    )
        public
        ERC721Metadata(name, symbol)
    {
        batchSize = _batchSize;
        ownerIDs.length = MAX_LENGTH;
        approvedIDs.length = MAX_LENGTH;
    }

    function _getUserID(address to)
        internal
        returns (uint48)
    {
        if (to == address(0)) {
            return 0;
        }
        uint48 uID = addressToUserID[to];
        if (uID == 0) {
            require(
                userCount + 1 > userCount,
                "BT: must not overflow"
            );
            uID = userCount++;
            userIDToAddress[uID] = to;
            addressToUserID[to] = uID;
        }
        return uID;
    }

    function _batchMint(
        address to,
        uint16 size
    )
        internal
        returns (uint)
    {
        require(
            to != address(0),
            "BT: must not be null"
        );

        require(
            size > 0 && size <= batchSize,
            "BT: size must be within limits"
        );

        uint256 start = nextBatch;
        uint48 uID = _getUserID(to);
        batches[start] = Batch({
            userID: uID,
            size: size
        });
        uint256 end = start.add(size);
        for (uint256 i = start; i < end; i++) {
            emit Transfer(address(0), to, i);
        }
        nextBatch = nextBatch.add(batchSize);
        _balances[to] = _balances[to].add(size);
        tokenCount = tokenCount.add(size);
        return start;
    }

    function getBatchStart(uint256 tokenId) public view returns (uint) {
        return tokenId.div(batchSize).mul(batchSize);
    }

    function getBatch(uint256 index) public view returns (uint48 userID, uint16 size) {
        return (batches[index].userID, batches[index].size);
    }

    // Overridden ERC721 functions
    // @OZ: please stop making variables/functions private

    function ownerOf(uint256 tokenId)
        public
        view
        returns (address)
    {
        uint48 uID = ownerIDs[tokenId];
        if (uID == 0) {
            uint256 start = getBatchStart(tokenId);
            Batch memory b = batches[start];

            require(
                start + b.size > tokenId,
                "BT: token does not exist"
            );

            uID = b.userID;
            require(
                uID != 0,
                "BT: bad batch owner"
            );
        }
        return userIDToAddress[uID];
    }

    function _transferFrom(
        address from,
        address to,
        uint256 tokenId
    )
        internal
    {
        require(
            ownerOf(tokenId) == from,
            "BT: transfer of token that is not own"
        );

        require(
            to != address(0),
            "BT: transfer to the zero address"
        );

        require(
            _isApprovedOrOwner(msg.sender, tokenId),
            "BT: caller is not owner nor approved"
        );

        _cancelApproval(tokenId);
        _balances[from] = _balances[from].sub(1);
        _balances[to] = _balances[to].add(1);
        ownerIDs[tokenId] = _getUserID(to);
        emit Transfer(from, to, tokenId);
    }

    function _burn(uint256 tokenId) internal {

        require(
            _isApprovedOrOwner(msg.sender, tokenId),
            "BT: caller is not owner nor approved"
        );

        _cancelApproval(tokenId);
        address owner = ownerOf(tokenId);
        _balances[owner] = _balances[owner].sub(1);
        ownerIDs[tokenId] = 0;
        tokenCount = tokenCount.sub(1);
        emit Transfer(owner, address(0), tokenId);
    }

    function _cancelApproval(uint256 tokenId) internal {
        if (approvedIDs[tokenId] != 0) {
            approvedIDs[tokenId] = 0;
        }
    }

    function approve(address to, uint256 tokenId) public {
        address owner = ownerOf(tokenId);

        require(
            to != owner,
            "BT: approval to current owner"
        );

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

        approvedIDs[tokenId] = _getUserID(to);
        emit Approval(owner, to, tokenId);
    }

    function _exists(uint256 tokenId)
        internal
        view
        returns (bool)
    {
        return ownerOf(tokenId) != address(0);
    }

    function getApproved(uint256 tokenId)
        public
        view
        returns (address)
    {
        require(
            _exists(tokenId),
            "BT: approved query for nonexistent token"
        );

        return userIDToAddress[approvedIDs[tokenId]];
    }

    function totalSupply()
        public
        view
        returns (uint)
    {
        return tokenCount;
    }

    function balanceOf(address _owner)
        public
        view
        returns (uint256)
    {
        return _balances[_owner];
    }

}

// solium-disable security/no-inline-assembly









contract NewCards is Ownable, MultiTransfer, BatchToken, InscribableToken {

    uint16 private constant MAX_UINT16 = 2**16 - 1;

    uint16[] internal cardProtos;
    uint8[] internal cardQualities;

    struct Season {
        uint16 high;
        uint16 low;
    }

    struct Proto {
        bool locked;
        bool exists;
        uint8 god;
        uint8 cardType;
        uint8 rarity;
        uint8 mana;
        uint8 attack;
        uint8 health;
        uint8 tribe;
    }

    event ProtoUpdated(
        uint16 indexed id
    );

    event SeasonStarted(
        uint16 indexed id,
        string name,
        uint16 indexed low,
        uint16 indexed high
    );

    event QualityChanged(
        uint256 indexed tokenId,
        uint8 quality,
        address factory
    );

    event CardsMinted(
        uint256 indexed start,
        address to,
        uint16[] protos,
        uint8[] qualities
    );

    // Value of index proto = season
    uint16[] public protoToSeason;

    address public propertyManager;

    // Array containing all protos
    Proto[] public protos;

    // Array containing all seasons
    Season[] public seasons;

    // Map whether a season is tradeable or not
    mapping(uint256 => bool) public seasonTradable;

    // Map whether a factory has been authorised or not
    mapping(address => mapping(uint256 => bool)) public factoryApproved;

    // Whether a factory is approved to create a particular mythic
    mapping(uint16 => mapping(address => bool)) public mythicApproved;

    // Whether a mythic is tradable
    mapping(uint16 => bool) public mythicTradable;

    // Map whether a mythic exists or not
    mapping(uint16 => bool) public mythicCreated;

    uint16 public constant MYTHIC_THRESHOLD = 65000;

    constructor(
        uint256 _batchSize,
        string memory _name,
        string memory _symbol
    )
        public
        BatchToken(_batchSize, _name, _symbol)
    {
        cardProtos.length = MAX_LENGTH;
        cardQualities.length = MAX_LENGTH;
        protoToSeason.length = MAX_LENGTH;
        protos.length = MAX_LENGTH;
        propertyManager = msg.sender;
    }

    function getDetails(
        uint256 tokenId
    )
        public
        view
        returns (uint16 proto, uint8 quality)
    {
        return (cardProtos[tokenId], cardQualities[tokenId]);
    }

    function mintCard(
        address to,
        uint16 _proto,
        uint8 _quality
    )
        public
        returns (uint id)
    {
        id = _batchMint(to, 1);
        _validateProto(_proto);
        cardProtos[id] = _proto;
        cardQualities[id] = _quality;

        uint16[] memory ps = new uint16[](1);
        ps[0] = _proto;

        uint8[] memory qs = new uint8[](1);
        qs[0] = _quality;

        emit CardsMinted(id, to, ps, qs);
        return id;
    }

    function mintCards(
        address to,
        uint16[] memory _protos,
        uint8[] memory _qualities
    )
        public
        returns (uint)
    {
        require(
            _protos.length > 0,
            "Core: must be some protos"
        );

        require(
            _protos.length == _qualities.length,
            "Core: must be the same number of protos/qualities"
        );

        uint256 start = _batchMint(to, uint16(_protos.length));
        _validateAndSaveDetails(start, _protos, _qualities);

        emit CardsMinted(start, to, _protos, _qualities);

        return start;
    }

    function addFactory(
        address _factory,
        uint256 _season
    )
        public
        onlyOwner
    {
        require(
            seasons.length >= _season,
            "Core: season must exist"
        );

        require(
            _season > 0,
            "Core: season must not be 0"
        );

        require(
            !factoryApproved[_factory][_season],
            "Core: this factory is already approved"
        );

        require(
            !seasonTradable[_season],
            "Core: season must not be tradable"
        );

        factoryApproved[_factory][_season] = true;
    }

    function approveForMythic(
        address _factory,
        uint16 _mythic
    )
        public
        onlyOwner
    {
        require(
            _mythic >= MYTHIC_THRESHOLD,
            "not a mythic"
        );

        require(
            !mythicApproved[_mythic][_factory],
            "Core: this factory is already approved for this mythic"
        );

        mythicApproved[_mythic][_factory] = true;
    }

    function makeMythicTradable(
        uint16 _mythic
    )
        public
        onlyOwner
    {
        require(
            _mythic >= MYTHIC_THRESHOLD,
            "Core: not a mythic"
        );

        require(
            !mythicTradable[_mythic],
            "Core: must not be tradable already"
        );

        mythicTradable[_mythic] = true;
    }

    function unlockTrading(
        uint256 _season
    )
        public
        onlyOwner
    {
        require(
            _season > 0 && _season <= seasons.length,
            "Core: must be a current season"
        );

        require(
            !seasonTradable[_season],
            "Core: season must not be tradable"
        );

        seasonTradable[_season] = true;
    }

    function _transferFrom(
        address from,
        address to,
        uint256 tokenId
    )
        internal
    {
        require(
            isTradable(tokenId),
            "Core: not yet tradable"
        );

        super._transferFrom(from, to, tokenId);
    }

    function burn(uint256 _tokenId) public {
        require(
            isTradable(_tokenId),
            "Core: not yet tradable"
        );

        super._burn(_tokenId);
    }

    function burnAll(uint256[] memory tokenIDs) public {
        for (uint256 i = 0; i < tokenIDs.length; i++) {
            burn(tokenIDs[i]);
        }
    }

    function isTradable(uint256 _tokenId) public view returns (bool) {
        uint16 proto = cardProtos[_tokenId];
        if (proto >= MYTHIC_THRESHOLD) {
            return mythicTradable[proto];
        }
        return seasonTradable[protoToSeason[proto]];
    }

    function startSeason(
        string memory name,
        uint16 low,
        uint16 high
    )
        public
        onlyOwner
        returns (uint)
    {
        require(
            low > 0,
            "Core: must not be zero proto"
        );

        require(
            high > low,
            "Core: must be a valid range"
        );

        require(
            seasons.length == 0 || low > seasons[seasons.length - 1].high,
            "Core: seasons cannot overlap"
        );

        require(
            MYTHIC_THRESHOLD > high,
            "Core: cannot go into mythic territory"
        );

        // seasons start at 1
        uint16 id = uint16(seasons.push(Season({ high: high, low: low })));

        uint256 cp;
        assembly { cp := protoToSeason_slot }
        StorageWrite.repeatUint16(cp, low, (high - low) + 1, id);

        emit SeasonStarted(id, name, low, high);

        return id;
    }

    function updateProtos(
        uint16[] memory _ids,
        uint8[] memory _gods,
        uint8[] memory _cardTypes,
        uint8[] memory _rarities,
        uint8[] memory _manas,
        uint8[] memory _attacks,
        uint8[] memory _healths,
        uint8[] memory _tribes
    ) public onlyOwner {
        for (uint256 i = 0; i < _ids.length; i++) {
            uint16 id = _ids[i];

            require(
                id > 0,
                "Core: proto must not be zero"
            );

            Proto memory proto = protos[id];
            require(
                !proto.locked,
                "Core: proto is locked"
            );

            protos[id] = Proto({
                locked: false,
                exists: true,
                god: _gods[i],
                cardType: _cardTypes[i],
                rarity: _rarities[i],
                mana: _manas[i],
                attack: _attacks[i],
                health: _healths[i],
                tribe: _tribes[i]
            });
            emit ProtoUpdated(id);
        }
    }

    function lockProtos(uint16[] memory _ids) public onlyOwner {
        require(
            _ids.length > 0,
            "must lock some"
        );

        for (uint256 i = 0; i < _ids.length; i++) {
            uint16 id = _ids[i];
            require(
                id > 0,
                "proto must not be zero"
            );

            Proto storage proto = protos[id];

            require(
                !proto.locked,
                "proto is locked"
            );

            require(
                proto.exists,
                "proto must exist"
            );

            proto.locked = true;
            emit ProtoUpdated(id);
        }
    }

    function _validateAndSaveDetails(
        uint256 start,
        uint16[] memory _protos,
        uint8[] memory _qualities
    )
        internal
    {
        _validateProtos(_protos);

        uint256 cp;
        assembly { cp := cardProtos_slot }
        StorageWrite.uint16s(cp, start, _protos);
        uint256 cq;
        assembly { cq := cardQualities_slot }
        StorageWrite.uint8s(cq, start, _qualities);
    }

    function _validateProto(uint16 proto) internal {
        if (proto >= MYTHIC_THRESHOLD) {
            _checkCanCreateMythic(proto);
        } else {

            uint256 season = protoToSeason[proto];

            require(
                season != 0,
                "Core: must have season set"
            );

            require(
                factoryApproved[msg.sender][season],
                "Core: must be approved factory for this season"
            );
        }
    }

    function _validateProtos(uint16[] memory _protos) internal {
        uint16 maxProto = 0;
        uint16 minProto = MAX_UINT16;
        for (uint256 i = 0; i < _protos.length; i++) {
            uint16 proto = _protos[i];
            if (proto >= MYTHIC_THRESHOLD) {
                _checkCanCreateMythic(proto);
            } else {
                if (proto > maxProto) {
                    maxProto = proto;
                }
                if (minProto > proto) {
                    minProto = proto;
                }
            }
        }

        if (maxProto != 0) {
            uint256 season = protoToSeason[maxProto];
            // cards must be from the same season
            require(
                season != 0,
                "Core: must have season set"
            );

            require(
                season == protoToSeason[minProto],
                "Core: can only create cards from the same season"
            );

            require(
                factoryApproved[msg.sender][season],
                "Core: must be approved factory for this season"
            );
        }
    }

    function _checkCanCreateMythic(uint16 proto) internal {

        require(
            mythicApproved[proto][msg.sender],
            "Core: not approved to create this mythic"
        );

        require(
            !mythicCreated[proto],
            "Core: mythic has already been created"
        );

        mythicCreated[proto] = true;
    }

    function setQuality(
        uint256 _tokenId,
        uint8 _quality
    )
        public
    {
        uint16 proto = cardProtos[_tokenId];
        // wont' be able to change mythic season
        uint256 season = protoToSeason[proto];

        require(
            factoryApproved[msg.sender][season],
            "Core: factory can't change quality of this season"
        );

        cardQualities[_tokenId] = _quality;
        emit QualityChanged(_tokenId, _quality, msg.sender);
    }

    function setPropertyManager(address _manager) public onlyOwner {
        propertyManager = _manager;
    }

    function setProperty(uint256 _id, bytes32 _key, bytes32 _value) public {
        require(
            msg.sender == propertyManager,
            "Core: must be property manager"
        );

        _setProperty(_id, _key, _value);
    }

    function setClassProperty(bytes32 _key, bytes32 _value) public {
        require(
            msg.sender == propertyManager,
            "Core: must be property manager"
        );

        _setClassProperty(_key, _value);
    }

    string public baseURI = "https://api.immutable.com/asset/";

    function setBaseURI(string memory uri) public onlyOwner {
        baseURI = uri;
    }

    function tokenURI(uint256 tokenId) external view returns (string memory) {
        return string(abi.encodePacked(
            baseURI,
            String.fromAddress(address(this)),
            "/",
            String.fromUint(tokenId)
        ));
    }

}


// solium-disable security/no-inline-assembly









contract Cards is Ownable, MultiTransfer, BatchToken, ImmutableToken, InscribableToken {

    uint16 private constant MAX_UINT16 = 2**16 - 1;

    uint16[] public cardProtos;
    uint8[] public cardQualities;

    struct Season {
        uint16 high;
        uint16 low;
    }

    struct Proto {
        bool locked;
        bool exists;
        uint8 god;
        uint8 cardType;
        uint8 rarity;
        uint8 mana;
        uint8 attack;
        uint8 health;
        uint8 tribe;
    }

    event ProtoUpdated(
        uint16 indexed id
    );

    event SeasonStarted(
        uint16 indexed id,
        string name,
        uint16 indexed low,
        uint16 indexed high
    );

    event QualityChanged(
        uint256 indexed tokenId,
        uint8 quality,
        address factory
    );

    event CardsMinted(
        uint256 indexed start,
        address to,
        uint16[] protos,
        uint8[] qualities
    );

    // Value of index proto = season
    uint16[] public protoToSeason;

    address public propertyManager;

    // Array containing all protos
    Proto[] public protos;

    // Array containing all seasons
    Season[] public seasons;

    // Map whether a season is tradeable or not
    mapping(uint256 => bool) public seasonTradable;

    // Map whether a factory has been authorised or not
    mapping(address => mapping(uint256 => bool)) public factoryApproved;

    // Whether a factory is approved to create a particular mythic
    mapping(uint16 => mapping(address => bool)) public mythicApproved;

    // Whether a mythic is tradable
    mapping(uint16 => bool) public mythicTradable;

    // Map whether a mythic exists or not
    mapping(uint16 => bool) public mythicCreated;

    uint16 public constant MYTHIC_THRESHOLD = 65000;

    constructor(
        uint256 _batchSize,
        string memory _name,
        string memory _symbol
    )
        public
        BatchToken(_batchSize, _name, _symbol)
    {
        cardProtos.length = MAX_LENGTH;
        cardQualities.length = MAX_LENGTH;
        protoToSeason.length = MAX_LENGTH;
        protos.length = MAX_LENGTH;
        propertyManager = msg.sender;
    }

    function getDetails(
        uint256 tokenId
    )
        public
        view
        returns (uint16 proto, uint8 quality)
    {
        return (cardProtos[tokenId], cardQualities[tokenId]);
    }

    function mintCard(
        address to,
        uint16 _proto,
        uint8 _quality
    )
        external
        returns (uint id)
    {
        id = _batchMint(to, 1);
        _validateProto(_proto);
        cardProtos[id] = _proto;
        cardQualities[id] = _quality;

        uint16[] memory ps = new uint16[](1);
        ps[0] = _proto;

        uint8[] memory qs = new uint8[](1);
        qs[0] = _quality;

        emit CardsMinted(id, to, ps, qs);
        return id;
    }

    function mintCards(
        address to,
        uint16[] calldata _protos,
        uint8[] calldata _qualities
    )
        external
        returns (uint)
    {
        require(
            _protos.length > 0,
            "Core: must be some protos"
        );

        require(
            _protos.length == _qualities.length,
            "Core: must be the same number of protos/qualities"
        );

        uint256 start = _batchMint(to, uint16(_protos.length));
        _validateAndSaveDetails(start, _protos, _qualities);

        emit CardsMinted(start, to, _protos, _qualities);

        return start;
    }

    function addFactory(
        address _factory,
        uint256 _season
    )
        public
        onlyOwner
    {
        require(
            seasons.length >= _season,
            "Core: season must exist"
        );

        require(
            _season > 0,
            "Core: season must not be 0"
        );

        require(
            !factoryApproved[_factory][_season],
            "Core: this factory is already approved"
        );

        require(
            !seasonTradable[_season],
            "Core: season must not be tradable"
        );

        factoryApproved[_factory][_season] = true;
    }

    function approveForMythic(
        address _factory,
        uint16 _mythic
    )
        public
        onlyOwner
    {
        require(
            _mythic >= MYTHIC_THRESHOLD,
            "not a mythic"
        );

        require(
            !mythicApproved[_mythic][_factory],
            "Core: this factory is already approved for this mythic"
        );

        mythicApproved[_mythic][_factory] = true;
    }

    function makeMythicTradable(
        uint16 _mythic
    )
        public
        onlyOwner
    {
        require(
            _mythic >= MYTHIC_THRESHOLD,
            "Core: not a mythic"
        );

        require(
            !mythicTradable[_mythic],
            "Core: must not be tradable already"
        );

        mythicTradable[_mythic] = true;
    }

    function unlockTrading(
        uint256 _season
    )
        public
        onlyOwner
    {
        require(
            _season > 0 && _season <= seasons.length,
            "Core: must be a current season"
        );

        require(
            !seasonTradable[_season],
            "Core: season must not be tradable"
        );

        seasonTradable[_season] = true;
    }

    function transferFrom(
        address from,
        address to,
        uint256 tokenId
    )
        public
    {
        require(
            isTradable(tokenId),
            "Core: not yet tradable"
        );

        super.transferFrom(from, to, tokenId);
    }

    function burn(uint256 _tokenId) public {
        require(
            isTradable(_tokenId),
            "Core: not yet tradable"
        );

        super._burn(_tokenId);
    }

    function burnAll(uint256[] memory tokenIDs) public {
        for (uint256 i = 0; i < tokenIDs.length; i++) {
            burn(tokenIDs[i]);
        }
    }

    function isTradable(uint256 _tokenId) public view returns (bool) {
        uint16 proto = cardProtos[_tokenId];
        if (proto >= MYTHIC_THRESHOLD) {
            return mythicTradable[proto];
        }
        return seasonTradable[protoToSeason[proto]];
    }

    function startSeason(
        string memory name,
        uint16 low,
        uint16 high
    )
        public
        onlyOwner
        returns (uint)
    {
        require(
            low > 0,
            "Core: must not be zero proto"
        );

        require(
            high > low,
            "Core: must be a valid range"
        );

        require(
            seasons.length == 0 || low > seasons[seasons.length - 1].high,
            "Core: seasons cannot overlap"
        );

        require(
            MYTHIC_THRESHOLD > high,
            "Core: cannot go into mythic territory"
        );

        // seasons start at 1
        uint16 id = uint16(seasons.push(Season({ high: high, low: low })));

        uint256 cp;
        assembly { cp := protoToSeason_slot }
        StorageWrite.repeatUint16(cp, low, (high - low) + 1, id);

        emit SeasonStarted(id, name, low, high);

        return id;
    }

    function updateProtos(
        uint16[] memory _ids,
        uint8[] memory _gods,
        uint8[] memory _cardTypes,
        uint8[] memory _rarities,
        uint8[] memory _manas,
        uint8[] memory _attacks,
        uint8[] memory _healths,
        uint8[] memory _tribes
    ) public onlyOwner {
        for (uint256 i = 0; i < _ids.length; i++) {
            uint16 id = _ids[i];

            require(
                id > 0,
                "Core: proto must not be zero"
            );

            Proto memory proto = protos[id];
            require(
                !proto.locked,
                "Core: proto is locked"
            );

            protos[id] = Proto({
                locked: false,
                exists: true,
                god: _gods[i],
                cardType: _cardTypes[i],
                rarity: _rarities[i],
                mana: _manas[i],
                attack: _attacks[i],
                health: _healths[i],
                tribe: _tribes[i]
            });
            emit ProtoUpdated(id);
        }
    }

    function lockProtos(uint16[] memory _ids) public onlyOwner {
        require(
            _ids.length > 0,
            "must lock some"
        );

        for (uint256 i = 0; i < _ids.length; i++) {
            uint16 id = _ids[i];
            require(
                id > 0,
                "proto must not be zero"
            );

            Proto storage proto = protos[id];

            require(
                !proto.locked,
                "proto is locked"
            );

            require(
                proto.exists,
                "proto must exist"
            );

            proto.locked = true;
            emit ProtoUpdated(id);
        }
    }

    function _validateAndSaveDetails(
        uint256 start,
        uint16[] memory _protos,
        uint8[] memory _qualities
    )
        internal
    {
        _validateProtos(_protos);

        uint256 cp;
        assembly { cp := cardProtos_slot }
        StorageWrite.uint16s(cp, start, _protos);
        uint256 cq;
        assembly { cq := cardQualities_slot }
        StorageWrite.uint8s(cq, start, _qualities);
    }

    function _validateProto(uint16 proto) internal {
        if (proto >= MYTHIC_THRESHOLD) {
            _checkCanCreateMythic(proto);
        } else {

            uint256 season = protoToSeason[proto];

            require(
                season != 0,
                "Core: must have season set"
            );

            require(
                factoryApproved[msg.sender][season],
                "Core: must be approved factory for this season"
            );
        }
    }

    function _validateProtos(uint16[] memory _protos) internal {
        uint16 maxProto = 0;
        uint16 minProto = MAX_UINT16;
        for (uint256 i = 0; i < _protos.length; i++) {
            uint16 proto = _protos[i];
            if (proto >= MYTHIC_THRESHOLD) {
                _checkCanCreateMythic(proto);
            } else {
                if (proto > maxProto) {
                    maxProto = proto;
                }
                if (minProto > proto) {
                    minProto = proto;
                }
            }
        }

        if (maxProto != 0) {
            uint256 season = protoToSeason[maxProto];
            // cards must be from the same season
            require(
                season != 0,
                "Core: must have season set"
            );

            require(
                season == protoToSeason[minProto],
                "Core: can only create cards from the same season"
            );

            require(
                factoryApproved[msg.sender][season],
                "Core: must be approved factory for this season"
            );
        }
    }

    function _checkCanCreateMythic(uint16 proto) internal {

        require(
            mythicApproved[proto][msg.sender],
            "Core: not approved to create this mythic"
        );

        require(
            !mythicCreated[proto],
            "Core: mythic has already been created"
        );

        mythicCreated[proto] = true;
    }

    function setQuality(
        uint256 _tokenId,
        uint8 _quality
    )
        public
    {
        uint16 proto = cardProtos[_tokenId];
        // wont' be able to change mythic season
        uint256 season = protoToSeason[proto];

        require(
            factoryApproved[msg.sender][season],
            "Core: factory can't change quality of this season"
        );

        cardQualities[_tokenId] = _quality;
        emit QualityChanged(_tokenId, _quality, msg.sender);
    }

    function setPropertyManager(address _manager) public onlyOwner {
        propertyManager = _manager;
    }

    function setProperty(uint256 _id, bytes32 _key, bytes32 _value) public {
        require(
            msg.sender == propertyManager,
            "Core: must be property manager"
        );

        _setProperty(_id, _key, _value);
    }

    function setClassProperty(bytes32 _key, bytes32 _value) public {
        require(
            msg.sender == propertyManager,
            "Core: must be property manager"
        );

        _setClassProperty(_key, _value);
    }

}



contract BatchWrapper is NewCards {

    uint16 private constant MAX_UINT16 = 2**16 - 1;
    Cards public old;
    bool public migrating;

    constructor(
        Cards _old,
        uint256 _batchSize,
        string memory _name,
        string memory _symbol
    ) public NewCards(_batchSize, _name, _symbol) {
        old = _old;
    }

    function setMigrating(bool _migrating) public onlyOwner {
        migrating = _migrating;
    }

    function copyUntil(uint gasThreshold) public {
        while (gasleft() > gasThreshold) {
            copyNextBatch();
        }
    }

    function mintCards(address _to, uint16[] memory _protos, uint8[] memory _qualities) public returns (uint id) {
        require(!migrating, "must not be migrating");
        super.mintCards(_to, _protos, _qualities);
    }

    function mintCard(address _to, uint16 _proto, uint8 _quality) public returns (uint id) {
        require(!migrating, "must not be migrating");
        super.mintCard(_to, _proto, _quality);
    }

    // copy all batches from the old contracts
    // leave ids intact
    function copyNextBatch() public {
        require(migrating, "must be migrating");
        uint256 start = nextBatch;
        (uint48 userID, uint16 size) = old.batches(start);
        require(size > 0 && userID > 0, "incorrect batch or limit reached");
        if (old.cardProtos(start) != 0) {
            address to = old.userIDToAddress(userID);
            uint48 uID = _getUserID(to);
            batches[start] = Batch({
                userID: uID,
                size: size
            });
            uint256 end = start.add(size);
            for (uint256 i = start; i < end; i++) {
                emit Transfer(address(0), to, i);
            }
            _balances[to] = _balances[to].add(size);
            tokenCount = tokenCount.add(size);
        }
        nextBatch = nextBatch.add(batchSize);
    }

    function isOld(uint _tokenId) public view returns (bool) {
        require(_exists(_tokenId), "card does not exist");
        return cardProtos[_tokenId] == 0;
    }

    function getProto(uint _tokenId) public view returns (uint16) {
        return isOld(_tokenId) ? old.cardProtos(_tokenId) : cardProtos[_tokenId];
    }

    function getQuality(uint _tokenId) public view returns (uint8) {
        return isOld(_tokenId) ? old.cardQualities(_tokenId) : cardQualities[_tokenId];
    }

    function getDetails(uint256 tokenId) public view returns (uint16 proto, uint8 quality) {
        return isOld(tokenId) ? old.getDetails(tokenId) : (cardProtos[tokenId], cardQualities[tokenId]);
    }

    function isTradable(uint256 _tokenId) public view returns (bool) {
        uint16 proto = getProto(_tokenId);
        if (proto >= MYTHIC_THRESHOLD) {
            return mythicTradable[proto];
        }
        return seasonTradable[protoToSeason[proto]];
    }

    function _transferFrom(address from, address to, uint tokenId) internal {
        require(
            isTradable(tokenId),
            "BW: not yet tradable"
        );
        super._transferFrom(from, to, tokenId);
    }

    // update validate protos to check if a proto is 0
    // prevent untradable cards
    function _validateProtos(uint16[] memory _protos) internal {

        uint16 maxProto = 0;
        uint16 minProto = MAX_UINT16;
        for (uint256 i = 0; i < _protos.length; i++) {
            uint16 proto = _protos[i];
            if (proto >= MYTHIC_THRESHOLD) {
                _checkCanCreateMythic(proto);
            } else {
                require(proto != 0, "proto is zero");
                if (proto > maxProto) {
                    maxProto = proto;
                }
                if (minProto > proto) {
                    minProto = proto;
                }
            }
        }

        if (maxProto != 0) {
            uint256 season = protoToSeason[maxProto];
            // cards must be from the same season
            require(
                season != 0,
                "Core: must have season set"
            );

            require(
                season == protoToSeason[minProto],
                "Core: can only create cards from the same season"
            );

            require(
                factoryApproved[msg.sender][season],
                "Core: must be approved factory for this season"
            );
        }
    }

}

Contract Security Audit

Contract ABI

[{"constant":true,"inputs":[{"internalType":"bytes4","name":"interfaceId","type":"bytes4"}],"name":"supportsInterface","outputs":[{"internalType":"bool","name":"","type":"bool"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"internalType":"uint16","name":"","type":"uint16"}],"name":"mythicTradable","outputs":[{"internalType":"bool","name":"","type":"bool"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"name","outputs":[{"internalType":"string","name":"","type":"string"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"getApproved","outputs":[{"internalType":"address","name":"","type":"address"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"approve","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"internalType":"address","name":"from","type":"address"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256[]","name":"tokenIDs","type":"uint256[]"}],"name":"transferAllFrom","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"internalType":"uint256[]","name":"tokenIDs","type":"uint256[]"}],"name":"burnAll","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[],"name":"totalSupply","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"internalType":"uint256","name":"_tokenId","type":"uint256"}],"name":"getProto","outputs":[{"internalType":"uint16","name":"","type":"uint16"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"internalType":"uint16[]","name":"_ids","type":"uint16[]"},{"internalType":"uint8[]","name":"_gods","type":"uint8[]"},{"internalType":"uint8[]","name":"_cardTypes","type":"uint8[]"},{"internalType":"uint8[]","name":"_rarities","type":"uint8[]"},{"internalType":"uint8[]","name":"_manas","type":"uint8[]"},{"internalType":"uint8[]","name":"_attacks","type":"uint8[]"},{"internalType":"uint8[]","name":"_healths","type":"uint8[]"},{"internalType":"uint8[]","name":"_tribes","type":"uint8[]"}],"name":"updateProtos","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"internalType":"address","name":"_manager","type":"address"}],"name":"setPropertyManager","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"addressToUserID","outputs":[{"internalType":"uint48","name":"","type":"uint48"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"internalType":"uint16","name":"","type":"uint16"},{"internalType":"address","name":"","type":"address"}],"name":"mythicApproved","outputs":[{"internalType":"bool","name":"","type":"bool"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"internalType":"uint256","name":"_tokenId","type":"uint256"}],"name":"isOld","outputs":[{"internalType":"bool","name":"","type":"bool"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"internalType":"address","name":"from","type":"address"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"transferFrom","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[{"internalType":"address","name":"","type":"address"},{"internalType":"uint256","name":"","type":"uint256"}],"name":"factoryApproved","outputs":[{"internalType":"bool","name":"","type":"bool"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"MYTHIC_THRESHOLD","outputs":[{"internalType":"uint16","name":"","type":"uint16"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"internalType":"uint16[]","name":"_ids","type":"uint16[]"}],"name":"lockProtos","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[{"internalType":"uint256","name":"_tokenId","type":"uint256"},{"internalType":"bytes32","name":"_key","type":"bytes32"}],"name":"getTokenKey","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"payable":false,"stateMutability":"pure","type":"function"},{"constant":true,"inputs":[{"internalType":"bytes32","name":"_key","type":"bytes32"}],"name":"getClassKey","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"payable":false,"stateMutability":"pure","type":"function"},{"constant":false,"inputs":[{"internalType":"address","name":"from","type":"address"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"safeTransferFrom","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"internalType":"uint256","name":"_tokenId","type":"uint256"}],"name":"burn","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"internalType":"uint256","name":"gasThreshold","type":"uint256"}],"name":"copyUntil","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[],"name":"migrating","outputs":[{"internalType":"bool","name":"","type":"bool"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"internalType":"string","name":"uri","type":"string"}],"name":"setBaseURI","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"internalType":"uint256","name":"_id","type":"uint256"},{"internalType":"bytes32","name":"_key","type":"bytes32"},{"internalType":"bytes32","name":"_value","type":"bytes32"}],"name":"setProperty","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[{"internalType":"uint256","name":"index","type":"uint256"}],"name":"getBatch","outputs":[{"internalType":"uint48","name":"userID","type":"uint48"},{"internalType":"uint16","name":"size","type":"uint16"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"internalType":"address","name":"_to","type":"address"},{"internalType":"uint16","name":"_proto","type":"uint16"},{"internalType":"uint8","name":"_quality","type":"uint8"}],"name":"mintCard","outputs":[{"internalType":"uint256","name":"id","type":"uint256"}],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"internalType":"address","name":"_factory","type":"address"},{"internalType":"uint16","name":"_mythic","type":"uint16"}],"name":"approveForMythic","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"ownerOf","outputs":[{"internalType":"address","name":"","type":"address"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"internalType":"uint48","name":"","type":"uint48"}],"name":"userIDToAddress","outputs":[{"internalType":"address","name":"","type":"address"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"baseURI","outputs":[{"internalType":"string","name":"","type":"string"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"internalType":"address","name":"_owner","type":"address"}],"name":"balanceOf","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[],"name":"renounceOwnership","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"internalType":"address","name":"from","type":"address"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256[]","name":"tokenIDs","type":"uint256[]"}],"name":"safeTransferAllFrom","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"getBatchStart","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"internalType":"string","name":"name","type":"string"},{"internalType":"uint16","name":"low","type":"uint16"},{"internalType":"uint16","name":"high","type":"uint16"}],"name":"startSeason","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[],"name":"owner","outputs":[{"internalType":"address","name":"","type":"address"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"isOwner","outputs":[{"internalType":"bool","name":"","type":"bool"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"symbol","outputs":[{"internalType":"string","name":"","type":"string"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"tokenCount","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"internalType":"bytes32","name":"_key","type":"bytes32"}],"name":"getClassProperty","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"internalType":"address","name":"to","type":"address"},{"internalType":"bool","name":"approved","type":"bool"}],"name":"setApprovalForAll","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"internalType":"bytes32","name":"_key","type":"bytes32"},{"internalType":"bytes32","name":"_value","type":"bytes32"}],"name":"setClassProperty","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[{"internalType":"uint256","name":"","type":"uint256"}],"name":"protos","outputs":[{"internalType":"bool","name":"locked","type":"bool"},{"internalType":"bool","name":"exists","type":"bool"},{"internalType":"uint8","name":"god","type":"uint8"},{"internalType":"uint8","name":"cardType","type":"uint8"},{"internalType":"uint8","name":"rarity","type":"uint8"},{"internalType":"uint8","name":"mana","type":"uint8"},{"internalType":"uint8","name":"attack","type":"uint8"},{"internalType":"uint8","name":"health","type":"uint8"},{"internalType":"uint8","name":"tribe","type":"uint8"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"internalType":"address","name":"from","type":"address"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"start","type":"uint256"},{"internalType":"uint256","name":"end","type":"uint256"}],"name":"safeTransferBatch","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[{"internalType":"uint256","name":"","type":"uint256"}],"name":"seasonTradable","outputs":[{"internalType":"bool","name":"","type":"bool"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"internalType":"uint256","name":"","type":"uint256"}],"name":"batches","outputs":[{"internalType":"uint48","name":"userID","type":"uint48"},{"internalType":"uint16","name":"size","type":"uint16"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"internalType":"uint256","name":"","type":"uint256"}],"name":"protoToSeason","outputs":[{"internalType":"uint16","name":"","type":"uint16"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"old","outputs":[{"internalType":"contract Cards","name":"","type":"address"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"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":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"getDetails","outputs":[{"internalType":"uint16","name":"proto","type":"uint16"},{"internalType":"uint8","name":"quality","type":"uint8"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"internalType":"uint256","name":"_season","type":"uint256"}],"name":"unlockTrading","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"name":"properties","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"internalType":"address","name":"from","type":"address"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"start","type":"uint256"},{"internalType":"uint256","name":"end","type":"uint256"}],"name":"transferBatch","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"tokenURI","outputs":[{"internalType":"string","name":"","type":"string"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"internalType":"address","name":"_to","type":"address"},{"internalType":"uint16[]","name":"_protos","type":"uint16[]"},{"internalType":"uint8[]","name":"_qualities","type":"uint8[]"}],"name":"mintCards","outputs":[{"internalType":"uint256","name":"id","type":"uint256"}],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[{"internalType":"uint256","name":"_id","type":"uint256"},{"internalType":"bytes32","name":"_key","type":"bytes32"}],"name":"getProperty","outputs":[{"internalType":"bytes32","name":"_value","type":"bytes32"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[],"name":"copyNextBatch","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[{"internalType":"uint16","name":"","type":"uint16"}],"name":"mythicCreated","outputs":[{"internalType":"bool","name":"","type":"bool"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"internalType":"uint256","name":"_tokenId","type":"uint256"}],"name":"isTradable","outputs":[{"internalType":"bool","name":"","type":"bool"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"internalType":"uint256","name":"_tokenId","type":"uint256"},{"internalType":"uint8","name":"_quality","type":"uint8"}],"name":"setQuality","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[],"name":"propertyManager","outputs":[{"internalType":"address","name":"","type":"address"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"nextBatch","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"internalType":"uint16","name":"_mythic","type":"uint16"}],"name":"makeMythicTradable","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[{"internalType":"address","name":"owner","type":"address"},{"internalType":"address","name":"operator","type":"address"}],"name":"isApprovedForAll","outputs":[{"internalType":"bool","name":"","type":"bool"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"internalType":"uint256","name":"_tokenId","type":"uint256"}],"name":"getQuality","outputs":[{"internalType":"uint8","name":"","type":"uint8"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"internalType":"address","name":"_factory","type":"address"},{"internalType":"uint256","name":"_season","type":"uint256"}],"name":"addFactory","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"internalType":"address","name":"newOwner","type":"address"}],"name":"transferOwnership","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[],"name":"batchSize","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"internalType":"uint256","name":"","type":"uint256"}],"name":"seasons","outputs":[{"internalType":"uint16","name":"high","type":"uint16"},{"internalType":"uint16","name":"low","type":"uint16"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"internalType":"bool","name":"_migrating","type":"bool"}],"name":"setMigrating","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"contract Cards","name":"_old","type":"address"},{"internalType":"uint256","name":"_batchSize","type":"uint256"},{"internalType":"string","name":"_name","type":"string"},{"internalType":"string","name":"_symbol","type":"string"}],"payable":false,"stateMutability":"nonpayable","type":"constructor"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"uint16","name":"id","type":"uint16"}],"name":"ProtoUpdated","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"uint16","name":"id","type":"uint16"},{"indexed":false,"internalType":"string","name":"name","type":"string"},{"indexed":true,"internalType":"uint16","name":"low","type":"uint16"},{"indexed":true,"internalType":"uint16","name":"high","type":"uint16"}],"name":"SeasonStarted","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"uint256","name":"tokenId","type":"uint256"},{"indexed":false,"internalType":"uint8","name":"quality","type":"uint8"},{"indexed":false,"internalType":"address","name":"factory","type":"address"}],"name":"QualityChanged","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"uint256","name":"start","type":"uint256"},{"indexed":false,"internalType":"address","name":"to","type":"address"},{"indexed":false,"internalType":"uint16[]","name":"protos","type":"uint16[]"},{"indexed":false,"internalType":"uint8[]","name":"qualities","type":"uint8[]"}],"name":"CardsMinted","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"bytes32","name":"key","type":"bytes32"},{"indexed":false,"internalType":"bytes32","name":"value","type":"bytes32"}],"name":"ClassPropertySet","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"uint256","name":"id","type":"uint256"},{"indexed":true,"internalType":"bytes32","name":"key","type":"bytes32"},{"indexed":false,"internalType":"bytes32","name":"value","type":"bytes32"}],"name":"TokenPropertySet","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":"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"}]

6011805465ffffffffffff1916600117905560c0604052602060808190527f68747470733a2f2f6170692e696d6d757461626c652e636f6d2f61737365742f60a09081526200005291601f9190620004a6565b503480156200006057600080fd5b506040516200644138038062006441833981810160405260808110156200008657600080fd5b81516020830151604080850180519151939592948301929184640100000000821115620000b257600080fd5b908301906020820185811115620000c857600080fd5b8251640100000000811182820188101715620000e357600080fd5b82525081516020918201929091019080838360005b8381101562000112578181015183820152602001620000f8565b50505050905090810190601f168015620001405780820380516001836020036101000a031916815260200191505b50604052602001805160405193929190846401000000008211156200016457600080fd5b9083019060208201858111156200017a57600080fd5b82516401000000008111828201881017156200019557600080fd5b82525081516020918201929091019080838360005b83811015620001c4578181015183820152602001620001aa565b50505050905090810190601f168015620001f25780820380516001836020036101000a031916815260200191505b50604052505050828282828282818162000211620003cf60201b60201c565b600080546001600160a01b0319166001600160a01b03928316178082556040519216917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0908290a36200028d7f01ffc9a7000000000000000000000000000000000000000000000000000000006001600160e01b03620003d416565b620002c17f80ac58cd000000000000000000000000000000000000000000000000000000006001600160e01b03620003d416565b8151620002d6906006906020850190620004a6565b508051620002ec906007906020840190620004a6565b50620003217f5b5e139f000000000000000000000000000000000000000000000000000000006001600160e01b03620003d416565b5050600b83905560001962000338600e826200052b565b5060001962000349600f826200052b565b505050506000196014816200035f919062000567565b50600019620003706015826200059e565b506000196200038160168262000567565b5060001962000392601882620005d5565b505060178054336001600160a01b031991821617909155602080549091166001600160a01b03979097169690961790955550620006409350505050565b335b90565b7fffffffff0000000000000000000000000000000000000000000000000000000080821614156200046657604080517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601c60248201527f4552433136353a20696e76616c696420696e7465726661636520696400000000604482015290519081900360640190fd5b7fffffffff00000000000000000000000000000000000000000000000000000000166000908152600160208190526040909120805460ff19169091179055565b828054600181600116156101000203166002900490600052602060002090601f016020900481019282601f10620004e957805160ff191683800117855562000519565b8280016001018555821562000519579182015b8281111562000519578251825591602001919060010190620004fc565b5062000527929150620005fc565b5090565b81548183558181111562000562576004016005900481600401600590048360005260206000209182019101620005629190620005fc565b505050565b8154818355818111156200056257600f016010900481600f01601090048360005260206000209182019101620005629190620005fc565b8154818355818111156200056257601f016020900481601f01602090048360005260206000209182019101620005629190620005fc565b81548183558181111562000562576000838152602090206200056291810190830162000619565b620003d191905b8082111562000527576000815560010162000603565b620003d191905b80821115620005275780546001600160481b031916815560010162000620565b615df180620006506000396000f3fe608060405234801561001057600080fd5b50600436106104285760003560e01c8063856516c31161022b578063c5f4127a11610130578063e7c51f1b116100b8578063ef42259b11610087578063ef42259b146116ba578063f2fde38b146116e6578063f4daaba11461170c578063f5d709a114611714578063f785f03d1461175257610428565b8063e7c51f1b14611630578063e8c238a114611638578063e985e9c514611659578063eb8d8ca11461168757610428565b8063cee15290116100ff578063cee15290146115bc578063e0c931df146115c4578063e27aa1d8146115e5578063e3fb1ac614611602578063e7356cb51461162857610428565b8063c5f4127a1461140d578063c87b56dd14611449578063c8be6b9b14611466578063cdc2cfe21461159957610428565b8063b0c4297c116101b3578063b83f866311610182578063b83f8663146112ca578063b88d4fde146112d2578063b93a89f714611396578063bc048525146113d3578063bd156273146113f057610428565b8063b0c4297c14611237578063b309c36b14611273578063b32c4d8d14611290578063b76e8d01146112ad57610428565b80639f181b5e116101fa5780639f181b5e14611151578063a138e44e14611159578063a22cb46514611176578063a9c1a200146111a4578063ab17d040146111c757610428565b8063856516c3146110845780638da5cb5b146111395780638f32d59b1461114157806395d89b411461114957610428565b806337514295116103315780635b65afe9116102b95780636c0360eb116102885780636c0360eb14610f7757806370a0823114610f7f578063715018a614610fa55780637962d59b14610fad578063815d9fa01461106757610428565b80635b65afe914610ecc5780636315a84d14610f055780636352211e14610f355780636602eaf914610f5257610428565b806345de9d431161030057806345de9d4314610d985780634956cf1c14610db557806355f804b314610dbd57806358895f6214610e615780635ac4428214610e8a57610428565b80633751429514610d055780633af0725614610d2857806342842e0e14610d4557806342966c6814610d7b57610428565b80631e41613c116103b4578063234f0e4611610383578063234f0e4614610bdd57806323b872dd14610bfa5780632488508714610c3057806324a01da114610c5c5780632fa438a314610c6457610428565b80631e41613c146107165780631e50739314610b465780631fe25e4f14610b6c57806321f3c46914610bad57610428565b8063095ea7b3116103fb578063095ea7b31461053f5780630bbe0ee31461056d578063100cdd911461062757806318160ddd146106c85780631dd0f662146106e257610428565b806301ffc9a71461042d57806304f8bcdf1461046857806306fdde0314610489578063081812fc14610506575b600080fd5b6104546004803603602081101561044357600080fd5b50356001600160e01b031916611771565b604080519115158252519081900360200190f35b6104546004803603602081101561047e57600080fd5b503561ffff16611794565b6104916117a9565b6040805160208082528351818301528351919283929083019185019080838360005b838110156104cb5781810151838201526020016104b3565b50505050905090810190601f1680156104f85780820380516001836020036101000a031916815260200191505b509250505060405180910390f35b6105236004803603602081101561051c57600080fd5b5035611840565b604080516001600160a01b039092168252519081900360200190f35b61056b6004803603604081101561055557600080fd5b506001600160a01b0381351690602001356118db565b005b61056b6004803603606081101561058357600080fd5b6001600160a01b038235811692602081013590911691810190606081016040820135600160201b8111156105b657600080fd5b8201836020820111156105c857600080fd5b803590602001918460208302840111600160201b831117156105e957600080fd5b919080806020026020016040519081016040528093929190818152602001838360200280828437600092019190915250929550611a39945050505050565b61056b6004803603602081101561063d57600080fd5b810190602081018135600160201b81111561065757600080fd5b82018360208201111561066957600080fd5b803590602001918460208302840111600160201b8311171561068a57600080fd5b919080806020026020016040519081016040528093929190818152602001838360200280828437600092019190915250929550611a71945050505050565b6106d0611aa5565b60408051918252519081900360200190f35b6106ff600480360360208110156106f857600080fd5b5035611aab565b6040805161ffff9092168252519081900360200190f35b61056b600480360361010081101561072d57600080fd5b810190602081018135600160201b81111561074757600080fd5b82018360208201111561075957600080fd5b803590602001918460208302840111600160201b8311171561077a57600080fd5b9190808060200260200160405190810160405280939291908181526020018383602002808284376000920191909152509295949360208101935035915050600160201b8111156107c957600080fd5b8201836020820111156107db57600080fd5b803590602001918460208302840111600160201b831117156107fc57600080fd5b9190808060200260200160405190810160405280939291908181526020018383602002808284376000920191909152509295949360208101935035915050600160201b81111561084b57600080fd5b82018360208201111561085d57600080fd5b803590602001918460208302840111600160201b8311171561087e57600080fd5b9190808060200260200160405190810160405280939291908181526020018383602002808284376000920191909152509295949360208101935035915050600160201b8111156108cd57600080fd5b8201836020820111156108df57600080fd5b803590602001918460208302840111600160201b8311171561090057600080fd5b9190808060200260200160405190810160405280939291908181526020018383602002808284376000920191909152509295949360208101935035915050600160201b81111561094f57600080fd5b82018360208201111561096157600080fd5b803590602001918460208302840111600160201b8311171561098257600080fd5b9190808060200260200160405190810160405280939291908181526020018383602002808284376000920191909152509295949360208101935035915050600160201b8111156109d157600080fd5b8201836020820111156109e357600080fd5b803590602001918460208302840111600160201b83111715610a0457600080fd5b9190808060200260200160405190810160405280939291908181526020018383602002808284376000920191909152509295949360208101935035915050600160201b811115610a5357600080fd5b820183602082011115610a6557600080fd5b803590602001918460208302840111600160201b83111715610a8657600080fd5b9190808060200260200160405190810160405280939291908181526020018383602002808284376000920191909152509295949360208101935035915050600160201b811115610ad557600080fd5b820183602082011115610ae757600080fd5b803590602001918460208302840111600160201b83111715610b0857600080fd5b919080806020026020016040519081016040528093929190818152602001838360200280828437600092019190915250929550611b6a945050505050565b61056b60048036036020811015610b5c57600080fd5b50356001600160a01b0316611f9b565b610b9260048036036020811015610b8257600080fd5b50356001600160a01b0316612004565b6040805165ffffffffffff9092168252519081900360200190f35b61045460048036036040811015610bc357600080fd5b50803561ffff1690602001356001600160a01b031661201e565b61045460048036036020811015610bf357600080fd5b503561203e565b61056b60048036036060811015610c1057600080fd5b506001600160a01b038135811691602081013590911690604001356120c6565b61045460048036036040811015610c4657600080fd5b506001600160a01b038135169060200135612122565b6106ff612142565b61056b60048036036020811015610c7a57600080fd5b810190602081018135600160201b811115610c9457600080fd5b820183602082011115610ca657600080fd5b803590602001918460208302840111600160201b83111715610cc757600080fd5b919080806020026020016040519081016040528093929190818152602001838360200280828437600092019190915250929550612148945050505050565b6106d060048036036040811015610d1b57600080fd5b5080359060200135612348565b6106d060048036036020811015610d3e57600080fd5b503561237e565b61056b60048036036060811015610d5b57600080fd5b506001600160a01b038135811691602081013590911690604001356123ad565b61056b60048036036020811015610d9157600080fd5b50356123c8565b61056b60048036036020811015610dae57600080fd5b5035612427565b61045461243c565b61056b60048036036020811015610dd357600080fd5b810190602081018135600160201b811115610ded57600080fd5b820183602082011115610dff57600080fd5b803590602001918460018302840111600160201b83111715610e2057600080fd5b91908080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525092955061244c945050505050565b61056b60048036036060811015610e7757600080fd5b50803590602081013590604001356124a6565b610ea760048036036020811015610ea057600080fd5b5035612510565b6040805165ffffffffffff909316835261ffff90911660208301528051918290030190f35b6106d060048036036060811015610ee257600080fd5b5080356001600160a01b031690602081013561ffff16906040013560ff16612538565b61056b60048036036040811015610f1b57600080fd5b5080356001600160a01b0316906020013561ffff166125a5565b61052360048036036020811015610f4b57600080fd5b50356126d0565b61052360048036036020811015610f6857600080fd5b503565ffffffffffff1661283a565b610491612855565b6106d060048036036020811015610f9557600080fd5b50356001600160a01b03166128e2565b61056b6128fd565b61056b60048036036060811015610fc357600080fd5b6001600160a01b038235811692602081013590911691810190606081016040820135600160201b811115610ff657600080fd5b82018360208201111561100857600080fd5b803590602001918460208302840111600160201b8311171561102957600080fd5b91908080602002602001604051908101604052809392919081815260200183836020028082843760009201919091525092955061298e945050505050565b6106d06004803603602081101561107d57600080fd5b50356129c0565b6106d06004803603606081101561109a57600080fd5b810190602081018135600160201b8111156110b457600080fd5b8201836020820111156110c657600080fd5b803590602001918460018302840111600160201b831117156110e757600080fd5b91908080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152509295505061ffff83358116945060209093013590921691506129e69050565b610523612cf8565b610454612d07565b610491612d2b565b6106d0612d8c565b6106d06004803603602081101561116f57600080fd5b5035612d92565b61056b6004803603604081101561118c57600080fd5b506001600160a01b0381351690602001351515612db7565b61056b600480360360408110156111ba57600080fd5b5080359060200135612ebc565b6111e4600480360360208110156111dd57600080fd5b5035612f25565b604080519915158a5297151560208a015260ff968716898901529486166060890152928516608088015290841660a0870152831660c0860152821660e08501521661010083015251908190036101200190f35b61056b6004803603608081101561124d57600080fd5b506001600160a01b03813581169160208101359091169060408101359060600135612f95565b6104546004803603602081101561128957600080fd5b5035612fb9565b610ea7600480360360208110156112a657600080fd5b5035612fce565b6106ff600480360360208110156112c357600080fd5b5035612ff5565b61052361302a565b61056b600480360360808110156112e857600080fd5b6001600160a01b03823581169260208101359091169160408201359190810190608081016060820135600160201b81111561132257600080fd5b82018360208201111561133457600080fd5b803590602001918460018302840111600160201b8311171561135557600080fd5b91908080601f016020809104026020016040519081016040528093929190818152602001838380828437600092019190915250929550613039945050505050565b6113b3600480360360208110156113ac57600080fd5b5035613091565b6040805161ffff909316835260ff90911660208301528051918290030190f35b61056b600480360360208110156113e957600080fd5b503561318a565b6106d06004803603602081101561140657600080fd5b503561329d565b61056b6004803603608081101561142357600080fd5b506001600160a01b038135811691602081013590911690604081013590606001356132af565b6104916004803603602081101561145f57600080fd5b50356132cc565b6106d06004803603606081101561147c57600080fd5b6001600160a01b038235169190810190604081016020820135600160201b8111156114a657600080fd5b8201836020820111156114b857600080fd5b803590602001918460208302840111600160201b831117156114d957600080fd5b9190808060200260200160405190810160405280939291908181526020018383602002808284376000920191909152509295949360208101935035915050600160201b81111561152857600080fd5b82018360208201111561153a57600080fd5b803590602001918460208302840111600160201b8311171561155b57600080fd5b919080806020026020016040519081016040528093929190818152602001838360200280828437600092019190915250929550613402945050505050565b6106d0600480360360408110156115af57600080fd5b5080359060200135613467565b61056b61348e565b610454600480360360208110156115da57600080fd5b503561ffff16613807565b610454600480360360208110156115fb57600080fd5b503561381c565b61056b6004803603604081101561161857600080fd5b508035906020013560ff166138a4565b6105236139e6565b6106d06139f5565b61056b6004803603602081101561164e57600080fd5b503561ffff166139fb565b6104546004803603604081101561166f57600080fd5b506001600160a01b0381358116916020013516613b04565b6116a46004803603602081101561169d57600080fd5b5035613b32565b6040805160ff9092168252519081900360200190f35b61056b600480360360408110156116d057600080fd5b506001600160a01b038135169060200135613bba565b61056b600480360360208110156116fc57600080fd5b50356001600160a01b0316613d8e565b6106d0613dde565b6117316004803603602081101561172a57600080fd5b5035613de4565b6040805161ffff938416815291909216602082015281519081900390910190f35b61056b6004803603602081101561176857600080fd5b50351515613e10565b6001600160e01b0319811660009081526001602052604090205460ff165b919050565b601d6020526000908152604090205460ff1681565b60068054604080516020601f60026000196101006001881615020190951694909404938401819004810282018101909252828152606093909290918301828280156118355780601f1061180a57610100808354040283529160200191611835565b820191906000526020600020905b81548152906001019060200180831161181857829003601f168201915b505050505090505b90565b600061184b82613e75565b6118865760405162461bcd60e51b8152600401808060200182810382526028815260200180615aa96028913960400191505060405180910390fd5b60096000600f848154811061189757fe5b6000918252602080832060058084049091015492066006026101000a90910465ffffffffffff1683528201929092526040019020546001600160a01b031692915050565b60006118e6826126d0565b9050806001600160a01b0316836001600160a01b0316141561194f576040805162461bcd60e51b815260206004820152601d60248201527f42543a20617070726f76616c20746f2063757272656e74206f776e6572000000604482015290519081900360640190fd5b336001600160a01b038216148061196b575061196b8133613b04565b6119a65760405162461bcd60e51b8152600401808060200182810382526034815260200180615bb16034913960400191505060405180910390fd5b6119af83613e92565b600f83815481106119bc57fe5b90600052602060002090600591828204019190066006026101000a81548165ffffffffffff021916908365ffffffffffff16021790555081836001600160a01b0316826001600160a01b03167f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b92560405160405180910390a4505050565b60005b8151811015611a6b57611a638484848481518110611a5657fe5b60200260200101516120c6565b600101611a3c565b50505050565b60005b8151811015611aa157611a99828281518110611a8c57fe5b60200260200101516123c8565b600101611a74565b5050565b600d5490565b6000611ab68261203e565b611af05760148281548110611ac757fe5b90600052602060002090601091828204019190066002029054906101000a900461ffff16611b64565b602080546040805163f3beae6b60e01b81526004810186905290516001600160a01b039092169263f3beae6b92602480840193829003018186803b158015611b3757600080fd5b505afa158015611b4b573d6000803e3d6000fd5b505050506040513d6020811015611b6157600080fd5b50515b92915050565b611b72612d07565b611bb1576040805162461bcd60e51b81526020600482018190526024820152600080516020615c91833981519152604482015290519081900360640190fd5b60005b8851811015611f90576000898281518110611bcb57fe5b6020026020010151905060008161ffff1611611c2e576040805162461bcd60e51b815260206004820152601c60248201527f436f72653a2070726f746f206d757374206e6f74206265207a65726f00000000604482015290519081900360640190fd5b611c36615935565b60188261ffff1681548110611c4757fe5b60009182526020918290206040805161012081018252929091015460ff808216158015855261010080840483161515968601969096526201000083048216938501939093526301000000820481166060850152600160201b820481166080850152650100000000008204811660a0850152600160301b8204811660c0850152600160381b8204811660e0850152600160401b90910416928201929092529150611d2f576040805162461bcd60e51b815260206004820152601560248201527410dbdc994e881c1c9bdd1bc81a5cc81b1bd8dad959605a1b604482015290519081900360640190fd5b6040518061012001604052806000151581526020016001151581526020018b8581518110611d5957fe5b602002602001015160ff1681526020018a8581518110611d7557fe5b602002602001015160ff168152602001898581518110611d9157fe5b602002602001015160ff168152602001888581518110611dad57fe5b602002602001015160ff168152602001878581518110611dc957fe5b602002602001015160ff168152602001868581518110611de557fe5b602002602001015160ff168152602001858581518110611e0157fe5b602002602001015160ff1681525060188361ffff1681548110611e2057fe5b9060005260206000200160008201518160000160006101000a81548160ff02191690831515021790555060208201518160000160016101000a81548160ff02191690831515021790555060408201518160000160026101000a81548160ff021916908360ff16021790555060608201518160000160036101000a81548160ff021916908360ff16021790555060808201518160000160046101000a81548160ff021916908360ff16021790555060a08201518160000160056101000a81548160ff021916908360ff16021790555060c08201518160000160066101000a81548160ff021916908360ff16021790555060e08201518160000160076101000a81548160ff021916908360ff1602179055506101008201518160000160086101000a81548160ff021916908360ff1602179055509050508161ffff167fe5d944d271f23cc2929e365ddfb8aa53de16aeb0e3c43908c454fc1110ceed7f60405160405180910390a25050600101611bb4565b505050505050505050565b611fa3612d07565b611fe2576040805162461bcd60e51b81526020600482018190526024820152600080516020615c91833981519152604482015290519081900360640190fd5b601780546001600160a01b0319166001600160a01b0392909216919091179055565b600a6020526000908152604090205465ffffffffffff1681565b601c60209081526000928352604080842090915290825290205460ff1681565b600061204982613e75565b612090576040805162461bcd60e51b815260206004820152601360248201527218d85c9908191bd95cc81b9bdd08195e1a5cdd606a1b604482015290519081900360640190fd5b6014828154811061209d57fe5b60009182526020909120601082040154600f9091166002026101000a900461ffff161592915050565b6120d76120d1613f99565b82613f9d565b6121125760405162461bcd60e51b8152600401808060200182810382526031815260200180615cf56031913960400191505060405180910390fd5b61211d838383614041565b505050565b601b60209081526000928352604080842090915290825290205460ff1681565b61fde881565b612150612d07565b61218f576040805162461bcd60e51b81526020600482018190526024820152600080516020615c91833981519152604482015290519081900360640190fd5b60008151116121d6576040805162461bcd60e51b815260206004820152600e60248201526d6d757374206c6f636b20736f6d6560901b604482015290519081900360640190fd5b60005b8151811015611aa15760008282815181106121f057fe5b6020026020010151905060008161ffff161161224c576040805162461bcd60e51b815260206004820152601660248201527570726f746f206d757374206e6f74206265207a65726f60501b604482015290519081900360640190fd5b600060188261ffff168154811061225f57fe5b6000918252602090912001805490915060ff16156122b6576040805162461bcd60e51b815260206004820152600f60248201526e1c1c9bdd1bc81a5cc81b1bd8dad959608a1b604482015290519081900360640190fd5b8054610100900460ff16612304576040805162461bcd60e51b815260206004820152601060248201526f1c1c9bdd1bc81b5d5cdd08195e1a5cdd60821b604482015290519081900360640190fd5b805460ff1916600117815560405161ffff8316907fe5d944d271f23cc2929e365ddfb8aa53de16aeb0e3c43908c454fc1110ceed7f90600090a250506001016121d9565b60408051600160208083019190915281830194909452606080820193909352815180820390930183526080019052805191012090565b604080516000602080830191909152818301939093528151808203830181526060909101909152805191012090565b61211d83838360405180602001604052806000815250613039565b6123d18161381c565b61241b576040805162461bcd60e51b8152602060048201526016602482015275436f72653a206e6f7420796574207472616461626c6560501b604482015290519081900360640190fd5b6124248161409d565b50565b805a11156124245761243761348e565b612427565b602054600160a01b900460ff1681565b612454612d07565b612493576040805162461bcd60e51b81526020600482018190526024820152600080516020615c91833981519152604482015290519081900360640190fd5b8051611aa190601f906020840190615981565b6017546001600160a01b03163314612505576040805162461bcd60e51b815260206004820152601e60248201527f436f72653a206d7573742062652070726f7065727479206d616e616765720000604482015290519081900360640190fd5b61211d8383836141c7565b60009081526010602052604090205465ffffffffffff811691600160301b90910461ffff1690565b602054600090600160a01b900460ff1615612592576040805162461bcd60e51b81526020600482015260156024820152746d757374206e6f74206265206d6967726174696e6760581b604482015290519081900360640190fd5b61259d848484614226565b509392505050565b6125ad612d07565b6125ec576040805162461bcd60e51b81526020600482018190526024820152600080516020615c91833981519152604482015290519081900360640190fd5b61fde861ffff82161015612636576040805162461bcd60e51b815260206004820152600c60248201526b6e6f742061206d797468696360a01b604482015290519081900360640190fd5b61ffff81166000908152601c602090815260408083206001600160a01b038616845290915290205460ff161561269d5760405162461bcd60e51b8152600401808060200182810382526036815260200180615d876036913960400191505060405180910390fd5b61ffff166000908152601c602090815260408083206001600160a01b03909416835292905220805460ff19166001179055565b600080600e83815481106126e057fe5b90600052602060002090600591828204019190066006029054906101000a900465ffffffffffff1690508065ffffffffffff1660001415612814576000612726846129c0565b90506127306159ff565b5060008181526010602090815260409182902082518084019093525465ffffffffffff81168352600160301b900461ffff16908201819052820185106127bd576040805162461bcd60e51b815260206004820152601860248201527f42543a20746f6b656e20646f6573206e6f742065786973740000000000000000604482015290519081900360640190fd5b8051925065ffffffffffff8316612811576040805162461bcd60e51b8152602060048201526013602482015272212a1d103130b2103130ba31b41037bbb732b960691b604482015290519081900360640190fd5b50505b65ffffffffffff166000908152600960205260409020546001600160a01b031692915050565b6009602052600090815260409020546001600160a01b031681565b601f80546040805160206002600019610100600187161502019094169390930480850184900484028201840190925281815292918301828280156128da5780601f106128af576101008083540402835291602001916128da565b820191906000526020600020905b8154815290600101906020018083116128bd57829003601f168201915b505050505081565b6001600160a01b031660009081526012602052604090205490565b612905612d07565b612944576040805162461bcd60e51b81526020600482018190526024820152600080516020615c91833981519152604482015290519081900360640190fd5b600080546040516001600160a01b03909116907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0908390a3600080546001600160a01b0319169055565b60005b8151811015611a6b576129b884848484815181106129ab57fe5b60200260200101516123ad565b600101612991565b600b54600090611b64906129da848263ffffffff61442916565b9063ffffffff61447216565b60006129f0612d07565b612a2f576040805162461bcd60e51b81526020600482018190526024820152600080516020615c91833981519152604482015290519081900360640190fd5b60008361ffff1611612a88576040805162461bcd60e51b815260206004820152601c60248201527f436f72653a206d757374206e6f74206265207a65726f2070726f746f00000000604482015290519081900360640190fd5b8261ffff168261ffff1611612ae4576040805162461bcd60e51b815260206004820152601b60248201527f436f72653a206d75737420626520612076616c69642072616e67650000000000604482015290519081900360640190fd5b6019541580612b175750601980546000198101908110612b0057fe5b60009182526020909120015461ffff908116908416115b612b68576040805162461bcd60e51b815260206004820152601c60248201527f436f72653a20736561736f6e732063616e6e6f74206f7665726c617000000000604482015290519081900360640190fd5b61ffff821661fde811612bac5760405162461bcd60e51b8152600401808060200182810382526025815260200180615b426025913960400191505060405180910390fd5b6040805180820190915261ffff80841682528481166020830181815260198054600181810180845560009390935295517f944998273e477b495144fb8794c914197f3ccb46be2900f4698fd0ef743c9695909101805493518616620100000263ffff00001992871661ffff1990951694909417919091169290921790915592601692612c43928492909189890390910116856144cb565b8361ffff168561ffff168361ffff167f894c7f27fb3eb8728566da10c21ff64cffafe6700bf22074e653fcd20acc8bba896040518080602001828103825283818151815260200191508051906020019080838360005b83811015612cb1578181015183820152602001612c99565b50505050905090810190601f168015612cde5780820380516001836020036101000a031916815260200191505b509250505060405180910390a45061ffff16949350505050565b6000546001600160a01b031690565b600080546001600160a01b0316612d1c613f99565b6001600160a01b031614905090565b60078054604080516020601f60026000196101006001881615020190951694909404938401819004810282018101909252828152606093909290918301828280156118355780601f1061180a57610100808354040283529160200191611835565b600d5481565b600060136000612da18461237e565b8152602001908152602001600020549050919050565b612dbf613f99565b6001600160a01b0316826001600160a01b03161415612e25576040805162461bcd60e51b815260206004820152601960248201527f4552433732313a20617070726f766520746f2063616c6c657200000000000000604482015290519081900360640190fd5b8060056000612e32613f99565b6001600160a01b03908116825260208083019390935260409182016000908120918716808252919093529120805460ff191692151592909217909155612e76613f99565b60408051841515815290516001600160a01b0392909216917f17307eab39ab6107e8899845ad3d59bd9653f200f220920489ca2b5937696c319181900360200190a35050565b6017546001600160a01b03163314612f1b576040805162461bcd60e51b815260206004820152601e60248201527f436f72653a206d7573742062652070726f7065727479206d616e616765720000604482015290519081900360640190fd5b611aa1828261450f565b60188181548110612f3257fe5b60009182526020909120015460ff8082169250610100820481169162010000810482169163010000008204811691600160201b8104821691650100000000008204811691600160301b8104821691600160381b8204811691600160401b90041689565b815b81811015612fb257612faa8585836123ad565b600101612f97565b5050505050565b601a6020526000908152604090205460ff1681565b60106020526000908152604090205465ffffffffffff811690600160301b900461ffff1682565b6016818154811061300257fe5b9060005260206000209060109182820401919006600202915054906101000a900461ffff1681565b6020546001600160a01b031681565b61304a613044613f99565b83613f9d565b6130855760405162461bcd60e51b8152600401808060200182810382526031815260200180615cf56031913960400191505060405180910390fd5b611a6b84848484614568565b60008061309d8361203e565b61310457601483815481106130ae57fe5b90600052602060002090601091828204019190066002029054906101000a900461ffff16601584815481106130df57fe5b90600052602060002090602091828204019190069054906101000a900460ff16613181565b6020546040805163b93a89f760e01b81526004810186905281516001600160a01b039093169263b93a89f792602480840193919291829003018186803b15801561314d57600080fd5b505afa158015613161573d6000803e3d6000fd5b505050506040513d604081101561317757600080fd5b5080516020909101515b91509150915091565b613192612d07565b6131d1576040805162461bcd60e51b81526020600482018190526024820152600080516020615c91833981519152604482015290519081900360640190fd5b6000811180156131e357506019548111155b613234576040805162461bcd60e51b815260206004820152601e60248201527f436f72653a206d75737420626520612063757272656e7420736561736f6e0000604482015290519081900360640190fd5b6000818152601a602052604090205460ff16156132825760405162461bcd60e51b8152600401808060200182810382526021815260200180615a316021913960400191505060405180910390fd5b6000908152601a60205260409020805460ff19166001179055565b60136020526000908152604090205481565b815b81811015612fb2576132c48585836120c6565b6001016132b1565b6060601f6132d9306145ba565b6132e284614758565b60405160200180848054600181600116156101000203166002900480156133405780601f1061331e576101008083540402835291820191613340565b820191906000526020600020905b81548152906001019060200180831161332c575b5050835160208501908083835b6020831061336c5780518252601f19909201916020918201910161334d565b6001836020036101000a03801982511681845116808217855250505050505090500180602f60f81b81525060010182805190602001908083835b602083106133c55780518252601f1990920191602091820191016133a6565b6001836020036101000a03801982511681845116808217855250505050505090500193505050506040516020818303038152906040529050919050565b602054600090600160a01b900460ff161561345c576040805162461bcd60e51b81526020600482015260156024820152746d757374206e6f74206265206d6967726174696e6760581b604482015290519081900360640190fd5b61259d84848461481c565b6000601360006134778585612348565b815260200190815260200160002054905092915050565b602054600160a01b900460ff166134e0576040805162461bcd60e51b81526020600482015260116024820152706d757374206265206d6967726174696e6760781b604482015290519081900360640190fd5b600c546020546040805163b32c4d8d60e01b815260048101849052815160009384936001600160a01b039091169263b32c4d8d9260248083019392829003018186803b15801561352f57600080fd5b505afa158015613543573d6000803e3d6000fd5b505050506040513d604081101561355957600080fd5b508051602090910151909250905061ffff811615801590613582575060008265ffffffffffff16115b6135d3576040805162461bcd60e51b815260206004820181905260248201527f696e636f7272656374206261746368206f72206c696d69742072656163686564604482015290519081900360640190fd5b602080546040805163f3beae6b60e01b81526004810187905290516001600160a01b039092169263f3beae6b92602480840193829003018186803b15801561361a57600080fd5b505afa15801561362e573d6000803e3d6000fd5b505050506040513d602081101561364457600080fd5b505161ffff16156137ea576020805460408051636602eaf960e01b815265ffffffffffff8616600482015290516000936001600160a01b0390931692636602eaf99260248082019391829003018186803b1580156136a157600080fd5b505afa1580156136b5573d6000803e3d6000fd5b505050506040513d60208110156136cb57600080fd5b5051905060006136da82613e92565b60408051808201825265ffffffffffff838116825261ffff878116602080850182815260008d8152601090925295812094518554965165ffffffffffff1990971694169390931767ffff0000000000001916600160301b95909216949094021790915591925061374b9087906149ab565b9050855b818110156137855760405181906001600160a01b03861690600090600080516020615cb1833981519152908290a460010161374f565b506001600160a01b0383166000908152601260205260409020546137b39061ffff861663ffffffff6149ab16565b6001600160a01b038416600090815260126020526040902055600d546137e39061ffff861663ffffffff6149ab16565b600d555050505b600b54600c546137ff9163ffffffff6149ab16565b600c55505050565b601e6020526000908152604090205460ff1681565b60008061382883611aab565b905061fde861ffff8216106138545761ffff166000908152601d602052604090205460ff16905061178f565b601a600060168361ffff168154811061386957fe5b60009182526020808320601083040154600f9092166002026101000a90910461ffff16835282019290925260400190205460ff169392505050565b6000601483815481106138b357fe5b90600052602060002090601091828204019190066002029054906101000a900461ffff169050600060168261ffff16815481106138ec57fe5b60009182526020808320601083040154338452601b82526040808520600f9094166002026101000a90910461ffff16808552929091529091205490915060ff166139675760405162461bcd60e51b8152600401808060200182810382526031815260200180615d266031913960400191505060405180910390fd5b826015858154811061397557fe5b600091825260209182902082820401805460ff948516601f9093166101000a92830292850219169190911790556040805192861683523391830191909152805186927f892269e637adec3404715b55a46b36fba9383a540f8f5859b364909469fcd04d92908290030190a250505050565b6017546001600160a01b031681565b600c5481565b613a03612d07565b613a42576040805162461bcd60e51b81526020600482018190526024820152600080516020615c91833981519152604482015290519081900360640190fd5b61fde861ffff82161015613a92576040805162461bcd60e51b8152602060048201526012602482015271436f72653a206e6f742061206d797468696360701b604482015290519081900360640190fd5b61ffff81166000908152601d602052604090205460ff1615613ae55760405162461bcd60e51b8152600401808060200182810382526022815260200180615b676022913960400191505060405180910390fd5b61ffff166000908152601d60205260409020805460ff19166001179055565b6001600160a01b03918216600090815260056020908152604080832093909416825291909152205460ff1690565b6000613b3d8261203e565b613b735760158281548110613b4e57fe5b90600052602060002090602091828204019190069054906101000a900460ff16611b64565b6020805460408051630158ce7560e11b81526004810186905290516001600160a01b03909216926302b19cea92602480840193829003018186803b158015611b3757600080fd5b613bc2612d07565b613c01576040805162461bcd60e51b81526020600482018190526024820152600080516020615c91833981519152604482015290519081900360640190fd5b601954811115613c58576040805162461bcd60e51b815260206004820152601760248201527f436f72653a20736561736f6e206d757374206578697374000000000000000000604482015290519081900360640190fd5b60008111613cad576040805162461bcd60e51b815260206004820152601a60248201527f436f72653a20736561736f6e206d757374206e6f742062652030000000000000604482015290519081900360640190fd5b6001600160a01b0382166000908152601b6020908152604080832084845290915290205460ff1615613d105760405162461bcd60e51b8152600401808060200182810382526026815260200180615af76026913960400191505060405180910390fd5b6000818152601a602052604090205460ff1615613d5e5760405162461bcd60e51b8152600401808060200182810382526021815260200180615a316021913960400191505060405180910390fd5b6001600160a01b039091166000908152601b6020908152604080832093835292905220805460ff19166001179055565b613d96612d07565b613dd5576040805162461bcd60e51b81526020600482018190526024820152600080516020615c91833981519152604482015290519081900360640190fd5b61242481614a05565b600b5481565b60198181548110613df157fe5b60009182526020909120015461ffff8082169250620100009091041682565b613e18612d07565b613e57576040805162461bcd60e51b81526020600482018190526024820152600080516020615c91833981519152604482015290519081900360640190fd5b60208054911515600160a01b0260ff60a01b19909216919091179055565b600080613e81836126d0565b6001600160a01b0316141592915050565b60006001600160a01b038216613eaa5750600061178f565b6001600160a01b0382166000908152600a602052604090205465ffffffffffff1680611b645760115465ffffffffffff9081166001810190911611613f2e576040805162461bcd60e51b815260206004820152601560248201527442543a206d757374206e6f74206f766572666c6f7760581b604482015290519081900360640190fd5b506011805465ffffffffffff8082166001810190911665ffffffffffff1992831617909255600082815260096020908152604080832080546001600160a01b0389166001600160a01b031990911681179091558352600a909152902080549091168217905592915050565b3390565b6000613fa882613e75565b613fe35760405162461bcd60e51b815260040180806020018281038252602c815260200180615be5602c913960400191505060405180910390fd5b6000613fee836126d0565b9050806001600160a01b0316846001600160a01b031614806140295750836001600160a01b031661401e84611840565b6001600160a01b0316145b8061403957506140398185613b04565b949350505050565b61404a8161381c565b614092576040805162461bcd60e51b815260206004820152601460248201527342573a206e6f7420796574207472616461626c6560601b604482015290519081900360640190fd5b61211d838383614aa5565b6140a73382613f9d565b6140e25760405162461bcd60e51b8152600401808060200182810382526024815260200180615cd16024913960400191505060405180910390fd5b6140eb81614b03565b60006140f6826126d0565b6001600160a01b03811660009081526012602052604090205490915061412390600163ffffffff614b9016565b6001600160a01b038216600090815260126020526040812091909155600e80548490811061414d57fe5b90600052602060002090600591828204019190066006026101000a81548165ffffffffffff021916908365ffffffffffff16021790555061419a6001600d54614b9090919063ffffffff16565b600d5560405182906000906001600160a01b03841690600080516020615cb1833981519152908390a45050565b80601360006141d68686612348565b81526020019081526020016000208190555081837fe437ad402a50c14d9de944e1d68d9708776aaccb860bd49a6e875a64e7d0b22a836040518082815260200191505060405180910390a3505050565b6000614233846001614bd2565b905061423e83614dcd565b826014828154811061424c57fe5b90600052602060002090601091828204019190066002026101000a81548161ffff021916908361ffff160217905550816015828154811061428957fe5b90600052602060002090602091828204019190066101000a81548160ff021916908360ff160217905550606060016040519080825280602002602001820160405280156142e0578160200160208202803883390190505b50905083816000815181106142f157fe5b61ffff90921660209283029190910190910152604080516001808252818301909252606091816020016020820280388339019050509050838160008151811061433657fe5b602002602001019060ff16908160ff1681525050827f9c681932e4a9582af05182ce765050b6b731e429b839bcdf8463177531afdae587848460405180846001600160a01b03166001600160a01b031681526020018060200180602001838103835285818151815260200191508051906020019060200280838360005b838110156143cb5781810151838201526020016143b3565b50505050905001838103825284818151815260200191508051906020019060200280838360005b8381101561440a5781810151838201526020016143f2565b505050509050019550505050505060405180910390a250509392505050565b600061446b83836040518060400160405280601a81526020017f536166654d6174683a206469766973696f6e206279207a65726f000000000000815250614eca565b9392505050565b60008261448157506000611b64565b8282028284828161448e57fe5b041461446b5760405162461bcd60e51b8152600401808060200182810382526021815260200180615c706021913960400191505060405180910390fd5b60606144da8585601086614f6c565b905060005b83811015614501576144f982866010848761ffff16615032565b6001016144df565b50612fb285856010846150ba565b60408051828152905183917fa065fb8968d66241513c49df78364990dc9917fcd41ede326cef2c15e82f4aec919081900360200190a280601360006145538561237e565b81526020810191909152604001600020555050565b614573848484614041565b61457f84848484615117565b611a6b5760405162461bcd60e51b8152600401808060200182810382526032815260200180615a776032913960400191505060405180910390fd5b60408051602a80825260608281019093526001600160a01b038416918391602082018180388339019050509050600360fc1b816000815181106145f957fe5b60200101906001600160f81b031916908160001a905350600f60fb1b8160018151811061462257fe5b60200101906001600160f81b031916908160001a90535060005b601481101561259d576040518060400160405280601081526020016f181899199a1a9b1b9c1cb0b131b232b360811b81525060048483600c016020811061467f57fe5b1a60f81b6001600160f81b031916901c60f81c60ff168151811061469f57fe5b602001015160f81c60f81b8282600202600201815181106146bc57fe5b60200101906001600160f81b031916908160001a9053506040518060400160405280601081526020016f181899199a1a9b1b9c1cb0b131b232b360811b8152508382600c016020811061470b57fe5b825191901a600f1690811061471c57fe5b602001015160f81c60f81b82826002026003018151811061473957fe5b60200101906001600160f81b031916908160001a90535060010161463c565b60608161477d57506040805180820190915260018152600360fc1b602082015261178f565b8160005b811561479557600101600a82049150614781565b6060816040519080825280601f01601f1916602001820160405280156147c2576020820181803883390190505b50859350905060001982015b831561481357600a840660300160f81b828280600190039350815181106147f157fe5b60200101906001600160f81b031916908160001a905350600a840493506147ce565b50949350505050565b600080835111614873576040805162461bcd60e51b815260206004820152601960248201527f436f72653a206d75737420626520736f6d652070726f746f7300000000000000604482015290519081900360640190fd5b81518351146148b35760405162461bcd60e51b8152600401808060200182810382526031815260200180615c116031913960400191505060405180910390fd5b60006148c0858551614bd2565b90506148cd81858561526e565b807f9c681932e4a9582af05182ce765050b6b731e429b839bcdf8463177531afdae586868660405180846001600160a01b03166001600160a01b031681526020018060200180602001838103835285818151815260200191508051906020019060200280838360005b8381101561494e578181015183820152602001614936565b50505050905001838103825284818151815260200191508051906020019060200280838360005b8381101561498d578181015183820152602001614975565b505050509050019550505050505060405180910390a2949350505050565b60008282018381101561446b576040805162461bcd60e51b815260206004820152601b60248201527f536166654d6174683a206164646974696f6e206f766572666c6f770000000000604482015290519081900360640190fd5b6001600160a01b038116614a4a5760405162461bcd60e51b8152600401808060200182810382526026815260200180615ad16026913960400191505060405180910390fd5b600080546040516001600160a01b03808516939216917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e091a3600080546001600160a01b0319166001600160a01b0392909216919091179055565b614aae8161381c565b614af8576040805162461bcd60e51b8152602060048201526016602482015275436f72653a206e6f7420796574207472616461626c6560501b604482015290519081900360640190fd5b61211d838383615291565b600f8181548110614b1057fe5b90600052602060002090600591828204019190066006029054906101000a900465ffffffffffff1665ffffffffffff16600014612424576000600f8281548110614b5657fe5b90600052602060002090600591828204019190066006026101000a81548165ffffffffffff021916908365ffffffffffff16021790555050565b600061446b83836040518060400160405280601e81526020017f536166654d6174683a207375627472616374696f6e206f766572666c6f77000081525061548c565b60006001600160a01b038316614c26576040805162461bcd60e51b815260206004820152601460248201527310950e881b5d5cdd081b9bdd081899481b9d5b1b60621b604482015290519081900360640190fd5b60008261ffff16118015614c405750600b548261ffff1611155b614c91576040805162461bcd60e51b815260206004820152601e60248201527f42543a2073697a65206d7573742062652077697468696e206c696d6974730000604482015290519081900360640190fd5b600c546000614c9f85613e92565b60408051808201825265ffffffffffff838116825261ffff888116602080850182815260008a8152601090925295812094518554965165ffffffffffff1990971694169390931767ffff0000000000001916600160301b959092169490940217909155919250614d109084906149ab565b9050825b81811015614d4a5760405181906001600160a01b03891690600090600080516020615cb1833981519152908290a4600101614d14565b50600b54600c54614d609163ffffffff6149ab16565b600c556001600160a01b038616600090815260126020526040902054614d909061ffff871663ffffffff6149ab16565b6001600160a01b038716600090815260126020526040902055600d54614dc09061ffff871663ffffffff6149ab16565b600d555090949350505050565b61fde861ffff821610614de857614de3816154e6565b612424565b600060168261ffff1681548110614dfb57fe5b60009182526020909120601082040154600f9091166002026101000a900461ffff16905080614e71576040805162461bcd60e51b815260206004820152601a60248201527f436f72653a206d757374206861766520736561736f6e20736574000000000000604482015290519081900360640190fd5b336000908152601b6020908152604080832084845290915290205460ff16611aa15760405162461bcd60e51b815260040180806020018281038252602e815260200180615c42602e913960400191505060405180910390fd5b60008183614f565760405162461bcd60e51b81526004018080602001828103825283818151815260200191508051906020019080838360005b83811015614f1b578181015183820152602001614f03565b50505050905090810190601f168015614f485780820380516001836020036101000a031916815260200191505b509250505060405180910390fd5b506000838581614f6257fe5b0495945050505050565b60606000614f7b8585856155b5565b905080604051908082528060200260200182016040528015614fa7578160200160208202803883390190505b5091506000614fb686866155e5565b9050614fc287826155f8565b83600081518110614fcf57fe5b6020026020010181815250506001821115615028576000614fff614ff9888763ffffffff6149ab16565b876155e5565b905061500b88826155f8565b84600185038151811061501a57fe5b602002602001018181525050505b5050949350505050565b6000836101008161503f57fe5b049050600081868161504d57fe5b0690506000828583018161505d57fe5b049050600086848988018161506e57fe5b0602905060005b878110156150ae578082018187901c60ff16901b8a848151811061509557fe5b6020908102919091010180519091179052600801615075565b50505050505050505050565b60006150d983610100816150ca57fe5b8691900463ffffffff61442916565b905060005b825181101561510f57615107868284018584815181106150fa57fe5b602002602001015161560e565b6001016150de565b505050505050565b600061512b846001600160a01b0316615623565b61513757506001614039565b6000846001600160a01b031663150b7a02615150613f99565b8887876040518563ffffffff1660e01b815260040180856001600160a01b03166001600160a01b03168152602001846001600160a01b03166001600160a01b0316815260200183815260200180602001828103825283818151815260200191508051906020019080838360005b838110156151d55781810151838201526020016151bd565b50505050905090810190601f1680156152025780820380516001836020036101000a031916815260200191505b5095505050505050602060405180830381600087803b15801561522457600080fd5b505af1158015615238573d6000803e3d6000fd5b505050506040513d602081101561524e57600080fd5b50516001600160e01b031916630a85bd0160e11b14915050949350505050565b6152778261565a565b6014615284818585615875565b6015612fb28186856158ce565b826001600160a01b03166152a4826126d0565b6001600160a01b0316146152e95760405162461bcd60e51b8152600401808060200182810382526025815260200180615b1d6025913960400191505060405180910390fd5b6001600160a01b038216615344576040805162461bcd60e51b815260206004820181905260248201527f42543a207472616e7366657220746f20746865207a65726f2061646472657373604482015290519081900360640190fd5b61534e3382613f9d565b6153895760405162461bcd60e51b8152600401808060200182810382526024815260200180615cd16024913960400191505060405180910390fd5b61539281614b03565b6001600160a01b0383166000908152601260205260409020546153bc90600163ffffffff614b9016565b6001600160a01b0380851660009081526012602052604080822093909355908416815220546153f290600163ffffffff6149ab16565b6001600160a01b03831660009081526012602052604090205561541482613e92565b600e828154811061542157fe5b90600052602060002090600591828204019190066006026101000a81548165ffffffffffff021916908365ffffffffffff16021790555080826001600160a01b0316846001600160a01b0316600080516020615cb183398151915260405160405180910390a4505050565b600081848411156154de5760405162461bcd60e51b8152602060048201818152835160248401528351909283926044909101919085019080838360008315614f1b578181015183820152602001614f03565b505050900390565b61ffff81166000908152601c6020908152604080832033845290915290205460ff166155435760405162461bcd60e51b8152600401808060200182810382526028815260200180615b896028913960400191505060405180910390fd5b61ffff81166000908152601e602052604090205460ff16156155965760405162461bcd60e51b8152600401808060200182810382526025815260200180615a526025913960400191505060405180910390fd5b61ffff166000908152601e60205260409020805460ff19166001179055565b6000808385816155c157fe5b049050600084848701816155d157fe5b049050818103600101925050509392505050565b60008183816155f057fe5b049392505050565b6000806156058484615926565b54949350505050565b600061561a8484615926565b91909155505050565b6000813f7fc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a47081158015906140395750141592915050565b600061ffff815b835181101561571857600084828151811061567857fe5b6020026020010151905061fde861ffff168161ffff16106156a15761569c816154e6565b61570f565b61ffff81166156e7576040805162461bcd60e51b815260206004820152600d60248201526c70726f746f206973207a65726f60981b604482015290519081900360640190fd5b8361ffff168161ffff1611156156fb578093505b8061ffff168361ffff16111561570f578092505b50600101615661565b5061ffff82161561211d57600060168361ffff168154811061573657fe5b60009182526020909120601082040154600f9091166002026101000a900461ffff169050806157ac576040805162461bcd60e51b815260206004820152601a60248201527f436f72653a206d757374206861766520736561736f6e20736574000000000000604482015290519081900360640190fd5b60168261ffff16815481106157bd57fe5b60009182526020909120601082040154600f9091166002026101000a900461ffff16811461581c5760405162461bcd60e51b8152600401808060200182810382526030815260200180615d576030913960400191505060405180910390fd5b336000908152601b6020908152604080832084845290915290205460ff16611a6b5760405162461bcd60e51b815260040180806020018281038252602e815260200180615c42602e913960400191505060405180910390fd5b6060615885848460108551614f6c565b905060005b82518110156158c0576158b882856010848786815181106158a757fe5b602002602001015161ffff16615032565b60010161588a565b50611a6b84846010846150ba565b60606158de848460208551614f6c565b905060005b825181101561591857615910828560088487868151811061590057fe5b602002602001015160ff16615032565b6001016158e3565b50611a6b84846008846150ba565b60405191825260209091200190565b6040805161012081018252600080825260208201819052918101829052606081018290526080810182905260a0810182905260c0810182905260e0810182905261010081019190915290565b828054600181600116156101000203166002900490600052602060002090601f016020900481019282601f106159c257805160ff19168380011785556159ef565b828001600101855582156159ef579182015b828111156159ef5782518255916020019190600101906159d4565b506159fb929150615a16565b5090565b604080518082019091526000808252602082015290565b61183d91905b808211156159fb5760008155600101615a1c56fe436f72653a20736561736f6e206d757374206e6f74206265207472616461626c65436f72653a206d79746869632068617320616c7265616479206265656e20637265617465644552433732313a207472616e7366657220746f206e6f6e20455243373231526563656976657220696d706c656d656e74657242543a20617070726f76656420717565727920666f72206e6f6e6578697374656e7420746f6b656e4f776e61626c653a206e6577206f776e657220697320746865207a65726f2061646472657373436f72653a207468697320666163746f727920697320616c726561647920617070726f76656442543a207472616e73666572206f6620746f6b656e2074686174206973206e6f74206f776e436f72653a2063616e6e6f7420676f20696e746f206d7974686963207465727269746f7279436f72653a206d757374206e6f74206265207472616461626c6520616c7265616479436f72653a206e6f7420617070726f76656420746f206372656174652074686973206d797468696342543a20617070726f76652063616c6c6572206973206e6f74206f776e6572206e6f7220617070726f76656420666f7220616c6c4552433732313a206f70657261746f7220717565727920666f72206e6f6e6578697374656e7420746f6b656e436f72653a206d757374206265207468652073616d65206e756d626572206f662070726f746f732f7175616c6974696573436f72653a206d75737420626520617070726f76656420666163746f727920666f72207468697320736561736f6e536166654d6174683a206d756c7469706c69636174696f6e206f766572666c6f774f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572ddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef42543a2063616c6c6572206973206e6f74206f776e6572206e6f7220617070726f7665644552433732313a207472616e736665722063616c6c6572206973206e6f74206f776e6572206e6f7220617070726f766564436f72653a20666163746f72792063616e2774206368616e6765207175616c697479206f66207468697320736561736f6e436f72653a2063616e206f6e6c79206372656174652063617264732066726f6d207468652073616d6520736561736f6e436f72653a207468697320666163746f727920697320616c726561647920617070726f76656420666f722074686973206d7974686963a265627a7a7231582043e9a7e6b7e4414fad1e9c0a5dedfe329bfdc975cacd75a9c559e1b495d6c26264736f6c634300050b0032000000000000000000000000629cdec6acc980ebeebea9e5003bcd44db9fc5ce00000000000000000000000000000000000000000000000000000000000004e3000000000000000000000000000000000000000000000000000000000000008000000000000000000000000000000000000000000000000000000000000000c00000000000000000000000000000000000000000000000000000000000000014476f647320556e636861696e656420436172647300000000000000000000000000000000000000000000000000000000000000000000000000000000000000044341524400000000000000000000000000000000000000000000000000000000

Deployed Bytecode

0x608060405234801561001057600080fd5b50600436106104285760003560e01c8063856516c31161022b578063c5f4127a11610130578063e7c51f1b116100b8578063ef42259b11610087578063ef42259b146116ba578063f2fde38b146116e6578063f4daaba11461170c578063f5d709a114611714578063f785f03d1461175257610428565b8063e7c51f1b14611630578063e8c238a114611638578063e985e9c514611659578063eb8d8ca11461168757610428565b8063cee15290116100ff578063cee15290146115bc578063e0c931df146115c4578063e27aa1d8146115e5578063e3fb1ac614611602578063e7356cb51461162857610428565b8063c5f4127a1461140d578063c87b56dd14611449578063c8be6b9b14611466578063cdc2cfe21461159957610428565b8063b0c4297c116101b3578063b83f866311610182578063b83f8663146112ca578063b88d4fde146112d2578063b93a89f714611396578063bc048525146113d3578063bd156273146113f057610428565b8063b0c4297c14611237578063b309c36b14611273578063b32c4d8d14611290578063b76e8d01146112ad57610428565b80639f181b5e116101fa5780639f181b5e14611151578063a138e44e14611159578063a22cb46514611176578063a9c1a200146111a4578063ab17d040146111c757610428565b8063856516c3146110845780638da5cb5b146111395780638f32d59b1461114157806395d89b411461114957610428565b806337514295116103315780635b65afe9116102b95780636c0360eb116102885780636c0360eb14610f7757806370a0823114610f7f578063715018a614610fa55780637962d59b14610fad578063815d9fa01461106757610428565b80635b65afe914610ecc5780636315a84d14610f055780636352211e14610f355780636602eaf914610f5257610428565b806345de9d431161030057806345de9d4314610d985780634956cf1c14610db557806355f804b314610dbd57806358895f6214610e615780635ac4428214610e8a57610428565b80633751429514610d055780633af0725614610d2857806342842e0e14610d4557806342966c6814610d7b57610428565b80631e41613c116103b4578063234f0e4611610383578063234f0e4614610bdd57806323b872dd14610bfa5780632488508714610c3057806324a01da114610c5c5780632fa438a314610c6457610428565b80631e41613c146107165780631e50739314610b465780631fe25e4f14610b6c57806321f3c46914610bad57610428565b8063095ea7b3116103fb578063095ea7b31461053f5780630bbe0ee31461056d578063100cdd911461062757806318160ddd146106c85780631dd0f662146106e257610428565b806301ffc9a71461042d57806304f8bcdf1461046857806306fdde0314610489578063081812fc14610506575b600080fd5b6104546004803603602081101561044357600080fd5b50356001600160e01b031916611771565b604080519115158252519081900360200190f35b6104546004803603602081101561047e57600080fd5b503561ffff16611794565b6104916117a9565b6040805160208082528351818301528351919283929083019185019080838360005b838110156104cb5781810151838201526020016104b3565b50505050905090810190601f1680156104f85780820380516001836020036101000a031916815260200191505b509250505060405180910390f35b6105236004803603602081101561051c57600080fd5b5035611840565b604080516001600160a01b039092168252519081900360200190f35b61056b6004803603604081101561055557600080fd5b506001600160a01b0381351690602001356118db565b005b61056b6004803603606081101561058357600080fd5b6001600160a01b038235811692602081013590911691810190606081016040820135600160201b8111156105b657600080fd5b8201836020820111156105c857600080fd5b803590602001918460208302840111600160201b831117156105e957600080fd5b919080806020026020016040519081016040528093929190818152602001838360200280828437600092019190915250929550611a39945050505050565b61056b6004803603602081101561063d57600080fd5b810190602081018135600160201b81111561065757600080fd5b82018360208201111561066957600080fd5b803590602001918460208302840111600160201b8311171561068a57600080fd5b919080806020026020016040519081016040528093929190818152602001838360200280828437600092019190915250929550611a71945050505050565b6106d0611aa5565b60408051918252519081900360200190f35b6106ff600480360360208110156106f857600080fd5b5035611aab565b6040805161ffff9092168252519081900360200190f35b61056b600480360361010081101561072d57600080fd5b810190602081018135600160201b81111561074757600080fd5b82018360208201111561075957600080fd5b803590602001918460208302840111600160201b8311171561077a57600080fd5b9190808060200260200160405190810160405280939291908181526020018383602002808284376000920191909152509295949360208101935035915050600160201b8111156107c957600080fd5b8201836020820111156107db57600080fd5b803590602001918460208302840111600160201b831117156107fc57600080fd5b9190808060200260200160405190810160405280939291908181526020018383602002808284376000920191909152509295949360208101935035915050600160201b81111561084b57600080fd5b82018360208201111561085d57600080fd5b803590602001918460208302840111600160201b8311171561087e57600080fd5b9190808060200260200160405190810160405280939291908181526020018383602002808284376000920191909152509295949360208101935035915050600160201b8111156108cd57600080fd5b8201836020820111156108df57600080fd5b803590602001918460208302840111600160201b8311171561090057600080fd5b9190808060200260200160405190810160405280939291908181526020018383602002808284376000920191909152509295949360208101935035915050600160201b81111561094f57600080fd5b82018360208201111561096157600080fd5b803590602001918460208302840111600160201b8311171561098257600080fd5b9190808060200260200160405190810160405280939291908181526020018383602002808284376000920191909152509295949360208101935035915050600160201b8111156109d157600080fd5b8201836020820111156109e357600080fd5b803590602001918460208302840111600160201b83111715610a0457600080fd5b9190808060200260200160405190810160405280939291908181526020018383602002808284376000920191909152509295949360208101935035915050600160201b811115610a5357600080fd5b820183602082011115610a6557600080fd5b803590602001918460208302840111600160201b83111715610a8657600080fd5b9190808060200260200160405190810160405280939291908181526020018383602002808284376000920191909152509295949360208101935035915050600160201b811115610ad557600080fd5b820183602082011115610ae757600080fd5b803590602001918460208302840111600160201b83111715610b0857600080fd5b919080806020026020016040519081016040528093929190818152602001838360200280828437600092019190915250929550611b6a945050505050565b61056b60048036036020811015610b5c57600080fd5b50356001600160a01b0316611f9b565b610b9260048036036020811015610b8257600080fd5b50356001600160a01b0316612004565b6040805165ffffffffffff9092168252519081900360200190f35b61045460048036036040811015610bc357600080fd5b50803561ffff1690602001356001600160a01b031661201e565b61045460048036036020811015610bf357600080fd5b503561203e565b61056b60048036036060811015610c1057600080fd5b506001600160a01b038135811691602081013590911690604001356120c6565b61045460048036036040811015610c4657600080fd5b506001600160a01b038135169060200135612122565b6106ff612142565b61056b60048036036020811015610c7a57600080fd5b810190602081018135600160201b811115610c9457600080fd5b820183602082011115610ca657600080fd5b803590602001918460208302840111600160201b83111715610cc757600080fd5b919080806020026020016040519081016040528093929190818152602001838360200280828437600092019190915250929550612148945050505050565b6106d060048036036040811015610d1b57600080fd5b5080359060200135612348565b6106d060048036036020811015610d3e57600080fd5b503561237e565b61056b60048036036060811015610d5b57600080fd5b506001600160a01b038135811691602081013590911690604001356123ad565b61056b60048036036020811015610d9157600080fd5b50356123c8565b61056b60048036036020811015610dae57600080fd5b5035612427565b61045461243c565b61056b60048036036020811015610dd357600080fd5b810190602081018135600160201b811115610ded57600080fd5b820183602082011115610dff57600080fd5b803590602001918460018302840111600160201b83111715610e2057600080fd5b91908080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525092955061244c945050505050565b61056b60048036036060811015610e7757600080fd5b50803590602081013590604001356124a6565b610ea760048036036020811015610ea057600080fd5b5035612510565b6040805165ffffffffffff909316835261ffff90911660208301528051918290030190f35b6106d060048036036060811015610ee257600080fd5b5080356001600160a01b031690602081013561ffff16906040013560ff16612538565b61056b60048036036040811015610f1b57600080fd5b5080356001600160a01b0316906020013561ffff166125a5565b61052360048036036020811015610f4b57600080fd5b50356126d0565b61052360048036036020811015610f6857600080fd5b503565ffffffffffff1661283a565b610491612855565b6106d060048036036020811015610f9557600080fd5b50356001600160a01b03166128e2565b61056b6128fd565b61056b60048036036060811015610fc357600080fd5b6001600160a01b038235811692602081013590911691810190606081016040820135600160201b811115610ff657600080fd5b82018360208201111561100857600080fd5b803590602001918460208302840111600160201b8311171561102957600080fd5b91908080602002602001604051908101604052809392919081815260200183836020028082843760009201919091525092955061298e945050505050565b6106d06004803603602081101561107d57600080fd5b50356129c0565b6106d06004803603606081101561109a57600080fd5b810190602081018135600160201b8111156110b457600080fd5b8201836020820111156110c657600080fd5b803590602001918460018302840111600160201b831117156110e757600080fd5b91908080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152509295505061ffff83358116945060209093013590921691506129e69050565b610523612cf8565b610454612d07565b610491612d2b565b6106d0612d8c565b6106d06004803603602081101561116f57600080fd5b5035612d92565b61056b6004803603604081101561118c57600080fd5b506001600160a01b0381351690602001351515612db7565b61056b600480360360408110156111ba57600080fd5b5080359060200135612ebc565b6111e4600480360360208110156111dd57600080fd5b5035612f25565b604080519915158a5297151560208a015260ff968716898901529486166060890152928516608088015290841660a0870152831660c0860152821660e08501521661010083015251908190036101200190f35b61056b6004803603608081101561124d57600080fd5b506001600160a01b03813581169160208101359091169060408101359060600135612f95565b6104546004803603602081101561128957600080fd5b5035612fb9565b610ea7600480360360208110156112a657600080fd5b5035612fce565b6106ff600480360360208110156112c357600080fd5b5035612ff5565b61052361302a565b61056b600480360360808110156112e857600080fd5b6001600160a01b03823581169260208101359091169160408201359190810190608081016060820135600160201b81111561132257600080fd5b82018360208201111561133457600080fd5b803590602001918460018302840111600160201b8311171561135557600080fd5b91908080601f016020809104026020016040519081016040528093929190818152602001838380828437600092019190915250929550613039945050505050565b6113b3600480360360208110156113ac57600080fd5b5035613091565b6040805161ffff909316835260ff90911660208301528051918290030190f35b61056b600480360360208110156113e957600080fd5b503561318a565b6106d06004803603602081101561140657600080fd5b503561329d565b61056b6004803603608081101561142357600080fd5b506001600160a01b038135811691602081013590911690604081013590606001356132af565b6104916004803603602081101561145f57600080fd5b50356132cc565b6106d06004803603606081101561147c57600080fd5b6001600160a01b038235169190810190604081016020820135600160201b8111156114a657600080fd5b8201836020820111156114b857600080fd5b803590602001918460208302840111600160201b831117156114d957600080fd5b9190808060200260200160405190810160405280939291908181526020018383602002808284376000920191909152509295949360208101935035915050600160201b81111561152857600080fd5b82018360208201111561153a57600080fd5b803590602001918460208302840111600160201b8311171561155b57600080fd5b919080806020026020016040519081016040528093929190818152602001838360200280828437600092019190915250929550613402945050505050565b6106d0600480360360408110156115af57600080fd5b5080359060200135613467565b61056b61348e565b610454600480360360208110156115da57600080fd5b503561ffff16613807565b610454600480360360208110156115fb57600080fd5b503561381c565b61056b6004803603604081101561161857600080fd5b508035906020013560ff166138a4565b6105236139e6565b6106d06139f5565b61056b6004803603602081101561164e57600080fd5b503561ffff166139fb565b6104546004803603604081101561166f57600080fd5b506001600160a01b0381358116916020013516613b04565b6116a46004803603602081101561169d57600080fd5b5035613b32565b6040805160ff9092168252519081900360200190f35b61056b600480360360408110156116d057600080fd5b506001600160a01b038135169060200135613bba565b61056b600480360360208110156116fc57600080fd5b50356001600160a01b0316613d8e565b6106d0613dde565b6117316004803603602081101561172a57600080fd5b5035613de4565b6040805161ffff938416815291909216602082015281519081900390910190f35b61056b6004803603602081101561176857600080fd5b50351515613e10565b6001600160e01b0319811660009081526001602052604090205460ff165b919050565b601d6020526000908152604090205460ff1681565b60068054604080516020601f60026000196101006001881615020190951694909404938401819004810282018101909252828152606093909290918301828280156118355780601f1061180a57610100808354040283529160200191611835565b820191906000526020600020905b81548152906001019060200180831161181857829003601f168201915b505050505090505b90565b600061184b82613e75565b6118865760405162461bcd60e51b8152600401808060200182810382526028815260200180615aa96028913960400191505060405180910390fd5b60096000600f848154811061189757fe5b6000918252602080832060058084049091015492066006026101000a90910465ffffffffffff1683528201929092526040019020546001600160a01b031692915050565b60006118e6826126d0565b9050806001600160a01b0316836001600160a01b0316141561194f576040805162461bcd60e51b815260206004820152601d60248201527f42543a20617070726f76616c20746f2063757272656e74206f776e6572000000604482015290519081900360640190fd5b336001600160a01b038216148061196b575061196b8133613b04565b6119a65760405162461bcd60e51b8152600401808060200182810382526034815260200180615bb16034913960400191505060405180910390fd5b6119af83613e92565b600f83815481106119bc57fe5b90600052602060002090600591828204019190066006026101000a81548165ffffffffffff021916908365ffffffffffff16021790555081836001600160a01b0316826001600160a01b03167f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b92560405160405180910390a4505050565b60005b8151811015611a6b57611a638484848481518110611a5657fe5b60200260200101516120c6565b600101611a3c565b50505050565b60005b8151811015611aa157611a99828281518110611a8c57fe5b60200260200101516123c8565b600101611a74565b5050565b600d5490565b6000611ab68261203e565b611af05760148281548110611ac757fe5b90600052602060002090601091828204019190066002029054906101000a900461ffff16611b64565b602080546040805163f3beae6b60e01b81526004810186905290516001600160a01b039092169263f3beae6b92602480840193829003018186803b158015611b3757600080fd5b505afa158015611b4b573d6000803e3d6000fd5b505050506040513d6020811015611b6157600080fd5b50515b92915050565b611b72612d07565b611bb1576040805162461bcd60e51b81526020600482018190526024820152600080516020615c91833981519152604482015290519081900360640190fd5b60005b8851811015611f90576000898281518110611bcb57fe5b6020026020010151905060008161ffff1611611c2e576040805162461bcd60e51b815260206004820152601c60248201527f436f72653a2070726f746f206d757374206e6f74206265207a65726f00000000604482015290519081900360640190fd5b611c36615935565b60188261ffff1681548110611c4757fe5b60009182526020918290206040805161012081018252929091015460ff808216158015855261010080840483161515968601969096526201000083048216938501939093526301000000820481166060850152600160201b820481166080850152650100000000008204811660a0850152600160301b8204811660c0850152600160381b8204811660e0850152600160401b90910416928201929092529150611d2f576040805162461bcd60e51b815260206004820152601560248201527410dbdc994e881c1c9bdd1bc81a5cc81b1bd8dad959605a1b604482015290519081900360640190fd5b6040518061012001604052806000151581526020016001151581526020018b8581518110611d5957fe5b602002602001015160ff1681526020018a8581518110611d7557fe5b602002602001015160ff168152602001898581518110611d9157fe5b602002602001015160ff168152602001888581518110611dad57fe5b602002602001015160ff168152602001878581518110611dc957fe5b602002602001015160ff168152602001868581518110611de557fe5b602002602001015160ff168152602001858581518110611e0157fe5b602002602001015160ff1681525060188361ffff1681548110611e2057fe5b9060005260206000200160008201518160000160006101000a81548160ff02191690831515021790555060208201518160000160016101000a81548160ff02191690831515021790555060408201518160000160026101000a81548160ff021916908360ff16021790555060608201518160000160036101000a81548160ff021916908360ff16021790555060808201518160000160046101000a81548160ff021916908360ff16021790555060a08201518160000160056101000a81548160ff021916908360ff16021790555060c08201518160000160066101000a81548160ff021916908360ff16021790555060e08201518160000160076101000a81548160ff021916908360ff1602179055506101008201518160000160086101000a81548160ff021916908360ff1602179055509050508161ffff167fe5d944d271f23cc2929e365ddfb8aa53de16aeb0e3c43908c454fc1110ceed7f60405160405180910390a25050600101611bb4565b505050505050505050565b611fa3612d07565b611fe2576040805162461bcd60e51b81526020600482018190526024820152600080516020615c91833981519152604482015290519081900360640190fd5b601780546001600160a01b0319166001600160a01b0392909216919091179055565b600a6020526000908152604090205465ffffffffffff1681565b601c60209081526000928352604080842090915290825290205460ff1681565b600061204982613e75565b612090576040805162461bcd60e51b815260206004820152601360248201527218d85c9908191bd95cc81b9bdd08195e1a5cdd606a1b604482015290519081900360640190fd5b6014828154811061209d57fe5b60009182526020909120601082040154600f9091166002026101000a900461ffff161592915050565b6120d76120d1613f99565b82613f9d565b6121125760405162461bcd60e51b8152600401808060200182810382526031815260200180615cf56031913960400191505060405180910390fd5b61211d838383614041565b505050565b601b60209081526000928352604080842090915290825290205460ff1681565b61fde881565b612150612d07565b61218f576040805162461bcd60e51b81526020600482018190526024820152600080516020615c91833981519152604482015290519081900360640190fd5b60008151116121d6576040805162461bcd60e51b815260206004820152600e60248201526d6d757374206c6f636b20736f6d6560901b604482015290519081900360640190fd5b60005b8151811015611aa15760008282815181106121f057fe5b6020026020010151905060008161ffff161161224c576040805162461bcd60e51b815260206004820152601660248201527570726f746f206d757374206e6f74206265207a65726f60501b604482015290519081900360640190fd5b600060188261ffff168154811061225f57fe5b6000918252602090912001805490915060ff16156122b6576040805162461bcd60e51b815260206004820152600f60248201526e1c1c9bdd1bc81a5cc81b1bd8dad959608a1b604482015290519081900360640190fd5b8054610100900460ff16612304576040805162461bcd60e51b815260206004820152601060248201526f1c1c9bdd1bc81b5d5cdd08195e1a5cdd60821b604482015290519081900360640190fd5b805460ff1916600117815560405161ffff8316907fe5d944d271f23cc2929e365ddfb8aa53de16aeb0e3c43908c454fc1110ceed7f90600090a250506001016121d9565b60408051600160208083019190915281830194909452606080820193909352815180820390930183526080019052805191012090565b604080516000602080830191909152818301939093528151808203830181526060909101909152805191012090565b61211d83838360405180602001604052806000815250613039565b6123d18161381c565b61241b576040805162461bcd60e51b8152602060048201526016602482015275436f72653a206e6f7420796574207472616461626c6560501b604482015290519081900360640190fd5b6124248161409d565b50565b805a11156124245761243761348e565b612427565b602054600160a01b900460ff1681565b612454612d07565b612493576040805162461bcd60e51b81526020600482018190526024820152600080516020615c91833981519152604482015290519081900360640190fd5b8051611aa190601f906020840190615981565b6017546001600160a01b03163314612505576040805162461bcd60e51b815260206004820152601e60248201527f436f72653a206d7573742062652070726f7065727479206d616e616765720000604482015290519081900360640190fd5b61211d8383836141c7565b60009081526010602052604090205465ffffffffffff811691600160301b90910461ffff1690565b602054600090600160a01b900460ff1615612592576040805162461bcd60e51b81526020600482015260156024820152746d757374206e6f74206265206d6967726174696e6760581b604482015290519081900360640190fd5b61259d848484614226565b509392505050565b6125ad612d07565b6125ec576040805162461bcd60e51b81526020600482018190526024820152600080516020615c91833981519152604482015290519081900360640190fd5b61fde861ffff82161015612636576040805162461bcd60e51b815260206004820152600c60248201526b6e6f742061206d797468696360a01b604482015290519081900360640190fd5b61ffff81166000908152601c602090815260408083206001600160a01b038616845290915290205460ff161561269d5760405162461bcd60e51b8152600401808060200182810382526036815260200180615d876036913960400191505060405180910390fd5b61ffff166000908152601c602090815260408083206001600160a01b03909416835292905220805460ff19166001179055565b600080600e83815481106126e057fe5b90600052602060002090600591828204019190066006029054906101000a900465ffffffffffff1690508065ffffffffffff1660001415612814576000612726846129c0565b90506127306159ff565b5060008181526010602090815260409182902082518084019093525465ffffffffffff81168352600160301b900461ffff16908201819052820185106127bd576040805162461bcd60e51b815260206004820152601860248201527f42543a20746f6b656e20646f6573206e6f742065786973740000000000000000604482015290519081900360640190fd5b8051925065ffffffffffff8316612811576040805162461bcd60e51b8152602060048201526013602482015272212a1d103130b2103130ba31b41037bbb732b960691b604482015290519081900360640190fd5b50505b65ffffffffffff166000908152600960205260409020546001600160a01b031692915050565b6009602052600090815260409020546001600160a01b031681565b601f80546040805160206002600019610100600187161502019094169390930480850184900484028201840190925281815292918301828280156128da5780601f106128af576101008083540402835291602001916128da565b820191906000526020600020905b8154815290600101906020018083116128bd57829003601f168201915b505050505081565b6001600160a01b031660009081526012602052604090205490565b612905612d07565b612944576040805162461bcd60e51b81526020600482018190526024820152600080516020615c91833981519152604482015290519081900360640190fd5b600080546040516001600160a01b03909116907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0908390a3600080546001600160a01b0319169055565b60005b8151811015611a6b576129b884848484815181106129ab57fe5b60200260200101516123ad565b600101612991565b600b54600090611b64906129da848263ffffffff61442916565b9063ffffffff61447216565b60006129f0612d07565b612a2f576040805162461bcd60e51b81526020600482018190526024820152600080516020615c91833981519152604482015290519081900360640190fd5b60008361ffff1611612a88576040805162461bcd60e51b815260206004820152601c60248201527f436f72653a206d757374206e6f74206265207a65726f2070726f746f00000000604482015290519081900360640190fd5b8261ffff168261ffff1611612ae4576040805162461bcd60e51b815260206004820152601b60248201527f436f72653a206d75737420626520612076616c69642072616e67650000000000604482015290519081900360640190fd5b6019541580612b175750601980546000198101908110612b0057fe5b60009182526020909120015461ffff908116908416115b612b68576040805162461bcd60e51b815260206004820152601c60248201527f436f72653a20736561736f6e732063616e6e6f74206f7665726c617000000000604482015290519081900360640190fd5b61ffff821661fde811612bac5760405162461bcd60e51b8152600401808060200182810382526025815260200180615b426025913960400191505060405180910390fd5b6040805180820190915261ffff80841682528481166020830181815260198054600181810180845560009390935295517f944998273e477b495144fb8794c914197f3ccb46be2900f4698fd0ef743c9695909101805493518616620100000263ffff00001992871661ffff1990951694909417919091169290921790915592601692612c43928492909189890390910116856144cb565b8361ffff168561ffff168361ffff167f894c7f27fb3eb8728566da10c21ff64cffafe6700bf22074e653fcd20acc8bba896040518080602001828103825283818151815260200191508051906020019080838360005b83811015612cb1578181015183820152602001612c99565b50505050905090810190601f168015612cde5780820380516001836020036101000a031916815260200191505b509250505060405180910390a45061ffff16949350505050565b6000546001600160a01b031690565b600080546001600160a01b0316612d1c613f99565b6001600160a01b031614905090565b60078054604080516020601f60026000196101006001881615020190951694909404938401819004810282018101909252828152606093909290918301828280156118355780601f1061180a57610100808354040283529160200191611835565b600d5481565b600060136000612da18461237e565b8152602001908152602001600020549050919050565b612dbf613f99565b6001600160a01b0316826001600160a01b03161415612e25576040805162461bcd60e51b815260206004820152601960248201527f4552433732313a20617070726f766520746f2063616c6c657200000000000000604482015290519081900360640190fd5b8060056000612e32613f99565b6001600160a01b03908116825260208083019390935260409182016000908120918716808252919093529120805460ff191692151592909217909155612e76613f99565b60408051841515815290516001600160a01b0392909216917f17307eab39ab6107e8899845ad3d59bd9653f200f220920489ca2b5937696c319181900360200190a35050565b6017546001600160a01b03163314612f1b576040805162461bcd60e51b815260206004820152601e60248201527f436f72653a206d7573742062652070726f7065727479206d616e616765720000604482015290519081900360640190fd5b611aa1828261450f565b60188181548110612f3257fe5b60009182526020909120015460ff8082169250610100820481169162010000810482169163010000008204811691600160201b8104821691650100000000008204811691600160301b8104821691600160381b8204811691600160401b90041689565b815b81811015612fb257612faa8585836123ad565b600101612f97565b5050505050565b601a6020526000908152604090205460ff1681565b60106020526000908152604090205465ffffffffffff811690600160301b900461ffff1682565b6016818154811061300257fe5b9060005260206000209060109182820401919006600202915054906101000a900461ffff1681565b6020546001600160a01b031681565b61304a613044613f99565b83613f9d565b6130855760405162461bcd60e51b8152600401808060200182810382526031815260200180615cf56031913960400191505060405180910390fd5b611a6b84848484614568565b60008061309d8361203e565b61310457601483815481106130ae57fe5b90600052602060002090601091828204019190066002029054906101000a900461ffff16601584815481106130df57fe5b90600052602060002090602091828204019190069054906101000a900460ff16613181565b6020546040805163b93a89f760e01b81526004810186905281516001600160a01b039093169263b93a89f792602480840193919291829003018186803b15801561314d57600080fd5b505afa158015613161573d6000803e3d6000fd5b505050506040513d604081101561317757600080fd5b5080516020909101515b91509150915091565b613192612d07565b6131d1576040805162461bcd60e51b81526020600482018190526024820152600080516020615c91833981519152604482015290519081900360640190fd5b6000811180156131e357506019548111155b613234576040805162461bcd60e51b815260206004820152601e60248201527f436f72653a206d75737420626520612063757272656e7420736561736f6e0000604482015290519081900360640190fd5b6000818152601a602052604090205460ff16156132825760405162461bcd60e51b8152600401808060200182810382526021815260200180615a316021913960400191505060405180910390fd5b6000908152601a60205260409020805460ff19166001179055565b60136020526000908152604090205481565b815b81811015612fb2576132c48585836120c6565b6001016132b1565b6060601f6132d9306145ba565b6132e284614758565b60405160200180848054600181600116156101000203166002900480156133405780601f1061331e576101008083540402835291820191613340565b820191906000526020600020905b81548152906001019060200180831161332c575b5050835160208501908083835b6020831061336c5780518252601f19909201916020918201910161334d565b6001836020036101000a03801982511681845116808217855250505050505090500180602f60f81b81525060010182805190602001908083835b602083106133c55780518252601f1990920191602091820191016133a6565b6001836020036101000a03801982511681845116808217855250505050505090500193505050506040516020818303038152906040529050919050565b602054600090600160a01b900460ff161561345c576040805162461bcd60e51b81526020600482015260156024820152746d757374206e6f74206265206d6967726174696e6760581b604482015290519081900360640190fd5b61259d84848461481c565b6000601360006134778585612348565b815260200190815260200160002054905092915050565b602054600160a01b900460ff166134e0576040805162461bcd60e51b81526020600482015260116024820152706d757374206265206d6967726174696e6760781b604482015290519081900360640190fd5b600c546020546040805163b32c4d8d60e01b815260048101849052815160009384936001600160a01b039091169263b32c4d8d9260248083019392829003018186803b15801561352f57600080fd5b505afa158015613543573d6000803e3d6000fd5b505050506040513d604081101561355957600080fd5b508051602090910151909250905061ffff811615801590613582575060008265ffffffffffff16115b6135d3576040805162461bcd60e51b815260206004820181905260248201527f696e636f7272656374206261746368206f72206c696d69742072656163686564604482015290519081900360640190fd5b602080546040805163f3beae6b60e01b81526004810187905290516001600160a01b039092169263f3beae6b92602480840193829003018186803b15801561361a57600080fd5b505afa15801561362e573d6000803e3d6000fd5b505050506040513d602081101561364457600080fd5b505161ffff16156137ea576020805460408051636602eaf960e01b815265ffffffffffff8616600482015290516000936001600160a01b0390931692636602eaf99260248082019391829003018186803b1580156136a157600080fd5b505afa1580156136b5573d6000803e3d6000fd5b505050506040513d60208110156136cb57600080fd5b5051905060006136da82613e92565b60408051808201825265ffffffffffff838116825261ffff878116602080850182815260008d8152601090925295812094518554965165ffffffffffff1990971694169390931767ffff0000000000001916600160301b95909216949094021790915591925061374b9087906149ab565b9050855b818110156137855760405181906001600160a01b03861690600090600080516020615cb1833981519152908290a460010161374f565b506001600160a01b0383166000908152601260205260409020546137b39061ffff861663ffffffff6149ab16565b6001600160a01b038416600090815260126020526040902055600d546137e39061ffff861663ffffffff6149ab16565b600d555050505b600b54600c546137ff9163ffffffff6149ab16565b600c55505050565b601e6020526000908152604090205460ff1681565b60008061382883611aab565b905061fde861ffff8216106138545761ffff166000908152601d602052604090205460ff16905061178f565b601a600060168361ffff168154811061386957fe5b60009182526020808320601083040154600f9092166002026101000a90910461ffff16835282019290925260400190205460ff169392505050565b6000601483815481106138b357fe5b90600052602060002090601091828204019190066002029054906101000a900461ffff169050600060168261ffff16815481106138ec57fe5b60009182526020808320601083040154338452601b82526040808520600f9094166002026101000a90910461ffff16808552929091529091205490915060ff166139675760405162461bcd60e51b8152600401808060200182810382526031815260200180615d266031913960400191505060405180910390fd5b826015858154811061397557fe5b600091825260209182902082820401805460ff948516601f9093166101000a92830292850219169190911790556040805192861683523391830191909152805186927f892269e637adec3404715b55a46b36fba9383a540f8f5859b364909469fcd04d92908290030190a250505050565b6017546001600160a01b031681565b600c5481565b613a03612d07565b613a42576040805162461bcd60e51b81526020600482018190526024820152600080516020615c91833981519152604482015290519081900360640190fd5b61fde861ffff82161015613a92576040805162461bcd60e51b8152602060048201526012602482015271436f72653a206e6f742061206d797468696360701b604482015290519081900360640190fd5b61ffff81166000908152601d602052604090205460ff1615613ae55760405162461bcd60e51b8152600401808060200182810382526022815260200180615b676022913960400191505060405180910390fd5b61ffff166000908152601d60205260409020805460ff19166001179055565b6001600160a01b03918216600090815260056020908152604080832093909416825291909152205460ff1690565b6000613b3d8261203e565b613b735760158281548110613b4e57fe5b90600052602060002090602091828204019190069054906101000a900460ff16611b64565b6020805460408051630158ce7560e11b81526004810186905290516001600160a01b03909216926302b19cea92602480840193829003018186803b158015611b3757600080fd5b613bc2612d07565b613c01576040805162461bcd60e51b81526020600482018190526024820152600080516020615c91833981519152604482015290519081900360640190fd5b601954811115613c58576040805162461bcd60e51b815260206004820152601760248201527f436f72653a20736561736f6e206d757374206578697374000000000000000000604482015290519081900360640190fd5b60008111613cad576040805162461bcd60e51b815260206004820152601a60248201527f436f72653a20736561736f6e206d757374206e6f742062652030000000000000604482015290519081900360640190fd5b6001600160a01b0382166000908152601b6020908152604080832084845290915290205460ff1615613d105760405162461bcd60e51b8152600401808060200182810382526026815260200180615af76026913960400191505060405180910390fd5b6000818152601a602052604090205460ff1615613d5e5760405162461bcd60e51b8152600401808060200182810382526021815260200180615a316021913960400191505060405180910390fd5b6001600160a01b039091166000908152601b6020908152604080832093835292905220805460ff19166001179055565b613d96612d07565b613dd5576040805162461bcd60e51b81526020600482018190526024820152600080516020615c91833981519152604482015290519081900360640190fd5b61242481614a05565b600b5481565b60198181548110613df157fe5b60009182526020909120015461ffff8082169250620100009091041682565b613e18612d07565b613e57576040805162461bcd60e51b81526020600482018190526024820152600080516020615c91833981519152604482015290519081900360640190fd5b60208054911515600160a01b0260ff60a01b19909216919091179055565b600080613e81836126d0565b6001600160a01b0316141592915050565b60006001600160a01b038216613eaa5750600061178f565b6001600160a01b0382166000908152600a602052604090205465ffffffffffff1680611b645760115465ffffffffffff9081166001810190911611613f2e576040805162461bcd60e51b815260206004820152601560248201527442543a206d757374206e6f74206f766572666c6f7760581b604482015290519081900360640190fd5b506011805465ffffffffffff8082166001810190911665ffffffffffff1992831617909255600082815260096020908152604080832080546001600160a01b0389166001600160a01b031990911681179091558352600a909152902080549091168217905592915050565b3390565b6000613fa882613e75565b613fe35760405162461bcd60e51b815260040180806020018281038252602c815260200180615be5602c913960400191505060405180910390fd5b6000613fee836126d0565b9050806001600160a01b0316846001600160a01b031614806140295750836001600160a01b031661401e84611840565b6001600160a01b0316145b8061403957506140398185613b04565b949350505050565b61404a8161381c565b614092576040805162461bcd60e51b815260206004820152601460248201527342573a206e6f7420796574207472616461626c6560601b604482015290519081900360640190fd5b61211d838383614aa5565b6140a73382613f9d565b6140e25760405162461bcd60e51b8152600401808060200182810382526024815260200180615cd16024913960400191505060405180910390fd5b6140eb81614b03565b60006140f6826126d0565b6001600160a01b03811660009081526012602052604090205490915061412390600163ffffffff614b9016565b6001600160a01b038216600090815260126020526040812091909155600e80548490811061414d57fe5b90600052602060002090600591828204019190066006026101000a81548165ffffffffffff021916908365ffffffffffff16021790555061419a6001600d54614b9090919063ffffffff16565b600d5560405182906000906001600160a01b03841690600080516020615cb1833981519152908390a45050565b80601360006141d68686612348565b81526020019081526020016000208190555081837fe437ad402a50c14d9de944e1d68d9708776aaccb860bd49a6e875a64e7d0b22a836040518082815260200191505060405180910390a3505050565b6000614233846001614bd2565b905061423e83614dcd565b826014828154811061424c57fe5b90600052602060002090601091828204019190066002026101000a81548161ffff021916908361ffff160217905550816015828154811061428957fe5b90600052602060002090602091828204019190066101000a81548160ff021916908360ff160217905550606060016040519080825280602002602001820160405280156142e0578160200160208202803883390190505b50905083816000815181106142f157fe5b61ffff90921660209283029190910190910152604080516001808252818301909252606091816020016020820280388339019050509050838160008151811061433657fe5b602002602001019060ff16908160ff1681525050827f9c681932e4a9582af05182ce765050b6b731e429b839bcdf8463177531afdae587848460405180846001600160a01b03166001600160a01b031681526020018060200180602001838103835285818151815260200191508051906020019060200280838360005b838110156143cb5781810151838201526020016143b3565b50505050905001838103825284818151815260200191508051906020019060200280838360005b8381101561440a5781810151838201526020016143f2565b505050509050019550505050505060405180910390a250509392505050565b600061446b83836040518060400160405280601a81526020017f536166654d6174683a206469766973696f6e206279207a65726f000000000000815250614eca565b9392505050565b60008261448157506000611b64565b8282028284828161448e57fe5b041461446b5760405162461bcd60e51b8152600401808060200182810382526021815260200180615c706021913960400191505060405180910390fd5b60606144da8585601086614f6c565b905060005b83811015614501576144f982866010848761ffff16615032565b6001016144df565b50612fb285856010846150ba565b60408051828152905183917fa065fb8968d66241513c49df78364990dc9917fcd41ede326cef2c15e82f4aec919081900360200190a280601360006145538561237e565b81526020810191909152604001600020555050565b614573848484614041565b61457f84848484615117565b611a6b5760405162461bcd60e51b8152600401808060200182810382526032815260200180615a776032913960400191505060405180910390fd5b60408051602a80825260608281019093526001600160a01b038416918391602082018180388339019050509050600360fc1b816000815181106145f957fe5b60200101906001600160f81b031916908160001a905350600f60fb1b8160018151811061462257fe5b60200101906001600160f81b031916908160001a90535060005b601481101561259d576040518060400160405280601081526020016f181899199a1a9b1b9c1cb0b131b232b360811b81525060048483600c016020811061467f57fe5b1a60f81b6001600160f81b031916901c60f81c60ff168151811061469f57fe5b602001015160f81c60f81b8282600202600201815181106146bc57fe5b60200101906001600160f81b031916908160001a9053506040518060400160405280601081526020016f181899199a1a9b1b9c1cb0b131b232b360811b8152508382600c016020811061470b57fe5b825191901a600f1690811061471c57fe5b602001015160f81c60f81b82826002026003018151811061473957fe5b60200101906001600160f81b031916908160001a90535060010161463c565b60608161477d57506040805180820190915260018152600360fc1b602082015261178f565b8160005b811561479557600101600a82049150614781565b6060816040519080825280601f01601f1916602001820160405280156147c2576020820181803883390190505b50859350905060001982015b831561481357600a840660300160f81b828280600190039350815181106147f157fe5b60200101906001600160f81b031916908160001a905350600a840493506147ce565b50949350505050565b600080835111614873576040805162461bcd60e51b815260206004820152601960248201527f436f72653a206d75737420626520736f6d652070726f746f7300000000000000604482015290519081900360640190fd5b81518351146148b35760405162461bcd60e51b8152600401808060200182810382526031815260200180615c116031913960400191505060405180910390fd5b60006148c0858551614bd2565b90506148cd81858561526e565b807f9c681932e4a9582af05182ce765050b6b731e429b839bcdf8463177531afdae586868660405180846001600160a01b03166001600160a01b031681526020018060200180602001838103835285818151815260200191508051906020019060200280838360005b8381101561494e578181015183820152602001614936565b50505050905001838103825284818151815260200191508051906020019060200280838360005b8381101561498d578181015183820152602001614975565b505050509050019550505050505060405180910390a2949350505050565b60008282018381101561446b576040805162461bcd60e51b815260206004820152601b60248201527f536166654d6174683a206164646974696f6e206f766572666c6f770000000000604482015290519081900360640190fd5b6001600160a01b038116614a4a5760405162461bcd60e51b8152600401808060200182810382526026815260200180615ad16026913960400191505060405180910390fd5b600080546040516001600160a01b03808516939216917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e091a3600080546001600160a01b0319166001600160a01b0392909216919091179055565b614aae8161381c565b614af8576040805162461bcd60e51b8152602060048201526016602482015275436f72653a206e6f7420796574207472616461626c6560501b604482015290519081900360640190fd5b61211d838383615291565b600f8181548110614b1057fe5b90600052602060002090600591828204019190066006029054906101000a900465ffffffffffff1665ffffffffffff16600014612424576000600f8281548110614b5657fe5b90600052602060002090600591828204019190066006026101000a81548165ffffffffffff021916908365ffffffffffff16021790555050565b600061446b83836040518060400160405280601e81526020017f536166654d6174683a207375627472616374696f6e206f766572666c6f77000081525061548c565b60006001600160a01b038316614c26576040805162461bcd60e51b815260206004820152601460248201527310950e881b5d5cdd081b9bdd081899481b9d5b1b60621b604482015290519081900360640190fd5b60008261ffff16118015614c405750600b548261ffff1611155b614c91576040805162461bcd60e51b815260206004820152601e60248201527f42543a2073697a65206d7573742062652077697468696e206c696d6974730000604482015290519081900360640190fd5b600c546000614c9f85613e92565b60408051808201825265ffffffffffff838116825261ffff888116602080850182815260008a8152601090925295812094518554965165ffffffffffff1990971694169390931767ffff0000000000001916600160301b959092169490940217909155919250614d109084906149ab565b9050825b81811015614d4a5760405181906001600160a01b03891690600090600080516020615cb1833981519152908290a4600101614d14565b50600b54600c54614d609163ffffffff6149ab16565b600c556001600160a01b038616600090815260126020526040902054614d909061ffff871663ffffffff6149ab16565b6001600160a01b038716600090815260126020526040902055600d54614dc09061ffff871663ffffffff6149ab16565b600d555090949350505050565b61fde861ffff821610614de857614de3816154e6565b612424565b600060168261ffff1681548110614dfb57fe5b60009182526020909120601082040154600f9091166002026101000a900461ffff16905080614e71576040805162461bcd60e51b815260206004820152601a60248201527f436f72653a206d757374206861766520736561736f6e20736574000000000000604482015290519081900360640190fd5b336000908152601b6020908152604080832084845290915290205460ff16611aa15760405162461bcd60e51b815260040180806020018281038252602e815260200180615c42602e913960400191505060405180910390fd5b60008183614f565760405162461bcd60e51b81526004018080602001828103825283818151815260200191508051906020019080838360005b83811015614f1b578181015183820152602001614f03565b50505050905090810190601f168015614f485780820380516001836020036101000a031916815260200191505b509250505060405180910390fd5b506000838581614f6257fe5b0495945050505050565b60606000614f7b8585856155b5565b905080604051908082528060200260200182016040528015614fa7578160200160208202803883390190505b5091506000614fb686866155e5565b9050614fc287826155f8565b83600081518110614fcf57fe5b6020026020010181815250506001821115615028576000614fff614ff9888763ffffffff6149ab16565b876155e5565b905061500b88826155f8565b84600185038151811061501a57fe5b602002602001018181525050505b5050949350505050565b6000836101008161503f57fe5b049050600081868161504d57fe5b0690506000828583018161505d57fe5b049050600086848988018161506e57fe5b0602905060005b878110156150ae578082018187901c60ff16901b8a848151811061509557fe5b6020908102919091010180519091179052600801615075565b50505050505050505050565b60006150d983610100816150ca57fe5b8691900463ffffffff61442916565b905060005b825181101561510f57615107868284018584815181106150fa57fe5b602002602001015161560e565b6001016150de565b505050505050565b600061512b846001600160a01b0316615623565b61513757506001614039565b6000846001600160a01b031663150b7a02615150613f99565b8887876040518563ffffffff1660e01b815260040180856001600160a01b03166001600160a01b03168152602001846001600160a01b03166001600160a01b0316815260200183815260200180602001828103825283818151815260200191508051906020019080838360005b838110156151d55781810151838201526020016151bd565b50505050905090810190601f1680156152025780820380516001836020036101000a031916815260200191505b5095505050505050602060405180830381600087803b15801561522457600080fd5b505af1158015615238573d6000803e3d6000fd5b505050506040513d602081101561524e57600080fd5b50516001600160e01b031916630a85bd0160e11b14915050949350505050565b6152778261565a565b6014615284818585615875565b6015612fb28186856158ce565b826001600160a01b03166152a4826126d0565b6001600160a01b0316146152e95760405162461bcd60e51b8152600401808060200182810382526025815260200180615b1d6025913960400191505060405180910390fd5b6001600160a01b038216615344576040805162461bcd60e51b815260206004820181905260248201527f42543a207472616e7366657220746f20746865207a65726f2061646472657373604482015290519081900360640190fd5b61534e3382613f9d565b6153895760405162461bcd60e51b8152600401808060200182810382526024815260200180615cd16024913960400191505060405180910390fd5b61539281614b03565b6001600160a01b0383166000908152601260205260409020546153bc90600163ffffffff614b9016565b6001600160a01b0380851660009081526012602052604080822093909355908416815220546153f290600163ffffffff6149ab16565b6001600160a01b03831660009081526012602052604090205561541482613e92565b600e828154811061542157fe5b90600052602060002090600591828204019190066006026101000a81548165ffffffffffff021916908365ffffffffffff16021790555080826001600160a01b0316846001600160a01b0316600080516020615cb183398151915260405160405180910390a4505050565b600081848411156154de5760405162461bcd60e51b8152602060048201818152835160248401528351909283926044909101919085019080838360008315614f1b578181015183820152602001614f03565b505050900390565b61ffff81166000908152601c6020908152604080832033845290915290205460ff166155435760405162461bcd60e51b8152600401808060200182810382526028815260200180615b896028913960400191505060405180910390fd5b61ffff81166000908152601e602052604090205460ff16156155965760405162461bcd60e51b8152600401808060200182810382526025815260200180615a526025913960400191505060405180910390fd5b61ffff166000908152601e60205260409020805460ff19166001179055565b6000808385816155c157fe5b049050600084848701816155d157fe5b049050818103600101925050509392505050565b60008183816155f057fe5b049392505050565b6000806156058484615926565b54949350505050565b600061561a8484615926565b91909155505050565b6000813f7fc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a47081158015906140395750141592915050565b600061ffff815b835181101561571857600084828151811061567857fe5b6020026020010151905061fde861ffff168161ffff16106156a15761569c816154e6565b61570f565b61ffff81166156e7576040805162461bcd60e51b815260206004820152600d60248201526c70726f746f206973207a65726f60981b604482015290519081900360640190fd5b8361ffff168161ffff1611156156fb578093505b8061ffff168361ffff16111561570f578092505b50600101615661565b5061ffff82161561211d57600060168361ffff168154811061573657fe5b60009182526020909120601082040154600f9091166002026101000a900461ffff169050806157ac576040805162461bcd60e51b815260206004820152601a60248201527f436f72653a206d757374206861766520736561736f6e20736574000000000000604482015290519081900360640190fd5b60168261ffff16815481106157bd57fe5b60009182526020909120601082040154600f9091166002026101000a900461ffff16811461581c5760405162461bcd60e51b8152600401808060200182810382526030815260200180615d576030913960400191505060405180910390fd5b336000908152601b6020908152604080832084845290915290205460ff16611a6b5760405162461bcd60e51b815260040180806020018281038252602e815260200180615c42602e913960400191505060405180910390fd5b6060615885848460108551614f6c565b905060005b82518110156158c0576158b882856010848786815181106158a757fe5b602002602001015161ffff16615032565b60010161588a565b50611a6b84846010846150ba565b60606158de848460208551614f6c565b905060005b825181101561591857615910828560088487868151811061590057fe5b602002602001015160ff16615032565b6001016158e3565b50611a6b84846008846150ba565b60405191825260209091200190565b6040805161012081018252600080825260208201819052918101829052606081018290526080810182905260a0810182905260c0810182905260e0810182905261010081019190915290565b828054600181600116156101000203166002900490600052602060002090601f016020900481019282601f106159c257805160ff19168380011785556159ef565b828001600101855582156159ef579182015b828111156159ef5782518255916020019190600101906159d4565b506159fb929150615a16565b5090565b604080518082019091526000808252602082015290565b61183d91905b808211156159fb5760008155600101615a1c56fe436f72653a20736561736f6e206d757374206e6f74206265207472616461626c65436f72653a206d79746869632068617320616c7265616479206265656e20637265617465644552433732313a207472616e7366657220746f206e6f6e20455243373231526563656976657220696d706c656d656e74657242543a20617070726f76656420717565727920666f72206e6f6e6578697374656e7420746f6b656e4f776e61626c653a206e6577206f776e657220697320746865207a65726f2061646472657373436f72653a207468697320666163746f727920697320616c726561647920617070726f76656442543a207472616e73666572206f6620746f6b656e2074686174206973206e6f74206f776e436f72653a2063616e6e6f7420676f20696e746f206d7974686963207465727269746f7279436f72653a206d757374206e6f74206265207472616461626c6520616c7265616479436f72653a206e6f7420617070726f76656420746f206372656174652074686973206d797468696342543a20617070726f76652063616c6c6572206973206e6f74206f776e6572206e6f7220617070726f76656420666f7220616c6c4552433732313a206f70657261746f7220717565727920666f72206e6f6e6578697374656e7420746f6b656e436f72653a206d757374206265207468652073616d65206e756d626572206f662070726f746f732f7175616c6974696573436f72653a206d75737420626520617070726f76656420666163746f727920666f72207468697320736561736f6e536166654d6174683a206d756c7469706c69636174696f6e206f766572666c6f774f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572ddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef42543a2063616c6c6572206973206e6f74206f776e6572206e6f7220617070726f7665644552433732313a207472616e736665722063616c6c6572206973206e6f74206f776e6572206e6f7220617070726f766564436f72653a20666163746f72792063616e2774206368616e6765207175616c697479206f66207468697320736561736f6e436f72653a2063616e206f6e6c79206372656174652063617264732066726f6d207468652073616d6520736561736f6e436f72653a207468697320666163746f727920697320616c726561647920617070726f76656420666f722074686973206d7974686963a265627a7a7231582043e9a7e6b7e4414fad1e9c0a5dedfe329bfdc975cacd75a9c559e1b495d6c26264736f6c634300050b0032

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

000000000000000000000000629cdec6acc980ebeebea9e5003bcd44db9fc5ce00000000000000000000000000000000000000000000000000000000000004e3000000000000000000000000000000000000000000000000000000000000008000000000000000000000000000000000000000000000000000000000000000c00000000000000000000000000000000000000000000000000000000000000014476f647320556e636861696e656420436172647300000000000000000000000000000000000000000000000000000000000000000000000000000000000000044341524400000000000000000000000000000000000000000000000000000000

-----Decoded View---------------
Arg [0] : _old (address): 0x629cDEc6aCc980ebeeBeA9E5003bcD44DB9fc5cE
Arg [1] : _batchSize (uint256): 1251
Arg [2] : _name (string): Gods Unchained Cards
Arg [3] : _symbol (string): CARD

-----Encoded View---------------
8 Constructor Arguments found :
Arg [0] : 000000000000000000000000629cdec6acc980ebeebea9e5003bcd44db9fc5ce
Arg [1] : 00000000000000000000000000000000000000000000000000000000000004e3
Arg [2] : 0000000000000000000000000000000000000000000000000000000000000080
Arg [3] : 00000000000000000000000000000000000000000000000000000000000000c0
Arg [4] : 0000000000000000000000000000000000000000000000000000000000000014
Arg [5] : 476f647320556e636861696e6564204361726473000000000000000000000000
Arg [6] : 0000000000000000000000000000000000000000000000000000000000000004
Arg [7] : 4341524400000000000000000000000000000000000000000000000000000000


Swarm Source

bzzr://43e9a7e6b7e4414fad1e9c0a5dedfe329bfdc975cacd75a9c559e1b495d6c262
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.