ETH Price: $3,332.92 (-2.71%)

Token

Clovers (CLV)
 

Overview

Max Total Supply

43,841 CLV

Holders

738

Total Transfers

-

Market

Volume (24H)

N/A

Min Price (24H)

N/A

Max Price (24H)

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

OVERVIEW

Discover, collect & trade cryptographic icons mined with Proof-of-Search.

# Exchange Pair Price  24H Volume % Volume

Contract Source Code Verified (Exact Match)

Contract Name:
Clovers

Compiler Version
v0.4.24+commit.e67f0147

Optimization Enabled:
Yes with 10000 runs

Other Settings:
default evmVersion, None license

Contract Source Code (Solidity)

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

// File: zeppelin-solidity/contracts/token/ERC20/ERC20Basic.sol

pragma solidity ^0.4.24;


/**
 * @title ERC20Basic
 * @dev Simpler version of ERC20 interface
 * See https://github.com/ethereum/EIPs/issues/179
 */
contract ERC20Basic {
  function totalSupply() public view returns (uint256);
  function balanceOf(address who) public view returns (uint256);
  function transfer(address to, uint256 value) public returns (bool);
  event Transfer(address indexed from, address indexed to, uint256 value);
}

// File: zeppelin-solidity/contracts/token/ERC20/ERC20.sol

pragma solidity ^0.4.24;



/**
 * @title ERC20 interface
 * @dev see https://github.com/ethereum/EIPs/issues/20
 */
contract ERC20 is ERC20Basic {
  function allowance(address owner, address spender)
    public view returns (uint256);

  function transferFrom(address from, address to, uint256 value)
    public returns (bool);

  function approve(address spender, uint256 value) public returns (bool);
  event Approval(
    address indexed owner,
    address indexed spender,
    uint256 value
  );
}

// File: zeppelin-solidity/contracts/introspection/ERC165.sol

pragma solidity ^0.4.24;


/**
 * @title ERC165
 * @dev https://github.com/ethereum/EIPs/blob/master/EIPS/eip-165.md
 */
interface ERC165 {

  /**
   * @notice Query if a contract implements an interface
   * @param _interfaceId The interface identifier, as specified in ERC-165
   * @dev Interface identification is specified in ERC-165. This function
   * uses less than 30,000 gas.
   */
  function supportsInterface(bytes4 _interfaceId)
    external
    view
    returns (bool);
}

// File: zeppelin-solidity/contracts/token/ERC721/ERC721Basic.sol

pragma solidity ^0.4.24;



/**
 * @title ERC721 Non-Fungible Token Standard basic interface
 * @dev see https://github.com/ethereum/EIPs/blob/master/EIPS/eip-721.md
 */
contract ERC721Basic is ERC165 {
  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
  );

  function balanceOf(address _owner) public view returns (uint256 _balance);
  function ownerOf(uint256 _tokenId) public view returns (address _owner);
  function exists(uint256 _tokenId) public view returns (bool _exists);

  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 transferFrom(address _from, address _to, uint256 _tokenId) public;
  function safeTransferFrom(address _from, address _to, uint256 _tokenId)
    public;

  function safeTransferFrom(
    address _from,
    address _to,
    uint256 _tokenId,
    bytes _data
  )
    public;
}

// File: zeppelin-solidity/contracts/token/ERC721/ERC721.sol

pragma solidity ^0.4.24;



/**
 * @title ERC-721 Non-Fungible Token Standard, optional enumeration extension
 * @dev See https://github.com/ethereum/EIPs/blob/master/EIPS/eip-721.md
 */
contract ERC721Enumerable is ERC721Basic {
  function totalSupply() public view returns (uint256);
  function tokenOfOwnerByIndex(
    address _owner,
    uint256 _index
  )
    public
    view
    returns (uint256 _tokenId);

  function tokenByIndex(uint256 _index) public view returns (uint256);
}


/**
 * @title ERC-721 Non-Fungible Token Standard, optional metadata extension
 * @dev See https://github.com/ethereum/EIPs/blob/master/EIPS/eip-721.md
 */
contract ERC721Metadata is ERC721Basic {
  function name() external view returns (string _name);
  function symbol() external view returns (string _symbol);
  function tokenURI(uint256 _tokenId) public view returns (string);
}


/**
 * @title ERC-721 Non-Fungible Token Standard, full implementation interface
 * @dev See https://github.com/ethereum/EIPs/blob/master/EIPS/eip-721.md
 */
contract ERC721 is ERC721Basic, ERC721Enumerable, ERC721Metadata {
}

// File: zeppelin-solidity/contracts/token/ERC721/ERC721Receiver.sol

pragma solidity ^0.4.24;


/**
 * @title ERC721 token receiver interface
 * @dev Interface for any contract that wants to support safeTransfers
 * from ERC721 asset contracts.
 */
contract ERC721Receiver {
  /**
   * @dev Magic value to be returned upon successful reception of an NFT
   *  Equals to `bytes4(keccak256("onERC721Received(address,address,uint256,bytes)"))`,
   *  which can be also obtained as `ERC721Receiver(0).onERC721Received.selector`
   */
  bytes4 internal constant ERC721_RECEIVED = 0x150b7a02;

  /**
   * @notice Handle the receipt of an NFT
   * @dev The ERC721 smart contract calls this function on the recipient
   * after a `safetransfer`. This function MAY throw to revert and reject the
   * transfer. Return of other than the magic value MUST result in the 
   * transaction being reverted.
   * Note: the 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 transfered
   * @param _data Additional data with no specified format
   * @return `bytes4(keccak256("onERC721Received(address,address,uint256,bytes)"))`
   */
  function onERC721Received(
    address _operator,
    address _from,
    uint256 _tokenId,
    bytes _data
  )
    public
    returns(bytes4);
}

// File: zeppelin-solidity/contracts/math/SafeMath.sol

pragma solidity ^0.4.24;


/**
 * @title SafeMath
 * @dev Math operations with safety checks that throw on error
 */
library SafeMath {

  /**
  * @dev Multiplies two numbers, throws on overflow.
  */
  function mul(uint256 a, uint256 b) internal pure returns (uint256 c) {
    // Gas optimization: this is cheaper than asserting 'a' not being zero, but the
    // benefit is lost if 'b' is also tested.
    // See: https://github.com/OpenZeppelin/openzeppelin-solidity/pull/522
    if (a == 0) {
      return 0;
    }

    c = a * b;
    assert(c / a == b);
    return c;
  }

  /**
  * @dev Integer division of two numbers, truncating the quotient.
  */
  function div(uint256 a, uint256 b) internal pure returns (uint256) {
    // assert(b > 0); // Solidity automatically throws when dividing by 0
    // uint256 c = a / b;
    // assert(a == b * c + a % b); // There is no case in which this doesn't hold
    return a / b;
  }

  /**
  * @dev Subtracts two numbers, throws on overflow (i.e. if subtrahend is greater than minuend).
  */
  function sub(uint256 a, uint256 b) internal pure returns (uint256) {
    assert(b <= a);
    return a - b;
  }

  /**
  * @dev Adds two numbers, throws on overflow.
  */
  function add(uint256 a, uint256 b) internal pure returns (uint256 c) {
    c = a + b;
    assert(c >= a);
    return c;
  }
}

// File: zeppelin-solidity/contracts/AddressUtils.sol

pragma solidity ^0.4.24;


/**
 * Utility library of inline functions on addresses
 */
library AddressUtils {

  /**
   * Returns whether the target address is a contract
   * @dev This function will return false if invoked during the constructor of a contract,
   * as the code is not actually created until after the constructor finishes.
   * @param addr address to check
   * @return whether the target address is a contract
   */
  function isContract(address addr) internal view returns (bool) {
    uint256 size;
    // XXX Currently there is no better way to check if there is a contract in an address
    // than to check the size of the code at that address.
    // See https://ethereum.stackexchange.com/a/14016/36603
    // for more details about how this works.
    // TODO Check this again before the Serenity release, because all addresses will be
    // contracts then.
    // solium-disable-next-line security/no-inline-assembly
    assembly { size := extcodesize(addr) }
    return size > 0;
  }

}

// File: zeppelin-solidity/contracts/introspection/SupportsInterfaceWithLookup.sol

pragma solidity ^0.4.24;



/**
 * @title SupportsInterfaceWithLookup
 * @author Matt Condon (@shrugs)
 * @dev Implements ERC165 using a lookup table.
 */
contract SupportsInterfaceWithLookup is ERC165 {
  bytes4 public constant InterfaceId_ERC165 = 0x01ffc9a7;
  /**
   * 0x01ffc9a7 ===
   *   bytes4(keccak256('supportsInterface(bytes4)'))
   */

  /**
   * @dev a mapping of interface id to whether or not it's supported
   */
  mapping(bytes4 => bool) internal supportedInterfaces;

  /**
   * @dev A contract implementing SupportsInterfaceWithLookup
   * implement ERC165 itself
   */
  constructor()
    public
  {
    _registerInterface(InterfaceId_ERC165);
  }

  /**
   * @dev implement supportsInterface(bytes4) using a lookup table
   */
  function supportsInterface(bytes4 _interfaceId)
    external
    view
    returns (bool)
  {
    return supportedInterfaces[_interfaceId];
  }

  /**
   * @dev private method for registering an interface
   */
  function _registerInterface(bytes4 _interfaceId)
    internal
  {
    require(_interfaceId != 0xffffffff);
    supportedInterfaces[_interfaceId] = true;
  }
}

// File: zeppelin-solidity/contracts/token/ERC721/ERC721BasicToken.sol

pragma solidity ^0.4.24;







/**
 * @title ERC721 Non-Fungible Token Standard basic implementation
 * @dev see https://github.com/ethereum/EIPs/blob/master/EIPS/eip-721.md
 */
contract ERC721BasicToken is SupportsInterfaceWithLookup, ERC721Basic {

  bytes4 private constant InterfaceId_ERC721 = 0x80ac58cd;
  /*
   * 0x80ac58cd ===
   *   bytes4(keccak256('balanceOf(address)')) ^
   *   bytes4(keccak256('ownerOf(uint256)')) ^
   *   bytes4(keccak256('approve(address,uint256)')) ^
   *   bytes4(keccak256('getApproved(uint256)')) ^
   *   bytes4(keccak256('setApprovalForAll(address,bool)')) ^
   *   bytes4(keccak256('isApprovedForAll(address,address)')) ^
   *   bytes4(keccak256('transferFrom(address,address,uint256)')) ^
   *   bytes4(keccak256('safeTransferFrom(address,address,uint256)')) ^
   *   bytes4(keccak256('safeTransferFrom(address,address,uint256,bytes)'))
   */

  bytes4 private constant InterfaceId_ERC721Exists = 0x4f558e79;
  /*
   * 0x4f558e79 ===
   *   bytes4(keccak256('exists(uint256)'))
   */

  using SafeMath for uint256;
  using AddressUtils for address;

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

  // Mapping from token ID to owner
  mapping (uint256 => address) internal tokenOwner;

  // Mapping from token ID to approved address
  mapping (uint256 => address) internal tokenApprovals;

  // Mapping from owner to number of owned token
  mapping (address => uint256) internal ownedTokensCount;

  // Mapping from owner to operator approvals
  mapping (address => mapping (address => bool)) internal operatorApprovals;

  /**
   * @dev Guarantees msg.sender is owner of the given token
   * @param _tokenId uint256 ID of the token to validate its ownership belongs to msg.sender
   */
  modifier onlyOwnerOf(uint256 _tokenId) {
    require(ownerOf(_tokenId) == msg.sender);
    _;
  }

  /**
   * @dev Checks msg.sender can transfer a token, by being owner, approved, or operator
   * @param _tokenId uint256 ID of the token to validate
   */
  modifier canTransfer(uint256 _tokenId) {
    require(isApprovedOrOwner(msg.sender, _tokenId));
    _;
  }

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

  /**
   * @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));
    return ownedTokensCount[_owner];
  }

  /**
   * @dev Gets the owner of the specified token ID
   * @param _tokenId uint256 ID of the token to query the owner of
   * @return owner 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));
    return owner;
  }

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

  /**
   * @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);
    require(msg.sender == owner || isApprovedForAll(owner, msg.sender));

    tokenApprovals[_tokenId] = _to;
    emit Approval(owner, _to, _tokenId);
  }

  /**
   * @dev Gets the approved address for a token ID, or zero if no address set
   * @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) {
    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 != msg.sender);
    operatorApprovals[msg.sender][_to] = _approved;
    emit ApprovalForAll(msg.sender, _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
    canTransfer(_tokenId)
  {
    require(_from != address(0));
    require(_to != address(0));

    clearApproval(_from, _tokenId);
    removeTokenFrom(_from, _tokenId);
    addTokenTo(_to, _tokenId);

    emit Transfer(_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 `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
    canTransfer(_tokenId)
  {
    // solium-disable-next-line arg-overflow
    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 `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 _data
  )
    public
    canTransfer(_tokenId)
  {
    transferFrom(_from, _to, _tokenId);
    // solium-disable-next-line arg-overflow
    require(checkAndCallSafeTransfer(_from, _to, _tokenId, _data));
  }

  /**
   * @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)
  {
    address owner = ownerOf(_tokenId);
    // Disable solium check because of
    // https://github.com/duaraghav8/Solium/issues/175
    // solium-disable-next-line operator-whitespace
    return (
      _spender == owner ||
      getApproved(_tokenId) == _spender ||
      isApprovedForAll(owner, _spender)
    );
  }

  /**
   * @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 by the msg.sender
   */
  function _mint(address _to, uint256 _tokenId) internal {
    require(_to != address(0));
    addTokenTo(_to, _tokenId);
    emit Transfer(address(0), _to, _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 by the msg.sender
   */
  function _burn(address _owner, uint256 _tokenId) internal {
    clearApproval(_owner, _tokenId);
    removeTokenFrom(_owner, _tokenId);
    emit Transfer(_owner, address(0), _tokenId);
  }

  /**
   * @dev Internal function to clear current approval of a given token ID
   * Reverts if the given address is not indeed the owner of the token
   * @param _owner owner of the token
   * @param _tokenId uint256 ID of the token to be transferred
   */
  function clearApproval(address _owner, uint256 _tokenId) internal {
    require(ownerOf(_tokenId) == _owner);
    if (tokenApprovals[_tokenId] != address(0)) {
      tokenApprovals[_tokenId] = address(0);
    }
  }

  /**
   * @dev Internal function to add a token ID to the list of a given address
   * @param _to address representing the new owner of the given token ID
   * @param _tokenId uint256 ID of the token to be added to the tokens list of the given address
   */
  function addTokenTo(address _to, uint256 _tokenId) internal {
    require(tokenOwner[_tokenId] == address(0));
    tokenOwner[_tokenId] = _to;
    ownedTokensCount[_to] = ownedTokensCount[_to].add(1);
  }

  /**
   * @dev Internal function to remove a token ID from the list of a given address
   * @param _from address representing the previous owner of the given token ID
   * @param _tokenId uint256 ID of the token to be removed from the tokens list of the given address
   */
  function removeTokenFrom(address _from, uint256 _tokenId) internal {
    require(ownerOf(_tokenId) == _from);
    ownedTokensCount[_from] = ownedTokensCount[_from].sub(1);
    tokenOwner[_tokenId] = address(0);
  }

  /**
   * @dev Internal function to invoke `onERC721Received` on a target address
   * The call is not executed if the target address is not a contract
   * @param _from address representing the previous owner of the given token ID
   * @param _to target address that will receive the tokens
   * @param _tokenId uint256 ID of the token to be transferred
   * @param _data bytes optional data to send along with the call
   * @return whether the call correctly returned the expected magic value
   */
  function checkAndCallSafeTransfer(
    address _from,
    address _to,
    uint256 _tokenId,
    bytes _data
  )
    internal
    returns (bool)
  {
    if (!_to.isContract()) {
      return true;
    }
    bytes4 retval = ERC721Receiver(_to).onERC721Received(
      msg.sender, _from, _tokenId, _data);
    return (retval == ERC721_RECEIVED);
  }
}

// File: zeppelin-solidity/contracts/token/ERC721/ERC721Token.sol

pragma solidity ^0.4.24;





/**
 * @title Full ERC721 Token
 * This implementation includes all the required and some optional functionality of the ERC721 standard
 * Moreover, it includes approve all functionality using operator terminology
 * @dev see https://github.com/ethereum/EIPs/blob/master/EIPS/eip-721.md
 */
contract ERC721Token is SupportsInterfaceWithLookup, ERC721BasicToken, ERC721 {

  bytes4 private constant InterfaceId_ERC721Enumerable = 0x780e9d63;
  /**
   * 0x780e9d63 ===
   *   bytes4(keccak256('totalSupply()')) ^
   *   bytes4(keccak256('tokenOfOwnerByIndex(address,uint256)')) ^
   *   bytes4(keccak256('tokenByIndex(uint256)'))
   */

  bytes4 private constant InterfaceId_ERC721Metadata = 0x5b5e139f;
  /**
   * 0x5b5e139f ===
   *   bytes4(keccak256('name()')) ^
   *   bytes4(keccak256('symbol()')) ^
   *   bytes4(keccak256('tokenURI(uint256)'))
   */

  // Token name
  string internal name_;

  // Token symbol
  string internal symbol_;

  // Mapping from owner to list of owned token IDs
  mapping(address => uint256[]) internal ownedTokens;

  // Mapping from token ID to index of the owner tokens list
  mapping(uint256 => uint256) internal ownedTokensIndex;

  // Array with all token ids, used for enumeration
  uint256[] internal allTokens;

  // Mapping from token id to position in the allTokens array
  mapping(uint256 => uint256) internal allTokensIndex;

  // Optional mapping for token URIs
  mapping(uint256 => string) internal tokenURIs;

  /**
   * @dev Constructor function
   */
  constructor(string _name, string _symbol) public {
    name_ = _name;
    symbol_ = _symbol;

    // register the supported interfaces to conform to ERC721 via ERC165
    _registerInterface(InterfaceId_ERC721Enumerable);
    _registerInterface(InterfaceId_ERC721Metadata);
  }

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

  /**
   * @dev Gets the token symbol
   * @return string representing the token symbol
   */
  function symbol() external view returns (string) {
    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) public view returns (string) {
    require(exists(_tokenId));
    return tokenURIs[_tokenId];
  }

  /**
   * @dev Gets the token ID at a given index of the tokens list of the requested owner
   * @param _owner address owning the tokens list to be accessed
   * @param _index uint256 representing the index to be accessed of the requested tokens list
   * @return uint256 token ID at the given index of the tokens list owned by the requested address
   */
  function tokenOfOwnerByIndex(
    address _owner,
    uint256 _index
  )
    public
    view
    returns (uint256)
  {
    require(_index < balanceOf(_owner));
    return ownedTokens[_owner][_index];
  }

  /**
   * @dev Gets the total amount of tokens stored by the contract
   * @return uint256 representing the total amount of tokens
   */
  function totalSupply() public view returns (uint256) {
    return allTokens.length;
  }

  /**
   * @dev Gets the token ID at a given index of all the tokens in this contract
   * Reverts if the index is greater or equal to the total number of tokens
   * @param _index uint256 representing the index to be accessed of the tokens list
   * @return uint256 token ID at the given index of the tokens list
   */
  function tokenByIndex(uint256 _index) public view returns (uint256) {
    require(_index < totalSupply());
    return allTokens[_index];
  }

  /**
   * @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 _uri) internal {
    require(exists(_tokenId));
    tokenURIs[_tokenId] = _uri;
  }

  /**
   * @dev Internal function to add a token ID to the list of a given address
   * @param _to address representing the new owner of the given token ID
   * @param _tokenId uint256 ID of the token to be added to the tokens list of the given address
   */
  function addTokenTo(address _to, uint256 _tokenId) internal {
    super.addTokenTo(_to, _tokenId);
    uint256 length = ownedTokens[_to].length;
    ownedTokens[_to].push(_tokenId);
    ownedTokensIndex[_tokenId] = length;
  }

  /**
   * @dev Internal function to remove a token ID from the list of a given address
   * @param _from address representing the previous owner of the given token ID
   * @param _tokenId uint256 ID of the token to be removed from the tokens list of the given address
   */
  function removeTokenFrom(address _from, uint256 _tokenId) internal {
    super.removeTokenFrom(_from, _tokenId);

    uint256 tokenIndex = ownedTokensIndex[_tokenId];
    uint256 lastTokenIndex = ownedTokens[_from].length.sub(1);
    uint256 lastToken = ownedTokens[_from][lastTokenIndex];

    ownedTokens[_from][tokenIndex] = lastToken;
    ownedTokens[_from][lastTokenIndex] = 0;
    // Note that this will handle single-element arrays. In that case, both tokenIndex and lastTokenIndex are going to
    // be zero. Then we can make sure that we will remove _tokenId from the ownedTokens list since we are first swapping
    // the lastToken to the first position, and then dropping the element placed in the last position of the list

    ownedTokens[_from].length--;
    ownedTokensIndex[_tokenId] = 0;
    ownedTokensIndex[lastToken] = tokenIndex;
  }

  /**
   * @dev Internal function to mint a new token
   * Reverts if the given token ID already exists
   * @param _to address the beneficiary that will own the minted token
   * @param _tokenId uint256 ID of the token to be minted by the msg.sender
   */
  function _mint(address _to, uint256 _tokenId) internal {
    super._mint(_to, _tokenId);

    allTokensIndex[_tokenId] = allTokens.length;
    allTokens.push(_tokenId);
  }

  /**
   * @dev Internal function to burn a specific token
   * Reverts if the token does not exist
   * @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];
    }

    // Reorg all tokens array
    uint256 tokenIndex = allTokensIndex[_tokenId];
    uint256 lastTokenIndex = allTokens.length.sub(1);
    uint256 lastToken = allTokens[lastTokenIndex];

    allTokens[tokenIndex] = lastToken;
    allTokens[lastTokenIndex] = 0;

    allTokens.length--;
    allTokensIndex[_tokenId] = 0;
    allTokensIndex[lastToken] = tokenIndex;
  }

}

// File: zeppelin-solidity/contracts/ownership/Ownable.sol

pragma solidity ^0.4.24;


/**
 * @title Ownable
 * @dev The Ownable contract has an owner address, and provides basic authorization control
 * functions, this simplifies the implementation of "user permissions".
 */
contract Ownable {
  address public owner;


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


  /**
   * @dev The Ownable constructor sets the original `owner` of the contract to the sender
   * account.
   */
  constructor() public {
    owner = msg.sender;
  }

  /**
   * @dev Throws if called by any account other than the owner.
   */
  modifier onlyOwner() {
    require(msg.sender == owner);
    _;
  }

  /**
   * @dev Allows the current owner to relinquish control of the contract.
   * @notice Renouncing to ownership will leave the contract without an owner.
   * It will not be possible to call the functions with the `onlyOwner`
   * modifier anymore.
   */
  function renounceOwnership() public onlyOwner {
    emit OwnershipRenounced(owner);
    owner = address(0);
  }

  /**
   * @dev Allows the current owner to transfer control of the contract to a newOwner.
   * @param _newOwner The address to transfer ownership to.
   */
  function transferOwnership(address _newOwner) public onlyOwner {
    _transferOwnership(_newOwner);
  }

  /**
   * @dev Transfers control of the contract to a newOwner.
   * @param _newOwner The address to transfer ownership to.
   */
  function _transferOwnership(address _newOwner) internal {
    require(_newOwner != address(0));
    emit OwnershipTransferred(owner, _newOwner);
    owner = _newOwner;
  }
}

// File: contracts/helpers/Admin.sol

pragma solidity ^0.4.24;


/**
 * @title Ownable
 * @dev The Ownable contract has an admin address, and provides basic authorization control
 * functions, this simplifies the implementation of "user permissions".
 */
contract Admin {
  mapping (address => bool) public admins;


  event AdminshipRenounced(address indexed previousAdmin);
  event AdminshipTransferred(
    address indexed previousAdmin,
    address indexed newAdmin
  );


  /**
   * @dev The Ownable constructor sets the original `admin` of the contract to the sender
   * account.
   */
  constructor() public {
    admins[msg.sender] = true;
  }

  /**
   * @dev Throws if called by any account other than the admin.
   */
  modifier onlyAdmin() {
    require(admins[msg.sender]);
    _;
  }

  function isAdmin(address _admin) public view returns(bool) {
    return admins[_admin];
  }

  /**
   * @dev Allows the current admin to relinquish control of the contract.
   * @notice Renouncing to adminship will leave the contract without an admin.
   * It will not be possible to call the functions with the `onlyAdmin`
   * modifier anymore.
   */
  function renounceAdminship(address _previousAdmin) public onlyAdmin {
    emit AdminshipRenounced(_previousAdmin);
    admins[_previousAdmin] = false;
  }

  /**
   * @dev Allows the current admin to transfer control of the contract to a newAdmin.
   * @param _newAdmin The address to transfer adminship to.
   */
  function transferAdminship(address _newAdmin) public onlyAdmin {
    _transferAdminship(_newAdmin);
  }

  /**
   * @dev Transfers control of the contract to a newAdmin.
   * @param _newAdmin The address to transfer adminship to.
   */
  function _transferAdminship(address _newAdmin) internal {
    require(_newAdmin != address(0));
    emit AdminshipTransferred(msg.sender, _newAdmin);
    admins[_newAdmin] = true;
  }
}

// File: contracts/helpers/strings.sol

/*
 * @title String & slice utility library for Solidity contracts.
 * @author Nick Johnson <[email protected]>
 *
 * @dev Functionality in this library is largely implemented using an
 *      abstraction called a 'slice'. A slice represents a part of a string -
 *      anything from the entire string to a single character, or even no
 *      characters at all (a 0-length slice). Since a slice only has to specify
 *      an offset and a length, copying and manipulating slices is a lot less
 *      expensive than copying and manipulating the strings they reference.
 *
 *      To further reduce gas costs, most functions on slice that need to return
 *      a slice modify the original one instead of allocating a new one; for
 *      instance, `s.split(".")` will return the text up to the first '.',
 *      modifying s to only contain the remainder of the string after the '.'.
 *      In situations where you do not want to modify the original slice, you
 *      can make a copy first with `.copy()`, for example:
 *      `s.copy().split(".")`. Try and avoid using this idiom in loops; since
 *      Solidity has no memory management, it will result in allocating many
 *      short-lived slices that are later discarded.
 *
 *      Functions that return two slices come in two versions: a non-allocating
 *      version that takes the second slice as an argument, modifying it in
 *      place, and an allocating version that allocates and returns the second
 *      slice; see `nextRune` for example.
 *
 *      Functions that have to copy string data will return strings rather than
 *      slices; these can be cast back to slices for further processing if
 *      required.
 *
 *      For convenience, some functions are provided with non-modifying
 *      variants that create a new slice and return both; for instance,
 *      `s.splitNew('.')` leaves s unmodified, and returns two values
 *      corresponding to the left and right parts of the string.
 */

pragma solidity ^0.4.14;

library strings {
    struct slice {
        uint _len;
        uint _ptr;
    }

    function memcpy(uint dest, uint src, uint len) private pure{
        // Copy word-length chunks while possible
        for(; len >= 32; len -= 32) {
            assembly {
                mstore(dest, mload(src))
            }
            dest += 32;
            src += 32;
        }

        // Copy remaining bytes
        uint mask = 256 ** (32 - len) - 1;
        assembly {
            let srcpart := and(mload(src), not(mask))
            let destpart := and(mload(dest), mask)
            mstore(dest, or(destpart, srcpart))
        }
    }

    /*
     * @dev Returns a slice containing the entire string.
     * @param self The string to make a slice from.
     * @return A newly allocated slice containing the entire string.
     */
    function toSlice(string self) internal pure returns (slice) {
        uint ptr;
        assembly {
            ptr := add(self, 0x20)
        }
        return slice(bytes(self).length, ptr);
    }

    /*
     * @dev Returns the length of a null-terminated bytes32 string.
     * @param self The value to find the length of.
     * @return The length of the string, from 0 to 32.
     */
    function len(bytes32 self) internal pure returns (uint) {
        uint ret;
        if (self == 0)
            return 0;
        if (self & 0xffffffffffffffffffffffffffffffff == 0) {
            ret += 16;
            self = bytes32(uint(self) / 0x100000000000000000000000000000000);
        }
        if (self & 0xffffffffffffffff == 0) {
            ret += 8;
            self = bytes32(uint(self) / 0x10000000000000000);
        }
        if (self & 0xffffffff == 0) {
            ret += 4;
            self = bytes32(uint(self) / 0x100000000);
        }
        if (self & 0xffff == 0) {
            ret += 2;
            self = bytes32(uint(self) / 0x10000);
        }
        if (self & 0xff == 0) {
            ret += 1;
        }
        return 32 - ret;
    }

    /*
     * @dev Returns a slice containing the entire bytes32, interpreted as a
     *      null-termintaed utf-8 string.
     * @param self The bytes32 value to convert to a slice.
     * @return A new slice containing the value of the input argument up to the
     *         first null.
     */
    function toSliceB32(bytes32 self) internal pure returns (slice ret) {
        // Allocate space for `self` in memory, copy it there, and point ret at it
        assembly {
            let ptr := mload(0x40)
            mstore(0x40, add(ptr, 0x20))
            mstore(ptr, self)
            mstore(add(ret, 0x20), ptr)
        }
        ret._len = len(self);
    }

    /*
     * @dev Returns a new slice containing the same data as the current slice.
     * @param self The slice to copy.
     * @return A new slice containing the same data as `self`.
     */
    function copy(slice self) internal pure returns (slice) {
        return slice(self._len, self._ptr);
    }

    /*
     * @dev Copies a slice to a new string.
     * @param self The slice to copy.
     * @return A newly allocated string containing the slice's text.
     */
    function toString(slice self) internal pure returns (string) {
        var ret = new string(self._len);
        uint retptr;
        assembly { retptr := add(ret, 32) }

        memcpy(retptr, self._ptr, self._len);
        return ret;
    }

    /*
     * @dev Returns the length in runes of the slice. Note that this operation
     *      takes time proportional to the length of the slice; avoid using it
     *      in loops, and call `slice.empty()` if you only need to know whether
     *      the slice is empty or not.
     * @param self The slice to operate on.
     * @return The length of the slice in runes.
     */
    function len(slice self) internal pure returns (uint l) {
        // Starting at ptr-31 means the LSB will be the byte we care about
        var ptr = self._ptr - 31;
        var end = ptr + self._len;
        for (l = 0; ptr < end; l++) {
            uint8 b;
            assembly { b := and(mload(ptr), 0xFF) }
            if (b < 0x80) {
                ptr += 1;
            } else if(b < 0xE0) {
                ptr += 2;
            } else if(b < 0xF0) {
                ptr += 3;
            } else if(b < 0xF8) {
                ptr += 4;
            } else if(b < 0xFC) {
                ptr += 5;
            } else {
                ptr += 6;
            }
        }
    }

    /*
     * @dev Returns true if the slice is empty (has a length of 0).
     * @param self The slice to operate on.
     * @return True if the slice is empty, False otherwise.
     */
    function empty(slice self) internal pure returns (bool) {
        return self._len == 0;
    }

    /*
     * @dev Returns a positive number if `other` comes lexicographically after
     *      `self`, a negative number if it comes before, or zero if the
     *      contents of the two slices are equal. Comparison is done per-rune,
     *      on unicode codepoints.
     * @param self The first slice to compare.
     * @param other The second slice to compare.
     * @return The result of the comparison.
     */
    function compare(slice self, slice other) internal pure returns (int) {
        uint shortest = self._len;
        if (other._len < self._len)
            shortest = other._len;

        var selfptr = self._ptr;
        var otherptr = other._ptr;
        for (uint idx = 0; idx < shortest; idx += 32) {
            uint a;
            uint b;
            assembly {
                a := mload(selfptr)
                b := mload(otherptr)
            }
            if (a != b) {
                // Mask out irrelevant bytes and check again
                uint mask = ~(2 ** (8 * (32 - shortest + idx)) - 1);
                var diff = (a & mask) - (b & mask);
                if (diff != 0)
                    return int(diff);
            }
            selfptr += 32;
            otherptr += 32;
        }
        return int(self._len) - int(other._len);
    }

    /*
     * @dev Returns true if the two slices contain the same text.
     * @param self The first slice to compare.
     * @param self The second slice to compare.
     * @return True if the slices are equal, false otherwise.
     */
    function equals(slice self, slice other) internal pure returns (bool) {
        return compare(self, other) == 0;
    }

    /*
     * @dev Extracts the first rune in the slice into `rune`, advancing the
     *      slice to point to the next rune and returning `self`.
     * @param self The slice to operate on.
     * @param rune The slice that will contain the first rune.
     * @return `rune`.
     */
    function nextRune(slice self, slice rune) internal pure returns (slice) {
        rune._ptr = self._ptr;

        if (self._len == 0) {
            rune._len = 0;
            return rune;
        }

        uint len;
        uint b;
        // Load the first byte of the rune into the LSBs of b
        assembly { b := and(mload(sub(mload(add(self, 32)), 31)), 0xFF) }
        if (b < 0x80) {
            len = 1;
        } else if(b < 0xE0) {
            len = 2;
        } else if(b < 0xF0) {
            len = 3;
        } else {
            len = 4;
        }

        // Check for truncated codepoints
        if (len > self._len) {
            rune._len = self._len;
            self._ptr += self._len;
            self._len = 0;
            return rune;
        }

        self._ptr += len;
        self._len -= len;
        rune._len = len;
        return rune;
    }

    /*
     * @dev Returns the first rune in the slice, advancing the slice to point
     *      to the next rune.
     * @param self The slice to operate on.
     * @return A slice containing only the first rune from `self`.
     */
    function nextRune(slice self) internal pure returns (slice ret) {
        nextRune(self, ret);
    }

    /*
     * @dev Returns the number of the first codepoint in the slice.
     * @param self The slice to operate on.
     * @return The number of the first codepoint in the slice.
     */
    function ord(slice self) internal pure returns (uint ret) {
        if (self._len == 0) {
            return 0;
        }

        uint word;
        uint length;
        uint divisor = 2 ** 248;

        // Load the rune into the MSBs of b
        assembly { word:= mload(mload(add(self, 32))) }
        var b = word / divisor;
        if (b < 0x80) {
            ret = b;
            length = 1;
        } else if(b < 0xE0) {
            ret = b & 0x1F;
            length = 2;
        } else if(b < 0xF0) {
            ret = b & 0x0F;
            length = 3;
        } else {
            ret = b & 0x07;
            length = 4;
        }

        // Check for truncated codepoints
        if (length > self._len) {
            return 0;
        }

        for (uint i = 1; i < length; i++) {
            divisor = divisor / 256;
            b = (word / divisor) & 0xFF;
            if (b & 0xC0 != 0x80) {
                // Invalid UTF-8 sequence
                return 0;
            }
            ret = (ret * 64) | (b & 0x3F);
        }

        return ret;
    }

    /*
     * @dev Returns the keccak-256 hash of the slice.
     * @param self The slice to hash.
     * @return The hash of the slice.
     */
    function keccak(slice self) internal pure returns (bytes32 ret) {
        assembly {
            ret := keccak256(mload(add(self, 32)), mload(self))
        }
    }

    /*
     * @dev Returns true if `self` starts with `needle`.
     * @param self The slice to operate on.
     * @param needle The slice to search for.
     * @return True if the slice starts with the provided text, false otherwise.
     */
    function startsWith(slice self, slice needle) internal pure returns (bool) {
        if (self._len < needle._len) {
            return false;
        }

        if (self._ptr == needle._ptr) {
            return true;
        }

        bool equal;
        assembly {
            let length := mload(needle)
            let selfptr := mload(add(self, 0x20))
            let needleptr := mload(add(needle, 0x20))
            equal := eq(keccak256(selfptr, length), keccak256(needleptr, length))
        }
        return equal;
    }

    /*
     * @dev If `self` starts with `needle`, `needle` is removed from the
     *      beginning of `self`. Otherwise, `self` is unmodified.
     * @param self The slice to operate on.
     * @param needle The slice to search for.
     * @return `self`
     */
    function beyond(slice self, slice needle) internal pure returns (slice) {
        if (self._len < needle._len) {
            return self;
        }

        bool equal = true;
        if (self._ptr != needle._ptr) {
            assembly {
                let length := mload(needle)
                let selfptr := mload(add(self, 0x20))
                let needleptr := mload(add(needle, 0x20))
                equal := eq(sha3(selfptr, length), sha3(needleptr, length))
            }
        }

        if (equal) {
            self._len -= needle._len;
            self._ptr += needle._len;
        }

        return self;
    }

    /*
     * @dev Returns true if the slice ends with `needle`.
     * @param self The slice to operate on.
     * @param needle The slice to search for.
     * @return True if the slice starts with the provided text, false otherwise.
     */
    function endsWith(slice self, slice needle) internal pure returns (bool) {
        if (self._len < needle._len) {
            return false;
        }

        var selfptr = self._ptr + self._len - needle._len;

        if (selfptr == needle._ptr) {
            return true;
        }

        bool equal;
        assembly {
            let length := mload(needle)
            let needleptr := mload(add(needle, 0x20))
            equal := eq(keccak256(selfptr, length), keccak256(needleptr, length))
        }

        return equal;
    }

    /*
     * @dev If `self` ends with `needle`, `needle` is removed from the
     *      end of `self`. Otherwise, `self` is unmodified.
     * @param self The slice to operate on.
     * @param needle The slice to search for.
     * @return `self`
     */
    function until(slice self, slice needle) internal pure returns (slice) {
        if (self._len < needle._len) {
            return self;
        }

        var selfptr = self._ptr + self._len - needle._len;
        bool equal = true;
        if (selfptr != needle._ptr) {
            assembly {
                let length := mload(needle)
                let needleptr := mload(add(needle, 0x20))
                equal := eq(keccak256(selfptr, length), keccak256(needleptr, length))
            }
        }

        if (equal) {
            self._len -= needle._len;
        }

        return self;
    }

    // Returns the memory address of the first byte of the first occurrence of
    // `needle` in `self`, or the first byte after `self` if not found.
    function findPtr(uint selflen, uint selfptr, uint needlelen, uint needleptr) private returns (uint) {
        uint ptr;
        uint idx;

        if (needlelen <= selflen) {
            if (needlelen <= 32) {
                // Optimized assembly for 68 gas per byte on short strings
                assembly {
                    let mask := not(sub(exp(2, mul(8, sub(32, needlelen))), 1))
                    let needledata := and(mload(needleptr), mask)
                    let end := add(selfptr, sub(selflen, needlelen))
                    ptr := selfptr
                    loop:
                    jumpi(exit, eq(and(mload(ptr), mask), needledata))
                    ptr := add(ptr, 1)
                    jumpi(loop, lt(sub(ptr, 1), end))
                    ptr := add(selfptr, selflen)
                    exit:
                }
                return ptr;
            } else {
                // For long needles, use hashing
                bytes32 hash;
                assembly { hash := sha3(needleptr, needlelen) }
                ptr = selfptr;
                for (idx = 0; idx <= selflen - needlelen; idx++) {
                    bytes32 testHash;
                    assembly { testHash := sha3(ptr, needlelen) }
                    if (hash == testHash)
                        return ptr;
                    ptr += 1;
                }
            }
        }
        return selfptr + selflen;
    }

    // Returns the memory address of the first byte after the last occurrence of
    // `needle` in `self`, or the address of `self` if not found.
    function rfindPtr(uint selflen, uint selfptr, uint needlelen, uint needleptr) private returns (uint) {
        uint ptr;

        if (needlelen <= selflen) {
            if (needlelen <= 32) {
                // Optimized assembly for 69 gas per byte on short strings
                assembly {
                    let mask := not(sub(exp(2, mul(8, sub(32, needlelen))), 1))
                    let needledata := and(mload(needleptr), mask)
                    ptr := add(selfptr, sub(selflen, needlelen))
                    loop:
                    jumpi(ret, eq(and(mload(ptr), mask), needledata))
                    ptr := sub(ptr, 1)
                    jumpi(loop, gt(add(ptr, 1), selfptr))
                    ptr := selfptr
                    jump(exit)
                    ret:
                    ptr := add(ptr, needlelen)
                    exit:
                }
                return ptr;
            } else {
                // For long needles, use hashing
                bytes32 hash;
                assembly { hash := sha3(needleptr, needlelen) }
                ptr = selfptr + (selflen - needlelen);
                while (ptr >= selfptr) {
                    bytes32 testHash;
                    assembly { testHash := sha3(ptr, needlelen) }
                    if (hash == testHash)
                        return ptr + needlelen;
                    ptr -= 1;
                }
            }
        }
        return selfptr;
    }

    /*
     * @dev Modifies `self` to contain everything from the first occurrence of
     *      `needle` to the end of the slice. `self` is set to the empty slice
     *      if `needle` is not found.
     * @param self The slice to search and modify.
     * @param needle The text to search for.
     * @return `self`.
     */
    function find(slice self, slice needle) internal returns (slice) {
        uint ptr = findPtr(self._len, self._ptr, needle._len, needle._ptr);
        self._len -= ptr - self._ptr;
        self._ptr = ptr;
        return self;
    }

    /*
     * @dev Modifies `self` to contain the part of the string from the start of
     *      `self` to the end of the first occurrence of `needle`. If `needle`
     *      is not found, `self` is set to the empty slice.
     * @param self The slice to search and modify.
     * @param needle The text to search for.
     * @return `self`.
     */
    function rfind(slice self, slice needle) internal returns (slice) {
        uint ptr = rfindPtr(self._len, self._ptr, needle._len, needle._ptr);
        self._len = ptr - self._ptr;
        return self;
    }

    /*
     * @dev Splits the slice, setting `self` to everything after the first
     *      occurrence of `needle`, and `token` to everything before it. If
     *      `needle` does not occur in `self`, `self` is set to the empty slice,
     *      and `token` is set to the entirety of `self`.
     * @param self The slice to split.
     * @param needle The text to search for in `self`.
     * @param token An output parameter to which the first token is written.
     * @return `token`.
     */
    function split(slice self, slice needle, slice token) internal returns (slice) {
        uint ptr = findPtr(self._len, self._ptr, needle._len, needle._ptr);
        token._ptr = self._ptr;
        token._len = ptr - self._ptr;
        if (ptr == self._ptr + self._len) {
            // Not found
            self._len = 0;
        } else {
            self._len -= token._len + needle._len;
            self._ptr = ptr + needle._len;
        }
        return token;
    }

    /*
     * @dev Splits the slice, setting `self` to everything after the first
     *      occurrence of `needle`, and returning everything before it. If
     *      `needle` does not occur in `self`, `self` is set to the empty slice,
     *      and the entirety of `self` is returned.
     * @param self The slice to split.
     * @param needle The text to search for in `self`.
     * @return The part of `self` up to the first occurrence of `delim`.
     */
    function split(slice self, slice needle) internal returns (slice token) {
        split(self, needle, token);
    }

    /*
     * @dev Splits the slice, setting `self` to everything before the last
     *      occurrence of `needle`, and `token` to everything after it. If
     *      `needle` does not occur in `self`, `self` is set to the empty slice,
     *      and `token` is set to the entirety of `self`.
     * @param self The slice to split.
     * @param needle The text to search for in `self`.
     * @param token An output parameter to which the first token is written.
     * @return `token`.
     */
    function rsplit(slice self, slice needle, slice token) internal returns (slice) {
        uint ptr = rfindPtr(self._len, self._ptr, needle._len, needle._ptr);
        token._ptr = ptr;
        token._len = self._len - (ptr - self._ptr);
        if (ptr == self._ptr) {
            // Not found
            self._len = 0;
        } else {
            self._len -= token._len + needle._len;
        }
        return token;
    }

    /*
     * @dev Splits the slice, setting `self` to everything before the last
     *      occurrence of `needle`, and returning everything after it. If
     *      `needle` does not occur in `self`, `self` is set to the empty slice,
     *      and the entirety of `self` is returned.
     * @param self The slice to split.
     * @param needle The text to search for in `self`.
     * @return The part of `self` after the last occurrence of `delim`.
     */
    function rsplit(slice self, slice needle) internal returns (slice token) {
        rsplit(self, needle, token);
    }

    /*
     * @dev Counts the number of nonoverlapping occurrences of `needle` in `self`.
     * @param self The slice to search.
     * @param needle The text to search for in `self`.
     * @return The number of occurrences of `needle` found in `self`.
     */
    function count(slice self, slice needle) internal returns (uint cnt) {
        uint ptr = findPtr(self._len, self._ptr, needle._len, needle._ptr) + needle._len;
        while (ptr <= self._ptr + self._len) {
            cnt++;
            ptr = findPtr(self._len - (ptr - self._ptr), ptr, needle._len, needle._ptr) + needle._len;
        }
    }

    /*
     * @dev Returns True if `self` contains `needle`.
     * @param self The slice to search.
     * @param needle The text to search for in `self`.
     * @return True if `needle` is found in `self`, false otherwise.
     */
    function contains(slice self, slice needle) internal returns (bool) {
        return rfindPtr(self._len, self._ptr, needle._len, needle._ptr) != self._ptr;
    }

    /*
     * @dev Returns a newly allocated string containing the concatenation of
     *      `self` and `other`.
     * @param self The first slice to concatenate.
     * @param other The second slice to concatenate.
     * @return The concatenation of the two strings.
     */
    function concat(slice self, slice other) internal pure returns (string) {
        var ret = new string(self._len + other._len);
        uint retptr;
        assembly { retptr := add(ret, 32) }
        memcpy(retptr, self._ptr, self._len);
        memcpy(retptr + self._len, other._ptr, other._len);
        return ret;
    }

    /*
     * @dev Joins an array of slices, using `self` as a delimiter, returning a
     *      newly allocated string.
     * @param self The delimiter to use.
     * @param parts A list of slices to join.
     * @return A newly allocated string containing all the slices in `parts`,
     *         joined with `self`.
     */
    function join(slice self, slice[] parts) internal pure returns (string) {
        if (parts.length == 0)
            return "";

        uint length = self._len * (parts.length - 1);
        for(uint i = 0; i < parts.length; i++)
            length += parts[i]._len;

        var ret = new string(length);
        uint retptr;
        assembly { retptr := add(ret, 32) }

        for(i = 0; i < parts.length; i++) {
            memcpy(retptr, parts[i]._ptr, parts[i]._len);
            retptr += parts[i]._len;
            if (i < parts.length - 1) {
                memcpy(retptr, self._ptr, self._len);
                retptr += self._len;
            }
        }

        return ret;
    }
}

// File: contracts/CloversMetadata.sol

pragma solidity ^0.4.18;

/**
* CloversMetadata contract is upgradeable and returns metadata about Clovers
*/



contract CloversMetadata {
    using strings for *;

    function tokenURI(uint _tokenId) public view returns (string _infoUrl) {
        string memory base = "https://api2.clovers.network/clovers/metadata/0x";
        string memory id = uint2hexstr(_tokenId);
        string memory suffix = "";
        return base.toSlice().concat(id.toSlice()).toSlice().concat(suffix.toSlice());
    }
    function uint2hexstr(uint i) internal pure returns (string) {
        if (i == 0) return "0";
        uint j = i;
        uint length;
        while (j != 0) {
            length++;
            j = j >> 4;
        }
        uint mask = 15;
        bytes memory bstr = new bytes(length);
        uint k = length - 1;
        while (i != 0){
            uint curr = (i & mask);
            bstr[k--] = curr > 9 ? byte(55 + curr) : byte(48 + curr); // 55 = 65 - 10
            i = i >> 4;
        }
        return string(bstr);
    }
}

// File: contracts/Clovers.sol

pragma solidity ^0.4.18;

/**
 * Digital Asset Registry for the Non Fungible Token Clover
 * with upgradeable contract reference for returning metadata.
 */







contract Clovers is ERC721Token, Admin, Ownable {

    address public cloversMetadata;
    uint256 public totalSymmetries;
    uint256[5] symmetries; // RotSym, Y0Sym, X0Sym, XYSym, XnYSym
    address public cloversController;
    address public clubTokenController;

    mapping (uint256 => Clover) public clovers;
    struct Clover {
        bool keep;
        uint256 symmetries;
        bytes28[2] cloverMoves;
        uint256 blockMinted;
        uint256 rewards;
    }

    modifier onlyOwnerOrController() {
        require(
            msg.sender == cloversController ||
            owner == msg.sender ||
            admins[msg.sender]
        );
        _;
    }


    /**
    * @dev Checks msg.sender can transfer a token, by being owner, approved, operator or cloversController
    * @param _tokenId uint256 ID of the token to validate
    */
    modifier canTransfer(uint256 _tokenId) {
        require(isApprovedOrOwner(msg.sender, _tokenId) || msg.sender == cloversController);
        _;
    }

    constructor(string name, string symbol) public
        ERC721Token(name, symbol)
    { }

    function () public payable {}

    function implementation() public view returns (address) {
        return cloversMetadata;
    }

    function tokenURI(uint _tokenId) public view returns (string _infoUrl) {
        return CloversMetadata(cloversMetadata).tokenURI(_tokenId);
    }
    function getHash(bytes28[2] moves) public pure returns (bytes32) {
        return keccak256(moves);
    }
    function getKeep(uint256 _tokenId) public view returns (bool) {
        return clovers[_tokenId].keep;
    }
    function getBlockMinted(uint256 _tokenId) public view returns (uint256) {
        return clovers[_tokenId].blockMinted;
    }
    function getCloverMoves(uint256 _tokenId) public view returns (bytes28[2]) {
        return clovers[_tokenId].cloverMoves;
    }
    function getReward(uint256 _tokenId) public view returns (uint256) {
        return clovers[_tokenId].rewards;
    }
    function getSymmetries(uint256 _tokenId) public view returns (uint256) {
        return clovers[_tokenId].symmetries;
    }
    function getAllSymmetries() public view returns (uint256, uint256, uint256, uint256, uint256, uint256) {
        return (
            totalSymmetries,
            symmetries[0], //RotSym,
            symmetries[1], //Y0Sym,
            symmetries[2], //X0Sym,
            symmetries[3], //XYSym,
            symmetries[4] //XnYSym
        );
    }

/* ---------------------------------------------------------------------------------------------------------------------- */

    /**
    * @dev Moves Eth to a certain address for use in the CloversController
    * @param _to The address to receive the Eth.
    * @param _amount The amount of Eth to be transferred.
    */
    function moveEth(address _to, uint256 _amount) public onlyOwnerOrController {
        require(_amount <= this.balance);
        _to.transfer(_amount);
    }
    /**
    * @dev Moves Token to a certain address for use in the CloversController
    * @param _to The address to receive the Token.
    * @param _amount The amount of Token to be transferred.
    * @param _token The address of the Token to be transferred.
    */
    function moveToken(address _to, uint256 _amount, address _token) public onlyOwnerOrController returns (bool) {
        require(_amount <= ERC20(_token).balanceOf(this));
        return ERC20(_token).transfer(_to, _amount);
    }
    /**
    * @dev Approves Tokens to a certain address for use in the CloversController
    * @param _to The address to receive the Token approval.
    * @param _amount The amount of Token to be approved.
    * @param _token The address of the Token to be approved.
    */
    function approveToken(address _to, uint256 _amount, address _token) public onlyOwnerOrController returns (bool) {
        return ERC20(_token).approve(_to, _amount);
    }

    /**
    * @dev Sets whether the minter will keep the clover
    * @param _tokenId The token Id.
    * @param value Whether the clover will be kept.
    */
    function setKeep(uint256 _tokenId, bool value) public onlyOwnerOrController {
        clovers[_tokenId].keep = value;
    }
    function setBlockMinted(uint256 _tokenId, uint256 value) public onlyOwnerOrController {
        clovers[_tokenId].blockMinted = value;
    }
    function setCloverMoves(uint256 _tokenId, bytes28[2] moves) public onlyOwnerOrController {
        clovers[_tokenId].cloverMoves = moves;
    }
    function setReward(uint256 _tokenId, uint256 _amount) public onlyOwnerOrController {
        clovers[_tokenId].rewards = _amount;
    }
    function setSymmetries(uint256 _tokenId, uint256 _symmetries) public onlyOwnerOrController {
        clovers[_tokenId].symmetries = _symmetries;
    }

    /**
    * @dev Sets total tallies of symmetry counts. For use by the controller to correct for invalid Clovers.
    * @param _totalSymmetries The total number of Symmetries.
    * @param RotSym The total number of RotSym Symmetries.
    * @param Y0Sym The total number of Y0Sym Symmetries.
    * @param X0Sym The total number of X0Sym Symmetries.
    * @param XYSym The total number of XYSym Symmetries.
    * @param XnYSym The total number of XnYSym Symmetries.
    */
    function setAllSymmetries(uint256 _totalSymmetries, uint256 RotSym, uint256 Y0Sym, uint256 X0Sym, uint256 XYSym, uint256 XnYSym) public onlyOwnerOrController {
        totalSymmetries = _totalSymmetries;
        symmetries[0] = RotSym;
        symmetries[1] = Y0Sym;
        symmetries[2] = X0Sym;
        symmetries[3] = XYSym;
        symmetries[4] = XnYSym;
    }

    /**
    * @dev Deletes data about a Clover.
    * @param _tokenId The Id of the clover token to be deleted.
    */
    function deleteClover(uint256 _tokenId) public onlyOwnerOrController {
        delete(clovers[_tokenId]);
        unmint(_tokenId);
    }
    /**
    * @dev Updates the CloversController contract address and approves that contract to manage the Clovers owned by the Clovers contract.
    * @param _cloversController The address of the new contract.
    */
    function updateCloversControllerAddress(address _cloversController) public onlyOwner {
        require(_cloversController != 0);
        cloversController = _cloversController;
    }



    /**
    * @dev Updates the CloversMetadata contract address.
    * @param _cloversMetadata The address of the new contract.
    */
    function updateCloversMetadataAddress(address _cloversMetadata) public onlyOwner {
        require(_cloversMetadata != 0);
        cloversMetadata = _cloversMetadata;
    }

    function updateClubTokenController(address _clubTokenController) public onlyOwner {
        require(_clubTokenController != 0);
        clubTokenController = _clubTokenController;
    }

    /**
    * @dev Mints new Clovers.
    * @param _to The address of the new clover owner.
    * @param _tokenId The Id of the new clover token.
    */
    function mint (address _to, uint256 _tokenId) public onlyOwnerOrController {
        super._mint(_to, _tokenId);
        setApprovalForAll(clubTokenController, true);
    }


    function mintMany(address[] _tos, uint256[] _tokenIds, bytes28[2][] memory _movess, uint256[] _symmetries) public onlyAdmin {
        require(_tos.length == _tokenIds.length && _tokenIds.length == _movess.length && _movess.length == _symmetries.length);
        for (uint256 i = 0; i < _tos.length; i++) {
            address _to = _tos[i];
            uint256 _tokenId = _tokenIds[i];
            bytes28[2] memory _moves = _movess[i];
            uint256 _symmetry = _symmetries[i];
            setCloverMoves(_tokenId, _moves);
            if (_symmetry > 0) {
                setSymmetries(_tokenId, _symmetry);
            }
            super._mint(_to, _tokenId);
            setApprovalForAll(clubTokenController, true);
        }
    }

    /**
    * @dev Unmints Clovers.
    * @param _tokenId The Id of the clover token to be destroyed.
    */
    function unmint (uint256 _tokenId) public onlyOwnerOrController {
        super._burn(ownerOf(_tokenId), _tokenId);
    }


}

Contract Security Audit

Contract ABI

[{"constant":true,"inputs":[{"name":"_interfaceId","type":"bytes4"}],"name":"supportsInterface","outputs":[{"name":"","type":"bool"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"name":"_tokenId","type":"uint256"}],"name":"getBlockMinted","outputs":[{"name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"name":"_to","type":"address"},{"name":"_amount","type":"uint256"},{"name":"_token","type":"address"}],"name":"moveToken","outputs":[{"name":"","type":"bool"}],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[{"name":"_tokenId","type":"uint256"}],"name":"getKeep","outputs":[{"name":"","type":"bool"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"name","outputs":[{"name":"","type":"string"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"name":"_tokenId","type":"uint256"}],"name":"getApproved","outputs":[{"name":"","type":"address"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"name":"_to","type":"address"},{"name":"_tokenId","type":"uint256"}],"name":"approve","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"name":"_tokenId","type":"uint256"},{"name":"moves","type":"bytes28[2]"}],"name":"setCloverMoves","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"name":"_tokenId","type":"uint256"}],"name":"deleteClover","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[],"name":"cloversController","outputs":[{"name":"","type":"address"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"name":"moves","type":"bytes28[2]"}],"name":"getHash","outputs":[{"name":"","type":"bytes32"}],"payable":false,"stateMutability":"pure","type":"function"},{"constant":true,"inputs":[],"name":"totalSupply","outputs":[{"name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"InterfaceId_ERC165","outputs":[{"name":"","type":"bytes4"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"name":"_tokenId","type":"uint256"}],"name":"getReward","outputs":[{"name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"name":"_to","type":"address"},{"name":"_amount","type":"uint256"}],"name":"moveEth","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"name":"_from","type":"address"},{"name":"_to","type":"address"},{"name":"_tokenId","type":"uint256"}],"name":"transferFrom","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[{"name":"_admin","type":"address"}],"name":"isAdmin","outputs":[{"name":"","type":"bool"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"name":"_owner","type":"address"},{"name":"_index","type":"uint256"}],"name":"tokenOfOwnerByIndex","outputs":[{"name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"name":"_to","type":"address"},{"name":"_tokenId","type":"uint256"}],"name":"mint","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"name":"_from","type":"address"},{"name":"_to","type":"address"},{"name":"_tokenId","type":"uint256"}],"name":"safeTransferFrom","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[{"name":"","type":"address"}],"name":"admins","outputs":[{"name":"","type":"bool"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"name":"_cloversMetadata","type":"address"}],"name":"updateCloversMetadataAddress","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[{"name":"_tokenId","type":"uint256"}],"name":"exists","outputs":[{"name":"","type":"bool"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"name":"_index","type":"uint256"}],"name":"tokenByIndex","outputs":[{"name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"totalSymmetries","outputs":[{"name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"name":"_newAdmin","type":"address"}],"name":"transferAdminship","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[],"name":"implementation","outputs":[{"name":"","type":"address"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"name":"_tokenId","type":"uint256"}],"name":"getCloverMoves","outputs":[{"name":"","type":"bytes28[2]"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"name":"_tokenId","type":"uint256"}],"name":"ownerOf","outputs":[{"name":"","type":"address"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"name":"_tokenId","type":"uint256"}],"name":"unmint","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"name":"_previousAdmin","type":"address"}],"name":"renounceAdminship","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[{"name":"","type":"uint256"}],"name":"clovers","outputs":[{"name":"keep","type":"bool"},{"name":"symmetries","type":"uint256"},{"name":"blockMinted","type":"uint256"},{"name":"rewards","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"name":"_owner","type":"address"}],"name":"balanceOf","outputs":[{"name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[],"name":"renounceOwnership","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"name":"_tokenId","type":"uint256"},{"name":"value","type":"bool"}],"name":"setKeep","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[],"name":"getAllSymmetries","outputs":[{"name":"","type":"uint256"},{"name":"","type":"uint256"},{"name":"","type":"uint256"},{"name":"","type":"uint256"},{"name":"","type":"uint256"},{"name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"name":"_tos","type":"address[]"},{"name":"_tokenIds","type":"uint256[]"},{"name":"_movess","type":"bytes28[2][]"},{"name":"_symmetries","type":"uint256[]"}],"name":"mintMany","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[],"name":"cloversMetadata","outputs":[{"name":"","type":"address"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"name":"_cloversController","type":"address"}],"name":"updateCloversControllerAddress","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"name":"_totalSymmetries","type":"uint256"},{"name":"RotSym","type":"uint256"},{"name":"Y0Sym","type":"uint256"},{"name":"X0Sym","type":"uint256"},{"name":"XYSym","type":"uint256"},{"name":"XnYSym","type":"uint256"}],"name":"setAllSymmetries","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[],"name":"owner","outputs":[{"name":"","type":"address"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"name":"_clubTokenController","type":"address"}],"name":"updateClubTokenController","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[],"name":"symbol","outputs":[{"name":"","type":"string"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"name":"_to","type":"address"},{"name":"_approved","type":"bool"}],"name":"setApprovalForAll","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"name":"_tokenId","type":"uint256"},{"name":"_amount","type":"uint256"}],"name":"setReward","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[],"name":"clubTokenController","outputs":[{"name":"","type":"address"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"name":"_from","type":"address"},{"name":"_to","type":"address"},{"name":"_tokenId","type":"uint256"},{"name":"_data","type":"bytes"}],"name":"safeTransferFrom","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[{"name":"_tokenId","type":"uint256"}],"name":"getSymmetries","outputs":[{"name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"name":"_to","type":"address"},{"name":"_amount","type":"uint256"},{"name":"_token","type":"address"}],"name":"approveToken","outputs":[{"name":"","type":"bool"}],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[{"name":"_tokenId","type":"uint256"}],"name":"tokenURI","outputs":[{"name":"_infoUrl","type":"string"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"name":"_tokenId","type":"uint256"},{"name":"_symmetries","type":"uint256"}],"name":"setSymmetries","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"name":"_tokenId","type":"uint256"},{"name":"value","type":"uint256"}],"name":"setBlockMinted","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[{"name":"_owner","type":"address"},{"name":"_operator","type":"address"}],"name":"isApprovedForAll","outputs":[{"name":"","type":"bool"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"name":"_newOwner","type":"address"}],"name":"transferOwnership","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"inputs":[{"name":"name","type":"string"},{"name":"symbol","type":"string"}],"payable":false,"stateMutability":"nonpayable","type":"constructor"},{"payable":true,"stateMutability":"payable","type":"fallback"},{"anonymous":false,"inputs":[{"indexed":true,"name":"previousOwner","type":"address"}],"name":"OwnershipRenounced","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"name":"previousOwner","type":"address"},{"indexed":true,"name":"newOwner","type":"address"}],"name":"OwnershipTransferred","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"name":"previousAdmin","type":"address"}],"name":"AdminshipRenounced","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"name":"previousAdmin","type":"address"},{"indexed":true,"name":"newAdmin","type":"address"}],"name":"AdminshipTransferred","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"name":"_from","type":"address"},{"indexed":true,"name":"_to","type":"address"},{"indexed":true,"name":"_tokenId","type":"uint256"}],"name":"Transfer","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"name":"_owner","type":"address"},{"indexed":true,"name":"_approved","type":"address"},{"indexed":true,"name":"_tokenId","type":"uint256"}],"name":"Approval","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"name":"_owner","type":"address"},{"indexed":true,"name":"_operator","type":"address"},{"indexed":false,"name":"_approved","type":"bool"}],"name":"ApprovalForAll","type":"event"}]

60806040523480156200001157600080fd5b506040516200325238038062003252833981016040528051602082015190820191018181620000697f01ffc9a7000000000000000000000000000000000000000000000000000000006401000000006200019d810204565b6200009d7f80ac58cd000000000000000000000000000000000000000000000000000000006401000000006200019d810204565b620000d17f4f558e79000000000000000000000000000000000000000000000000000000006401000000006200019d810204565b8151620000e69060059060208501906200020a565b508051620000fc9060069060208401906200020a565b50620001317f780e9d63000000000000000000000000000000000000000000000000000000006401000000006200019d810204565b620001657f5b5e139f000000000000000000000000000000000000000000000000000000006401000000006200019d810204565b5050336000818152600c60205260409020805460ff19166001179055600d8054600160a060020a031916909117905550620002af9050565b7fffffffff000000000000000000000000000000000000000000000000000000008082161415620001cd57600080fd5b7fffffffff00000000000000000000000000000000000000000000000000000000166000908152602081905260409020805460ff19166001179055565b828054600181600116156101000203166002900490600052602060002090601f016020900481019282601f106200024d57805160ff19168380011785556200027d565b828001600101855582156200027d579182015b828111156200027d57825182559160200191906001019062000260565b506200028b9291506200028f565b5090565b620002ac91905b808211156200028b576000815560010162000296565b90565b612f9380620002bf6000396000f3006080604052600436106102875763ffffffff7c010000000000000000000000000000000000000000000000000000000060003504166301ffc9a7811461028957806303a53d6b146102d7578063048e62ca14610301578063049526311461033957806306fdde0314610351578063081812fc146103db578063095ea7b31461041c5780630b6283951461044d5780630e8310d61461049057806312414198146104a85780631732e941146104bd57806318160ddd146104fd57806319fa8f50146105125780631c4b774b1461055c5780631cc1472d1461057457806323b872dd146105a557806324d7806c146105dc5780632f745c591461060a57806340c10f191461063b57806342842e0e1461066c578063429b62e5146106a35780634e485f88146106d15780634f558e79146106ff5780634f6ccce71461071757806350a98a641461072f5780635be7cc16146107445780635c60da1b1461077257806362f9acf9146107875780636352211e146107da57806364e779b1146107f25780636fce9d881461080a578063708fa7f71461083857806370a0823114610878578063715018a6146108a657806376e4a87f146108bb578063785d8d71146108d85780638810ee8b1461092057806388b6e7a514610a5a5780638a56a22614610a6f5780638b1b2ba814610a9d5780638da5cb5b14610ac45780639564e18014610ad957806395d89b4114610b07578063a22cb46514610b1c578063a47bd49614610b4f578063a89b55da14610b6a578063b88d4fde14610b7f578063c53b4bf914610bfb578063c863bac114610c13578063c87b56dd14610c4b578063dc3f775814610c63578063e3100d1e14610c7e578063e985e9c514610c99578063f2fde38b14610ccd575b005b34801561029557600080fd5b506102c37fffffffff0000000000000000000000000000000000000000000000000000000060043516610cfb565b604080519115158252519081900360200190f35b3480156102e357600080fd5b506102ef600435610d32565b60408051918252519081900360200190f35b34801561030d57600080fd5b506102c373ffffffffffffffffffffffffffffffffffffffff6004358116906024359060443516610d47565b34801561034557600080fd5b506102c3600435610f29565b34801561035d57600080fd5b50610366610f3e565b6040805160208082528351818301528351919283929083019185019080838360005b838110156103a0578181015183820152602001610388565b50505050905090810190601f1680156103cd5780820380516001836020036101000a031916815260200191505b509250505060405180910390f35b3480156103e757600080fd5b506103f3600435610ff3565b6040805173ffffffffffffffffffffffffffffffffffffffff9092168252519081900360200190f35b34801561042857600080fd5b5061028773ffffffffffffffffffffffffffffffffffffffff6004351660243561101b565b34801561045957600080fd5b5060408051808201825261028791600480359236926064919060249060029083908390808284375093965061110395505050505050565b34801561049c57600080fd5b50610287600435611189565b3480156104b457600080fd5b506103f3611250565b3480156104c957600080fd5b506040805180820182526102ef91369160049160449190839060029083908390808284375093965061126c95505050505050565b34801561050957600080fd5b506102ef6112b0565b34801561051e57600080fd5b506105276112b6565b604080517fffffffff000000000000000000000000000000000000000000000000000000009092168252519081900360200190f35b34801561056857600080fd5b506102ef6004356112da565b34801561058057600080fd5b5061028773ffffffffffffffffffffffffffffffffffffffff600435166024356112ef565b3480156105b157600080fd5b5061028773ffffffffffffffffffffffffffffffffffffffff600435811690602435166044356113a2565b3480156105e857600080fd5b506102c373ffffffffffffffffffffffffffffffffffffffff6004351661149d565b34801561061657600080fd5b506102ef73ffffffffffffffffffffffffffffffffffffffff600435166024356114c8565b34801561064757600080fd5b5061028773ffffffffffffffffffffffffffffffffffffffff60043516602435611522565b34801561067857600080fd5b5061028773ffffffffffffffffffffffffffffffffffffffff600435811690602435166044356115b6565b3480156106af57600080fd5b506102c373ffffffffffffffffffffffffffffffffffffffff60043516611610565b3480156106dd57600080fd5b5061028773ffffffffffffffffffffffffffffffffffffffff60043516611625565b34801561070b57600080fd5b506102c36004356116b2565b34801561072357600080fd5b506102ef6004356116dc565b34801561073b57600080fd5b506102ef611711565b34801561075057600080fd5b5061028773ffffffffffffffffffffffffffffffffffffffff60043516611717565b34801561077e57600080fd5b506103f361173e565b34801561079357600080fd5b5061079f60043561175a565b6040518082600260200280838360005b838110156107c75781810151838201526020016107af565b5050505090500191505060405180910390f35b3480156107e657600080fd5b506103f36004356117cf565b3480156107fe57600080fd5b50610287600435611806565b34801561081657600080fd5b5061028773ffffffffffffffffffffffffffffffffffffffff6004351661187a565b34801561084457600080fd5b50610850600435611925565b6040805194151585526020850193909352838301919091526060830152519081900360800190f35b34801561088457600080fd5b506102ef73ffffffffffffffffffffffffffffffffffffffff60043516611950565b3480156108b257600080fd5b5061028761199d565b3480156108c757600080fd5b506102876004356024351515611a30565b3480156108e457600080fd5b506108ed611ad0565b604080519687526020870195909552858501939093526060850191909152608084015260a0830152519081900360c00190f35b34801561092c57600080fd5b506040805160206004803580820135838102808601850190965280855261028795369593946024949385019291829185019084908082843750506040805187358901803560208181028481018201909552818452989b9a9989019892975090820195509350839250850190849080828437505060408051873589018035602081810284018101909452808352979a999883019791965082019450925082915060009085015b82821015610a0a5760408051808201825290808402870190600290839083908082843750505091835250506001909101906020016109d1565b50505050509192919290803590602001908201803590602001908080602002602001604051908101604052809392919081815260200183836020028082843750949750611b0d9650505050505050565b348015610a6657600080fd5b506103f3611c39565b348015610a7b57600080fd5b5061028773ffffffffffffffffffffffffffffffffffffffff60043516611c55565b348015610aa957600080fd5b5061028760043560243560443560643560843560a435611ce2565b348015610ad057600080fd5b506103f3611d61565b348015610ae557600080fd5b5061028773ffffffffffffffffffffffffffffffffffffffff60043516611d7d565b348015610b1357600080fd5b50610366611e0a565b348015610b2857600080fd5b5061028773ffffffffffffffffffffffffffffffffffffffff600435166024351515611e89565b348015610b5b57600080fd5b50610287600435602435611f45565b348015610b7657600080fd5b506103f3611fbc565b348015610b8b57600080fd5b50604080516020601f6064356004818101359283018490048402850184019095528184526102879473ffffffffffffffffffffffffffffffffffffffff8135811695602480359092169560443595369560849401918190840183828082843750949750611fd89650505050505050565b348015610c0757600080fd5b506102ef600435612039565b348015610c1f57600080fd5b506102c373ffffffffffffffffffffffffffffffffffffffff600435811690602435906044351661204e565b348015610c5757600080fd5b50610366600435612156565b348015610c6f57600080fd5b50610287600435602435612275565b348015610c8a57600080fd5b506102876004356024356122ec565b348015610ca557600080fd5b506102c373ffffffffffffffffffffffffffffffffffffffff60043581169060243516612363565b348015610cd957600080fd5b5061028773ffffffffffffffffffffffffffffffffffffffff6004351661239e565b7fffffffff000000000000000000000000000000000000000000000000000000001660009081526020819052604090205460ff1690565b60009081526017602052604090206004015490565b60155460009073ffffffffffffffffffffffffffffffffffffffff16331480610d875750600d5473ffffffffffffffffffffffffffffffffffffffff1633145b80610da15750336000908152600c602052604090205460ff165b1515610dac57600080fd5b604080517f70a08231000000000000000000000000000000000000000000000000000000008152306004820152905173ffffffffffffffffffffffffffffffffffffffff8416916370a082319160248083019260209291908290030181600087803b158015610e1a57600080fd5b505af1158015610e2e573d6000803e3d6000fd5b505050506040513d6020811015610e4457600080fd5b5051831115610e5257600080fd5b8173ffffffffffffffffffffffffffffffffffffffff1663a9059cbb85856040518363ffffffff167c0100000000000000000000000000000000000000000000000000000000028152600401808373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200182815260200192505050602060405180830381600087803b158015610ef557600080fd5b505af1158015610f09573d6000803e3d6000fd5b505050506040513d6020811015610f1f57600080fd5b5051949350505050565b60009081526017602052604090205460ff1690565b60058054604080516020601f60027fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff610100600188161502019095169490940493840181900481028201810190925282815260609390929091830182828015610fe85780601f10610fbd57610100808354040283529160200191610fe8565b820191906000526020600020905b815481529060010190602001808311610fcb57829003601f168201915b505050505090505b90565b60009081526002602052604090205473ffffffffffffffffffffffffffffffffffffffff1690565b6000611026826117cf565b905073ffffffffffffffffffffffffffffffffffffffff838116908216141561104e57600080fd5b3373ffffffffffffffffffffffffffffffffffffffff8216148061107757506110778133612363565b151561108257600080fd5b60008281526002602052604080822080547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff87811691821790925591518593918516917f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b92591a4505050565b60155473ffffffffffffffffffffffffffffffffffffffff163314806111405750600d5473ffffffffffffffffffffffffffffffffffffffff1633145b8061115a5750336000908152600c602052604090205460ff165b151561116557600080fd5b6000828152601760205260409020611184906002908101908390612e12565b505050565b60155473ffffffffffffffffffffffffffffffffffffffff163314806111c65750600d5473ffffffffffffffffffffffffffffffffffffffff1633145b806111e05750336000908152600c602052604090205460ff165b15156111eb57600080fd5b600081815260176020526040812080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0016815560018101829055906112346002830182612e80565b5060006004820181905560059091015561124d81611806565b50565b60155473ffffffffffffffffffffffffffffffffffffffff1681565b6000816040518082600260200280838360005b8381101561129757818101518382015260200161127f565b5050505090500191505060405180910390209050919050565b60095490565b7f01ffc9a70000000000000000000000000000000000000000000000000000000081565b60009081526017602052604090206005015490565b60155473ffffffffffffffffffffffffffffffffffffffff1633148061132c5750600d5473ffffffffffffffffffffffffffffffffffffffff1633145b806113465750336000908152600c602052604090205460ff165b151561135157600080fd5b303181111561135f57600080fd5b60405173ffffffffffffffffffffffffffffffffffffffff83169082156108fc029083906000818181858888f19350505050158015611184573d6000803e3d6000fd5b806113ad33826123cb565b806113cf575060155473ffffffffffffffffffffffffffffffffffffffff1633145b15156113da57600080fd5b73ffffffffffffffffffffffffffffffffffffffff841615156113fc57600080fd5b73ffffffffffffffffffffffffffffffffffffffff8316151561141e57600080fd5b611428848361245e565b61143284836124ff565b61143c83836126a4565b818373ffffffffffffffffffffffffffffffffffffffff168573ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef60405160405180910390a450505050565b73ffffffffffffffffffffffffffffffffffffffff166000908152600c602052604090205460ff1690565b60006114d383611950565b82106114de57600080fd5b73ffffffffffffffffffffffffffffffffffffffff8316600090815260076020526040902080548390811061150f57fe5b9060005260206000200154905092915050565b60155473ffffffffffffffffffffffffffffffffffffffff1633148061155f5750600d5473ffffffffffffffffffffffffffffffffffffffff1633145b806115795750336000908152600c602052604090205460ff165b151561158457600080fd5b61158e82826126fa565b6016546115b29073ffffffffffffffffffffffffffffffffffffffff166001611e89565b5050565b806115c133826123cb565b806115e3575060155473ffffffffffffffffffffffffffffffffffffffff1633145b15156115ee57600080fd5b61160a8484846020604051908101604052806000815250611fd8565b50505050565b600c6020526000908152604090205460ff1681565b600d5473ffffffffffffffffffffffffffffffffffffffff16331461164957600080fd5b73ffffffffffffffffffffffffffffffffffffffff8116151561166b57600080fd5b600e80547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff92909216919091179055565b60009081526001602052604090205473ffffffffffffffffffffffffffffffffffffffff16151590565b60006116e66112b0565b82106116f157600080fd5b60098054839081106116ff57fe5b90600052602060002001549050919050565b600f5481565b336000908152600c602052604090205460ff16151561173557600080fd5b61124d81612749565b600e5473ffffffffffffffffffffffffffffffffffffffff1690565b611762612e8e565b60008281526017602052604090819020815180830192839052916002918201919082845b8154640100000000027fffffffffffffffffffffffffffffffffffffffffffffffffffffffff000000001681526001909101906020018083116117865750505050509050919050565b60008181526001602052604081205473ffffffffffffffffffffffffffffffffffffffff1680151561180057600080fd5b92915050565b60155473ffffffffffffffffffffffffffffffffffffffff163314806118435750600d5473ffffffffffffffffffffffffffffffffffffffff1633145b8061185d5750336000908152600c602052604090205460ff165b151561186857600080fd5b61124d611874826117cf565b826127fd565b336000908152600c602052604090205460ff16151561189857600080fd5b60405173ffffffffffffffffffffffffffffffffffffffff8216907f1a2dbeec1a0714342f862f53c671a69a6cb438bf5aa44fc01a7ccff6fbde85ef90600090a273ffffffffffffffffffffffffffffffffffffffff166000908152600c6020526040902080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00169055565b601760205260009081526040902080546001820154600483015460059093015460ff90921692909184565b600073ffffffffffffffffffffffffffffffffffffffff8216151561197457600080fd5b5073ffffffffffffffffffffffffffffffffffffffff1660009081526003602052604090205490565b600d5473ffffffffffffffffffffffffffffffffffffffff1633146119c157600080fd5b600d5460405173ffffffffffffffffffffffffffffffffffffffff909116907ff8df31144d9c2f0f6b59d69b8b98abd5459d07f2742c4df920b25aae33c6482090600090a2600d80547fffffffffffffffffffffffff0000000000000000000000000000000000000000169055565b60155473ffffffffffffffffffffffffffffffffffffffff16331480611a6d5750600d5473ffffffffffffffffffffffffffffffffffffffff1633145b80611a875750336000908152600c602052604090205460ff165b1515611a9257600080fd5b60009182526017602052604090912080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0016911515919091179055565b600080600080600080600f5460106000600581101515611aec57fe5b0154601154601254601354601454949b939a50919850965094509092509050565b6000806000611b1a612e8e565b336000908152600c602052604081205460ff161515611b3857600080fd5b87518951148015611b4a575086518851145b8015611b57575085518751145b1515611b6257600080fd5b600094505b8851851015611c2e578885815181101515611b7e57fe5b9060200190602002015193508785815181101515611b9857fe5b9060200190602002015192508685815181101515611bb257fe5b9060200190602002015191508585815181101515611bcc57fe5b906020019060200201519050611be28383611103565b6000811115611bf557611bf58382612275565b611bff84846126fa565b601654611c239073ffffffffffffffffffffffffffffffffffffffff166001611e89565b600190940193611b67565b505050505050505050565b600e5473ffffffffffffffffffffffffffffffffffffffff1681565b600d5473ffffffffffffffffffffffffffffffffffffffff163314611c7957600080fd5b73ffffffffffffffffffffffffffffffffffffffff81161515611c9b57600080fd5b601580547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff92909216919091179055565b60155473ffffffffffffffffffffffffffffffffffffffff16331480611d1f5750600d5473ffffffffffffffffffffffffffffffffffffffff1633145b80611d395750336000908152600c602052604090205460ff165b1515611d4457600080fd5b600f95909555601093909355601191909155601255601355601455565b600d5473ffffffffffffffffffffffffffffffffffffffff1681565b600d5473ffffffffffffffffffffffffffffffffffffffff163314611da157600080fd5b73ffffffffffffffffffffffffffffffffffffffff81161515611dc357600080fd5b601680547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff92909216919091179055565b60068054604080516020601f60027fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff610100600188161502019095169490940493840181900481028201810190925282815260609390929091830182828015610fe85780601f10610fbd57610100808354040283529160200191610fe8565b73ffffffffffffffffffffffffffffffffffffffff8216331415611eac57600080fd5b33600081815260046020908152604080832073ffffffffffffffffffffffffffffffffffffffff87168085529083529281902080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0016861515908117909155815190815290519293927f17307eab39ab6107e8899845ad3d59bd9653f200f220920489ca2b5937696c31929181900390910190a35050565b60155473ffffffffffffffffffffffffffffffffffffffff16331480611f825750600d5473ffffffffffffffffffffffffffffffffffffffff1633145b80611f9c5750336000908152600c602052604090205460ff165b1515611fa757600080fd5b60009182526017602052604090912060050155565b60165473ffffffffffffffffffffffffffffffffffffffff1681565b81611fe333826123cb565b80612005575060155473ffffffffffffffffffffffffffffffffffffffff1633145b151561201057600080fd5b61201b8585856113a2565b61202785858585612933565b151561203257600080fd5b5050505050565b60009081526017602052604090206001015490565b60155460009073ffffffffffffffffffffffffffffffffffffffff1633148061208e5750600d5473ffffffffffffffffffffffffffffffffffffffff1633145b806120a85750336000908152600c602052604090205460ff165b15156120b357600080fd5b8173ffffffffffffffffffffffffffffffffffffffff1663095ea7b385856040518363ffffffff167c0100000000000000000000000000000000000000000000000000000000028152600401808373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200182815260200192505050602060405180830381600087803b158015610ef557600080fd5b600e54604080517fc87b56dd00000000000000000000000000000000000000000000000000000000815260048101849052905160609273ffffffffffffffffffffffffffffffffffffffff169163c87b56dd91602480830192600092919082900301818387803b1580156121c957600080fd5b505af11580156121dd573d6000803e3d6000fd5b505050506040513d6000823e601f3d9081017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0168201604052602081101561222457600080fd5b81019080805164010000000081111561223c57600080fd5b8201602081018481111561224f57600080fd5b815164010000000081118282018710171561226957600080fd5b50909695505050505050565b60155473ffffffffffffffffffffffffffffffffffffffff163314806122b25750600d5473ffffffffffffffffffffffffffffffffffffffff1633145b806122cc5750336000908152600c602052604090205460ff165b15156122d757600080fd5b60009182526017602052604090912060010155565b60155473ffffffffffffffffffffffffffffffffffffffff163314806123295750600d5473ffffffffffffffffffffffffffffffffffffffff1633145b806123435750336000908152600c602052604090205460ff165b151561234e57600080fd5b60009182526017602052604090912060040155565b73ffffffffffffffffffffffffffffffffffffffff918216600090815260046020908152604080832093909416825291909152205460ff1690565b600d5473ffffffffffffffffffffffffffffffffffffffff1633146123c257600080fd5b61124d81612ad2565b6000806123d7836117cf565b90508073ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff16148061244657508373ffffffffffffffffffffffffffffffffffffffff1661242e84610ff3565b73ffffffffffffffffffffffffffffffffffffffff16145b8061245657506124568185612363565b949350505050565b8173ffffffffffffffffffffffffffffffffffffffff1661247e826117cf565b73ffffffffffffffffffffffffffffffffffffffff161461249e57600080fd5b60008181526002602052604090205473ffffffffffffffffffffffffffffffffffffffff16156115b257600090815260026020526040902080547fffffffffffffffffffffffff000000000000000000000000000000000000000016905550565b600080600061250e8585612b82565b60008481526008602090815260408083205473ffffffffffffffffffffffffffffffffffffffff8916845260079092529091205490935061255690600163ffffffff612c5716565b73ffffffffffffffffffffffffffffffffffffffff861660009081526007602052604090208054919350908390811061258b57fe5b9060005260206000200154905080600760008773ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020848154811015156125e557fe5b600091825260208083209091019290925573ffffffffffffffffffffffffffffffffffffffff8716815260079091526040812080548490811061262457fe5b600091825260208083209091019290925573ffffffffffffffffffffffffffffffffffffffff87168152600790915260409020805490612686907fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8301612ea9565b50600093845260086020526040808520859055908452909220555050565b60006126b08383612c69565b5073ffffffffffffffffffffffffffffffffffffffff9091166000908152600760209081526040808320805460018101825590845282842081018590559383526008909152902055565b6127048282612d2b565b600980546000838152600a60205260408120829055600182018355919091527f6e1540171b6c0c960b71a7020d9f60077f6af931a8bbf590da0223dacf75c7af015550565b73ffffffffffffffffffffffffffffffffffffffff8116151561276b57600080fd5b60405173ffffffffffffffffffffffffffffffffffffffff82169033907f2931ebb3d190545dcf6801c37aa686b74f2e1000e753d0fac6e471a2aa5a621390600090a373ffffffffffffffffffffffffffffffffffffffff166000908152600c6020526040902080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00166001179055565b600080600061280c8585612da0565b6000848152600b602052604090205460027fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff610100600184161502019091160415612868576000848152600b6020526040812061286891612ecd565b6000848152600a602052604090205460095490935061288e90600163ffffffff612c5716565b915060098281548110151561289f57fe5b90600052602060002001549050806009848154811015156128bc57fe5b600091825260208220019190915560098054849081106128d857fe5b6000918252602090912001556009805490612915907fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8301612ea9565b506000938452600a6020526040808520859055908452909220555050565b6000806129558573ffffffffffffffffffffffffffffffffffffffff16612dfd565b15156129645760019150612ac9565b6040517f150b7a02000000000000000000000000000000000000000000000000000000008152336004820181815273ffffffffffffffffffffffffffffffffffffffff898116602485015260448401889052608060648501908152875160848601528751918a169463150b7a0294938c938b938b93909160a490910190602085019080838360005b83811015612a045781810151838201526020016129ec565b50505050905090810190601f168015612a315780820380516001836020036101000a031916815260200191505b5095505050505050602060405180830381600087803b158015612a5357600080fd5b505af1158015612a67573d6000803e3d6000fd5b505050506040513d6020811015612a7d57600080fd5b50517fffffffff0000000000000000000000000000000000000000000000000000000081167f150b7a020000000000000000000000000000000000000000000000000000000014925090505b50949350505050565b73ffffffffffffffffffffffffffffffffffffffff81161515612af457600080fd5b600d5460405173ffffffffffffffffffffffffffffffffffffffff8084169216907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e090600090a3600d80547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff92909216919091179055565b8173ffffffffffffffffffffffffffffffffffffffff16612ba2826117cf565b73ffffffffffffffffffffffffffffffffffffffff1614612bc257600080fd5b73ffffffffffffffffffffffffffffffffffffffff8216600090815260036020526040902054612bf990600163ffffffff612c5716565b73ffffffffffffffffffffffffffffffffffffffff90921660009081526003602090815260408083209490945591815260019091522080547fffffffffffffffffffffffff0000000000000000000000000000000000000000169055565b600082821115612c6357fe5b50900390565b60008181526001602052604090205473ffffffffffffffffffffffffffffffffffffffff1615612c9857600080fd5b600081815260016020818152604080842080547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff88169081179091558452600390915290912054612cfe91612e05565b73ffffffffffffffffffffffffffffffffffffffff90921660009081526003602052604090209190915550565b73ffffffffffffffffffffffffffffffffffffffff82161515612d4d57600080fd5b612d5782826126a4565b604051819073ffffffffffffffffffffffffffffffffffffffff8416906000907fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef908290a45050565b612daa828261245e565b612db482826124ff565b604051819060009073ffffffffffffffffffffffffffffffffffffffff8516907fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef908390a45050565b6000903b1190565b8181018281101561180057fe5b8260028101928215612e70579160200282015b82811115612e7057825182547fffffffff0000000000000000000000000000000000000000000000000000000016640100000000909104178255602090920191600190910190612e25565b50612e7c929150612f11565b5090565b506000815560010160009055565b60408051808201825290600290829080388339509192915050565b81548183558181111561118457600083815260209020611184918101908301612f4d565b50805460018160011615610100020316600290046000825580601f10612ef3575061124d565b601f01602090049060005260206000209081019061124d9190612f4d565b610ff091905b80821115612e7c5780547fffffffff00000000000000000000000000000000000000000000000000000000168155600101612f17565b610ff091905b80821115612e7c5760008155600101612f535600a165627a7a72305820960980b154bd42565b2d1b7087d1601a349d5c75699fb7c7d9c2f7234140b38d0029000000000000000000000000000000000000000000000000000000000000004000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000007436c6f76657273000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000003434c560000000000000000000000000000000000000000000000000000000000

Deployed Bytecode

0x6080604052600436106102875763ffffffff7c010000000000000000000000000000000000000000000000000000000060003504166301ffc9a7811461028957806303a53d6b146102d7578063048e62ca14610301578063049526311461033957806306fdde0314610351578063081812fc146103db578063095ea7b31461041c5780630b6283951461044d5780630e8310d61461049057806312414198146104a85780631732e941146104bd57806318160ddd146104fd57806319fa8f50146105125780631c4b774b1461055c5780631cc1472d1461057457806323b872dd146105a557806324d7806c146105dc5780632f745c591461060a57806340c10f191461063b57806342842e0e1461066c578063429b62e5146106a35780634e485f88146106d15780634f558e79146106ff5780634f6ccce71461071757806350a98a641461072f5780635be7cc16146107445780635c60da1b1461077257806362f9acf9146107875780636352211e146107da57806364e779b1146107f25780636fce9d881461080a578063708fa7f71461083857806370a0823114610878578063715018a6146108a657806376e4a87f146108bb578063785d8d71146108d85780638810ee8b1461092057806388b6e7a514610a5a5780638a56a22614610a6f5780638b1b2ba814610a9d5780638da5cb5b14610ac45780639564e18014610ad957806395d89b4114610b07578063a22cb46514610b1c578063a47bd49614610b4f578063a89b55da14610b6a578063b88d4fde14610b7f578063c53b4bf914610bfb578063c863bac114610c13578063c87b56dd14610c4b578063dc3f775814610c63578063e3100d1e14610c7e578063e985e9c514610c99578063f2fde38b14610ccd575b005b34801561029557600080fd5b506102c37fffffffff0000000000000000000000000000000000000000000000000000000060043516610cfb565b604080519115158252519081900360200190f35b3480156102e357600080fd5b506102ef600435610d32565b60408051918252519081900360200190f35b34801561030d57600080fd5b506102c373ffffffffffffffffffffffffffffffffffffffff6004358116906024359060443516610d47565b34801561034557600080fd5b506102c3600435610f29565b34801561035d57600080fd5b50610366610f3e565b6040805160208082528351818301528351919283929083019185019080838360005b838110156103a0578181015183820152602001610388565b50505050905090810190601f1680156103cd5780820380516001836020036101000a031916815260200191505b509250505060405180910390f35b3480156103e757600080fd5b506103f3600435610ff3565b6040805173ffffffffffffffffffffffffffffffffffffffff9092168252519081900360200190f35b34801561042857600080fd5b5061028773ffffffffffffffffffffffffffffffffffffffff6004351660243561101b565b34801561045957600080fd5b5060408051808201825261028791600480359236926064919060249060029083908390808284375093965061110395505050505050565b34801561049c57600080fd5b50610287600435611189565b3480156104b457600080fd5b506103f3611250565b3480156104c957600080fd5b506040805180820182526102ef91369160049160449190839060029083908390808284375093965061126c95505050505050565b34801561050957600080fd5b506102ef6112b0565b34801561051e57600080fd5b506105276112b6565b604080517fffffffff000000000000000000000000000000000000000000000000000000009092168252519081900360200190f35b34801561056857600080fd5b506102ef6004356112da565b34801561058057600080fd5b5061028773ffffffffffffffffffffffffffffffffffffffff600435166024356112ef565b3480156105b157600080fd5b5061028773ffffffffffffffffffffffffffffffffffffffff600435811690602435166044356113a2565b3480156105e857600080fd5b506102c373ffffffffffffffffffffffffffffffffffffffff6004351661149d565b34801561061657600080fd5b506102ef73ffffffffffffffffffffffffffffffffffffffff600435166024356114c8565b34801561064757600080fd5b5061028773ffffffffffffffffffffffffffffffffffffffff60043516602435611522565b34801561067857600080fd5b5061028773ffffffffffffffffffffffffffffffffffffffff600435811690602435166044356115b6565b3480156106af57600080fd5b506102c373ffffffffffffffffffffffffffffffffffffffff60043516611610565b3480156106dd57600080fd5b5061028773ffffffffffffffffffffffffffffffffffffffff60043516611625565b34801561070b57600080fd5b506102c36004356116b2565b34801561072357600080fd5b506102ef6004356116dc565b34801561073b57600080fd5b506102ef611711565b34801561075057600080fd5b5061028773ffffffffffffffffffffffffffffffffffffffff60043516611717565b34801561077e57600080fd5b506103f361173e565b34801561079357600080fd5b5061079f60043561175a565b6040518082600260200280838360005b838110156107c75781810151838201526020016107af565b5050505090500191505060405180910390f35b3480156107e657600080fd5b506103f36004356117cf565b3480156107fe57600080fd5b50610287600435611806565b34801561081657600080fd5b5061028773ffffffffffffffffffffffffffffffffffffffff6004351661187a565b34801561084457600080fd5b50610850600435611925565b6040805194151585526020850193909352838301919091526060830152519081900360800190f35b34801561088457600080fd5b506102ef73ffffffffffffffffffffffffffffffffffffffff60043516611950565b3480156108b257600080fd5b5061028761199d565b3480156108c757600080fd5b506102876004356024351515611a30565b3480156108e457600080fd5b506108ed611ad0565b604080519687526020870195909552858501939093526060850191909152608084015260a0830152519081900360c00190f35b34801561092c57600080fd5b506040805160206004803580820135838102808601850190965280855261028795369593946024949385019291829185019084908082843750506040805187358901803560208181028481018201909552818452989b9a9989019892975090820195509350839250850190849080828437505060408051873589018035602081810284018101909452808352979a999883019791965082019450925082915060009085015b82821015610a0a5760408051808201825290808402870190600290839083908082843750505091835250506001909101906020016109d1565b50505050509192919290803590602001908201803590602001908080602002602001604051908101604052809392919081815260200183836020028082843750949750611b0d9650505050505050565b348015610a6657600080fd5b506103f3611c39565b348015610a7b57600080fd5b5061028773ffffffffffffffffffffffffffffffffffffffff60043516611c55565b348015610aa957600080fd5b5061028760043560243560443560643560843560a435611ce2565b348015610ad057600080fd5b506103f3611d61565b348015610ae557600080fd5b5061028773ffffffffffffffffffffffffffffffffffffffff60043516611d7d565b348015610b1357600080fd5b50610366611e0a565b348015610b2857600080fd5b5061028773ffffffffffffffffffffffffffffffffffffffff600435166024351515611e89565b348015610b5b57600080fd5b50610287600435602435611f45565b348015610b7657600080fd5b506103f3611fbc565b348015610b8b57600080fd5b50604080516020601f6064356004818101359283018490048402850184019095528184526102879473ffffffffffffffffffffffffffffffffffffffff8135811695602480359092169560443595369560849401918190840183828082843750949750611fd89650505050505050565b348015610c0757600080fd5b506102ef600435612039565b348015610c1f57600080fd5b506102c373ffffffffffffffffffffffffffffffffffffffff600435811690602435906044351661204e565b348015610c5757600080fd5b50610366600435612156565b348015610c6f57600080fd5b50610287600435602435612275565b348015610c8a57600080fd5b506102876004356024356122ec565b348015610ca557600080fd5b506102c373ffffffffffffffffffffffffffffffffffffffff60043581169060243516612363565b348015610cd957600080fd5b5061028773ffffffffffffffffffffffffffffffffffffffff6004351661239e565b7fffffffff000000000000000000000000000000000000000000000000000000001660009081526020819052604090205460ff1690565b60009081526017602052604090206004015490565b60155460009073ffffffffffffffffffffffffffffffffffffffff16331480610d875750600d5473ffffffffffffffffffffffffffffffffffffffff1633145b80610da15750336000908152600c602052604090205460ff165b1515610dac57600080fd5b604080517f70a08231000000000000000000000000000000000000000000000000000000008152306004820152905173ffffffffffffffffffffffffffffffffffffffff8416916370a082319160248083019260209291908290030181600087803b158015610e1a57600080fd5b505af1158015610e2e573d6000803e3d6000fd5b505050506040513d6020811015610e4457600080fd5b5051831115610e5257600080fd5b8173ffffffffffffffffffffffffffffffffffffffff1663a9059cbb85856040518363ffffffff167c0100000000000000000000000000000000000000000000000000000000028152600401808373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200182815260200192505050602060405180830381600087803b158015610ef557600080fd5b505af1158015610f09573d6000803e3d6000fd5b505050506040513d6020811015610f1f57600080fd5b5051949350505050565b60009081526017602052604090205460ff1690565b60058054604080516020601f60027fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff610100600188161502019095169490940493840181900481028201810190925282815260609390929091830182828015610fe85780601f10610fbd57610100808354040283529160200191610fe8565b820191906000526020600020905b815481529060010190602001808311610fcb57829003601f168201915b505050505090505b90565b60009081526002602052604090205473ffffffffffffffffffffffffffffffffffffffff1690565b6000611026826117cf565b905073ffffffffffffffffffffffffffffffffffffffff838116908216141561104e57600080fd5b3373ffffffffffffffffffffffffffffffffffffffff8216148061107757506110778133612363565b151561108257600080fd5b60008281526002602052604080822080547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff87811691821790925591518593918516917f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b92591a4505050565b60155473ffffffffffffffffffffffffffffffffffffffff163314806111405750600d5473ffffffffffffffffffffffffffffffffffffffff1633145b8061115a5750336000908152600c602052604090205460ff165b151561116557600080fd5b6000828152601760205260409020611184906002908101908390612e12565b505050565b60155473ffffffffffffffffffffffffffffffffffffffff163314806111c65750600d5473ffffffffffffffffffffffffffffffffffffffff1633145b806111e05750336000908152600c602052604090205460ff165b15156111eb57600080fd5b600081815260176020526040812080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0016815560018101829055906112346002830182612e80565b5060006004820181905560059091015561124d81611806565b50565b60155473ffffffffffffffffffffffffffffffffffffffff1681565b6000816040518082600260200280838360005b8381101561129757818101518382015260200161127f565b5050505090500191505060405180910390209050919050565b60095490565b7f01ffc9a70000000000000000000000000000000000000000000000000000000081565b60009081526017602052604090206005015490565b60155473ffffffffffffffffffffffffffffffffffffffff1633148061132c5750600d5473ffffffffffffffffffffffffffffffffffffffff1633145b806113465750336000908152600c602052604090205460ff165b151561135157600080fd5b303181111561135f57600080fd5b60405173ffffffffffffffffffffffffffffffffffffffff83169082156108fc029083906000818181858888f19350505050158015611184573d6000803e3d6000fd5b806113ad33826123cb565b806113cf575060155473ffffffffffffffffffffffffffffffffffffffff1633145b15156113da57600080fd5b73ffffffffffffffffffffffffffffffffffffffff841615156113fc57600080fd5b73ffffffffffffffffffffffffffffffffffffffff8316151561141e57600080fd5b611428848361245e565b61143284836124ff565b61143c83836126a4565b818373ffffffffffffffffffffffffffffffffffffffff168573ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef60405160405180910390a450505050565b73ffffffffffffffffffffffffffffffffffffffff166000908152600c602052604090205460ff1690565b60006114d383611950565b82106114de57600080fd5b73ffffffffffffffffffffffffffffffffffffffff8316600090815260076020526040902080548390811061150f57fe5b9060005260206000200154905092915050565b60155473ffffffffffffffffffffffffffffffffffffffff1633148061155f5750600d5473ffffffffffffffffffffffffffffffffffffffff1633145b806115795750336000908152600c602052604090205460ff165b151561158457600080fd5b61158e82826126fa565b6016546115b29073ffffffffffffffffffffffffffffffffffffffff166001611e89565b5050565b806115c133826123cb565b806115e3575060155473ffffffffffffffffffffffffffffffffffffffff1633145b15156115ee57600080fd5b61160a8484846020604051908101604052806000815250611fd8565b50505050565b600c6020526000908152604090205460ff1681565b600d5473ffffffffffffffffffffffffffffffffffffffff16331461164957600080fd5b73ffffffffffffffffffffffffffffffffffffffff8116151561166b57600080fd5b600e80547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff92909216919091179055565b60009081526001602052604090205473ffffffffffffffffffffffffffffffffffffffff16151590565b60006116e66112b0565b82106116f157600080fd5b60098054839081106116ff57fe5b90600052602060002001549050919050565b600f5481565b336000908152600c602052604090205460ff16151561173557600080fd5b61124d81612749565b600e5473ffffffffffffffffffffffffffffffffffffffff1690565b611762612e8e565b60008281526017602052604090819020815180830192839052916002918201919082845b8154640100000000027fffffffffffffffffffffffffffffffffffffffffffffffffffffffff000000001681526001909101906020018083116117865750505050509050919050565b60008181526001602052604081205473ffffffffffffffffffffffffffffffffffffffff1680151561180057600080fd5b92915050565b60155473ffffffffffffffffffffffffffffffffffffffff163314806118435750600d5473ffffffffffffffffffffffffffffffffffffffff1633145b8061185d5750336000908152600c602052604090205460ff165b151561186857600080fd5b61124d611874826117cf565b826127fd565b336000908152600c602052604090205460ff16151561189857600080fd5b60405173ffffffffffffffffffffffffffffffffffffffff8216907f1a2dbeec1a0714342f862f53c671a69a6cb438bf5aa44fc01a7ccff6fbde85ef90600090a273ffffffffffffffffffffffffffffffffffffffff166000908152600c6020526040902080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00169055565b601760205260009081526040902080546001820154600483015460059093015460ff90921692909184565b600073ffffffffffffffffffffffffffffffffffffffff8216151561197457600080fd5b5073ffffffffffffffffffffffffffffffffffffffff1660009081526003602052604090205490565b600d5473ffffffffffffffffffffffffffffffffffffffff1633146119c157600080fd5b600d5460405173ffffffffffffffffffffffffffffffffffffffff909116907ff8df31144d9c2f0f6b59d69b8b98abd5459d07f2742c4df920b25aae33c6482090600090a2600d80547fffffffffffffffffffffffff0000000000000000000000000000000000000000169055565b60155473ffffffffffffffffffffffffffffffffffffffff16331480611a6d5750600d5473ffffffffffffffffffffffffffffffffffffffff1633145b80611a875750336000908152600c602052604090205460ff165b1515611a9257600080fd5b60009182526017602052604090912080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0016911515919091179055565b600080600080600080600f5460106000600581101515611aec57fe5b0154601154601254601354601454949b939a50919850965094509092509050565b6000806000611b1a612e8e565b336000908152600c602052604081205460ff161515611b3857600080fd5b87518951148015611b4a575086518851145b8015611b57575085518751145b1515611b6257600080fd5b600094505b8851851015611c2e578885815181101515611b7e57fe5b9060200190602002015193508785815181101515611b9857fe5b9060200190602002015192508685815181101515611bb257fe5b9060200190602002015191508585815181101515611bcc57fe5b906020019060200201519050611be28383611103565b6000811115611bf557611bf58382612275565b611bff84846126fa565b601654611c239073ffffffffffffffffffffffffffffffffffffffff166001611e89565b600190940193611b67565b505050505050505050565b600e5473ffffffffffffffffffffffffffffffffffffffff1681565b600d5473ffffffffffffffffffffffffffffffffffffffff163314611c7957600080fd5b73ffffffffffffffffffffffffffffffffffffffff81161515611c9b57600080fd5b601580547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff92909216919091179055565b60155473ffffffffffffffffffffffffffffffffffffffff16331480611d1f5750600d5473ffffffffffffffffffffffffffffffffffffffff1633145b80611d395750336000908152600c602052604090205460ff165b1515611d4457600080fd5b600f95909555601093909355601191909155601255601355601455565b600d5473ffffffffffffffffffffffffffffffffffffffff1681565b600d5473ffffffffffffffffffffffffffffffffffffffff163314611da157600080fd5b73ffffffffffffffffffffffffffffffffffffffff81161515611dc357600080fd5b601680547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff92909216919091179055565b60068054604080516020601f60027fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff610100600188161502019095169490940493840181900481028201810190925282815260609390929091830182828015610fe85780601f10610fbd57610100808354040283529160200191610fe8565b73ffffffffffffffffffffffffffffffffffffffff8216331415611eac57600080fd5b33600081815260046020908152604080832073ffffffffffffffffffffffffffffffffffffffff87168085529083529281902080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0016861515908117909155815190815290519293927f17307eab39ab6107e8899845ad3d59bd9653f200f220920489ca2b5937696c31929181900390910190a35050565b60155473ffffffffffffffffffffffffffffffffffffffff16331480611f825750600d5473ffffffffffffffffffffffffffffffffffffffff1633145b80611f9c5750336000908152600c602052604090205460ff165b1515611fa757600080fd5b60009182526017602052604090912060050155565b60165473ffffffffffffffffffffffffffffffffffffffff1681565b81611fe333826123cb565b80612005575060155473ffffffffffffffffffffffffffffffffffffffff1633145b151561201057600080fd5b61201b8585856113a2565b61202785858585612933565b151561203257600080fd5b5050505050565b60009081526017602052604090206001015490565b60155460009073ffffffffffffffffffffffffffffffffffffffff1633148061208e5750600d5473ffffffffffffffffffffffffffffffffffffffff1633145b806120a85750336000908152600c602052604090205460ff165b15156120b357600080fd5b8173ffffffffffffffffffffffffffffffffffffffff1663095ea7b385856040518363ffffffff167c0100000000000000000000000000000000000000000000000000000000028152600401808373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200182815260200192505050602060405180830381600087803b158015610ef557600080fd5b600e54604080517fc87b56dd00000000000000000000000000000000000000000000000000000000815260048101849052905160609273ffffffffffffffffffffffffffffffffffffffff169163c87b56dd91602480830192600092919082900301818387803b1580156121c957600080fd5b505af11580156121dd573d6000803e3d6000fd5b505050506040513d6000823e601f3d9081017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0168201604052602081101561222457600080fd5b81019080805164010000000081111561223c57600080fd5b8201602081018481111561224f57600080fd5b815164010000000081118282018710171561226957600080fd5b50909695505050505050565b60155473ffffffffffffffffffffffffffffffffffffffff163314806122b25750600d5473ffffffffffffffffffffffffffffffffffffffff1633145b806122cc5750336000908152600c602052604090205460ff165b15156122d757600080fd5b60009182526017602052604090912060010155565b60155473ffffffffffffffffffffffffffffffffffffffff163314806123295750600d5473ffffffffffffffffffffffffffffffffffffffff1633145b806123435750336000908152600c602052604090205460ff165b151561234e57600080fd5b60009182526017602052604090912060040155565b73ffffffffffffffffffffffffffffffffffffffff918216600090815260046020908152604080832093909416825291909152205460ff1690565b600d5473ffffffffffffffffffffffffffffffffffffffff1633146123c257600080fd5b61124d81612ad2565b6000806123d7836117cf565b90508073ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff16148061244657508373ffffffffffffffffffffffffffffffffffffffff1661242e84610ff3565b73ffffffffffffffffffffffffffffffffffffffff16145b8061245657506124568185612363565b949350505050565b8173ffffffffffffffffffffffffffffffffffffffff1661247e826117cf565b73ffffffffffffffffffffffffffffffffffffffff161461249e57600080fd5b60008181526002602052604090205473ffffffffffffffffffffffffffffffffffffffff16156115b257600090815260026020526040902080547fffffffffffffffffffffffff000000000000000000000000000000000000000016905550565b600080600061250e8585612b82565b60008481526008602090815260408083205473ffffffffffffffffffffffffffffffffffffffff8916845260079092529091205490935061255690600163ffffffff612c5716565b73ffffffffffffffffffffffffffffffffffffffff861660009081526007602052604090208054919350908390811061258b57fe5b9060005260206000200154905080600760008773ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020848154811015156125e557fe5b600091825260208083209091019290925573ffffffffffffffffffffffffffffffffffffffff8716815260079091526040812080548490811061262457fe5b600091825260208083209091019290925573ffffffffffffffffffffffffffffffffffffffff87168152600790915260409020805490612686907fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8301612ea9565b50600093845260086020526040808520859055908452909220555050565b60006126b08383612c69565b5073ffffffffffffffffffffffffffffffffffffffff9091166000908152600760209081526040808320805460018101825590845282842081018590559383526008909152902055565b6127048282612d2b565b600980546000838152600a60205260408120829055600182018355919091527f6e1540171b6c0c960b71a7020d9f60077f6af931a8bbf590da0223dacf75c7af015550565b73ffffffffffffffffffffffffffffffffffffffff8116151561276b57600080fd5b60405173ffffffffffffffffffffffffffffffffffffffff82169033907f2931ebb3d190545dcf6801c37aa686b74f2e1000e753d0fac6e471a2aa5a621390600090a373ffffffffffffffffffffffffffffffffffffffff166000908152600c6020526040902080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00166001179055565b600080600061280c8585612da0565b6000848152600b602052604090205460027fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff610100600184161502019091160415612868576000848152600b6020526040812061286891612ecd565b6000848152600a602052604090205460095490935061288e90600163ffffffff612c5716565b915060098281548110151561289f57fe5b90600052602060002001549050806009848154811015156128bc57fe5b600091825260208220019190915560098054849081106128d857fe5b6000918252602090912001556009805490612915907fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8301612ea9565b506000938452600a6020526040808520859055908452909220555050565b6000806129558573ffffffffffffffffffffffffffffffffffffffff16612dfd565b15156129645760019150612ac9565b6040517f150b7a02000000000000000000000000000000000000000000000000000000008152336004820181815273ffffffffffffffffffffffffffffffffffffffff898116602485015260448401889052608060648501908152875160848601528751918a169463150b7a0294938c938b938b93909160a490910190602085019080838360005b83811015612a045781810151838201526020016129ec565b50505050905090810190601f168015612a315780820380516001836020036101000a031916815260200191505b5095505050505050602060405180830381600087803b158015612a5357600080fd5b505af1158015612a67573d6000803e3d6000fd5b505050506040513d6020811015612a7d57600080fd5b50517fffffffff0000000000000000000000000000000000000000000000000000000081167f150b7a020000000000000000000000000000000000000000000000000000000014925090505b50949350505050565b73ffffffffffffffffffffffffffffffffffffffff81161515612af457600080fd5b600d5460405173ffffffffffffffffffffffffffffffffffffffff8084169216907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e090600090a3600d80547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff92909216919091179055565b8173ffffffffffffffffffffffffffffffffffffffff16612ba2826117cf565b73ffffffffffffffffffffffffffffffffffffffff1614612bc257600080fd5b73ffffffffffffffffffffffffffffffffffffffff8216600090815260036020526040902054612bf990600163ffffffff612c5716565b73ffffffffffffffffffffffffffffffffffffffff90921660009081526003602090815260408083209490945591815260019091522080547fffffffffffffffffffffffff0000000000000000000000000000000000000000169055565b600082821115612c6357fe5b50900390565b60008181526001602052604090205473ffffffffffffffffffffffffffffffffffffffff1615612c9857600080fd5b600081815260016020818152604080842080547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff88169081179091558452600390915290912054612cfe91612e05565b73ffffffffffffffffffffffffffffffffffffffff90921660009081526003602052604090209190915550565b73ffffffffffffffffffffffffffffffffffffffff82161515612d4d57600080fd5b612d5782826126a4565b604051819073ffffffffffffffffffffffffffffffffffffffff8416906000907fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef908290a45050565b612daa828261245e565b612db482826124ff565b604051819060009073ffffffffffffffffffffffffffffffffffffffff8516907fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef908390a45050565b6000903b1190565b8181018281101561180057fe5b8260028101928215612e70579160200282015b82811115612e7057825182547fffffffff0000000000000000000000000000000000000000000000000000000016640100000000909104178255602090920191600190910190612e25565b50612e7c929150612f11565b5090565b506000815560010160009055565b60408051808201825290600290829080388339509192915050565b81548183558181111561118457600083815260209020611184918101908301612f4d565b50805460018160011615610100020316600290046000825580601f10612ef3575061124d565b601f01602090049060005260206000209081019061124d9190612f4d565b610ff091905b80821115612e7c5780547fffffffff00000000000000000000000000000000000000000000000000000000168155600101612f17565b610ff091905b80821115612e7c5760008155600101612f535600a165627a7a72305820960980b154bd42565b2d1b7087d1601a349d5c75699fb7c7d9c2f7234140b38d0029

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

000000000000000000000000000000000000000000000000000000000000004000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000007436c6f76657273000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000003434c560000000000000000000000000000000000000000000000000000000000

-----Decoded View---------------
Arg [0] : name (string): Clovers
Arg [1] : symbol (string): CLV

-----Encoded View---------------
6 Constructor Arguments found :
Arg [0] : 0000000000000000000000000000000000000000000000000000000000000040
Arg [1] : 0000000000000000000000000000000000000000000000000000000000000080
Arg [2] : 0000000000000000000000000000000000000000000000000000000000000007
Arg [3] : 436c6f7665727300000000000000000000000000000000000000000000000000
Arg [4] : 0000000000000000000000000000000000000000000000000000000000000003
Arg [5] : 434c560000000000000000000000000000000000000000000000000000000000


Deployed Bytecode Sourcemap

60054:8346:0:-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;9285:148;;8:9:-1;5:2;;;30:1;27;20:12;5:2;-1:-1;9285:148:0;;;;;;;;;;;;;;;;;;;;;;;;;61728:127;;8:9:-1;5:2;;;30:1;27;20:12;5:2;-1:-1;61728:127:0;;;;;;;;;;;;;;;;;;;;;63384:231;;8:9:-1;5:2;;;30:1;27;20:12;5:2;-1:-1;63384:231:0;;;;;;;;;;;;;;;61612:110;;8:9:-1;5:2;;;30:1;27;20:12;5:2;-1:-1;61612:110:0;;;;;24084:72;;8:9:-1;5:2;;;30:1;27;20:12;5:2;24084:72:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;8:100:-1;33:3;30:1;27:10;8:100;;;90:11;;;84:18;71:11;;;64:39;52:2;45:10;8:100;;;12:14;24084:72:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;14295:113;;8:9:-1;5:2;;;30:1;27;20:12;5:2;-1:-1;14295:113:0;;;;;;;;;;;;;;;;;;;;;;;;13777:284;;8:9:-1;5:2;;;30:1;27;20:12;5:2;-1:-1;13777:284:0;;;;;;;;;64525:145;;8:9:-1;5:2;;;30:1;27;20:12;5:2;-1:-1;64525:145:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;64525:145:0;;-1:-1:-1;64525:145:0;;-1:-1:-1;;;;;;64525:145:0;65966:140;;8:9:-1;5:2;;;30:1;27;20:12;5:2;-1:-1;65966:140:0;;;;;60252:32;;8:9:-1;5:2;;;30:1;27;20:12;5:2;60252:32:0;;;;61499:107;;8:9:-1;5:2;;;30:1;27;20:12;5:2;-1:-1;61499:107:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;61499:107:0;;-1:-1:-1;61499:107:0;;-1:-1:-1;;;;;;61499:107:0;25397:89;;8:9:-1;5:2;;;30:1;27;20:12;5:2;25397:89:0;;;;8716:54;;8:9:-1;5:2;;;30:1;27;20:12;5:2;8716:54:0;;;;;;;;;;;;;;;;;;;;;;;61997:118;;8:9:-1;5:2;;;30:1;27;20:12;5:2;-1:-1;61997:118:0;;;;;62946:159;;8:9:-1;5:2;;;30:1;27;20:12;5:2;-1:-1;62946:159:0;;;;;;;;;15827:358;;8:9:-1;5:2;;;30:1;27;20:12;5:2;-1:-1;15827:358:0;;;;;;;;;;;;;;31938:93;;8:9:-1;5:2;;;30:1;27;20:12;5:2;-1:-1;31938:93:0;;;;;;;25036:213;;8:9:-1;5:2;;;30:1;27;20:12;5:2;-1:-1;25036:213:0;;;;;;;;;67207:175;;8:9:-1;5:2;;;30:1;27;20:12;5:2;-1:-1;67207:175:0;;;;;;;;;16815:235;;8:9:-1;5:2;;;30:1;27;20:12;5:2;-1:-1;16815:235:0;;;;;;;;;;;;;;31384:39;;8:9:-1;5:2;;;30:1;27;20:12;5:2;-1:-1;31384:39:0;;;;;;;66670:175;;8:9:-1;5:2;;;30:1;27;20:12;5:2;-1:-1;66670:175:0;;;;;;;13219:143;;8:9:-1;5:2;;;30:1;27;20:12;5:2;-1:-1;13219:143:0;;;;;25818;;8:9:-1;5:2;;;30:1;27;20:12;5:2;-1:-1;25818:143:0;;;;;60148:30;;8:9:-1;5:2;;;30:1;27;20:12;5:2;60148:30:0;;;;32628:105;;8:9:-1;5:2;;;30:1;27;20:12;5:2;-1:-1;32628:105:0;;;;;;;61240:97;;8:9:-1;5:2;;;30:1;27;20:12;5:2;61240:97:0;;;;61861:130;;8:9:-1;5:2;;;30:1;27;20:12;5:2;-1:-1;61861:130:0;;;;;;;;;;;;;;;;23:1:-1;8:100;33:3;30:1;27:10;8:100;;;90:11;;;84:18;71:11;;;64:39;52:2;45:10;8:100;;;12:14;61861:130:0;;;;;;;;;;;;;;;;12866:168;;8:9:-1;5:2;;;30:1;27;20:12;5:2;-1:-1;12866:168:0;;;;;68270:123;;8:9:-1;5:2;;;30:1;27;20:12;5:2;-1:-1;68270:123:0;;;;;32303:157;;8:9:-1;5:2;;;30:1;27;20:12;5:2;-1:-1;32303:157:0;;;;;;;60334:42;;8:9:-1;5:2;;;30:1;27;20:12;5:2;-1:-1;60334:42:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;12501:145;;8:9:-1;5:2;;;30:1;27;20:12;5:2;-1:-1;12501:145:0;;;;;;;30389:114;;8:9:-1;5:2;;;30:1;27;20:12;5:2;30389:114:0;;;;64246:125;;8:9:-1;5:2;;;30:1;27;20:12;5:2;-1:-1;64246:125:0;;;;;;;;;62252:356;;8:9:-1;5:2;;;30:1;27;20:12;5:2;62252:356:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;67392:757;;8:9:-1;5:2;;;30:1;27;20:12;5:2;-1:-1;67392:757:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;67392:757:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;67392:757:0;;;;-1:-1:-1;67392:757:0;-1:-1:-1;67392:757:0;;-1:-1:-1;67392:757:0;;;;;;;;;-1:-1:-1;;67392:757:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;67392:757:0;;;-1:-1:-1;67392:757:0;-1:-1:-1;67392:757:0;;-1:-1:-1;;;67392:757:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;67392:757:0;;;-1:-1:-1;;67392:757:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;67392:757:0;;-1:-1:-1;67392:757:0;;-1:-1:-1;;;;;;;67392:757:0;60111:30;;8:9:-1;5:2;;;30:1;27;20:12;5:2;60111:30:0;;;;66334:185;;8:9:-1;5:2;;;30:1;27;20:12;5:2;-1:-1;66334:185:0;;;;;;;65462:373;;8:9:-1;5:2;;;30:1;27;20:12;5:2;-1:-1;65462:373:0;;;;;;;;;;;;;;;29594:20;;8:9:-1;5:2;;;30:1;27;20:12;5:2;29594:20:0;;;;66853:188;;8:9:-1;5:2;;;30:1;27;20:12;5:2;-1:-1;66853:188:0;;;;;;;24260:76;;8:9:-1;5:2;;;30:1;27;20:12;5:2;24260:76:0;;;;14696:209;;8:9:-1;5:2;;;30:1;27;20:12;5:2;-1:-1;14696:209:0;;;;;;;;;;;64676:137;;8:9:-1;5:2;;;30:1;27;20:12;5:2;-1:-1;64676:137:0;;;;;;;60291:34;;8:9:-1;5:2;;;30:1;27;20:12;5:2;60291:34:0;;;;17746:314;;8:9:-1;5:2;;;30:1;27;20:12;5:2;-1:-1;17746:314:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;17746:314:0;;-1:-1:-1;17746:314:0;;-1:-1:-1;;;;;;;17746:314:0;62121:125;;8:9:-1;5:2;;;30:1;27;20:12;5:2;-1:-1;62121:125:0;;;;;63901:173;;8:9:-1;5:2;;;30:1;27;20:12;5:2;-1:-1;63901:173:0;;;;;;;;;;;;;;;61345:148;;8:9:-1;5:2;;;30:1;27;20:12;5:2;-1:-1;61345:148:0;;;;;64819:152;;8:9:-1;5:2;;;30:1;27;20:12;5:2;-1:-1;64819:152:0;;;;;;;64377:142;;8:9:-1;5:2;;;30:1;27;20:12;5:2;-1:-1;64377:142:0;;;;;;;15222:177;;8:9:-1;5:2;;;30:1;27;20:12;5:2;-1:-1;15222:177:0;;;;;;;;;;;;30671:105;;8:9:-1;5:2;;;30:1;27;20:12;5:2;-1:-1;30671:105:0;;;;;;;9285:148;9394:33;;9371:4;9394:33;;;;;;;;;;;;;;9285:148::o;61728:127::-;61791:7;61818:17;;;:7;:17;;;;;:29;;;;61728:127::o;63384:231::-;60631:17;;63487:4;;60631:17;;60617:10;:31;;:67;;-1:-1:-1;60665:5:0;;:19;:5;60674:10;60665:19;60617:67;:102;;;-1:-1:-1;60708:10:0;60701:18;;;;:6;:18;;;;;;;;60617:102;60595:135;;;;;;;;63523:29;;;;;;63547:4;63523:29;;;;;;:23;;;;;;:29;;;;;;;;;;;;;;-1:-1:-1;63523:23:0;:29;;;5:2:-1;;;;30:1;27;20:12;5:2;63523:29:0;;;;8:9:-1;5:2;;;45:16;42:1;39;24:38;77:16;74:1;67:27;5:2;63523:29:0;;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;-1:-1;63523:29:0;63512:40;;;63504:49;;;;;;63577:6;63571:22;;;63594:3;63599:7;63571:36;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;8:9:-1;5:2;;;30:1;27;20:12;5:2;63571:36:0;;;;8:9:-1;5:2;;;45:16;42:1;39;24:38;77:16;74:1;67:27;5:2;63571:36:0;;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;-1:-1;63571:36:0;;63384:231;-1:-1:-1;;;;63384:231:0:o;61612:110::-;61668:4;61692:17;;;:7;:17;;;;;:22;;;;61612:110::o;24084:72::-;24145:5;24138:12;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;24123:6;;24138:12;;24145:5;;24138:12;;24145:5;24138:12;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;24084:72;;:::o;14295:113::-;14355:7;14378:24;;;:14;:24;;;;;;;;;14295:113::o;13777:284::-;13839:13;13855:17;13863:8;13855:7;:17::i;:::-;13839:33;-1:-1:-1;13887:12:0;;;;;;;;;13879:21;;;;;;13915:10;:19;;;;;:58;;;13938:35;13955:5;13962:10;13938:16;:35::i;:::-;13907:67;;;;;;;;13983:24;;;;:14;:24;;;;;;:30;;;;;;;;;;;;;;14025;;13983:24;;14025:30;;;;;;;13777:284;;;:::o;64525:145::-;60631:17;;;;60617:10;:31;;:67;;-1:-1:-1;60665:5:0;;:19;:5;60674:10;60665:19;60617:67;:102;;;-1:-1:-1;60708:10:0;60701:18;;;;:6;:18;;;;;;;;60617:102;60595:135;;;;;;;;64625:17;;;;:7;:17;;;;;:37;;:29;;;;;64657:5;;64625:37;:::i;:::-;;64525:145;;:::o;65966:140::-;60631:17;;;;60617:10;:31;;:67;;-1:-1:-1;60665:5:0;;:19;:5;60674:10;60665:19;60617:67;:102;;;-1:-1:-1;60708:10:0;60701:18;;;;:6;:18;;;;;;;;60617:102;60595:135;;;;;;;;66053:17;;;;:7;:17;;;;;66046:25;;;;;;;;;;;;66053:17;66046:25;;;;66053:17;66046:25;:::i;:::-;-1:-1:-1;66046:25:0;;;;;;;;;;;;66082:16;66089:8;66082:6;:16::i;:::-;65966:140;:::o;60252:32::-;;;;;;:::o;61499:107::-;61555:7;61592:5;61582:16;;;;;;;;;;23:1:-1;8:100;33:3;30:1;27:10;8:100;;;90:11;;;84:18;71:11;;;64:39;52:2;45:10;8:100;;;12:14;61582:16:0;;;;;;;;;;;;;;;;61575:23;;61499:107;;;:::o;25397:89::-;25464:9;:16;25397:89;:::o;8716:54::-;;;:::o;61997:118::-;62055:7;62082:17;;;:7;:17;;;;;:25;;;;61997:118::o;62946:159::-;60631:17;;;;60617:10;:31;;:67;;-1:-1:-1;60665:5:0;;:19;:5;60674:10;60665:19;60617:67;:102;;;-1:-1:-1;60708:10:0;60701:18;;;;:6;:18;;;;;;;;60617:102;60595:135;;;;;;;;63052:4;:12;63041:23;;;63033:32;;;;;;63076:21;;:12;;;;:21;;;;;63089:7;;63076:21;;;;63089:7;63076:12;:21;;;;;;;;8:9:-1;5:2;;;45:16;42:1;39;24:38;77:16;74:1;67:27;15827:358:0;15944:8;61002:39;61020:10;61032:8;61002:17;:39::i;:::-;:74;;;-1:-1:-1;61059:17:0;;;;61045:10;:31;61002:74;60994:83;;;;;;;;15972:19;;;;;15964:28;;;;;;16007:17;;;;;15999:26;;;;;;16034:30;16048:5;16055:8;16034:13;:30::i;:::-;16071:32;16087:5;16094:8;16071:15;:32::i;:::-;16110:25;16121:3;16126:8;16110:10;:25::i;:::-;16170:8;16165:3;16149:30;;16158:5;16149:30;;;;;;;;;;;;15827:358;;;;:::o;31938:93::-;32011:14;;31991:4;32011:14;;;:6;:14;;;;;;;;;31938:93::o;25036:213::-;25148:7;25184:17;25194:6;25184:9;:17::i;:::-;25175:26;;25167:35;;;;;;25216:19;;;;;;;:11;:19;;;;;:27;;25236:6;;25216:27;;;;;;;;;;;;;;25209:34;;25036:213;;;;:::o;67207:175::-;60631:17;;;;60617:10;:31;;:67;;-1:-1:-1;60665:5:0;;:19;:5;60674:10;60665:19;60617:67;:102;;;-1:-1:-1;60708:10:0;60701:18;;;;:6;:18;;;;;;;;60617:102;60595:135;;;;;;;;67293:26;67305:3;67310:8;67293:11;:26::i;:::-;67348:19;;67330:44;;67348:19;;;67330:17;:44::i;:::-;67207:175;;:::o;16815:235::-;16936:8;61002:39;61020:10;61032:8;61002:17;:39::i;:::-;:74;;;-1:-1:-1;61059:17:0;;;;61045:10;:31;61002:74;60994:83;;;;;;;;17002:42;17019:5;17026:3;17031:8;17002:42;;;;;;;;;;;;;:16;:42::i;:::-;16815:235;;;;:::o;31384:39::-;;;;;;;;;;;;;;;:::o;66670:175::-;30097:5;;;;30083:10;:19;30075:28;;;;;;66770:21;;;;;66762:30;;;;;;66803:15;:34;;;;;;;;;;;;;;;66670:175::o;13219:143::-;13274:4;13303:20;;;:10;:20;;;;;;;;13337:19;;;13219:143::o;25818:::-;25877:7;25910:13;:11;:13::i;:::-;25901:22;;25893:31;;;;;;25938:9;:17;;25948:6;;25938:17;;;;;;;;;;;;;;25931:24;;25818:143;;;:::o;60148:30::-;;;;:::o;32628:105::-;31906:10;31899:18;;;;:6;:18;;;;;;;;31891:27;;;;;;;;32698:29;32717:9;32698:18;:29::i;61240:97::-;61314:15;;;;61240:97;:::o;61861:130::-;61924:10;;:::i;:::-;61954:17;;;;:7;:17;;;;;;;61947:36;;;;;;;;;;61954:29;;;;;;;61947:36;;;;;;;;;;;;;;;;;;;;;;;;;;;;;61861:130;;;:::o;12866:168::-;12922:7;12954:20;;;:10;:20;;;;;;;;12989:19;;;12981:28;;;;;;13023:5;12866:168;-1:-1:-1;;12866:168:0:o;68270:123::-;60631:17;;;;60617:10;:31;;:67;;-1:-1:-1;60665:5:0;;:19;:5;60674:10;60665:19;60617:67;:102;;;-1:-1:-1;60708:10:0;60701:18;;;;:6;:18;;;;;;;;60617:102;60595:135;;;;;;;;68345:40;68357:17;68365:8;68357:7;:17::i;:::-;68376:8;68345:11;:40::i;32303:157::-;31906:10;31899:18;;;;:6;:18;;;;;;;;31891:27;;;;;;;;32383:34;;;;;;;;;;;32424:22;;32449:5;32424:22;;;:6;:22;;;;;:30;;;;;;32303:157::o;60334:42::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::o;12501:145::-;12557:7;12581:20;;;;;12573:29;;;;;;-1:-1:-1;12616:24:0;;;;;;:16;:24;;;;;;;12501:145::o;30389:114::-;30097:5;;;;30083:10;:19;30075:28;;;;;;30466:5;;30447:25;;30466:5;;;;;30447:25;;30466:5;;30447:25;30479:5;:18;;;;;;30389:114::o;64246:125::-;60631:17;;;;60617:10;:31;;:67;;-1:-1:-1;60665:5:0;;:19;:5;60674:10;60665:19;60617:67;:102;;;-1:-1:-1;60708:10:0;60701:18;;;;:6;:18;;;;;;;;60617:102;60595:135;;;;;;;;64333:17;;;;:7;:17;;;;;;:30;;;;;;;;;;;;;64246:125::o;62252:356::-;62301:7;62310;62319;62328;62337;62346;62388:15;;62418:10;62429:1;62418:13;;;;;;;;;;;62456;;62493;;62530;;62567;;62366:234;;62418:13;;-1:-1:-1;62456:13:0;;-1:-1:-1;62493:13:0;-1:-1:-1;62530:13:0;-1:-1:-1;62567:13:0;;-1:-1:-1;62366:234:0;-1:-1:-1;62252:356:0:o;67392:757::-;67661:9;67713:11;67749:16;67795:24;;:::i;:::-;31906:10;67847:17;31899:18;;;:6;:18;;;;;;;;31891:27;;;;;;;;67550:9;:16;67535:4;:11;:31;:69;;;;;67590:7;:14;67570:9;:16;:34;67535:69;:109;;;;;67626:11;:18;67608:7;:14;:36;67535:109;67527:118;;;;;;;;67673:1;67661:13;;67656:486;67680:4;:11;67676:1;:15;67656:486;;;67727:4;67732:1;67727:7;;;;;;;;;;;;;;;;;;67713:21;;67768:9;67778:1;67768:12;;;;;;;;;;;;;;;;;;67749:31;;67822:7;67830:1;67822:10;;;;;;;;;;;;;;;;;;67795:37;;67867:11;67879:1;67867:14;;;;;;;;;;;;;;;;;;67847:34;;67896:32;67911:8;67921:6;67896:14;:32::i;:::-;67959:1;67947:9;:13;67943:88;;;67981:34;67995:8;68005:9;67981:13;:34::i;:::-;68045:26;68057:3;68062:8;68045:11;:26::i;:::-;68104:19;;68086:44;;68104:19;;;68086:17;:44::i;:::-;67693:3;;;;;67656:486;;;67392:757;;;;;;;;;:::o;60111:30::-;;;;;;:::o;66334:185::-;30097:5;;;;30083:10;:19;30075:28;;;;;;66438:23;;;;;66430:32;;;;;;66473:17;:38;;;;;;;;;;;;;;;66334:185::o;65462:373::-;60631:17;;;;60617:10;:31;;:67;;-1:-1:-1;60665:5:0;;:19;:5;60674:10;60665:19;60617:67;:102;;;-1:-1:-1;60708:10:0;60701:18;;;;:6;:18;;;;;;;;60617:102;60595:135;;;;;;;;65631:15;:34;;;;65676:10;:22;;;;65709:13;:21;;;;65741:13;:21;65773:13;:21;65805:13;:22;65462:373::o;29594:20::-;;;;;;:::o;66853:188::-;30097:5;;;;30083:10;:19;30075:28;;;;;;66954:25;;;;;66946:34;;;;;;66991:19;:42;;;;;;;;;;;;;;;66853:188::o;24260:76::-;24323:7;24316:14;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;24301:6;;24316:14;;24323:7;;24316:14;;24323:7;24316:14;;;;;;;;;;;;;;;;;;;;;;;;14696:209;14774:17;;;14781:10;14774:17;;14766:26;;;;;;14817:10;14799:29;;;;:17;:29;;;;;;;;;:34;;;;;;;;;;;;:46;;;;;;;;;;;;;14857:42;;;;;;;14799:34;;14817:10;14857:42;;;;;;;;;;;14696:209;;:::o;64676:137::-;60631:17;;;;60617:10;:31;;:67;;-1:-1:-1;60665:5:0;;:19;:5;60674:10;60665:19;60617:67;:102;;;-1:-1:-1;60708:10:0;60701:18;;;;:6;:18;;;;;;;;60617:102;60595:135;;;;;;;;64770:17;;;;:7;:17;;;;;;:25;;:35;64676:137::o;60291:34::-;;;;;;:::o;17746:314::-;17885:8;61002:39;61020:10;61032:8;61002:17;:39::i;:::-;:74;;;-1:-1:-1;61059:17:0;;;;61045:10;:31;61002:74;60994:83;;;;;;;;17905:34;17918:5;17925:3;17930:8;17905:12;:34::i;:::-;18000:53;18025:5;18032:3;18037:8;18047:5;18000:24;:53::i;:::-;17992:62;;;;;;;;17746:314;;;;;:::o;62121:125::-;62183:7;62210:17;;;:7;:17;;;;;:28;;;;62121:125::o;63901:173::-;60631:17;;64007:4;;60631:17;;60617:10;:31;;:67;;-1:-1:-1;60665:5:0;;:19;:5;60674:10;60665:19;60617:67;:102;;;-1:-1:-1;60708:10:0;60701:18;;;;:6;:18;;;;;;;;60617:102;60595:135;;;;;;;;64037:6;64031:21;;;64053:3;64058:7;64031:35;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;8:9:-1;5:2;;;30:1;27;20:12;61345:148:0;61450:15;;61434:51;;;;;;;;;;;;;;61399:15;;61450;;;61434:41;;:51;;;;;61450:15;;61434:51;;;;;;;61450:15;;61434:51;;;5:2:-1;;;;30:1;27;20:12;5:2;61434:51:0;;;;8:9:-1;5:2;;;45:16;42:1;39;24:38;77:16;74:1;67:27;5:2;61434:51:0;;;;;;39:16:-1;36:1;17:17;2:54;101:4;61434:51:0;80:15:-1;;;97:9;76:31;65:43;;120:4;113:20;13:2;5:11;;2:2;;;29:1;26;19:12;2:2;61434:51:0;;;;;;20:11:-1;15:3;12:20;9:2;;;45:1;42;35:12;9:2;64:21;;126:4;117:14;;142:31;;;139:2;;;186:1;183;176:12;139:2;218:10;;268:11;251:29;;293:43;;;290:58;-1:-1;239:118;236:2;;;370:1;367;360:12;236:2;-1:-1;61434:51:0;;61345:148;-1:-1:-1;;;;;;61345:148:0:o;64819:152::-;60631:17;;;;60617:10;:31;;:67;;-1:-1:-1;60665:5:0;;:19;:5;60674:10;60665:19;60617:67;:102;;;-1:-1:-1;60708:10:0;60701:18;;;;:6;:18;;;;;;;;60617:102;60595:135;;;;;;;;64921:17;;;;:7;:17;;;;;;:28;;:42;64819:152::o;64377:142::-;60631:17;;;;60617:10;:31;;:67;;-1:-1:-1;60665:5:0;;:19;:5;60674:10;60665:19;60617:67;:102;;;-1:-1:-1;60708:10:0;60701:18;;;;:6;:18;;;;;;;;60617:102;60595:135;;;;;;;;64474:17;;;;:7;:17;;;;;;:29;;:37;64377:142::o;15222:177::-;15357:25;;;;15334:4;15357:25;;;:17;:25;;;;;;;;:36;;;;;;;;;;;;;;;15222:177::o;30671:105::-;30097:5;;;;30083:10;:19;30075:28;;;;;;30741:29;30760:9;30741:18;:29::i;18416:455::-;18532:4;18548:13;18564:17;18572:8;18564:7;:17::i;:::-;18548:33;;18765:5;18753:17;;:8;:17;;;:61;;;;18806:8;18781:33;;:21;18793:8;18781:11;:21::i;:::-;:33;;;18753:61;:105;;;;18825:33;18842:5;18849:8;18825:16;:33::i;:::-;18737:128;18416:455;-1:-1:-1;;;;18416:455:0:o;19956:219::-;20058:6;20037:27;;:17;20045:8;20037:7;:17::i;:::-;:27;;;20029:36;;;;;;20112:1;20076:24;;;:14;:24;;;;;;:38;:24;:38;20072:98;;20160:1;20125:24;;;:14;:24;;;;;:37;;;;;;-1:-1:-1;19956:219:0:o;27114:872::-;27235:18;27289:22;27353:17;27188:38;27210:5;27217:8;27188:21;:38::i;:::-;27256:26;;;;:16;:26;;;;;;;;;27314:18;;;;;:11;:18;;;;;;:25;27256:26;;-1:-1:-1;27314:32:0;;27344:1;27314:32;:29;:32;:::i;:::-;27373:18;;;;;;;:11;:18;;;;;:34;;27289:57;;-1:-1:-1;27373:18:0;27289:57;;27373:34;;;;;;;;;;;;;;27353:54;;27449:9;27416:11;:18;27428:5;27416:18;;;;;;;;;;;;;;;27435:10;27416:30;;;;;;;;;;;;;;;;;;;;;:42;;;;27465:18;;;;;:11;:18;;;;;;:34;;27484:14;;27465:34;;;;;;;;;;;;;;;;;:38;;;;27869:18;;;;;:11;:18;;;;;;:27;;;;;;;;;:::i;:::-;-1:-1:-1;27932:1:0;27903:26;;;:16;:26;;;;;;:30;;;27940:27;;;;;;:40;-1:-1:-1;;27114:872:0:o;26597:231::-;26702:14;26664:31;26681:3;26686:8;26664:16;:31::i;:::-;-1:-1:-1;26719:16:0;;;;;;;;:11;:16;;;;;;;;:23;;39:1:-1;23:18;;45:23;;26749:31:0;;;;;;;;;;;26787:26;;;:16;:26;;;;;:35;26597:231::o;28255:177::-;28317:26;28329:3;28334:8;28317:11;:26::i;:::-;28379:9;:16;;28352:24;;;;:14;:24;;;;;:43;;;39:1:-1;23:18;;45:23;;28402:24:0;;;;;;;-1:-1:-1;28255:177:0:o;32874:187::-;32945:23;;;;;32937:32;;;;;;32981:43;;;;;;33002:10;;32981:43;;;;;33031:17;;;;;;:6;:17;;;;;:24;;;;33051:4;33031:24;;;32874:187::o;28672:604::-;28933:18;28985:22;29040:17;28737:29;28749:6;28757:8;28737:11;:29::i;:::-;28817:19;;;;:9;:19;;;;;28811:33;;;;;;;;;;;;;;:38;28807:87;;28867:19;;;;:9;:19;;;;;28860:26;;;:::i;:::-;28954:24;;;;:14;:24;;;;;;29010:9;:16;28954:24;;-1:-1:-1;29010:23:0;;29031:1;29010:23;:20;:23;:::i;:::-;28985:48;;29060:9;29070:14;29060:25;;;;;;;;;;;;;;;;;;29040:45;;29118:9;29094;29104:10;29094:21;;;;;;;;;;;;;;;;;;:33;;;;29134:9;:25;;29144:14;;29134:25;;;;;;;;;;;;;;;:29;29172:9;:18;;;;;;;;;:::i;:::-;-1:-1:-1;29224:1:0;29197:24;;;:14;:24;;;;;;:28;;;29232:25;;;;;;:38;-1:-1:-1;;28672:604:0:o;21674:362::-;21820:4;21893:13;21841:16;:3;:14;;;:16::i;:::-;21840:17;21836:51;;;21875:4;21868:11;;;;21836:51;21909:80;;;;;21954:10;21909:80;;;;;;:36;:80;;;;;;;;;;;;;;;;;;;;;;;;;;;;:36;;;;;;21954:10;21966:5;;21973:8;;21983:5;;21909:80;;;;;;;;;;;;;;-1:-1:-1;8:100;33:3;30:1;27:10;8:100;;;90:11;;;84:18;71:11;;;64:39;52:2;45:10;8:100;;;12:14;21909:80:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;8:9:-1;5:2;;;30:1;27;20:12;5:2;21909:80:0;;;;8:9:-1;5:2;;;45:16;42:1;39;24:38;77:16;74:1;67:27;5:2;21909:80:0;;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;-1:-1;21909:80:0;22004:25;;;22014:15;22004:25;;-1:-1:-1;21909:80:0;-1:-1:-1;21674:362:0;;;;;;;;:::o;30917:175::-;30988:23;;;;;30980:32;;;;;;31045:5;;31024:38;;;;;;;31045:5;;31024:38;;31045:5;;31024:38;31069:5;:17;;;;;;;;;;;;;;;30917:175::o;20939:218::-;21042:5;21021:26;;:17;21029:8;21021:7;:17::i;:::-;:26;;;21013:35;;;;;;21081:23;;;;;;;:16;:23;;;;;;:30;;21109:1;21081:30;:27;:30;:::i;:::-;21055:23;;;;;;;;:16;:23;;;;;;;;:56;;;;21118:20;;;:10;:20;;;;:33;;;;;;20939:218::o;6995:113::-;7053:7;7076:6;;;;7069:14;;;;-1:-1:-1;7097:5:0;;;6995:113::o;20445:208::-;20552:1;20520:20;;;:10;:20;;;;;;:34;:20;:34;20512:43;;;;;;20562:20;;;;:10;:20;;;;;;;;:26;;;;;;;;;;;;;20619:21;;:16;:21;;;;;;;:28;;:25;:28::i;:::-;20595:21;;;;;;;;:16;:21;;;;;:52;;;;-1:-1:-1;20445:208:0:o;19128:173::-;19198:17;;;;;19190:26;;;;;;19223:25;19234:3;19239:8;19223:10;:25::i;:::-;19260:35;;19286:8;;19260:35;;;;19277:1;;19260:35;;19277:1;;19260:35;19128:173;;:::o;19494:192::-;19559:31;19573:6;19581:8;19559:13;:31::i;:::-;19597:33;19613:6;19621:8;19597:15;:33::i;:::-;19642:38;;19671:8;;19667:1;;19642:38;;;;;;19667:1;;19642:38;19494:192;;:::o;7818:587::-;7875:4;8359:17;;8391:8;;7818:587::o;7175:127::-;7255:5;;;7274:6;;;;7267:14;;;60054:8346;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;60054:8346:0;;;;;;;-1:-1:-1;60054:8346:0;;;-1:-1:-1;60054:8346:0;:::i;:::-;;;:::o;:::-;;;;;;;;;;:::o;:::-;;;;;;;;;;;;;;;105:10:-1;60054:8346:0;88:34:-1;-1:-1;60054:8346:0;;;-1:-1:-1;;60054:8346:0:o;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

Swarm Source

bzzr://960980b154bd42565b2d1b7087d1601a349d5c75699fb7c7d9c2f7234140b38d
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.