ETH Price: $3,102.29 (+1.11%)
Gas: 11 Gwei

Token

Dyverse (KYDY)
 

Overview

Max Total Supply

1,358 KYDY

Holders

197

Market

Volume (24H)

N/A

Min Price (24H)

N/A

Max Price (24H)

N/A
Filtered by Token Holder
archivist.eth
Balance
1 KYDY
0x478087e12db15302a364c64cdb79f14ae6c5c9b7
Loading...
Loading
Loading...
Loading
Loading...
Loading

OVERVIEW

Through the Dyverse, you can collect and trade 3D characters that you can use to create VR/AR and social content creation.

# Exchange Pair Price  24H Volume % Volume

Contract Source Code Verified (Exact Match)

Contract Name:
KydyCore

Compiler Version
v0.4.24+commit.e67f0147

Optimization Enabled:
Yes with 200 runs

Other Settings:
default evmVersion

Contract Source Code (Solidity)

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

pragma solidity ^0.4.24;

/// @title New Child Kydy's Genes
contract GeneSynthesisInterface {
    /// @dev boolean to check this is the contract we expect to be
    function isGeneSynthesis() public pure returns (bool);

    /**
     * @dev Synthesizes the genes of yin and yang Kydy, and returns the result as the child's genes. 
     * @param gene1 genes of yin Kydy
     * @param gene2 genes of yang Kydy
     * @return the genes of the child
     */
    function synthGenes(uint256 gene1, uint256 gene2) public returns (uint256);
}

/**
 * @title Part of KydyCore that manages special access controls.
 * @author VREX Lab Co., Ltd
 * @dev See the KydyCore contract documentation to understand how the various contracts are arranged.
 */
contract KydyAccessControl {
    /**
     * This contract defines access control for the following important roles of the Dyverse:
     *
     *     - The CEO: The CEO can assign roles and change the addresses of the smart contracts. 
     *         It can also solely unpause the smart contract. 
     *
     *     - The CFO: The CFO can withdraw funds from the KydyCore and the auction contracts.
     *
     *     - The COO: The COO can release Generation 0 Kydys and create promotional-type Kydys.
     *
     */

    /// @dev Used when contract is upgraded. 
    event ContractUpgrade(address newContract);

    // The assigned addresses of each role, as defined in this contract. 
    address public ceoAddress;
    address public cfoAddress;
    address public cooAddress;

    /// @dev Checks if the contract is paused. When paused, most of the functions of this contract will also be stopped.
    bool public paused = false;

    /// @dev Access modifier for CEO-only
    modifier onlyCEO() {
        require(msg.sender == ceoAddress);
        _;
    }

    /// @dev Access modifier for CFO-only
    modifier onlyCFO() {
        require(msg.sender == cfoAddress);
        _;
    }

    /// @dev Access modifier for COO-only
    modifier onlyCOO() {
        require(msg.sender == cooAddress);
        _;
    }

    /// @dev Access modifier for CEO, CFO, COO
    modifier onlyCLevel() {
        require(
            msg.sender == ceoAddress ||
            msg.sender == cfoAddress ||
            msg.sender == cooAddress
        );
        _;
    }

    /**
     * @dev Assigns a new address to the CEO. Only the current CEO has the authority.
     * @param _newCEO The address of the new CEO
     */
    function setCEO(address _newCEO) external onlyCEO {
        require(_newCEO != address(0));

        ceoAddress = _newCEO;
    }

    /**
     * @dev Assigns a new address to the CFO. Only the current CEO has the authority.
     * @param _newCFO The address of the new CFO
     */
    function setCFO(address _newCFO) external onlyCEO {
        require(_newCFO != address(0));

        cfoAddress = _newCFO;
    }

    /**
     * @dev Assigns a new address to the COO. Only the current CEO has the authority.
     * @param _newCOO The address of the new COO
     */
    function setCOO(address _newCOO) external onlyCEO {
        require(_newCOO != address(0));

        cooAddress = _newCOO;
    }

    /*** Pausable functionality adapted from OpenZeppelin ***/

    /// @dev Modifier to allow actions only when the contract IS NOT paused
    modifier whenNotPaused() {
        require(!paused);
        _;
    }

    /// @dev Modifier to allow actions only when the contract IS paused
    modifier whenPaused {
        require(paused);
        _;
    }

    /**
     * @dev Called by any "C-level" role to pause the contract. Used only when
     *  a bug or exploit is detected to limit the damage.
     */
    function pause() external onlyCLevel whenNotPaused {
        paused = true;
    }

    /**
     * @dev Unpauses the smart contract. Can only be called by the CEO, since
     *  one reason we may pause the contract is when CFO or COO accounts are
     *  compromised.
     * @notice This is public rather than external so it can be called by
     *  derived contracts.
     */
    function unpause() public onlyCEO whenPaused {
        // can't unpause if contract was upgraded
        paused = false;
    }
}

contract ERC165Interface {
    /**
     * @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.
     * @return `true` if the contract implements `interfaceID` and
     *  `interfaceID` is not 0xffffffff, `false` otherwise
     */
    function supportsInterface(bytes4 interfaceID) external view returns (bool);
}

contract ERC165 is ERC165Interface {
    /**
     * @dev a mapping of interface id to whether or not it's supported
     */
    mapping(bytes4 => bool) private _supportedInterfaces;

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

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

// Every ERC-721 compliant contract must implement the ERC721 and ERC165 interfaces.
/** 
 * @title ERC-721 Non-Fungible Token Standard
 * @dev See https://github.com/ethereum/EIPs/blob/master/EIPS/eip-721.md
 * Note: the ERC-165 identifier for this interface is 0x80ac58cd.
 */
contract ERC721Basic is ERC165 {
    // Below is MUST

    /**
     * @dev This emits when ownership of any NFT changes by any mechanism.
     *  This event emits when NFTs are created (`from` == 0) and destroyed
     *  (`to` == 0). Exception: during contract creation, any number of NFTs
     *  may be created and assigned without emitting Transfer. At the time of
     *  any transfer, the approved address for that NFT (if any) is reset to none.
     */
    event Transfer(address indexed _from, address indexed _to, uint256 indexed _tokenId);

    /**
     * @dev This emits when the approved address for an NFT is changed or
     *  reaffirmed. The zero address indicates there is no approved address.
     *  When a Transfer event emits, this also indicates that the approved
     *  address for that NFT (if any) is reset to none.
     */
    event Approval(address indexed _owner, address indexed _approved, uint256 indexed _tokenId);

    /**
     * @dev This emits when an operator is enabled or disabled for an owner.
     *  The operator can manage all NFTs of the owner.
     */
    event ApprovalForAll(address indexed _owner, address indexed _operator, bool _approved);

    /**
     * @notice Count all NFTs assigned to an owner
     * @dev NFTs assigned to the zero address are considered invalid, and this
     *  function throws for queries about the zero address.
     * @param _owner An address for whom to query the balance
     * @return The number of NFTs owned by `_owner`, possibly zero
     */
    function balanceOf(address _owner) public view returns (uint256);

    /**
     * @notice Find the owner of an NFT
     * @dev NFTs assigned to zero address are considered invalid, and queries
     *  about them do throw.
     * @param _tokenId The identifier for an NFT
     * @return The address of the owner of the NFT
     */
    function ownerOf(uint256 _tokenId) public view returns (address);

    /**
     * @notice Transfers the ownership of an NFT from one address to another address
     * @dev Throws unless `msg.sender` is the current owner, an authorized
     *  operator, or the approved address for this NFT. Throws if `_from` is
     *  not the current owner. Throws if `_to` is the zero address. Throws if
     *  `_tokenId` is not a valid NFT. When transfer is complete, this function
     *  checks if `_to` is a smart contract (code size > 0). If so, it calls
     *  `onERC721Received` on `_to` and throws if the return value is not
     *  `bytes4(keccak256("onERC721Received(address,address,uint256,bytes)"))`.
     * @param _from The current owner of the NFT
     * @param _to The new owner
     * @param _tokenId The NFT to transfer
     * @param data Additional data with no specified format, sent in call to `_to`
     */
    function safeTransferFrom(address _from, address _to, uint256 _tokenId, bytes data) public;

    /**
     * @notice Transfers the ownership of an NFT from one address to another address
     * @dev This works identically to the other function with an extra data parameter,
     *  except this function just sets data to "".
     * @param _from The current owner of the NFT
     * @param _to The new owner
     * @param _tokenId The NFT to transfer
     */
    function safeTransferFrom(address _from, address _to, uint256 _tokenId) public;

    /**
     * @notice Transfer ownership of an NFT -- THE CALLER IS RESPONSIBLE
     *  TO CONFIRM THAT `_to` IS CAPABLE OF RECEIVING NFTS OR ELSE
     *  THEY MAY BE PERMANENTLY LOST
     * @dev Throws unless `msg.sender` is the current owner, an authorized
     *  operator, or the approved address for this NFT. Throws if `_from` is
     *  not the current owner. Throws if `_to` is the zero address. Throws if
     *  `_tokenId` is not a valid NFT.
     * @param _from The current owner of the NFT
     * @param _to The new owner
     * @param _tokenId The NFT to transfer
     */
    function transferFrom(address _from, address _to, uint256 _tokenId) public;

    /**
     * @notice Change or reaffirm the approved address for an NFT
     * @dev The zero address indicates there is no approved address.
     *  Throws unless `msg.sender` is the current NFT owner, or an authorized
     *  operator of the current owner.
     * @param _approved The new approved NFT controller
     * @param _tokenId The NFT to approve
     */
    function approve(address _approved, uint256 _tokenId) external;

    /**
     * @notice Enable or disable approval for a third party ("operator") to manage
     *  all of `msg.sender`'s assets
     * @dev Emits the ApprovalForAll event. The contract MUST allow
     *  multiple operators per owner.
     * @param _operator Address to add to the set of authorized operators
     * @param _approved True if the operator is approved, false to revoke approval
     */
    function setApprovalForAll(address _operator, bool _approved) external;

    /**
     * @notice Get the approved address for a single NFT
     * @dev Throws if `_tokenId` is not a valid NFT.
     * @param _tokenId The NFT to find the approved address for
     * @return The approved address for this NFT, or the zero address if there is none
     */
    function getApproved(uint256 _tokenId) public view returns (address);

    /**
     * @notice Query if an address is an authorized operator for another address
     * @param _owner The address that owns the NFTs
     * @param _operator The address that acts on behalf of the owner
     * @return True if `_operator` is an approved operator for `_owner`, false otherwise
     */
    function isApprovedForAll(address _owner, address _operator) public view returns (bool);

    // Below is OPTIONAL

    // ERC721Metadata
    // The metadata extension is OPTIONAL for ERC-721 smart contracts (see "caveats", below). This allows your smart contract to be interrogated for its name and for details about the assets which your NFTs represent.
    
    /**
     * @title ERC-721 Non-Fungible Token Standard, optional metadata extension
     * @dev See https://github.com/ethereum/EIPs/blob/master/EIPS/eip-721.md
     *  Note: the ERC-165 identifier for this interface is 0x5b5e139f.
     */

    /// @notice A descriptive name for a collection of NFTs in this contract
    function name() external view returns (string _name);

    /// @notice An abbreviated name for NFTs in this contract
    function symbol() external view returns (string _symbol);

    /**
     * @notice A distinct Uniform Resource Identifier (URI) for a given asset.
     * @dev Throws if `_tokenId` is not a valid NFT. URIs are defined in RFC
     *  3986. The URI may point to a JSON file that conforms to the "ERC721
     *  Metadata JSON Schema".
     */
    function tokenURI(uint256 _tokenId) external view returns (string);

    // ERC721Enumerable
    // The enumeration extension is OPTIONAL for ERC-721 smart contracts (see "caveats", below). This allows your contract to publish its full list of NFTs and make them discoverable.

    /**
     * @title ERC-721 Non-Fungible Token Standard, optional enumeration extension
     * @dev See https://github.com/ethereum/EIPs/blob/master/EIPS/eip-721.md
     *  Note: the ERC-165 identifier for this interface is 0x780e9d63.
     */

    /**
     * @notice Count NFTs tracked by this contract
     * @return A count of valid NFTs tracked by this contract, where each one of
     *  them has an assigned and queryable owner not equal to the zero address
     */
    function totalSupply() public view returns (uint256);
}

/**
 * @title SafeMath
 * @dev Math operations with safety checks that revert on error
 */
library SafeMath {
    /**
    * @dev Multiplies two numbers, reverts on overflow.
    */
    function mul(uint256 a, uint256 b) internal pure returns (uint256) {
        // Gas optimization: this is cheaper than requiring 'a' not being zero, but the
        // benefit is lost if 'b' is also tested.
        // See: https://github.com/OpenZeppelin/openzeppelin-solidity/pull/522
        if (a == 0) {
            return 0;
        }

        uint256 c = a * b;
        require(c / a == b);

        return c;
    }

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

        return c;
    }

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

        return c;
    }

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

        return c;
    }

    /**
    * @dev Divides two numbers and returns the remainder (unsigned integer modulo),
    * reverts when dividing by zero.
    */
    function mod(uint256 a, uint256 b) internal pure returns (uint256) {
        require(b != 0);
        return a % b;
    }
}

/**
 * Utility library of inline functions on addresses
 */
library Address {
    /**
     * 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 account address of the account to check
     * @return whether the target address is a contract
     */
    function isContract(address account) 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(account) }
        return size > 0;
    }
}

/**
 * @title The base contract of Dyverse. ERC-721 compliant.
 * @author VREX Lab Co., Ltd
 * @dev See the KydyCore contract for more info on details. 
 */
contract KydyBase is KydyAccessControl, ERC721Basic {
    using SafeMath for uint256;
    using Address for address;

    /*** EVENT ***/

    /**
     * @dev The Creation event takes place whenever a new Kydy is created via Synthesis or minted by the COO.  
     */
    event Created(address indexed owner, uint256 kydyId, uint256 yinId, uint256 yangId, uint256 genes);

    /*** DATA TYPES ***/

    /**
     * @dev Every Kydy in the Dyverse is a copy of this structure. 
     */
    struct Kydy {
        // The Kydy's genetic code is stored into 256-bits and never changes.
        uint256 genes;

        // The timestamp of the block when this Kydy was created
        uint64 createdTime;

        // The timestamp of when this Kydy can synthesize again.
        uint64 rechargeEndBlock;

        // The ID of the parents (Yin, female, and Yang, male). It is 0 for Generation 0 Kydys.
        uint32 yinId;
        uint32 yangId;

        // The ID of the yang Kydy that the yin Kydy is creating with. 
        uint32 synthesizingWithId;

        // The recharge index that represents the duration of the recharge for this Kydy. 
        // After each synthesis, this increases by one for both yin and yang Kydys of the synthesis. 
        uint16 rechargeIndex;

        // The generation index of this Kydy. The newly created Kydy takes the generation index of the parent 
        // with a larger generation index. 
        uint16 generation;
    }

    /*** CONSTANTS ***/

    /**
     * @dev An array table of the recharge duration. Referred to as "creation time" for yin 
     *  and "synthesis recharge" for yang Kydys. Maximum duration is 4 days. 
     */
    uint32[14] public recharges = [
        uint32(1 minutes),
        uint32(2 minutes),
        uint32(5 minutes),
        uint32(10 minutes),
        uint32(30 minutes),
        uint32(1 hours),
        uint32(2 hours),
        uint32(4 hours),
        uint32(8 hours),
        uint32(16 hours),
        uint32(1 days),
        uint32(2 days),
        uint32(4 days)
    ];

    // An approximation of seconds between blocks.
    uint256 public secondsPerBlock = 15;

    /*** STORAGE ***/

    /**
     * @dev This array contains the ID of every Kydy as an index. 
     */
    Kydy[] kydys;

    /**
     * @dev This maps each Kydy ID to the address of the owner. Every Kydy must have an owner, even Gen 0 Kydys.
     *  You can view this mapping via `ownerOf()`.
     */
    mapping (uint256 => address) internal kydyIndexToOwner;

    /**
     * @dev This maps the owner's address to the number of Kydys that the address owns.
     *  You can view this mapping via `balanceOf()`.
     */
    mapping (address => uint256) internal ownershipTokenCount;

    /**
     * @dev This maps transferring Kydy IDs to the the approved address to call safeTransferFrom().
     *  You can view this mapping via `getApproved()`.
     */
    mapping (uint256 => address) internal kydyIndexToApproved;

    /**
     * @dev This maps KydyIDs to the address approved to synthesize via synthesizeWithAuto().
     *  You can view this mapping via `getSynthesizeApproved()`.
     */
    mapping (uint256 => address) internal synthesizeAllowedToAddress;

    /**
     * @dev This maps the owner to operator approvals, for the usage of setApprovalForAll().
     */
    mapping (address => mapping (address => bool)) private _operatorApprovals;

    /**
     * @dev Returns the owner of the given Kydy ID. Required for ERC-721 compliance.
     * @param _tokenId uint256 ID of the Kydy in query
     * @return the address of the owner of the given Kydy ID
     */
    function ownerOf(uint256 _tokenId) public view returns (address) {
        address owner = kydyIndexToOwner[_tokenId];
        require(owner != address(0));
        return owner;
    }

    /**
     * @dev Returns the approved address of the receiving owner for a Kydy ID. Required for ERC-721 compliance.
     * @param tokenId uint256 ID of the Kydy in query
     * @return the address of the approved, receiving owner for the given Kydy ID
     */
    function getApproved(uint256 tokenId) public view returns (address) {
        require(_exists(tokenId));
        return kydyIndexToApproved[tokenId];
    }

    /**
     * @dev Returns the synthesize approved address of the Kydy ID.
     * @param tokenId uint256 ID of the Kydy in query
     * @return the address of the synthesizing approved of the given Kydy ID
     */
    function getSynthesizeApproved(uint256 tokenId) external view returns (address) {
        require(_exists(tokenId));
        return synthesizeAllowedToAddress[tokenId];
    }

    /**
     * @dev Returns whether an operator is approved by the owner. Required for ERC-721 compliance.
     * @param owner owner address to check whether it is approved
     * @param operator operator address to check whether it is approved
     * @return bool whether the operator is approved or not
     */
    function isApprovedForAll(address owner, address operator) public view returns (bool) {
        return _operatorApprovals[owner][operator];
    }

    /**
     * @dev Sets or unsets the approval of the operator. Required for ERC-721 compliance.
     * @param to operator address to set the approval
     * @param approved the status to be set
     */
    function setApprovalForAll(address to, bool approved) external {
        require(to != msg.sender);
        _operatorApprovals[msg.sender][to] = approved;
        emit ApprovalForAll(msg.sender, to, approved);
    }

    /// @dev Assigns ownership of this Kydy to an address.
    function _transfer(address _from, address _to, uint256 _tokenId) internal {
        ownershipTokenCount[_to] = ownershipTokenCount[_to].add(1);
        // Transfers the ownership of this Kydy.
        kydyIndexToOwner[_tokenId] = _to;

        ownershipTokenCount[_from] = ownershipTokenCount[_from].sub(1);
        // After a transfer, synthesis allowance is also reset.
        delete synthesizeAllowedToAddress[_tokenId];
        // Clears any previously approved transfer.
        delete kydyIndexToApproved[_tokenId];

        // Emit the transfer event.
        emit Transfer(_from, _to, _tokenId);
    }

    /**
     * @dev Returns whether the given Kydy ID exists
     * @param _tokenId uint256 ID of the Kydy in query
     * @return whether the Kydy exists
     */
    function _exists(uint256 _tokenId) internal view returns (bool) {
        address owner = kydyIndexToOwner[_tokenId];
        return owner != address(0);
    }

    /**
     * @dev Returns whether the given spender can transfer the Kydy ID
     * @param _spender address of the spender to query
     * @param _tokenId uint256 ID of the Kydy to be transferred
     * @return bool whether the msg.sender is approved
     */
    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 add a Kydy ID to the new owner's list.
     * @param _to address the new owner's address
     * @param _tokenId uint256 ID of the transferred Kydy 
     */
    function _addTokenTo(address _to, uint256 _tokenId) internal {
        // Checks if the owner of the Kydy is 0x0 before the transfer.
        require(kydyIndexToOwner[_tokenId] == address(0));
        // Transfers the ownership to the new owner.
        kydyIndexToOwner[_tokenId] = _to;
        // Increases the total Kydy count of the new owner.
        ownershipTokenCount[_to] = ownershipTokenCount[_to].add(1);
    }

    /**
     * @dev Internal function to remove a Kydy ID from the previous owner's list.
     * @param _from address the previous owner's address
     * @param _tokenId uint256 ID of the transferred Kydy 
     */
    function _removeTokenFrom(address _from, uint256 _tokenId) internal {
        // Checks the current owner of the Kydy is '_from'.
        require(ownerOf(_tokenId) == _from);
        // Reduces the total Kydy count of the previous owner.
        ownershipTokenCount[_from] = ownershipTokenCount[_from].sub(1);
        // Deletes the transferred Kydy from the current owner's list.
        kydyIndexToOwner[_tokenId] = address(0);
    }

    /**
     * @dev Internal function to mint a new Kydy.
     * @param _to The address that owns the newly minted Kydy
     * @param _tokenId uint256 ID of the newly minted Kydy
     */
    function _mint(address _to, uint256 _tokenId) internal {
        require(!_exists(_tokenId));
        _addTokenTo(_to, _tokenId);
        emit Transfer(address(0), _to, _tokenId);
    }

    /**
     * @dev Internal function to clear current approvals of a given Kydy ID.
     * @param _owner owner of the Kydy
     * @param _tokenId uint256 ID of the Kydy to be transferred
     */
    function _clearApproval(address _owner, uint256 _tokenId) internal {
        require(ownerOf(_tokenId) == _owner);
        if (kydyIndexToApproved[_tokenId] != address(0)) {
            kydyIndexToApproved[_tokenId] = address(0);
        }
        if (synthesizeAllowedToAddress[_tokenId] != address(0)) {
            synthesizeAllowedToAddress[_tokenId] = address(0);
        }
    }

    /**
     * @dev Internal function that creates a new Kydy and stores it. 
     * @param _yinId The ID of the yin Kydy (zero for Generation 0 Kydy)
     * @param _yangId The ID of the yang Kydy (zero for Generation 0 Kydy)
     * @param _generation The generation number of the new Kydy.
     * @param _genes The Kydy's gene code
     * @param _owner The owner of this Kydy, must be non-zero (except for the ID 0)
     */
    function _createKydy(
        uint256 _yinId,
        uint256 _yangId,
        uint256 _generation,
        uint256 _genes,
        address _owner
    )
        internal
        returns (uint)
    {
        require(_yinId == uint256(uint32(_yinId)));
        require(_yangId == uint256(uint32(_yangId)));
        require(_generation == uint256(uint16(_generation)));

        // New Kydy's recharge index is its generation / 2.
        uint16 rechargeIndex = uint16(_generation / 2);
        if (rechargeIndex > 13) {
            rechargeIndex = 13;
        }

        Kydy memory _kyd = Kydy({
            genes: _genes,
            createdTime: uint64(now),
            rechargeEndBlock: 0,
            yinId: uint32(_yinId),
            yangId: uint32(_yangId),
            synthesizingWithId: 0,
            rechargeIndex: rechargeIndex,
            generation: uint16(_generation)
        });
        uint256 newbabyKydyId = kydys.push(_kyd) - 1;

        // Just in case.
        require(newbabyKydyId == uint256(uint32(newbabyKydyId)));

        // Emits the Created event.
        emit Created(
            _owner,
            newbabyKydyId,
            uint256(_kyd.yinId),
            uint256(_kyd.yangId),
            _kyd.genes
        );

        // Here grants ownership, and also emits the Transfer event.
        _mint(_owner, newbabyKydyId);

        return newbabyKydyId;
    }

    // Any C-level roles can change the seconds per block
    function setSecondsPerBlock(uint256 secs) external onlyCLevel {
        require(secs < recharges[0]);
        secondsPerBlock = secs;
    }
}

/**
 * @notice This is MUST to be implemented.
 *  A wallet/broker/auction application MUST implement the wallet interface if it will accept safe transfers.
 * @dev Note: the ERC-165 identifier for this interface is 0x150b7a02.
 */
contract ERC721TokenReceiver {
    /**
     * @notice Handle the receipt of an NFT
     * @dev The ERC721 smart contract calls this function on the recipient
     *  after a `transfer`. 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 transferred
     * @param _data Additional data with no specified format
     * @return `bytes4(keccak256("onERC721Received(address,address,uint256,bytes)"))`
     *  unless throwing
     */
    function onERC721Received(address _operator, address _from, uint256 _tokenId, bytes _data) public returns (bytes4);
}

// File: contracts/lib/Strings.sol

library Strings {
    // via https://github.com/oraclize/ethereum-api/blob/master/oraclizeAPI_0.5.sol
    function strConcat(string _a, string _b, string _c, string _d, string _e) internal pure returns (string) {
        bytes memory _ba = bytes(_a);
        bytes memory _bb = bytes(_b);
        bytes memory _bc = bytes(_c);
        bytes memory _bd = bytes(_d);
        bytes memory _be = bytes(_e);
        string memory abcde = new string(_ba.length + _bb.length + _bc.length + _bd.length + _be.length);
        bytes memory babcde = bytes(abcde);
        uint k = 0;
        for (uint i = 0; i < _ba.length; i++) babcde[k++] = _ba[i];
        for (i = 0; i < _bb.length; i++) babcde[k++] = _bb[i];
        for (i = 0; i < _bc.length; i++) babcde[k++] = _bc[i];
        for (i = 0; i < _bd.length; i++) babcde[k++] = _bd[i];
        for (i = 0; i < _be.length; i++) babcde[k++] = _be[i];
        return string(babcde);
    }

    function strConcat(string _a, string _b, string _c, string _d) internal pure returns (string) {
        return strConcat(_a, _b, _c, _d, "");
    }

    function strConcat(string _a, string _b, string _c) internal pure returns (string) {
        return strConcat(_a, _b, _c, "", "");
    }

    function strConcat(string _a, string _b) internal pure returns (string) {
        return strConcat(_a, _b, "", "", "");
    }

    function uint2str(uint i) internal pure returns (string) {
        if (i == 0) return "0";
        uint j = i;
        uint len;
        while (j != 0){
            len++;
            j /= 10;
        }
        bytes memory bstr = new bytes(len);
        uint k = len - 1;
        while (i != 0){
            bstr[k--] = byte(48 + i % 10);
            i /= 10;
        }
        return string(bstr);
    }
}

/**
 * @title Part of the KydyCore contract that manages ownership, ERC-721 compliant.
 * @author VREX Lab Co., Ltd
 * @dev Ref: https://github.com/ethereum/EIPs/blob/master/EIPS/eip-721.md
 *  See the KydyCore contract documentation to understand how the various contracts are arranged.
 */
contract KydyOwnership is KydyBase {
    using Strings for string;

    /// @notice Name and symbol of the non fungible token, as defined in ERC721.
    string public constant _name = "Dyverse";
    string public constant _symbol = "KYDY";

    // Base Server Address for Token MetaData URI
    string internal tokenURIBase = "http://testapi.dyver.se/api/KydyMetadata/";

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

    bytes4 private constant _InterfaceId_ERC165 = 0x01ffc9a7;
    /**
     * 0x01ffc9a7 ===
     *     bytes4(keccak256('supportsInterface(bytes4)'))
     */

    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_ERC721Metadata = 0x5b5e139f;
    /**
     * 0x5b5e139f ===
     *     bytes4(keccak256('name()')) ^
     *     bytes4(keccak256('symbol()')) ^
     *     bytes4(keccak256('tokenURI(uint256)'))
     */

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

    /**
     * @dev Checks if a given address is the current owner of this Kydy.
     * @param _claimant the address which we want to query the ownership of the Kydy ID.
     * @param _tokenId Kydy id, only valid when > 0
     */
    function _owns(address _claimant, uint256 _tokenId) internal view returns (bool) {
        return kydyIndexToOwner[_tokenId] == _claimant;
    }

    /**
     * @dev Grants an approval to the given address for safeTransferFrom(), overwriting any
     *  previous approval. Setting _approved to address(0) clears all transfer approval.
     *  Note that _approve() does NOT emit the Approval event. This is intentional because
     *  _approve() and safeTransferFrom() are used together when putting Kydys to the auction,
     *  and there is no need to spam the log with Approval events in that case.
     */
    function _approve(uint256 _tokenId, address _approved) internal {
        kydyIndexToApproved[_tokenId] = _approved;
    }

    /**
     * @dev Transfers a Kydy owned by this contract to the specified address.
     *  Used to rescue lost Kydys. (There is no "proper" flow where this contract
     *  should be the owner of any Kydy. This function exists for us to reassign
     *  the ownership of Kydys that users may have accidentally sent to our address.)
     * @param _kydyId ID of the lost Kydy
     * @param _recipient address to send the Kydy to
     */
    function rescueLostKydy(uint256 _kydyId, address _recipient) external onlyCOO whenNotPaused {
        require(_owns(this, _kydyId));
        _transfer(this, _recipient, _kydyId);
    }

    /**
     * @dev Gets the number of Kydys owned by the given address.
     *  Required for ERC-721 compliance.
     * @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 ownershipTokenCount[_owner];
    }

    /**
     * @dev Approves another address to transfer the given Kydy ID.
     *  The zero address indicates that there is no approved address.
     *  There can only be one approved address per Kydy at a given time.
     *  Can only be called by the Kydy owner or an approved operator.
     *  Required for ERC-721 compliance.
     * @param to address to be approved for the given Kydy ID
     * @param tokenId uint256 ID of the Kydy to be approved
     */
    function approve(address to, uint256 tokenId) external whenNotPaused {
        address owner = ownerOf(tokenId);
        require(to != owner);
        // Owner or approved operator by owner can approve the another address
        // to transfer the Kydy.
        require(msg.sender == owner || isApprovedForAll(owner, msg.sender));

        // Approves the given address.
        _approve(tokenId, to);

        // Emits the Approval event.
        emit Approval(owner, to, tokenId);
    }

    /**
     * @dev Transfers the ownership of the Kydy to another address.
     *  Usage of this function is discouraged, use `safeTransferFrom` whenever possible.
     *  Requires the msg sender to be the owner, approved, or operator.
     *  Required for ERC-721 compliance.
     * @param from current owner of the Kydy
     * @param to address to receive the ownership of the given Kydy ID
     * @param tokenId uint256 ID of the Kydy to be transferred
     */
    function transferFrom(address from, address to, uint256 tokenId) public whenNotPaused {
        // Checks the caller is the owner or approved one or an operator.
        require(_isApprovedOrOwner(msg.sender, tokenId));
        // Safety check to prevent from transferring Kydy to 0x0 address.
        require(to != address(0));

        // Clears approval from current owner.
        _clearApproval(from, tokenId);
        // Resets the ownership of this Kydy from current owner and sets it to 0x0.
        _removeTokenFrom(from, tokenId);
        // Grants the ownership of this Kydy to new owner.
        _addTokenTo(to, tokenId);

        // Emits the Transfer event.
        emit Transfer(from, to, tokenId);
    }

    /**
     * @dev Safely transfers the ownership of a given Kydy 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.
     *  Required for ERC-721 compliance.
     * @param from current owner of the Kydy
     * @param to address to receive the ownership of the given Kydy ID
     * @param tokenId uint256 ID of the Kydy to be transferred
     */
    function safeTransferFrom(address from, address to, uint256 tokenId) public {
        // solium-disable-next-line arg-overflow
        safeTransferFrom(from, to, tokenId, "");
    }

    /**
     * @dev Safely transfers the ownership of a given Kydy 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.
     *  Required for ERC-721 compliance.
     * @param from current owner of the Kydy
     * @param to address to receive the ownership of the given Kydy ID
     * @param tokenId uint256 ID of the Kydy 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 {
        transferFrom(from, to, tokenId);
        // solium-disable-next-line arg-overflow
        require(_checkOnERC721Received(from, to, tokenId, _data));
    }

    /**
     * @dev Internal function to invoke `onERC721Received` on a target address.
     *  This function is not executed if the target address is not a contract.
     * @param _from address representing the previous owner of the given Kydy ID
     * @param _to target address that will receive the Kydys
     * @param _tokenId uint256 ID of the Kydy 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 _checkOnERC721Received(address _from, address _to, uint256 _tokenId, bytes _data) internal returns (bool) {
        if (!_to.isContract()) {
            return true;
        }

        bytes4 retval = ERC721TokenReceiver(_to).onERC721Received(msg.sender, _from, _tokenId, _data);
        return (retval == _ERC721_RECEIVED);
    }
    
    /**
     * @dev Gets the token name.
     *  Required for ERC721Metadata compliance.
     * @return string representing the token name
     */
    function name() external view returns (string) {
        return _name;
    }

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

    /**
     * @dev Returns an URI for a given Kydy ID.
     *  Throws if the token ID does not exist. May return an empty string.
     *  Required for ERC721Metadata compliance.
     * @param tokenId uint256 ID of the token to query
     */
    function tokenURI(uint256 tokenId) external view returns (string) {
        require(_exists(tokenId));
        return Strings.strConcat(
            tokenURIBase,
            Strings.uint2str(tokenId)
        );
    }

    /**
     * @dev Gets the total amount of Kydys stored in the contract
     * @return uint256 representing the total amount of Kydys
     */
    function totalSupply() public view returns (uint256) {
        return kydys.length - 1;
    }

    /**
     * @notice Returns a list of all Kydy IDs assigned to an address.
     * @param _owner The owner whose Kydys we are interested in.
     * @dev This function MUST NEVER be called by smart contract code. It's pretty
     *  expensive (it looks into the entire Kydy array looking for Kydys belonging to owner),
     *  and it also returns a dynamic array, which is only supported for web3 calls, and
     *  not contract-to-contract calls.
     */
    function tokensOfOwner(address _owner) external view returns(uint256[] ownerTokens) {
        uint256 tokenCount = balanceOf(_owner);

        if (tokenCount == 0) {
            // Return an empty array
            return new uint256[](0);
        } else {
            uint256[] memory result = new uint256[](tokenCount);
            uint256 totalKydys = totalSupply();
            uint256 resultIndex = 0;

            // All Kydys have IDs starting at 1 and increasing sequentially up to the totalKydy count.
            uint256 kydyId;

            for (kydyId = 1; kydyId <= totalKydys; kydyId++) {
                if (kydyIndexToOwner[kydyId] == _owner) {
                    result[resultIndex] = kydyId;
                    resultIndex++;
                }
            }

            return result;
        }
    }
}

/**
 * @title This manages synthesis and creation of Kydys.
 * @author VREX Lab Co., Ltd
 * @dev Please reference the KydyCore contract for details. 
 */
contract KydySynthesis is KydyOwnership {

    /**
     * @dev The Creating event is emitted when two Kydys synthesize and the creation
     *  timer begins by the yin.
     */
    event Creating(address owner, uint256 yinId, uint256 yangId, uint256 rechargeEndBlock);

    /**
     * @notice The minimum payment required for synthesizeWithAuto(). This fee is for
     *  the gas cost paid by whoever calls bringKydyHome(), and can be updated by the COO address.
     */
    uint256 public autoCreationFee = 14 finney;

    // Number of the Kydys that are creating a new Kydy.
    uint256 public creatingKydys;

    /**
     * @dev The address of the sibling contract that mixes and combines genes of the two parent Kydys. 
     */
    GeneSynthesisInterface public geneSynthesis;

    /**
     * @dev Updates the address of the genetic contract. Only CEO may call this function.
     * @param _address An address of the new GeneSynthesis contract instance.
     */
    function setGeneSynthesisAddress(address _address) external onlyCEO {
        GeneSynthesisInterface candidateContract = GeneSynthesisInterface(_address);

        // Verifies that the contract is valid.
        require(candidateContract.isGeneSynthesis());

        // Sets the new GeneSynthesis contract address.
        geneSynthesis = candidateContract;
    }

    /**
     * @dev Checks that the Kydy is able to synthesize. 
     */
    function _isReadyToSynthesize(Kydy _kyd) internal view returns (bool) {
        // Double-checking if there is any pending creation event. 
        return (_kyd.synthesizingWithId == 0) && (_kyd.rechargeEndBlock <= uint64(block.number));
    }

    /**
     * @dev Checks if a yang Kydy has been approved to synthesize with this yin Kydy.
     */
    function _isSynthesizingAllowed(uint256 _yangId, uint256 _yinId) internal view returns (bool) {
        address yinOwner = kydyIndexToOwner[_yinId];
        address yangOwner = kydyIndexToOwner[_yangId];

        return (yinOwner == yangOwner || synthesizeAllowedToAddress[_yangId] == yinOwner);
    }

    /**
     * @dev Sets the rechargeEndTime for the given Kydy, based on its current rechargeIndex.
     *  The rechargeIndex increases until it hits the cap.
     * @param _kyd A reference to the Kydy that needs its timer to be started.
     */
    function _triggerRecharge(Kydy storage _kyd) internal {
        // Computes the approximation of the end of recharge time in blocks (based on current rechargeIndex).
        _kyd.rechargeEndBlock = uint64((recharges[_kyd.rechargeIndex] / secondsPerBlock) + block.number);

        // Increases this Kydy's synthesizing count, and the cap is fixed at 12.
        if (_kyd.rechargeIndex < 12) {
            _kyd.rechargeIndex += 1;
        }
    }

    /**
     * @notice Grants approval to another user to synthesize with one of your Kydys.
     * @param _address The approved address of the yin Kydy that can synthesize with your yang Kydy. 
     * @param _yangId Your kydy that _address can now synthesize with.
     */
    function approveSynthesizing(address _address, uint256 _yangId)
        external
        whenNotPaused
    {
        require(_owns(msg.sender, _yangId));
        synthesizeAllowedToAddress[_yangId] = _address;
    }

    /**
     * @dev Updates the minimum payment required for calling bringKydyHome(). Only COO
     *  can call this function. 
     */
    function setAutoCreationFee(uint256 value) external onlyCOO {
        autoCreationFee = value;
    }

    /// @dev Checks if this Kydy is creating and if the creation period is complete. 
    function _isReadyToBringKydyHome(Kydy _yin) private view returns (bool) {
        return (_yin.synthesizingWithId != 0) && (_yin.rechargeEndBlock <= uint64(block.number));
    }

    /**
     * @notice Checks if this Kydy is able to synthesize 
     * @param _kydyId reference the ID of the Kydy
     */
    function isReadyToSynthesize(uint256 _kydyId)
        public
        view
        returns (bool)
    {
        require(_kydyId > 0);
        Kydy storage kyd = kydys[_kydyId];
        return _isReadyToSynthesize(kyd);
    }

    /**
     * @dev Checks if the Kydy is currently creating.
     * @param _kydyId reference the ID of the Kydy
     */
    function isCreating(uint256 _kydyId)
        public
        view
        returns (bool)
    {
        require(_kydyId > 0);

        return kydys[_kydyId].synthesizingWithId != 0;
    }

    /**
     * @dev Internal check to see if these yang and yin are a valid couple. 
     * @param _yin A reference to the Kydy struct of the potential yin.
     * @param _yinId The yin's ID.
     * @param _yang A reference to the Kydy struct of the potential yang.
     * @param _yangId The yang's ID
     */
    function _isValidCouple(
        Kydy storage _yin,
        uint256 _yinId,
        Kydy storage _yang,
        uint256 _yangId
    )
        private
        view
        returns(bool)
    {
        // Kydy can't synthesize with itself.
        if (_yinId == _yangId) {
            return false;
        }

        // Kydys can't synthesize with their parents.
        if (_yin.yinId == _yangId || _yin.yangId == _yangId) {
            return false;
        }
        if (_yang.yinId == _yinId || _yang.yangId == _yinId) {
            return false;
        }

        // Skip sibling check for Gen 0
        if (_yang.yinId == 0 || _yin.yinId == 0) {
            return true;
        }

        // Kydys can't synthesize with full or half siblings.
        if (_yang.yinId == _yin.yinId || _yang.yinId == _yin.yangId) {
            return false;
        }
        if (_yang.yangId == _yin.yinId || _yang.yangId == _yin.yangId) {
            return false;
        }
        return true;
    }

    /**
     * @dev Internal check to see if these yang and yin Kydys, connected via market, are a valid couple for synthesis. 
     */
    function _canSynthesizeWithViaAuction(uint256 _yinId, uint256 _yangId)
        internal
        view
        returns (bool)
    {
        Kydy storage yin = kydys[_yinId];
        Kydy storage yang = kydys[_yangId];
        return _isValidCouple(yin, _yinId, yang, _yangId);
    }

    /**
     * @dev Checks if the two Kydys can synthesize together, including checks for ownership and synthesizing approvals. 
     * @param _yinId ID of the yin Kydy
     * @param _yangId ID of the yang Kydy
     */
    function canSynthesizeWith(uint256 _yinId, uint256 _yangId)
        external
        view
        returns(bool)
    {
        require(_yinId > 0);
        require(_yangId > 0);
        Kydy storage yin = kydys[_yinId];
        Kydy storage yang = kydys[_yangId];
        return _isValidCouple(yin, _yinId, yang, _yangId) &&
            _isSynthesizingAllowed(_yangId, _yinId);
    }

    /**
     * @dev Internal function to start synthesizing, when all the conditions are met
     */
    function _synthesizeWith(uint256 _yinId, uint256 _yangId) internal {
        Kydy storage yang = kydys[_yangId];
        Kydy storage yin = kydys[_yinId];

        // Marks this yin as creating, and make note of who the yang Kydy is.
        yin.synthesizingWithId = uint32(_yangId);

        // Triggers the recharge for both parents.
        _triggerRecharge(yang);
        _triggerRecharge(yin);

        // Clears synthesizing permission for both parents, just in case.
        delete synthesizeAllowedToAddress[_yinId];
        delete synthesizeAllowedToAddress[_yangId];

        // When a Kydy starts creating, this number is increased. 
        creatingKydys++;

        // Emits the Creating event.
        emit Creating(kydyIndexToOwner[_yinId], _yinId, _yangId, yin.rechargeEndBlock);
    }

    /**
     * @dev Synthesis between two approved Kydys. Requires a pre-payment of the fee to the first caller of bringKydyHome().
     * @param _yinId ID of the Kydy which will be a yin (will start creation if successful)
     * @param _yangId ID of the Kydy which will be a yang (will begin its synthesizing cooldown if successful)
     */
    function synthesizeWithAuto(uint256 _yinId, uint256 _yangId)
        external
        payable
        whenNotPaused
    {
        // Checks for pre-payment.
        require(msg.value >= autoCreationFee);

        // Caller must be the yin's owner.
        require(_owns(msg.sender, _yinId));

        // Checks if the caller has valid authority for this synthesis
        require(_isSynthesizingAllowed(_yangId, _yinId));

        // Gets a reference of the potential yin.
        Kydy storage yin = kydys[_yinId];

        // Checks that the potential yin is ready to synthesize
        require(_isReadyToSynthesize(yin));

        // Gets a reference of the potential yang.
        Kydy storage yang = kydys[_yangId];

        // Checks that the potential yang is ready to synthesize
        require(_isReadyToSynthesize(yang));

        // Checks that these Kydys are a valid couple.
        require(_isValidCouple(
            yin,
            _yinId,
            yang,
            _yangId
        ));

        // All checks passed! Yin Kydy starts creating.
        _synthesizeWith(_yinId, _yangId);

    }

    /**
     * @notice Let's bring the new Kydy to it's home!
     * @param _yinId A Kydy which is ready to bring the newly created Kydy to home.
     * @return The Kydy ID of the newly created Kydy.
     * @dev The newly created Kydy is transferred to the owner of the yin Kydy. Anyone is welcome to call this function.
     */
    function bringKydyHome(uint256 _yinId)
        external
        whenNotPaused
        returns(uint256)
    {
        // Gets a reference of the yin from storage.
        Kydy storage yin = kydys[_yinId];

        // Checks that the yin is a valid Kydy.
        require(yin.createdTime != 0);

        // Checks that the yin is in creation mode, and the creating period is over.
        require(_isReadyToBringKydyHome(yin));

        // Gets a reference of the yang from storage.
        uint256 yangId = yin.synthesizingWithId;
        Kydy storage yang = kydys[yangId];

        // Ascertains which has the higher generation number between the two parents.
        uint16 parentGen = yin.generation;
        if (yang.generation > yin.generation) {
            parentGen = yang.generation;
        }

        // The baby Kydy receives its genes 
        uint256 childGenes = geneSynthesis.synthGenes(yin.genes, yang.genes);

        // The baby Kydy is now on blockchain
        address owner = kydyIndexToOwner[_yinId];
        uint256 kydyId = _createKydy(_yinId, yin.synthesizingWithId, parentGen + 1, childGenes, owner);

        // Clears the synthesis status of the parents
        delete yin.synthesizingWithId;

        // When a baby Kydy is created, this number is decreased back. 
        creatingKydys--;

        // Sends the fee to the person who called this. 
        msg.sender.transfer(autoCreationFee);

        // Returns the new Kydy's ID.
        return kydyId;
    }
}

contract ERC721Holder is ERC721TokenReceiver {
    function onERC721Received(address, address, uint256, bytes) public returns (bytes4) {
        return this.onERC721Received.selector;
    }
}

/**
 * @title Base auction contract of the Dyverse
 * @author VREX Lab Co., Ltd
 * @dev Contains necessary functions and variables for the auction.
 *  Inherits `ERC721Holder` contract which is the implementation of the `ERC721TokenReceiver`.
 *  This is to accept safe transfers.
 */
contract AuctionBase is ERC721Holder {
    using SafeMath for uint256;

    // Represents an auction on an NFT
    struct Auction {
        // Current owner of NFT
        address seller;
        // Price (in wei) of NFT
        uint128 price;
        // Time when the auction started
        // NOTE: 0 if this auction has been concluded
        uint64 startedAt;
    }

    // Reference to contract tracking NFT ownership
    ERC721Basic public nonFungibleContract;

    // The amount owner takes from the sale, (in basis points, which are 1/100 of a percent).
    uint256 public ownerCut;

    // Maps token ID to it's corresponding auction.
    mapping (uint256 => Auction) tokenIdToAuction;

    event AuctionCreated(uint256 tokenId, uint256 price);
    event AuctionSuccessful(uint256 tokenId, uint256 totalPrice, address bidder);
    event AuctionCanceled(uint256 tokenId);

    /// @dev Disables sending funds to this contract.
    function() external {}

    /// @dev A modifier to check if the given value can fit in 64-bits.
    modifier canBeStoredWith64Bits(uint256 _value) {
        require(_value <= (2**64 - 1));
        _;
    }

    /// @dev A modifier to check if the given value can fit in 128-bits.
    modifier canBeStoredWith128Bits(uint256 _value) {
        require(_value <= (2**128 - 1));
        _;
    }

    /**
     * @dev Returns true if the claimant owns the token.
     * @param _claimant An address which to query the ownership of the token.
     * @param _tokenId ID of the token to query the owner of.
     */
    function _owns(address _claimant, uint256 _tokenId) internal view returns (bool) {
        return (nonFungibleContract.ownerOf(_tokenId) == _claimant);
    }

    /**
     * @dev Escrows the NFT. Grants the ownership of the NFT to this contract safely.
     *  Throws if the escrow fails.
     * @param _owner Current owner of the token.
     * @param _tokenId ID of the token to escrow.
     */
    function _escrow(address _owner, uint256 _tokenId) internal {
        nonFungibleContract.safeTransferFrom(_owner, this, _tokenId);
    }

    /**
     * @dev Transfers an NFT owned by this contract to another address safely.
     * @param _receiver The receiving address of NFT.
     * @param _tokenId ID of the token to transfer.
     */
    function _transfer(address _receiver, uint256 _tokenId) internal {
        nonFungibleContract.safeTransferFrom(this, _receiver, _tokenId);
    }

    /**
     * @dev Adds an auction to the list of open auctions. 
     * @param _tokenId ID of the token to be put on auction.
     * @param _auction Auction information of this token to open.
     */
    function _addAuction(uint256 _tokenId, Auction _auction) internal {
        tokenIdToAuction[_tokenId] = _auction;

        emit AuctionCreated(
            uint256(_tokenId),
            uint256(_auction.price)
        );
    }

    /// @dev Cancels the auction which the _seller wants.
    function _cancelAuction(uint256 _tokenId, address _seller) internal {
        _removeAuction(_tokenId);
        _transfer(_seller, _tokenId);
        emit AuctionCanceled(_tokenId);
    }

    /**
     * @dev Computes the price and sends it to the seller.
     *  Note that this does NOT transfer the ownership of the token.
     */
    function _bid(uint256 _tokenId, uint256 _bidAmount)
        internal
        returns (uint256)
    {
        // Gets a reference of the token from auction storage.
        Auction storage auction = tokenIdToAuction[_tokenId];

        // Checks that this auction is currently open
        require(_isOnAuction(auction));

        // Checks that the bid is greater than or equal to the current token price.
        uint256 price = _currentPrice(auction);
        require(_bidAmount >= price);

        // Gets a reference of the seller before the auction gets deleted.
        address seller = auction.seller;

        // Removes the auction before sending the proceeds to the sender
        _removeAuction(_tokenId);

        // Transfers proceeds to the seller.
        if (price > 0) {
            uint256 auctioneerCut = _computeCut(price);
            uint256 sellerProceeds = price.sub(auctioneerCut);

            seller.transfer(sellerProceeds);
        }

        // Computes the excess funds included with the bid and transfers it back to bidder. 
        uint256 bidExcess = _bidAmount - price;

        // Returns the exceeded funds.
        msg.sender.transfer(bidExcess);

        // Emits the AuctionSuccessful event.
        emit AuctionSuccessful(_tokenId, price, msg.sender);

        return price;
    }

    /**
     * @dev Removes an auction from the list of open auctions.
     * @param _tokenId ID of the NFT on auction to be removed.
     */
    function _removeAuction(uint256 _tokenId) internal {
        delete tokenIdToAuction[_tokenId];
    }

    /**
     * @dev Returns true if the NFT is on auction.
     * @param _auction An auction to check if it exists.
     */
    function _isOnAuction(Auction storage _auction) internal view returns (bool) {
        return (_auction.startedAt > 0);
    }

    /// @dev Returns the current price of an NFT on auction.
    function _currentPrice(Auction storage _auction)
        internal
        view
        returns (uint256)
    {
        return _auction.price;
    }

    /**
     * @dev Computes the owner's receiving amount from the sale.
     * @param _price Sale price of the NFT.
     */
    function _computeCut(uint256 _price) internal view returns (uint256) {
        return _price * ownerCut / 10000;
    }
}

contract Ownable {
  address public owner;


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


  constructor() public {
    owner = msg.sender;
  }

  modifier onlyOwner() {
    require(msg.sender == owner);
    _;
  }

  function transferOwnership(address newOwner) public onlyOwner {
    require(newOwner != address(0));
    emit OwnershipTransferred(owner, newOwner);
    owner = newOwner;
  }
}

contract Pausable is Ownable {
  event Pause();
  event Unpause();

  bool public paused = false;

  modifier whenNotPaused() {
    require(!paused);
    _;
  }

  modifier whenPaused() {
    require(paused);
    _;
  }

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

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

/**
 * @title Auction for NFT.
 * @author VREX Lab Co., Ltd
 */
contract Auction is Pausable, AuctionBase {

    /**
     * @dev Removes all Ether from the contract to the NFT contract.
     */
    function withdrawBalance() external {
        address nftAddress = address(nonFungibleContract);

        require(
            msg.sender == owner ||
            msg.sender == nftAddress
        );
        nftAddress.transfer(address(this).balance);
    }

    /**
     * @dev Creates and begins a new auction.
     * @param _tokenId ID of the token to creat an auction, caller must be it's owner.
     * @param _price Price of the token (in wei).
     * @param _seller Seller of this token.
     */
    function createAuction(
        uint256 _tokenId,
        uint256 _price,
        address _seller
    )
        external
        whenNotPaused
        canBeStoredWith128Bits(_price)
    {
        require(_owns(msg.sender, _tokenId));
        _escrow(msg.sender, _tokenId);
        Auction memory auction = Auction(
            _seller,
            uint128(_price),
            uint64(now)
        );
        _addAuction(_tokenId, auction);
    }

    /**
     * @dev Bids on an open auction, completing the auction and transferring
     *  ownership of the NFT if enough Ether is supplied.
     * @param _tokenId - ID of token to bid on.
     */
    function bid(uint256 _tokenId)
        external
        payable
        whenNotPaused
    {
        _bid(_tokenId, msg.value);
        _transfer(msg.sender, _tokenId);
    }

    /**
     * @dev Cancels an auction and returns the NFT to the current owner.
     * @param _tokenId ID of the token on auction to cancel.
     * @param _seller The seller's address.
     */
    function cancelAuction(uint256 _tokenId, address _seller)
        external
    {
        // Requires that this function should only be called from the
        // `cancelSaleAuction()` of NFT ownership contract. This function gets
        // the _seller directly from it's arguments, so if this check doesn't
        // exist, then anyone can cancel the auction! OMG!
        require(msg.sender == address(nonFungibleContract));
        Auction storage auction = tokenIdToAuction[_tokenId];
        require(_isOnAuction(auction));
        address seller = auction.seller;
        require(_seller == seller);
        _cancelAuction(_tokenId, seller);
    }

    /**
     * @dev Cancels an auction when the contract is paused.
     * Only the owner may do this, and NFTs are returned to the seller. 
     * @param _tokenId ID of the token on auction to cancel.
     */
    function cancelAuctionWhenPaused(uint256 _tokenId)
        external
        whenPaused
        onlyOwner
    {
        Auction storage auction = tokenIdToAuction[_tokenId];
        require(_isOnAuction(auction));
        _cancelAuction(_tokenId, auction.seller);
    }

    /**
     * @dev Returns the auction information for an NFT
     * @param _tokenId ID of the NFT on auction
     */
    function getAuction(uint256 _tokenId)
        external
        view
        returns
    (
        address seller,
        uint256 price,
        uint256 startedAt
    ) {
        Auction storage auction = tokenIdToAuction[_tokenId];
        require(_isOnAuction(auction));
        return (
            auction.seller,
            auction.price,
            auction.startedAt
        );
    }

    /**
     * @dev Returns the current price of the token on auction.
     * @param _tokenId ID of the token
     */
    function getCurrentPrice(uint256 _tokenId)
        external
        view
        returns (uint256)
    {
        Auction storage auction = tokenIdToAuction[_tokenId];
        require(_isOnAuction(auction));
        return _currentPrice(auction);
    }
}

/**
 * @title  Auction for synthesizing
 * @author VREX Lab Co., Ltd
 * @notice Reset fallback function to prevent accidental fund sending to this contract.
 */
contract SynthesizingAuction is Auction {

    /**
     * @dev Sanity check that allows us to ensure that we are pointing to the
     *  right auction in our `setSynthesizingAuctionAddress()` call.
     */
    bool public isSynthesizingAuction = true;

    /**
     * @dev Creates a reference to the NFT ownership contract and checks the owner cut is valid
     * @param _nftAddress Address of a deployed NFT interface contract
     * @param _cut Percent cut which the owner takes on each auction, between 0-10,000.
     */
    constructor(address _nftAddress, uint256 _cut) public {
        require(_cut <= 10000);
        ownerCut = _cut;

        ERC721Basic candidateContract = ERC721Basic(_nftAddress);
        nonFungibleContract = candidateContract;
    }

    /**
     * @dev Creates and begins a new auction. Since this function is wrapped,
     *  requires the caller to be KydyCore contract.
     * @param _tokenId ID of token to auction, sender must be it's owner.
     * @param _price Price of the token (in wei).
     * @param _seller Seller of this token.
     */
    function createAuction(
        uint256 _tokenId,
        uint256 _price,
        address _seller
    )
        external
        canBeStoredWith128Bits(_price)
    {
        require(msg.sender == address(nonFungibleContract));
        _escrow(_seller, _tokenId);
        Auction memory auction = Auction(
            _seller,
            uint128(_price),
            uint64(now)
        );
        _addAuction(_tokenId, auction);
    }

    /**
     * @dev Places a bid for synthesizing. Requires the caller
     *  is the KydyCore contract because all bid functions
     *  should be wrapped. Also returns the Kydy to the
     *  seller rather than the bidder.
     */
    function bid(uint256 _tokenId)
        external
        payable
    {
        require(msg.sender == address(nonFungibleContract));
        address seller = tokenIdToAuction[_tokenId].seller;
        // _bid() checks that the token ID is valid and will throw if bid fails
        _bid(_tokenId, msg.value);
        // Transfers the Kydy back to the seller, and the bidder will get
        // the baby Kydy.
        _transfer(seller, _tokenId);
    }
}

/**
 * @title Auction for sale of Kydys.
 * @author VREX Lab Co., Ltd
 */
contract SaleAuction is Auction {

    /**
     * @dev To make sure we are addressing to the right auction. 
     */
    bool public isSaleAuction = true;

    // Last 5 sale price of Generation 0 Kydys.
    uint256[5] public lastGen0SalePrices;
    
    // Total number of Generation 0 Kydys sold.
    uint256 public gen0SaleCount;

    /**
     * @dev Creates a reference to the NFT ownership contract and checks the owner cut is valid
     * @param _nftAddress Address of a deployed NFT interface contract
     * @param _cut Percent cut which the owner takes on each auction, between 0-10,000.
     */
    constructor(address _nftAddress, uint256 _cut) public {
        require(_cut <= 10000);
        ownerCut = _cut;

        ERC721Basic candidateContract = ERC721Basic(_nftAddress);
        nonFungibleContract = candidateContract;
    }

    /**
     * @dev Creates and begins a new auction.
     * @param _tokenId ID of token to auction, sender must be it's owner.
     * @param _price Price of the token (in wei).
     * @param _seller Seller of this token.
     */
    function createAuction(
        uint256 _tokenId,
        uint256 _price,
        address _seller
    )
        external
        canBeStoredWith128Bits(_price)
    {
        require(msg.sender == address(nonFungibleContract));
        _escrow(_seller, _tokenId);
        Auction memory auction = Auction(
            _seller,
            uint128(_price),
            uint64(now)
        );
        _addAuction(_tokenId, auction);
    }

    /**
     * @dev Updates lastSalePrice only if the seller is nonFungibleContract. 
     */
    function bid(uint256 _tokenId)
        external
        payable
    {
        // _bid verifies token ID
        address seller = tokenIdToAuction[_tokenId].seller;
        uint256 price = _bid(_tokenId, msg.value);
        _transfer(msg.sender, _tokenId);

        // If the last sale was not Generation 0 Kydy's, the lastSalePrice doesn't change.
        if (seller == address(nonFungibleContract)) {
            // Tracks gen0's latest sale prices.
            lastGen0SalePrices[gen0SaleCount % 5] = price;
            gen0SaleCount++;
        }
    }

    /// @dev Gives the new average Generation 0 sale price after each Generation 0 Kydy sale.
    function averageGen0SalePrice() external view returns (uint256) {
        uint256 sum = 0;
        for (uint256 i = 0; i < 5; i++) {
            sum = sum.add(lastGen0SalePrices[i]);
        }
        return sum / 5;
    }
}

/**
 * @title This contract defines how sales and synthesis auctions for Kydys are created. 
 * @author VREX Lab Co., Ltd
 */
contract KydyAuction is KydySynthesis {

    /**
     * @dev The address of the Auction contract which handles ALL sales of Kydys, both user-generated and Generation 0. 
     */
    SaleAuction public saleAuction;

    /**
     * @dev The address of another Auction contract which handles synthesis auctions. 
     */
    SynthesizingAuction public synthesizingAuction;

    /**
     * @dev Sets the address for the sales auction. Only CEO may call this function. 
     * @param _address The address of the sale contract.
     */
    function setSaleAuctionAddress(address _address) external onlyCEO {
        SaleAuction candidateContract = SaleAuction(_address);

        // Verifies that the contract is correct
        require(candidateContract.isSaleAuction());

        // Sets the new sale auction contract address.
        saleAuction = candidateContract;
    }

    /**
     * @dev Sets the address to the synthesis auction. Only CEO may call this function.
     * @param _address The address of the synthesis contract.
     */
    function setSynthesizingAuctionAddress(address _address) external onlyCEO {
        SynthesizingAuction candidateContract = SynthesizingAuction(_address);

        require(candidateContract.isSynthesizingAuction());

        synthesizingAuction = candidateContract;
    }

    /**
     * @dev Creates a Kydy sale.
     */
    function createSaleAuction(
        uint256 _kydyId,
        uint256 _price
    )
        external
        whenNotPaused
    {
        require(_owns(msg.sender, _kydyId));
        require(!isCreating(_kydyId));
        _approve(_kydyId, saleAuction);
 
        saleAuction.createAuction(
            _kydyId,
            _price,
            msg.sender
        );
    }

    /**
     * @dev Creates a synthesis auction. 
     */
    function createSynthesizingAuction(
        uint256 _kydyId,
        uint256 _price
    )
        external
        whenNotPaused
    {
        require(_owns(msg.sender, _kydyId));
        require(isReadyToSynthesize(_kydyId));
        _approve(_kydyId, synthesizingAuction);

        synthesizingAuction.createAuction(
            _kydyId,
            _price,
            msg.sender
        );
    }

    /**
     * @dev After bidding for a synthesis auction is accepted, this starts the actual synthesis process.
     * @param _yangId ID of the yang Kydy on the synthesis auction.
     * @param _yinId ID of the yin Kydy owned by the bidder.
     */
    function bidOnSynthesizingAuction(
        uint256 _yangId,
        uint256 _yinId
    )
        external
        payable
        whenNotPaused
    {
        require(_owns(msg.sender, _yinId));
        require(isReadyToSynthesize(_yinId));
        require(_canSynthesizeWithViaAuction(_yinId, _yangId));

        uint256 currentPrice = synthesizingAuction.getCurrentPrice(_yangId);

        require (msg.value >= currentPrice + autoCreationFee);

        synthesizingAuction.bid.value(msg.value - autoCreationFee)(_yangId);

        _synthesizeWith(uint32(_yinId), uint32(_yangId));
    }

    /**
     * @dev Cancels a sale and returns the Kydy back to the owner.
     * @param _kydyId ID of the Kydy on sale that the owner wishes to cancel.
     */
    function cancelSaleAuction(
        uint256 _kydyId
    )
        external
        whenNotPaused
    {
        // Checks if the Kydy is in auction. 
        require(_owns(saleAuction, _kydyId));
        // Gets the seller of the Kydy.
        (address seller,,) = saleAuction.getAuction(_kydyId);
        // Checks that the caller is the real seller.
        require(msg.sender == seller);
        // Cancels the sale auction of this kydy by it's seller's request.
        saleAuction.cancelAuction(_kydyId, msg.sender);
    }

    /**
     * @dev Cancels an synthesis auction. 
     * @param _kydyId ID of the Kydy on the synthesis auction. 
     */
    function cancelSynthesizingAuction(
        uint256 _kydyId
    )
        external
        whenNotPaused
    {
        require(_owns(synthesizingAuction, _kydyId));
        (address seller,,) = synthesizingAuction.getAuction(_kydyId);
        require(msg.sender == seller);
        synthesizingAuction.cancelAuction(_kydyId, msg.sender);
    }

    /**
     * @dev Transfers the balance. 
     */
    function withdrawAuctionBalances() external onlyCLevel {
        saleAuction.withdrawBalance();
        synthesizingAuction.withdrawBalance();
    }
}

/**
 * @title All functions related to creating Kydys
 * @author VREX Lab Co., Ltd
 */
contract KydyMinting is KydyAuction {

    // Limits of the number of Kydys that COO can create.
    uint256 public constant promoCreationLimit = 888;
    uint256 public constant gen0CreationLimit = 8888;

    uint256 public constant gen0StartingPrice = 10 finney;

    // Counts the number of Kydys that COO has created.
    uint256 public promoCreatedCount;
    uint256 public gen0CreatedCount;

    /**
     * @dev Creates promo Kydys, up to a limit. Only COO can call this function.
     * @param _genes Encoded genes of the Kydy to be created.
     * @param _owner Future owner of the created Kydys. COO is the default owner.
     */
    function createPromoKydy(uint256 _genes, address _owner) external onlyCOO {
        address kydyOwner = _owner;
        if (kydyOwner == address(0)) {
            kydyOwner = cooAddress;
        }
        require(promoCreatedCount < promoCreationLimit);

        promoCreatedCount++;
        _createKydy(0, 0, 0, _genes, kydyOwner);
    }

    /**
     * @dev Creates a new gen0 Kydy with the given genes and
     *  creates an sale auction of it.
     */
    function createGen0Auction(uint256 _genes) external onlyCOO {
        require(gen0CreatedCount < gen0CreationLimit);

        uint256 kydyId = _createKydy(0, 0, 0, _genes, address(this));
        _approve(kydyId, saleAuction);

        saleAuction.createAuction(
            kydyId,
            _computeNextGen0Price(),
            address(this)
        );

        gen0CreatedCount++;
    }

    /**
     * @dev Computes the next gen0 auction price. It will be
     *  the average of the past 5 prices + 50%.
     */
    function _computeNextGen0Price() internal view returns (uint256) {
        uint256 averagePrice = saleAuction.averageGen0SalePrice();

        // Sanity check to ensure not to overflow arithmetic.
        require(averagePrice == uint256(uint128(averagePrice)));

        uint256 nextPrice = averagePrice.add(averagePrice / 2);

        // New gen0 auction price will not be less than the
        // starting price always.
        if (nextPrice < gen0StartingPrice) {
            nextPrice = gen0StartingPrice;
        }

        return nextPrice;
    }
}

contract KydyTravelInterface {
    function balanceOfUnclaimedTT(address _user) public view returns(uint256);
    function transferTTProduction(address _from, address _to, uint256 _kydyId) public;
    function getProductionOf(address _user) public view returns (uint256);
}

/**
 * @title The Dyverse : A decentralized universe of Kydys, the unique 3D characters and avatars on the Blockchain.
 * @author VREX Lab Co., Ltd
 * @dev This is the main KydyCore contract. It keeps track of the kydys over the blockchain, and manages
 *  general operation of the contracts, metadata and important addresses, including defining who can withdraw 
 *  the balance from the contract.
 */
contract KydyCore is KydyMinting {

    // This is the main Kydy contract. To keep the code upgradable and secure, we broke up the code in two different ways.  
    // First, we separated auction and gene combination functions into several sibling contracts. This allows us to securely 
    // fix bugs and upgrade contracts, if necessary. Please note that while we try to make most code open source, 
    // some code regarding gene combination is not open-source to make it more intriguing for users. 
    // However, as always, advanced users will be able to figure out how it works. 
    //
    // We also break the core function into a few files, having one contract for each of the major functionalities of the Dyverse. 
    // The breakdown is as follows:
    //
    //      - KydyBase: This contract defines the most fundamental core functionalities, including data storage and management.
    //
    //      - KydyAccessControl: This contract manages the roles, addresses and constraints for CEO, CFO and COO.
    //
    //      - KydyOwnership: This contract provides the methods required for basic non-fungible token transactions.
    //
    //      - KydySynthesis: This contract contains how new baby Kydy is created via a process called the Synthesis. 
    //
    //      - KydyAuction: This contract manages auction creation and bidding. 
    //
    //      - KydyMinting: This contract defines how we create new Generation 0 Kydys. There is a limit of 8,888 Gen 0 Kydys. 

    // Upgraded version of the core contract.
    // Should be used when the core contract is broken and an upgrade is required.
    address public newContractAddress;

    /// @notice Creates the main Kydy smart contract instance.
    constructor() public {
        // Starts with the contract is paused.
        paused = true;

        // The creator of the contract is the initial CEO
        ceoAddress = msg.sender;

        // Starts with the Kydy ID 0 which is invalid one.
        // So we don't have generation-0 parent issues.
        _createKydy(0, 0, 0, uint256(-1), address(0));
    }

    /**
     * @dev Used to mark the smart contract as upgraded when an upgrade happens. 
     * @param _v2Address Upgraded version of the core contract.
     */
    function setNewAddress(address _v2Address) external onlyCEO whenPaused {
        // We'll announce if the upgrade is needed.
        newContractAddress = _v2Address;
        emit ContractUpgrade(_v2Address);
    }

    /**
     * @dev Rejects all Ether being sent from unregistered addresses, so that users don't accidentally end us Ether.
     */
    function() external payable {
        require(
            msg.sender == address(saleAuction) ||
            msg.sender == address(synthesizingAuction)
        );
    }

    /**
     * @notice Returns all info about a given Kydy. 
     * @param _id ID of the Kydy you are enquiring about. 
     */
    function getKydy(uint256 _id)
        external
        view
        returns (
        bool isCreating,
        bool isReady,
        uint256 rechargeIndex,
        uint256 nextActionAt,
        uint256 synthesizingWithId,
        uint256 createdTime,
        uint256 yinId,
        uint256 yangId,
        uint256 generation,
        uint256 genes
    ) {
        Kydy storage kyd = kydys[_id];

        // If this is setted to 0 then it's not at creating mode.
        isCreating = (kyd.synthesizingWithId != 0);
        isReady = (kyd.rechargeEndBlock <= block.number);
        rechargeIndex = uint256(kyd.rechargeIndex);
        nextActionAt = uint256(kyd.rechargeEndBlock);
        synthesizingWithId = uint256(kyd.synthesizingWithId);
        createdTime = uint256(kyd.createdTime);
        yinId = uint256(kyd.yinId);
        yangId = uint256(kyd.yangId);
        generation = uint256(kyd.generation);
        genes = kyd.genes;
    }

    /**
     * @dev Overrides unpause() to make sure that all external contract addresses are set before unpause. 
     * @notice This should be public rather than external.
     */
    function unpause() public onlyCEO whenPaused {
        require(saleAuction != address(0));
        require(synthesizingAuction != address(0));
        require(geneSynthesis != address(0));
        require(newContractAddress == address(0));

        // Now the contract actually unpauses.
        super.unpause();
    }

    /// @dev CFO can withdraw the balance available from the contract.
    function withdrawBalance() external onlyCFO {
        uint256 balance = address(this).balance;

        // Subtracts all creation fees needed to be given to the bringKydyHome() callers,
        // and plus 1 of margin.
        uint256 subtractFees = (creatingKydys + 1) * autoCreationFee;

        if (balance > subtractFees) {
            cfoAddress.transfer(balance - subtractFees);
        }
    }

    /// @dev Sets new tokenURI API for token metadata.
    function setNewTokenURI(string _newTokenURI) external onlyCLevel {
        tokenURIBase = _newTokenURI;
    }

    // An address of Kydy Travel Plugin.
    KydyTravelInterface public travelCore;

    /**
     * @dev Adds the Kydy Travel Plugin contract to the Kydy Core contract.
     * @notice We have a plan to add some fun features to the Dyverse. 
     *  Your Kydy will travel all over our world while you carry on with your life.
     *  During their travel, they will earn some valuable coins which will then be given to you.
     *  Please stay tuned!
     */
    function setTravelCore(address _newTravelCore) external onlyCEO whenPaused {
        travelCore = KydyTravelInterface(_newTravelCore);
    }
}

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":"cfoAddress","outputs":[{"name":"","type":"address"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"promoCreatedCount","outputs":[{"name":"","type":"uint256"}],"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":"_yinId","type":"uint256"}],"name":"bringKydyHome","outputs":[{"name":"","type":"uint256"}],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"name":"to","type":"address"},{"name":"tokenId","type":"uint256"}],"name":"approve","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[],"name":"ceoAddress","outputs":[{"name":"","type":"address"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"name":"_address","type":"address"}],"name":"setGeneSynthesisAddress","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[],"name":"totalSupply","outputs":[{"name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"synthesizingAuction","outputs":[{"name":"","type":"address"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"name":"_kydyId","type":"uint256"},{"name":"_price","type":"uint256"}],"name":"createSaleAuction","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":"_id","type":"uint256"}],"name":"getKydy","outputs":[{"name":"isCreating","type":"bool"},{"name":"isReady","type":"bool"},{"name":"rechargeIndex","type":"uint256"},{"name":"nextActionAt","type":"uint256"},{"name":"synthesizingWithId","type":"uint256"},{"name":"createdTime","type":"uint256"},{"name":"yinId","type":"uint256"},{"name":"yangId","type":"uint256"},{"name":"generation","type":"uint256"},{"name":"genes","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"name":"_address","type":"address"},{"name":"_yangId","type":"uint256"}],"name":"approveSynthesizing","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"name":"_newCEO","type":"address"}],"name":"setCEO","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[{"name":"","type":"uint256"}],"name":"recharges","outputs":[{"name":"","type":"uint32"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"name":"_newCOO","type":"address"}],"name":"setCOO","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[{"name":"tokenId","type":"uint256"}],"name":"getSynthesizeApproved","outputs":[{"name":"","type":"address"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"name":"_yangId","type":"uint256"},{"name":"_yinId","type":"uint256"}],"name":"bidOnSynthesizingAuction","outputs":[],"payable":true,"stateMutability":"payable","type":"function"},{"constant":false,"inputs":[],"name":"unpause","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"name":"_newTravelCore","type":"address"}],"name":"setTravelCore","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[],"name":"gen0CreationLimit","outputs":[{"name":"","type":"uint256"}],"payable":false,"stateMutability":"view","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":false,"inputs":[{"name":"_yinId","type":"uint256"},{"name":"_yangId","type":"uint256"}],"name":"synthesizeWithAuto","outputs":[],"payable":true,"stateMutability":"payable","type":"function"},{"constant":false,"inputs":[{"name":"_newCFO","type":"address"}],"name":"setCFO","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"name":"secs","type":"uint256"}],"name":"setSecondsPerBlock","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[],"name":"paused","outputs":[{"name":"","type":"bool"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[],"name":"withdrawBalance","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[],"name":"geneSynthesis","outputs":[{"name":"","type":"address"}],"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":true,"inputs":[],"name":"newContractAddress","outputs":[{"name":"","type":"address"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"name":"_address","type":"address"}],"name":"setSaleAuctionAddress","outputs":[],"payable":false,"stateMutability":"nonpayable","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":"_v2Address","type":"address"}],"name":"setNewAddress","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[],"name":"secondsPerBlock","outputs":[{"name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[],"name":"pause","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[{"name":"_owner","type":"address"}],"name":"tokensOfOwner","outputs":[{"name":"ownerTokens","type":"uint256[]"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[],"name":"withdrawAuctionBalances","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"name":"_address","type":"address"}],"name":"setSynthesizingAuctionAddress","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[],"name":"autoCreationFee","outputs":[{"name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"symbol","outputs":[{"name":"","type":"string"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"name":"_genes","type":"uint256"},{"name":"_owner","type":"address"}],"name":"createPromoKydy","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[{"name":"_yinId","type":"uint256"},{"name":"_yangId","type":"uint256"}],"name":"canSynthesizeWith","outputs":[{"name":"","type":"bool"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"name":"_kydyId","type":"uint256"},{"name":"_price","type":"uint256"}],"name":"createSynthesizingAuction","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"name":"to","type":"address"},{"name":"approved","type":"bool"}],"name":"setApprovalForAll","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[{"name":"_kydyId","type":"uint256"}],"name":"isCreating","outputs":[{"name":"","type":"bool"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"gen0StartingPrice","outputs":[{"name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"cooAddress","outputs":[{"name":"","type":"address"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"_symbol","outputs":[{"name":"","type":"string"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"promoCreationLimit","outputs":[{"name":"","type":"uint256"}],"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":false,"inputs":[{"name":"_kydyId","type":"uint256"}],"name":"cancelSaleAuction","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"name":"_genes","type":"uint256"}],"name":"createGen0Auction","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[{"name":"tokenId","type":"uint256"}],"name":"tokenURI","outputs":[{"name":"","type":"string"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"name":"_kydyId","type":"uint256"},{"name":"_recipient","type":"address"}],"name":"rescueLostKydy","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[],"name":"_name","outputs":[{"name":"","type":"string"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"name":"_kydyId","type":"uint256"}],"name":"cancelSynthesizingAuction","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[],"name":"travelCore","outputs":[{"name":"","type":"address"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"name":"_newTokenURI","type":"string"}],"name":"setNewTokenURI","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[],"name":"saleAuction","outputs":[{"name":"","type":"address"}],"payable":false,"stateMutability":"view","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":true,"inputs":[],"name":"creatingKydys","outputs":[{"name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"gen0CreatedCount","outputs":[{"name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"name":"value","type":"uint256"}],"name":"setAutoCreationFee","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[{"name":"_kydyId","type":"uint256"}],"name":"isReadyToSynthesize","outputs":[{"name":"","type":"bool"}],"payable":false,"stateMutability":"view","type":"function"},{"inputs":[],"payable":false,"stateMutability":"nonpayable","type":"constructor"},{"payable":true,"stateMutability":"payable","type":"fallback"},{"anonymous":false,"inputs":[{"indexed":false,"name":"owner","type":"address"},{"indexed":false,"name":"yinId","type":"uint256"},{"indexed":false,"name":"yangId","type":"uint256"},{"indexed":false,"name":"rechargeEndBlock","type":"uint256"}],"name":"Creating","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"name":"owner","type":"address"},{"indexed":false,"name":"kydyId","type":"uint256"},{"indexed":false,"name":"yinId","type":"uint256"},{"indexed":false,"name":"yangId","type":"uint256"},{"indexed":false,"name":"genes","type":"uint256"}],"name":"Created","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"},{"anonymous":false,"inputs":[{"indexed":false,"name":"newContract","type":"address"}],"name":"ContractUpgrade","type":"event"}]

6002805460a060020a60ff0219169055610220604052603c6080908152607860a05261012c60c05261025860e05261070861010052610e1061012052611c2061014052613840610160526170806101805261e1006101a052620151806101c0526202a3006101e05262054600610200526200007f90600490600d6200069a565b50600f6006556040805160608101825260298082527f687474703a2f2f746573746170692e64797665722e73652f6170692f4b796479602083019081527f4d657461646174612f00000000000000000000000000000000000000000000009290930191909152620000f391600d916200073d565b506631bced02db0000600e553480156200010c57600080fd5b50620001417f01ffc9a70000000000000000000000000000000000000000000000000000000064010000000062000203810204565b620001757f80ac58cd0000000000000000000000000000000000000000000000000000000064010000000062000203810204565b620001a97f5b5e139f0000000000000000000000000000000000000000000000000000000064010000000062000203810204565b6002805460a060020a60ff0219167401000000000000000000000000000000000000000017905560008054600160a060020a03191633178155620001fc9080806000198164010000000062000270810204565b5062000846565b7fffffffff0000000000000000000000000000000000000000000000000000000080821614156200023357600080fd5b7fffffffff00000000000000000000000000000000000000000000000000000000166000908152600360205260409020805460ff19166001179055565b6000806200027d620007be565b600063ffffffff891689146200029257600080fd5b63ffffffff88168814620002a557600080fd5b61ffff87168714620002b657600080fd5b600287049250600d8361ffff161115620002cf57600d92505b505060408051610100810182528581524267ffffffffffffffff90811660208301908152600093830184815263ffffffff8c8116606086019081528c82166080870190815260a0870188815261ffff8a811660c08a019081528f821660e08b01908152600780546001810182559c528a517fa66cc928b5edb82af9bd49922954155ab7b0942694bea4ce44661d9a8736c68860028e029081019190915598517fa66cc928b5edb82af9bd49922954155ab7b0942694bea4ce44661d9a8736c689909901805498519651955194519251915167ffffffffffffffff19909916998b1699909917604060020a608060020a0319166801000000000000000096909a169590950298909817608060020a63ffffffff021916700100000000000000000000000000000000938616939093029290921760a060020a63ffffffff02191674010000000000000000000000000000000000000000918516919091021760c060020a63ffffffff0219167801000000000000000000000000000000000000000000000000968416969096029590951760e060020a61ffff0219167c01000000000000000000000000000000000000000000000000000000009186169190910217600160f060020a03167e01000000000000000000000000000000000000000000000000000000000000929094169190910292909217905590919081168114620004d757600080fd5b60608281015160808085015185516040805187815263ffffffff95861660208201529490921684830152938301939093529151600160a060020a038816927f7191c0804172ee8ac080b63e93fd6c2f26bbea256aed023d843c2a9f3dee0d3b928290030190a26200055285826401000000006200055e810204565b98975050505050505050565b6200057281640100000000620005ce810204565b156200057d57600080fd5b620005928282640100000000620005eb810204565b6040518190600160a060020a038416906000907fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef908290a45050565b600090815260086020526040902054600160a060020a0316151590565b600081815260086020526040902054600160a060020a0316156200060e57600080fd5b60008181526008602090815260408083208054600160a060020a031916600160a060020a0387169081179091558352600990915290205462000660906001640100000000620006808102620037661704565b600160a060020a0390921660009081526009602052604090209190915550565b6000828201838110156200069357600080fd5b9392505050565b6002830191839082156200072b5791602002820160005b83821115620006f757835183826101000a81548163ffffffff021916908363ffffffff1602179055509260200192600401602081600301049283019260010302620006b1565b8015620007295782816101000a81549063ffffffff0219169055600401602081600301049283019260010302620006f7565b505b506200073992915062000802565b5090565b828054600181600116156101000203166002900490600052602060002090601f016020900481019282601f106200078057805160ff1916838001178555620007b0565b82800160010185558215620007b0579182015b82811115620007b057825182559160200191906001019062000793565b506200073992915062000829565b6040805161010081018252600080825260208201819052918101829052606081018290526080810182905260a0810182905260c0810182905260e081019190915290565b6200082691905b808211156200073957805463ffffffff1916815560010162000809565b90565b6200082691905b8082111562000739576000815560010162000830565b613bd280620008566000396000f3006080604052600436106102f25763ffffffff60e060020a60003504166301ffc9a781146103225780630519ce791461036d57806305e455461461039e57806306fdde03146103c5578063081812fc1461044f5780630910c71514610467578063095ea7b31461047f5780630a0f8168146104a35780630f401cbc146104b857806318160ddd146104d9578063192ec99d146104ee57806319d70e0b1461050357806323b872dd1461051e57806324dc793f14610548578063254b1ddf146105b257806327d7874c146105d65780632b11654a146105f75780632ba73c1514610628578063380862b21461064957806339e395e2146106615780633f4ba83a1461066f5780633fe0522c14610684578063404d0e3e146106a557806342842e0e146106ba57806348e68e30146106e45780634e0a3379146106f25780635663896e146107135780635c975abb1461072b5780635fd8c7101461074057806361a4b168146107555780636352211e1461076a5780636af04a57146107825780636fbde40d1461079757806370a08231146107b857806371587988146107d95780637a7d4937146107fa5780638456cb591461080f5780638462151c1461082457806391876e57146108955780639307cdf4146108aa57806395b138f6146108cb57806395d89b41146108e0578063978f8934146108f557806398ba2453146109195780639bacf1ed14610934578063a22cb4651461094f578063aabd390414610975578063ae4d0ff71461098d578063b047fb50146109a2578063b09f1266146109b7578063b5319335146109cc578063b88d4fde146109e1578063c31f586d14610a50578063c3bea9af14610a68578063c87b56dd14610a80578063cd47f39014610a98578063d28d885214610abc578063d5f48e7614610ad1578063e07974e614610ae9578063e5af0e8914610afe578063e6cbe35114610b1e578063e985e9c514610b33578063e9c0b8e914610b5a578063f1ca941014610b6f578063f3d89c4914610b84578063fa061d4814610b9c575b601154600160a060020a03163314806103155750601254600160a060020a031633145b151561032057600080fd5b005b34801561032e57600080fd5b506103597bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1960043516610bb4565b604080519115158252519081900360200190f35b34801561037957600080fd5b50610382610be8565b60408051600160a060020a039092168252519081900360200190f35b3480156103aa57600080fd5b506103b3610bf7565b60408051918252519081900360200190f35b3480156103d157600080fd5b506103da610bfd565b6040805160208082528351818301528351919283929083019185019080838360005b838110156104145781810151838201526020016103fc565b50505050905090810190601f1680156104415780820380516001836020036101000a031916815260200191505b509250505060405180910390f35b34801561045b57600080fd5b50610382600435610c35565b34801561047357600080fd5b506103b3600435610c67565b34801561048b57600080fd5b50610320600160a060020a0360043516602435610f2d565b3480156104af57600080fd5b50610382610fe2565b3480156104c457600080fd5b50610320600160a060020a0360043516610ff1565b3480156104e557600080fd5b506103b36110a4565b3480156104fa57600080fd5b506103826110ae565b34801561050f57600080fd5b506103206004356024356110bd565b34801561052a57600080fd5b50610320600160a060020a03600435811690602435166044356111a2565b34801561055457600080fd5b50610560600435611247565b604080519a15158b5298151560208b0152898901979097526060890195909552608088019390935260a087019190915260c086015260e085015261010084015261012083015251908190036101400190f35b3480156105be57600080fd5b50610320600160a060020a03600435166024356113a8565b3480156105e257600080fd5b50610320600160a060020a0360043516611402565b34801561060357600080fd5b5061060f600435611450565b6040805163ffffffff9092168252519081900360200190f35b34801561063457600080fd5b50610320600160a060020a036004351661147d565b34801561065557600080fd5b506103826004356114cb565b6103206004356024356114fd565b34801561067b57600080fd5b5061032061169c565b34801561069057600080fd5b50610320600160a060020a0360043516611730565b3480156106b157600080fd5b506103b3611781565b3480156106c657600080fd5b50610320600160a060020a0360043581169060243516604435611787565b6103206004356024356117a3565b3480156106fe57600080fd5b50610320600160a060020a03600435166119a7565b34801561071f57600080fd5b506103206004356119f5565b34801561073757600080fd5b50610359611a51565b34801561074c57600080fd5b50610320611a61565b34801561076157600080fd5b50610382611ad5565b34801561077657600080fd5b50610382600435611ae4565b34801561078e57600080fd5b50610382611b0e565b3480156107a357600080fd5b50610320600160a060020a0360043516611b1d565b3480156107c457600080fd5b506103b3600160a060020a0360043516611bd0565b3480156107e557600080fd5b50610320600160a060020a0360043516611c03565b34801561080657600080fd5b506103b3611c86565b34801561081b57600080fd5b50610320611c8c565b34801561083057600080fd5b50610845600160a060020a0360043516611d0c565b60408051602080825283518183015283519192839290830191858101910280838360005b83811015610881578181015183820152602001610869565b505050509050019250505060405180910390f35b3480156108a157600080fd5b50610320611dde565b3480156108b657600080fd5b50610320600160a060020a0360043516611ef3565b3480156108d757600080fd5b506103b3611fa6565b3480156108ec57600080fd5b506103da611fac565b34801561090157600080fd5b50610320600435600160a060020a0360243516611fe3565b34801561092557600080fd5b50610359600435602435612044565b34801561094057600080fd5b506103206004356024356120c4565b34801561095b57600080fd5b50610320600160a060020a0360043516602435151561218e565b34801561098157600080fd5b50610359600435612212565b34801561099957600080fd5b506103b3612257565b3480156109ae57600080fd5b50610382612262565b3480156109c357600080fd5b506103da612271565b3480156109d857600080fd5b506103b36122a8565b3480156109ed57600080fd5b50604080516020601f60643560048181013592830184900484028501840190955281845261032094600160a060020a0381358116956024803590921695604435953695608494019181908401838280828437509497506122ae9650505050505050565b348015610a5c57600080fd5b506103206004356122d0565b348015610a7457600080fd5b50610320600435612421565b348015610a8c57600080fd5b506103da60043561250d565b348015610aa457600080fd5b50610320600435600160a060020a03602435166125c3565b348015610ac857600080fd5b506103da612611565b348015610add57600080fd5b50610320600435612648565b348015610af557600080fd5b50610382612799565b348015610b0a57600080fd5b5061032060048035602481019101356127a8565b348015610b2a57600080fd5b506103826127f7565b348015610b3f57600080fd5b50610359600160a060020a0360043581169060243516612806565b348015610b6657600080fd5b506103b3612834565b348015610b7b57600080fd5b506103b361283a565b348015610b9057600080fd5b50610320600435612840565b348015610ba857600080fd5b5061035960043561285c565b7bffffffffffffffffffffffffffffffffffffffffffffffffffffffff191660009081526003602052604090205460ff1690565b600154600160a060020a031681565b60135481565b60408051808201909152600781527f447976657273650000000000000000000000000000000000000000000000000060208201525b90565b6000610c408261292b565b1515610c4b57600080fd5b506000908152600a6020526040902054600160a060020a031690565b600080600080600080600080600260149054906101000a900460ff16151515610c8f57600080fd5b600780548a908110610c9d57fe5b60009182526020909120600290910201600181015490975067ffffffffffffffff161515610cca57600080fd5b604080516101008101825288548152600189015467ffffffffffffffff8082166020840152680100000000000000008204169282019290925263ffffffff608060020a83048116606083015260a060020a83048116608083015260c060020a83041660a082015261ffff60e060020a8304811660c083015260f060020a90920490911660e0820152610d5b90612948565b1515610d6657600080fd5b60018701546007805460c060020a90920463ffffffff1697509087908110610d8a57fe5b600091825260209091206001808a015460029093029091019081015490965061ffff60f060020a928390048116965091900416841015610dd757600185015460f060020a900461ffff1693505b60105487548654604080517f960fa70f0000000000000000000000000000000000000000000000000000000081526004810193909352602483019190915251600160a060020a039092169163960fa70f916044808201926020929091908290030181600087803b158015610e4a57600080fd5b505af1158015610e5e573d6000803e3d6000fd5b505050506040513d6020811015610e7457600080fd5b505160008a815260086020526040902054600189810154929550600160a060020a039091169350610ebd918b9160c060020a90910463ffffffff1690870161ffff168686612978565b6001880180547bffffffff00000000000000000000000000000000000000000000000019169055600f8054600019019055600e54604051919250339181156108fc0291906000818181858888f19350505050158015610f20573d6000803e3d6000fd5b5098975050505050505050565b60025460009060a060020a900460ff1615610f4757600080fd5b610f5082611ae4565b9050600160a060020a038381169082161415610f6b57600080fd5b33600160a060020a0382161480610f875750610f878133612806565b1515610f9257600080fd5b610f9c8284612c4b565b8183600160a060020a031682600160a060020a03167f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b92560405160405180910390a4505050565b600054600160a060020a031681565b60008054600160a060020a0316331461100957600080fd5b81905080600160a060020a0316632e39ff846040518163ffffffff1660e060020a028152600401602060405180830381600087803b15801561104a57600080fd5b505af115801561105e573d6000803e3d6000fd5b505050506040513d602081101561107457600080fd5b5051151561108157600080fd5b60108054600160a060020a031916600160a060020a039290921691909117905550565b6007546000190190565b601254600160a060020a031681565b60025460a060020a900460ff16156110d457600080fd5b6110de3383612c79565b15156110e957600080fd5b6110f282612212565b156110fc57600080fd5b601154611113908390600160a060020a0316612c4b565b601154604080517f54279bdd00000000000000000000000000000000000000000000000000000000815260048101859052602481018490523360448201529051600160a060020a03909216916354279bdd9160648082019260009290919082900301818387803b15801561118657600080fd5b505af115801561119a573d6000803e3d6000fd5b505050505050565b60025460a060020a900460ff16156111b957600080fd5b6111c33382612c99565b15156111ce57600080fd5b600160a060020a03821615156111e357600080fd5b6111ed8382612cf8565b6111f78382612d94565b6112018282612e1d565b8082600160a060020a031684600160a060020a03167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef60405160405180910390a4505050565b600080600080600080600080600080600060078c81548110151561126757fe5b906000526020600020906002020190508060010160189054906101000a900463ffffffff1663ffffffff16600014159a50438160010160089054906101000a900467ffffffffffffffff1667ffffffffffffffff161115995080600101601c9054906101000a900461ffff1661ffff1698508060010160089054906101000a900467ffffffffffffffff1667ffffffffffffffff1697508060010160189054906101000a900463ffffffff1663ffffffff1696508060010160009054906101000a900467ffffffffffffffff1667ffffffffffffffff1695508060010160109054906101000a900463ffffffff1663ffffffff1694508060010160149054906101000a900463ffffffff1663ffffffff16935080600101601e9054906101000a900461ffff1661ffff16925080600001549150509193959799509193959799565b60025460a060020a900460ff16156113bf57600080fd5b6113c93382612c79565b15156113d457600080fd5b6000908152600b602052604090208054600160a060020a031916600160a060020a0392909216919091179055565b600054600160a060020a0316331461141957600080fd5b600160a060020a038116151561142e57600080fd5b60008054600160a060020a031916600160a060020a0392909216919091179055565b600481600e811061145d57fe5b60089182820401919006600402915054906101000a900463ffffffff1681565b600054600160a060020a0316331461149457600080fd5b600160a060020a03811615156114a957600080fd5b60028054600160a060020a031916600160a060020a0392909216919091179055565b60006114d68261292b565b15156114e157600080fd5b506000908152600b6020526040902054600160a060020a031690565b60025460009060a060020a900460ff161561151757600080fd5b6115213383612c79565b151561152c57600080fd5b6115358261285c565b151561154057600080fd5b61154a8284612ea1565b151561155557600080fd5b601254604080517fc55d0f56000000000000000000000000000000000000000000000000000000008152600481018690529051600160a060020a039092169163c55d0f56916024808201926020929091908290030181600087803b1580156115bc57600080fd5b505af11580156115d0573d6000803e3d6000fd5b505050506040513d60208110156115e657600080fd5b5051600e5490915081013410156115fc57600080fd5b601254600e54604080517f454a2ab3000000000000000000000000000000000000000000000000000000008152600481018790529051600160a060020a039093169263454a2ab39234039160248082019260009290919082900301818588803b15801561166857600080fd5b505af115801561167c573d6000803e3d6000fd5b50505050506116978263ffffffff168463ffffffff16612ef0565b505050565b600054600160a060020a031633146116b357600080fd5b60025460a060020a900460ff1615156116cb57600080fd5b601154600160a060020a031615156116e257600080fd5b601254600160a060020a031615156116f957600080fd5b601054600160a060020a0316151561171057600080fd5b601554600160a060020a03161561172657600080fd5b61172e61302e565b565b600054600160a060020a0316331461174757600080fd5b60025460a060020a900460ff16151561175f57600080fd5b60168054600160a060020a031916600160a060020a0392909216919091179055565b6122b881565b61169783838360206040519081016040528060008152506122ae565b600254600090819060a060020a900460ff16156117bf57600080fd5b600e543410156117ce57600080fd5b6117d83385612c79565b15156117e357600080fd5b6117ed838561307d565b15156117f857600080fd5b600780548590811061180657fe5b60009182526020918290206040805161010081018252600290930290910180548352600181015467ffffffffffffffff808216958501959095526801000000000000000081049094169183019190915263ffffffff608060020a84048116606084015260a060020a84048116608084015260c060020a84041660a083015261ffff60e060020a8404811660c084015260f060020a90930490921660e08201529092506118b1906130d2565b15156118bc57600080fd5b60078054849081106118ca57fe5b60009182526020918290206040805161010081018252600290930290910180548352600181015467ffffffffffffffff808216958501959095526801000000000000000081049094169183019190915263ffffffff608060020a84048116606084015260a060020a84048116608084015260c060020a84041660a083015261ffff60e060020a8404811660c084015260f060020a90930490921660e0820152909150611975906130d2565b151561198057600080fd5b61198c82858386613101565b151561199757600080fd5b6119a18484612ef0565b50505050565b600054600160a060020a031633146119be57600080fd5b600160a060020a03811615156119d357600080fd5b60018054600160a060020a031916600160a060020a0392909216919091179055565b600054600160a060020a0316331480611a185750600154600160a060020a031633145b80611a2d5750600254600160a060020a031633145b1515611a3857600080fd5b60045463ffffffff168110611a4c57600080fd5b600655565b60025460a060020a900460ff1681565b6001546000908190600160a060020a03163314611a7d57600080fd5b5050600e54600f5430319160019091010280821115611ad157600154604051600160a060020a039091169082840380156108fc02916000818181858888f19350505050158015611697573d6000803e3d6000fd5b5050565b601054600160a060020a031681565b600081815260086020526040812054600160a060020a0316801515611b0857600080fd5b92915050565b601554600160a060020a031681565b60008054600160a060020a03163314611b3557600080fd5b81905080600160a060020a031663d25c07676040518163ffffffff1660e060020a028152600401602060405180830381600087803b158015611b7657600080fd5b505af1158015611b8a573d6000803e3d6000fd5b505050506040513d6020811015611ba057600080fd5b50511515611bad57600080fd5b60118054600160a060020a031916600160a060020a039290921691909117905550565b6000600160a060020a0382161515611be757600080fd5b50600160a060020a031660009081526009602052604090205490565b600054600160a060020a03163314611c1a57600080fd5b60025460a060020a900460ff161515611c3257600080fd5b60158054600160a060020a038316600160a060020a0319909116811790915560408051918252517f450db8da6efbe9c22f2347f7c2021231df1fc58d3ae9a2fa75d39fa4461993059181900360200190a150565b60065481565b600054600160a060020a0316331480611caf5750600154600160a060020a031633145b80611cc45750600254600160a060020a031633145b1515611ccf57600080fd5b60025460a060020a900460ff1615611ce657600080fd5b6002805474ff0000000000000000000000000000000000000000191660a060020a179055565b6060600060606000806000611d2087611bd0565b9450841515611d3f576040805160008152602081019091529550611dd4565b84604051908082528060200260200182016040528015611d69578160200160208202803883390190505b509350611d746110a4565b925060009150600190505b828111611dd057600081815260086020526040902054600160a060020a0388811691161415611dc857808483815181101515611db757fe5b602090810290910101526001909101905b600101611d7f565b8395505b5050505050919050565b600054600160a060020a0316331480611e015750600154600160a060020a031633145b80611e165750600254600160a060020a031633145b1515611e2157600080fd5b601160009054906101000a9004600160a060020a0316600160a060020a0316635fd8c7106040518163ffffffff1660e060020a028152600401600060405180830381600087803b158015611e7457600080fd5b505af1158015611e88573d6000803e3d6000fd5b50505050601260009054906101000a9004600160a060020a0316600160a060020a0316635fd8c7106040518163ffffffff1660e060020a028152600401600060405180830381600087803b158015611edf57600080fd5b505af11580156119a1573d6000803e3d6000fd5b60008054600160a060020a03163314611f0b57600080fd5b81905080600160a060020a031663994b2dd06040518163ffffffff1660e060020a028152600401602060405180830381600087803b158015611f4c57600080fd5b505af1158015611f60573d6000803e3d6000fd5b505050506040513d6020811015611f7657600080fd5b50511515611f8357600080fd5b60128054600160a060020a031916600160a060020a039290921691909117905550565b600e5481565b60408051808201909152600481527f4b59445900000000000000000000000000000000000000000000000000000000602082015290565b600254600090600160a060020a03163314611ffd57600080fd5b5080600160a060020a038116151561201d5750600254600160a060020a03165b6013546103781161202d57600080fd5b6013805460010190556119a1600080808685612978565b6000808080851161205457600080fd5b6000841161206157600080fd5b600780548690811061206f57fe5b9060005260206000209060020201915060078481548110151561208e57fe5b906000526020600020906002020190506120aa82868387613101565b80156120bb57506120bb848661307d565b95945050505050565b60025460a060020a900460ff16156120db57600080fd5b6120e53383612c79565b15156120f057600080fd5b6120f98261285c565b151561210457600080fd5b60125461211b908390600160a060020a0316612c4b565b601254604080517f54279bdd00000000000000000000000000000000000000000000000000000000815260048101859052602481018490523360448201529051600160a060020a03909216916354279bdd9160648082019260009290919082900301818387803b15801561118657600080fd5b600160a060020a0382163314156121a457600080fd5b336000818152600c60209081526040808320600160a060020a03871680855290835292819020805460ff1916861515908117909155815190815290519293927f17307eab39ab6107e8899845ad3d59bd9653f200f220920489ca2b5937696c31929181900390910190a35050565b600080821161222057600080fd5b600780548390811061222e57fe5b600091825260209091206002909102016001015460c060020a900463ffffffff16151592915050565b662386f26fc1000081565b600254600160a060020a031681565b60408051808201909152600481527f4b59445900000000000000000000000000000000000000000000000000000000602082015281565b61037881565b6122b98484846111a2565b6122c584848484613280565b15156119a157600080fd5b60025460009060a060020a900460ff16156122ea57600080fd5b60115461230090600160a060020a031683612c79565b151561230b57600080fd5b601154604080517f78bd7935000000000000000000000000000000000000000000000000000000008152600481018590529051600160a060020a03909216916378bd7935916024808201926060929091908290030181600087803b15801561237257600080fd5b505af1158015612386573d6000803e3d6000fd5b505050506040513d606081101561239c57600080fd5b5051905033600160a060020a038216146123b557600080fd5b601154604080517f4e8eaa13000000000000000000000000000000000000000000000000000000008152600481018590523360248201529051600160a060020a0390921691634e8eaa139160448082019260009290919082900301818387803b15801561118657600080fd5b600254600090600160a060020a0316331461243b57600080fd5b6014546122b81161244b57600080fd5b61245a60008060008530612978565b601154909150612474908290600160a060020a0316612c4b565b601154600160a060020a03166354279bdd8261248e613402565b306040518463ffffffff1660e060020a0281526004018084815260200183815260200182600160a060020a0316600160a060020a031681526020019350505050600060405180830381600087803b1580156124e857600080fd5b505af11580156124fc573d6000803e3d6000fd5b505060148054600101905550505050565b60606125188261292b565b151561252357600080fd5b600d8054604080516020601f60026000196101006001881615020190951694909404938401819004810282018101909252828152611b0893909290918301828280156125b05780601f10612585576101008083540402835291602001916125b0565b820191906000526020600020905b81548152906001019060200180831161259357829003601f168201915b50505050506125be846134d3565b6135c6565b600254600160a060020a031633146125da57600080fd5b60025460a060020a900460ff16156125f157600080fd5b6125fb3083612c79565b151561260657600080fd5b611ad13082846135fb565b60408051808201909152600781527f4479766572736500000000000000000000000000000000000000000000000000602082015281565b60025460009060a060020a900460ff161561266257600080fd5b60125461267890600160a060020a031683612c79565b151561268357600080fd5b601254604080517f78bd7935000000000000000000000000000000000000000000000000000000008152600481018590529051600160a060020a03909216916378bd7935916024808201926060929091908290030181600087803b1580156126ea57600080fd5b505af11580156126fe573d6000803e3d6000fd5b505050506040513d606081101561271457600080fd5b5051905033600160a060020a0382161461272d57600080fd5b601254604080517f4e8eaa13000000000000000000000000000000000000000000000000000000008152600481018590523360248201529051600160a060020a0390921691634e8eaa139160448082019260009290919082900301818387803b15801561118657600080fd5b601654600160a060020a031681565b600054600160a060020a03163314806127cb5750600154600160a060020a031633145b806127e05750600254600160a060020a031633145b15156127eb57600080fd5b611697600d8383613aca565b601154600160a060020a031681565b600160a060020a039182166000908152600c6020908152604080832093909416825291909152205460ff1690565b600f5481565b60145481565b600254600160a060020a0316331461285757600080fd5b600e55565b60008080831161286b57600080fd5b600780548490811061287957fe5b60009182526020918290206040805161010081018252600290930290910180548352600181015467ffffffffffffffff808216958501959095526801000000000000000081049094169183019190915263ffffffff608060020a84048116606084015260a060020a84048116608084015260c060020a84041660a083015261ffff60e060020a8404811660c084015260f060020a90930490921660e0820152909150612924906130d2565b9392505050565b600090815260086020526040902054600160a060020a0316151590565b60008160a0015163ffffffff16600014158015611b085750506040015167ffffffffffffffff4381169116111590565b600080612983613b48565b600063ffffffff8916891461299757600080fd5b63ffffffff881688146129a957600080fd5b61ffff871687146129b957600080fd5b600287049250600d8361ffff1611156129d157600d92505b505060408051610100810182528581524267ffffffffffffffff90811660208301908152600093830184815263ffffffff8c8116606086019081528c82166080870190815260a0870188815261ffff8a811660c08a019081528f821660e08b01908152600780546001810182559c528a517fa66cc928b5edb82af9bd49922954155ab7b0942694bea4ce44661d9a8736c68860028e029081019190915598517fa66cc928b5edb82af9bd49922954155ab7b0942694bea4ce44661d9a8736c689909901805498519651955194519251915167ffffffffffffffff19909916998b16999099176fffffffffffffffff000000000000000019166801000000000000000096909a16959095029890981773ffffffff000000000000000000000000000000001916608060020a938616939093029290921777ffffffff0000000000000000000000000000000000000000191660a060020a91851691909102177bffffffff000000000000000000000000000000000000000000000000191660c060020a96841696909602959095177fffff0000ffffffffffffffffffffffffffffffffffffffffffffffffffffffff1660e060020a91861691909102177dffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1660f060020a929094169190910292909217905590919081168114612bcf57600080fd5b60608281015160808085015185516040805187815263ffffffff95861660208201529490921684830152938301939093529151600160a060020a038816927f7191c0804172ee8ac080b63e93fd6c2f26bbea256aed023d843c2a9f3dee0d3b928290030190a2612c3f85826136f6565b98975050505050505050565b6000918252600a60205260409091208054600160a060020a031916600160a060020a03909216919091179055565b600090815260086020526040902054600160a060020a0391821691161490565b600080612ca583611ae4565b905080600160a060020a031684600160a060020a03161480612ce0575083600160a060020a0316612cd584610c35565b600160a060020a0316145b80612cf05750612cf08185612806565b949350505050565b81600160a060020a0316612d0b82611ae4565b600160a060020a031614612d1e57600080fd5b6000818152600a6020526040902054600160a060020a031615612d58576000818152600a602052604090208054600160a060020a03191690555b6000818152600b6020526040902054600160a060020a031615611ad1576000908152600b602052604090208054600160a060020a031916905550565b81600160a060020a0316612da782611ae4565b600160a060020a031614612dba57600080fd5b600160a060020a038216600090815260096020526040902054612de490600163ffffffff61374f16565b600160a060020a039092166000908152600960209081526040808320949094559181526008909152208054600160a060020a0319169055565b600081815260086020526040902054600160a060020a031615612e3f57600080fd5b60008181526008602090815260408083208054600160a060020a031916600160a060020a03871690811790915583526009909152902054612e81906001613766565b600160a060020a0390921660009081526009602052604090209190915550565b6000806000600785815481101515612eb557fe5b90600052602060002090600202019150600784815481101515612ed457fe5b906000526020600020906002020190506120bb82868387613101565b600080600783815481101515612f0257fe5b90600052602060002090600202019150600784815481101515612f2157fe5b600091825260209091206002909102016001810180547bffffffff000000000000000000000000000000000000000000000000191660c060020a63ffffffff8716021790559050612f7182613778565b612f7a81613778565b6000848152600b602090815260408083208054600160a060020a031990811690915586845281842080549091169055600f80546001908101909155878452600883529281902054928401548151600160a060020a0390941684529183018790528281018690526801000000000000000090910467ffffffffffffffff166060830152517f0424154dc3e27f052d934e01126bedb53185fe060b7bcf8799972a1c8b7015ff916080908290030190a150505050565b600054600160a060020a0316331461304557600080fd5b60025460a060020a900460ff16151561305d57600080fd5b6002805474ff000000000000000000000000000000000000000019169055565b6000818152600860205260408082205484835290822054600160a060020a039182169116808214806120bb57506000858152600b6020526040902054600160a060020a03908116908316149250505092915050565b60008160a0015163ffffffff166000148015611b085750506040015167ffffffffffffffff4381169116111590565b60008184141561311357506000612cf0565b6001850154608060020a900463ffffffff168214806131425750600185015460a060020a900463ffffffff1682145b1561314f57506000612cf0565b6001830154608060020a900463ffffffff1684148061317e5750600183015460a060020a900463ffffffff1684145b1561318b57506000612cf0565b6001830154608060020a900463ffffffff1615806131b857506001850154608060020a900463ffffffff16155b156131c557506001612cf0565b60018581015490840154608060020a9182900463ffffffff90811692909104161480613210575060018086015490840154608060020a900463ffffffff90811660a060020a90920416145b1561321d57506000612cf0565b6001808601549084015460a060020a900463ffffffff908116608060020a90920416148061326857506001858101549084015460a060020a9182900463ffffffff9081169290910416145b1561327557506000612cf0565b506001949350505050565b60008061329585600160a060020a0316613861565b15156132a457600191506133f9565b6040517f150b7a020000000000000000000000000000000000000000000000000000000081523360048201818152600160a060020a03898116602485015260448401889052608060648501908152875160848601528751918a169463150b7a0294938c938b938b93909160a490910190602085019080838360005b8381101561333757818101518382015260200161331f565b50505050905090810190601f1680156133645780820380516001836020036101000a031916815260200191505b5095505050505050602060405180830381600087803b15801561338657600080fd5b505af115801561339a573d6000803e3d6000fd5b505050506040513d60208110156133b057600080fd5b50517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1981167f150b7a020000000000000000000000000000000000000000000000000000000014925090505b50949350505050565b6000806000601160009054906101000a9004600160a060020a0316600160a060020a031663eac9d94c6040518163ffffffff1660e060020a028152600401602060405180830381600087803b15801561345a57600080fd5b505af115801561346e573d6000803e3d6000fd5b505050506040513d602081101561348457600080fd5b505191506fffffffffffffffffffffffffffffffff821682146134a657600080fd5b6134b38260028104613766565b9050662386f26fc10000811015611b085750662386f26fc1000092915050565b6060600080828185151561351c5760408051808201909152600181527f3000000000000000000000000000000000000000000000000000000000000000602082015294506135bd565b8593505b831561353757600190920191600a84049350613520565b826040519080825280601f01601f191660200182016040528015613565578160200160208202803883390190505b5091505060001982015b85156135b957815160001982019160f860020a6030600a8a06010291849190811061359657fe5b906020010190600160f860020a031916908160001a905350600a8604955061356f565b8194505b50505050919050565b604080516020818101835260008083528351808301855281815284519283019094528152606092612924928692869290613869565b600160a060020a03821660009081526009602052604090205461362590600163ffffffff61376616565b600160a060020a03808416600081815260096020818152604080842096909655868352600881528583208054600160a060020a0319169094179093559287168152919052205461367c90600163ffffffff61374f16565b600160a060020a03808516600081815260096020908152604080832095909555858252600b81528482208054600160a060020a0319908116909155600a9091528482208054909116905592518493928616927fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef91a4505050565b6136ff8161292b565b1561370957600080fd5b6137138282612e1d565b6040518190600160a060020a038416906000907fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef908290a45050565b6000808383111561375f57600080fd5b5050900390565b60008282018381101561292457600080fd5b600654600182015443919060049060e060020a900461ffff16600e811061379b57fe5b600891828204019190066004029054906101000a900463ffffffff1663ffffffff168115156137c657fe5b6001840180546fffffffffffffffff0000000000000000191668010000000000000000939092049390930167ffffffffffffffff16919091021790819055600c60e060020a90910461ffff16101561385e576001818101805461ffff60e060020a8083048216909401169092027fffff0000ffffffffffffffffffffffffffffffffffffffffffffffffffffffff9092169190911790555b50565b6000903b1190565b6060806060806060806060806000808e98508d97508c96508b95508a94508451865188518a518c51010101016040519080825280601f01601f1916602001820160405280156138c2578160200160208202803883390190505b50935083925060009150600090505b885181101561392f5788818151811015156138e857fe5b90602001015160f860020a900460f860020a02838380600101945081518110151561390f57fe5b906020010190600160f860020a031916908160001a9053506001016138d1565b5060005b875181101561399157878181518110151561394a57fe5b90602001015160f860020a900460f860020a02838380600101945081518110151561397157fe5b906020010190600160f860020a031916908160001a905350600101613933565b5060005b86518110156139f35786818151811015156139ac57fe5b90602001015160f860020a900460f860020a0283838060010194508151811015156139d357fe5b906020010190600160f860020a031916908160001a905350600101613995565b5060005b8551811015613a55578581815181101515613a0e57fe5b90602001015160f860020a900460f860020a028383806001019450815181101515613a3557fe5b906020010190600160f860020a031916908160001a9053506001016139f7565b5060005b8451811015613ab7578481815181101515613a7057fe5b90602001015160f860020a900460f860020a028383806001019450815181101515613a9757fe5b906020010190600160f860020a031916908160001a905350600101613a59565b50909d9c50505050505050505050505050565b828054600181600116156101000203166002900490600052602060002090601f016020900481019282601f10613b0b5782800160ff19823516178555613b38565b82800160010185558215613b38579182015b82811115613b38578235825591602001919060010190613b1d565b50613b44929150613b8c565b5090565b6040805161010081018252600080825260208201819052918101829052606081018290526080810182905260a0810182905260c0810182905260e081019190915290565b610c3291905b80821115613b445760008155600101613b925600a165627a7a72305820984728e95ce5f0c01a687d1e7a73daa4abbc56d2875bd49459d0d51c1a2448050029

Deployed Bytecode

0x6080604052600436106102f25763ffffffff60e060020a60003504166301ffc9a781146103225780630519ce791461036d57806305e455461461039e57806306fdde03146103c5578063081812fc1461044f5780630910c71514610467578063095ea7b31461047f5780630a0f8168146104a35780630f401cbc146104b857806318160ddd146104d9578063192ec99d146104ee57806319d70e0b1461050357806323b872dd1461051e57806324dc793f14610548578063254b1ddf146105b257806327d7874c146105d65780632b11654a146105f75780632ba73c1514610628578063380862b21461064957806339e395e2146106615780633f4ba83a1461066f5780633fe0522c14610684578063404d0e3e146106a557806342842e0e146106ba57806348e68e30146106e45780634e0a3379146106f25780635663896e146107135780635c975abb1461072b5780635fd8c7101461074057806361a4b168146107555780636352211e1461076a5780636af04a57146107825780636fbde40d1461079757806370a08231146107b857806371587988146107d95780637a7d4937146107fa5780638456cb591461080f5780638462151c1461082457806391876e57146108955780639307cdf4146108aa57806395b138f6146108cb57806395d89b41146108e0578063978f8934146108f557806398ba2453146109195780639bacf1ed14610934578063a22cb4651461094f578063aabd390414610975578063ae4d0ff71461098d578063b047fb50146109a2578063b09f1266146109b7578063b5319335146109cc578063b88d4fde146109e1578063c31f586d14610a50578063c3bea9af14610a68578063c87b56dd14610a80578063cd47f39014610a98578063d28d885214610abc578063d5f48e7614610ad1578063e07974e614610ae9578063e5af0e8914610afe578063e6cbe35114610b1e578063e985e9c514610b33578063e9c0b8e914610b5a578063f1ca941014610b6f578063f3d89c4914610b84578063fa061d4814610b9c575b601154600160a060020a03163314806103155750601254600160a060020a031633145b151561032057600080fd5b005b34801561032e57600080fd5b506103597bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1960043516610bb4565b604080519115158252519081900360200190f35b34801561037957600080fd5b50610382610be8565b60408051600160a060020a039092168252519081900360200190f35b3480156103aa57600080fd5b506103b3610bf7565b60408051918252519081900360200190f35b3480156103d157600080fd5b506103da610bfd565b6040805160208082528351818301528351919283929083019185019080838360005b838110156104145781810151838201526020016103fc565b50505050905090810190601f1680156104415780820380516001836020036101000a031916815260200191505b509250505060405180910390f35b34801561045b57600080fd5b50610382600435610c35565b34801561047357600080fd5b506103b3600435610c67565b34801561048b57600080fd5b50610320600160a060020a0360043516602435610f2d565b3480156104af57600080fd5b50610382610fe2565b3480156104c457600080fd5b50610320600160a060020a0360043516610ff1565b3480156104e557600080fd5b506103b36110a4565b3480156104fa57600080fd5b506103826110ae565b34801561050f57600080fd5b506103206004356024356110bd565b34801561052a57600080fd5b50610320600160a060020a03600435811690602435166044356111a2565b34801561055457600080fd5b50610560600435611247565b604080519a15158b5298151560208b0152898901979097526060890195909552608088019390935260a087019190915260c086015260e085015261010084015261012083015251908190036101400190f35b3480156105be57600080fd5b50610320600160a060020a03600435166024356113a8565b3480156105e257600080fd5b50610320600160a060020a0360043516611402565b34801561060357600080fd5b5061060f600435611450565b6040805163ffffffff9092168252519081900360200190f35b34801561063457600080fd5b50610320600160a060020a036004351661147d565b34801561065557600080fd5b506103826004356114cb565b6103206004356024356114fd565b34801561067b57600080fd5b5061032061169c565b34801561069057600080fd5b50610320600160a060020a0360043516611730565b3480156106b157600080fd5b506103b3611781565b3480156106c657600080fd5b50610320600160a060020a0360043581169060243516604435611787565b6103206004356024356117a3565b3480156106fe57600080fd5b50610320600160a060020a03600435166119a7565b34801561071f57600080fd5b506103206004356119f5565b34801561073757600080fd5b50610359611a51565b34801561074c57600080fd5b50610320611a61565b34801561076157600080fd5b50610382611ad5565b34801561077657600080fd5b50610382600435611ae4565b34801561078e57600080fd5b50610382611b0e565b3480156107a357600080fd5b50610320600160a060020a0360043516611b1d565b3480156107c457600080fd5b506103b3600160a060020a0360043516611bd0565b3480156107e557600080fd5b50610320600160a060020a0360043516611c03565b34801561080657600080fd5b506103b3611c86565b34801561081b57600080fd5b50610320611c8c565b34801561083057600080fd5b50610845600160a060020a0360043516611d0c565b60408051602080825283518183015283519192839290830191858101910280838360005b83811015610881578181015183820152602001610869565b505050509050019250505060405180910390f35b3480156108a157600080fd5b50610320611dde565b3480156108b657600080fd5b50610320600160a060020a0360043516611ef3565b3480156108d757600080fd5b506103b3611fa6565b3480156108ec57600080fd5b506103da611fac565b34801561090157600080fd5b50610320600435600160a060020a0360243516611fe3565b34801561092557600080fd5b50610359600435602435612044565b34801561094057600080fd5b506103206004356024356120c4565b34801561095b57600080fd5b50610320600160a060020a0360043516602435151561218e565b34801561098157600080fd5b50610359600435612212565b34801561099957600080fd5b506103b3612257565b3480156109ae57600080fd5b50610382612262565b3480156109c357600080fd5b506103da612271565b3480156109d857600080fd5b506103b36122a8565b3480156109ed57600080fd5b50604080516020601f60643560048181013592830184900484028501840190955281845261032094600160a060020a0381358116956024803590921695604435953695608494019181908401838280828437509497506122ae9650505050505050565b348015610a5c57600080fd5b506103206004356122d0565b348015610a7457600080fd5b50610320600435612421565b348015610a8c57600080fd5b506103da60043561250d565b348015610aa457600080fd5b50610320600435600160a060020a03602435166125c3565b348015610ac857600080fd5b506103da612611565b348015610add57600080fd5b50610320600435612648565b348015610af557600080fd5b50610382612799565b348015610b0a57600080fd5b5061032060048035602481019101356127a8565b348015610b2a57600080fd5b506103826127f7565b348015610b3f57600080fd5b50610359600160a060020a0360043581169060243516612806565b348015610b6657600080fd5b506103b3612834565b348015610b7b57600080fd5b506103b361283a565b348015610b9057600080fd5b50610320600435612840565b348015610ba857600080fd5b5061035960043561285c565b7bffffffffffffffffffffffffffffffffffffffffffffffffffffffff191660009081526003602052604090205460ff1690565b600154600160a060020a031681565b60135481565b60408051808201909152600781527f447976657273650000000000000000000000000000000000000000000000000060208201525b90565b6000610c408261292b565b1515610c4b57600080fd5b506000908152600a6020526040902054600160a060020a031690565b600080600080600080600080600260149054906101000a900460ff16151515610c8f57600080fd5b600780548a908110610c9d57fe5b60009182526020909120600290910201600181015490975067ffffffffffffffff161515610cca57600080fd5b604080516101008101825288548152600189015467ffffffffffffffff8082166020840152680100000000000000008204169282019290925263ffffffff608060020a83048116606083015260a060020a83048116608083015260c060020a83041660a082015261ffff60e060020a8304811660c083015260f060020a90920490911660e0820152610d5b90612948565b1515610d6657600080fd5b60018701546007805460c060020a90920463ffffffff1697509087908110610d8a57fe5b600091825260209091206001808a015460029093029091019081015490965061ffff60f060020a928390048116965091900416841015610dd757600185015460f060020a900461ffff1693505b60105487548654604080517f960fa70f0000000000000000000000000000000000000000000000000000000081526004810193909352602483019190915251600160a060020a039092169163960fa70f916044808201926020929091908290030181600087803b158015610e4a57600080fd5b505af1158015610e5e573d6000803e3d6000fd5b505050506040513d6020811015610e7457600080fd5b505160008a815260086020526040902054600189810154929550600160a060020a039091169350610ebd918b9160c060020a90910463ffffffff1690870161ffff168686612978565b6001880180547bffffffff00000000000000000000000000000000000000000000000019169055600f8054600019019055600e54604051919250339181156108fc0291906000818181858888f19350505050158015610f20573d6000803e3d6000fd5b5098975050505050505050565b60025460009060a060020a900460ff1615610f4757600080fd5b610f5082611ae4565b9050600160a060020a038381169082161415610f6b57600080fd5b33600160a060020a0382161480610f875750610f878133612806565b1515610f9257600080fd5b610f9c8284612c4b565b8183600160a060020a031682600160a060020a03167f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b92560405160405180910390a4505050565b600054600160a060020a031681565b60008054600160a060020a0316331461100957600080fd5b81905080600160a060020a0316632e39ff846040518163ffffffff1660e060020a028152600401602060405180830381600087803b15801561104a57600080fd5b505af115801561105e573d6000803e3d6000fd5b505050506040513d602081101561107457600080fd5b5051151561108157600080fd5b60108054600160a060020a031916600160a060020a039290921691909117905550565b6007546000190190565b601254600160a060020a031681565b60025460a060020a900460ff16156110d457600080fd5b6110de3383612c79565b15156110e957600080fd5b6110f282612212565b156110fc57600080fd5b601154611113908390600160a060020a0316612c4b565b601154604080517f54279bdd00000000000000000000000000000000000000000000000000000000815260048101859052602481018490523360448201529051600160a060020a03909216916354279bdd9160648082019260009290919082900301818387803b15801561118657600080fd5b505af115801561119a573d6000803e3d6000fd5b505050505050565b60025460a060020a900460ff16156111b957600080fd5b6111c33382612c99565b15156111ce57600080fd5b600160a060020a03821615156111e357600080fd5b6111ed8382612cf8565b6111f78382612d94565b6112018282612e1d565b8082600160a060020a031684600160a060020a03167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef60405160405180910390a4505050565b600080600080600080600080600080600060078c81548110151561126757fe5b906000526020600020906002020190508060010160189054906101000a900463ffffffff1663ffffffff16600014159a50438160010160089054906101000a900467ffffffffffffffff1667ffffffffffffffff161115995080600101601c9054906101000a900461ffff1661ffff1698508060010160089054906101000a900467ffffffffffffffff1667ffffffffffffffff1697508060010160189054906101000a900463ffffffff1663ffffffff1696508060010160009054906101000a900467ffffffffffffffff1667ffffffffffffffff1695508060010160109054906101000a900463ffffffff1663ffffffff1694508060010160149054906101000a900463ffffffff1663ffffffff16935080600101601e9054906101000a900461ffff1661ffff16925080600001549150509193959799509193959799565b60025460a060020a900460ff16156113bf57600080fd5b6113c93382612c79565b15156113d457600080fd5b6000908152600b602052604090208054600160a060020a031916600160a060020a0392909216919091179055565b600054600160a060020a0316331461141957600080fd5b600160a060020a038116151561142e57600080fd5b60008054600160a060020a031916600160a060020a0392909216919091179055565b600481600e811061145d57fe5b60089182820401919006600402915054906101000a900463ffffffff1681565b600054600160a060020a0316331461149457600080fd5b600160a060020a03811615156114a957600080fd5b60028054600160a060020a031916600160a060020a0392909216919091179055565b60006114d68261292b565b15156114e157600080fd5b506000908152600b6020526040902054600160a060020a031690565b60025460009060a060020a900460ff161561151757600080fd5b6115213383612c79565b151561152c57600080fd5b6115358261285c565b151561154057600080fd5b61154a8284612ea1565b151561155557600080fd5b601254604080517fc55d0f56000000000000000000000000000000000000000000000000000000008152600481018690529051600160a060020a039092169163c55d0f56916024808201926020929091908290030181600087803b1580156115bc57600080fd5b505af11580156115d0573d6000803e3d6000fd5b505050506040513d60208110156115e657600080fd5b5051600e5490915081013410156115fc57600080fd5b601254600e54604080517f454a2ab3000000000000000000000000000000000000000000000000000000008152600481018790529051600160a060020a039093169263454a2ab39234039160248082019260009290919082900301818588803b15801561166857600080fd5b505af115801561167c573d6000803e3d6000fd5b50505050506116978263ffffffff168463ffffffff16612ef0565b505050565b600054600160a060020a031633146116b357600080fd5b60025460a060020a900460ff1615156116cb57600080fd5b601154600160a060020a031615156116e257600080fd5b601254600160a060020a031615156116f957600080fd5b601054600160a060020a0316151561171057600080fd5b601554600160a060020a03161561172657600080fd5b61172e61302e565b565b600054600160a060020a0316331461174757600080fd5b60025460a060020a900460ff16151561175f57600080fd5b60168054600160a060020a031916600160a060020a0392909216919091179055565b6122b881565b61169783838360206040519081016040528060008152506122ae565b600254600090819060a060020a900460ff16156117bf57600080fd5b600e543410156117ce57600080fd5b6117d83385612c79565b15156117e357600080fd5b6117ed838561307d565b15156117f857600080fd5b600780548590811061180657fe5b60009182526020918290206040805161010081018252600290930290910180548352600181015467ffffffffffffffff808216958501959095526801000000000000000081049094169183019190915263ffffffff608060020a84048116606084015260a060020a84048116608084015260c060020a84041660a083015261ffff60e060020a8404811660c084015260f060020a90930490921660e08201529092506118b1906130d2565b15156118bc57600080fd5b60078054849081106118ca57fe5b60009182526020918290206040805161010081018252600290930290910180548352600181015467ffffffffffffffff808216958501959095526801000000000000000081049094169183019190915263ffffffff608060020a84048116606084015260a060020a84048116608084015260c060020a84041660a083015261ffff60e060020a8404811660c084015260f060020a90930490921660e0820152909150611975906130d2565b151561198057600080fd5b61198c82858386613101565b151561199757600080fd5b6119a18484612ef0565b50505050565b600054600160a060020a031633146119be57600080fd5b600160a060020a03811615156119d357600080fd5b60018054600160a060020a031916600160a060020a0392909216919091179055565b600054600160a060020a0316331480611a185750600154600160a060020a031633145b80611a2d5750600254600160a060020a031633145b1515611a3857600080fd5b60045463ffffffff168110611a4c57600080fd5b600655565b60025460a060020a900460ff1681565b6001546000908190600160a060020a03163314611a7d57600080fd5b5050600e54600f5430319160019091010280821115611ad157600154604051600160a060020a039091169082840380156108fc02916000818181858888f19350505050158015611697573d6000803e3d6000fd5b5050565b601054600160a060020a031681565b600081815260086020526040812054600160a060020a0316801515611b0857600080fd5b92915050565b601554600160a060020a031681565b60008054600160a060020a03163314611b3557600080fd5b81905080600160a060020a031663d25c07676040518163ffffffff1660e060020a028152600401602060405180830381600087803b158015611b7657600080fd5b505af1158015611b8a573d6000803e3d6000fd5b505050506040513d6020811015611ba057600080fd5b50511515611bad57600080fd5b60118054600160a060020a031916600160a060020a039290921691909117905550565b6000600160a060020a0382161515611be757600080fd5b50600160a060020a031660009081526009602052604090205490565b600054600160a060020a03163314611c1a57600080fd5b60025460a060020a900460ff161515611c3257600080fd5b60158054600160a060020a038316600160a060020a0319909116811790915560408051918252517f450db8da6efbe9c22f2347f7c2021231df1fc58d3ae9a2fa75d39fa4461993059181900360200190a150565b60065481565b600054600160a060020a0316331480611caf5750600154600160a060020a031633145b80611cc45750600254600160a060020a031633145b1515611ccf57600080fd5b60025460a060020a900460ff1615611ce657600080fd5b6002805474ff0000000000000000000000000000000000000000191660a060020a179055565b6060600060606000806000611d2087611bd0565b9450841515611d3f576040805160008152602081019091529550611dd4565b84604051908082528060200260200182016040528015611d69578160200160208202803883390190505b509350611d746110a4565b925060009150600190505b828111611dd057600081815260086020526040902054600160a060020a0388811691161415611dc857808483815181101515611db757fe5b602090810290910101526001909101905b600101611d7f565b8395505b5050505050919050565b600054600160a060020a0316331480611e015750600154600160a060020a031633145b80611e165750600254600160a060020a031633145b1515611e2157600080fd5b601160009054906101000a9004600160a060020a0316600160a060020a0316635fd8c7106040518163ffffffff1660e060020a028152600401600060405180830381600087803b158015611e7457600080fd5b505af1158015611e88573d6000803e3d6000fd5b50505050601260009054906101000a9004600160a060020a0316600160a060020a0316635fd8c7106040518163ffffffff1660e060020a028152600401600060405180830381600087803b158015611edf57600080fd5b505af11580156119a1573d6000803e3d6000fd5b60008054600160a060020a03163314611f0b57600080fd5b81905080600160a060020a031663994b2dd06040518163ffffffff1660e060020a028152600401602060405180830381600087803b158015611f4c57600080fd5b505af1158015611f60573d6000803e3d6000fd5b505050506040513d6020811015611f7657600080fd5b50511515611f8357600080fd5b60128054600160a060020a031916600160a060020a039290921691909117905550565b600e5481565b60408051808201909152600481527f4b59445900000000000000000000000000000000000000000000000000000000602082015290565b600254600090600160a060020a03163314611ffd57600080fd5b5080600160a060020a038116151561201d5750600254600160a060020a03165b6013546103781161202d57600080fd5b6013805460010190556119a1600080808685612978565b6000808080851161205457600080fd5b6000841161206157600080fd5b600780548690811061206f57fe5b9060005260206000209060020201915060078481548110151561208e57fe5b906000526020600020906002020190506120aa82868387613101565b80156120bb57506120bb848661307d565b95945050505050565b60025460a060020a900460ff16156120db57600080fd5b6120e53383612c79565b15156120f057600080fd5b6120f98261285c565b151561210457600080fd5b60125461211b908390600160a060020a0316612c4b565b601254604080517f54279bdd00000000000000000000000000000000000000000000000000000000815260048101859052602481018490523360448201529051600160a060020a03909216916354279bdd9160648082019260009290919082900301818387803b15801561118657600080fd5b600160a060020a0382163314156121a457600080fd5b336000818152600c60209081526040808320600160a060020a03871680855290835292819020805460ff1916861515908117909155815190815290519293927f17307eab39ab6107e8899845ad3d59bd9653f200f220920489ca2b5937696c31929181900390910190a35050565b600080821161222057600080fd5b600780548390811061222e57fe5b600091825260209091206002909102016001015460c060020a900463ffffffff16151592915050565b662386f26fc1000081565b600254600160a060020a031681565b60408051808201909152600481527f4b59445900000000000000000000000000000000000000000000000000000000602082015281565b61037881565b6122b98484846111a2565b6122c584848484613280565b15156119a157600080fd5b60025460009060a060020a900460ff16156122ea57600080fd5b60115461230090600160a060020a031683612c79565b151561230b57600080fd5b601154604080517f78bd7935000000000000000000000000000000000000000000000000000000008152600481018590529051600160a060020a03909216916378bd7935916024808201926060929091908290030181600087803b15801561237257600080fd5b505af1158015612386573d6000803e3d6000fd5b505050506040513d606081101561239c57600080fd5b5051905033600160a060020a038216146123b557600080fd5b601154604080517f4e8eaa13000000000000000000000000000000000000000000000000000000008152600481018590523360248201529051600160a060020a0390921691634e8eaa139160448082019260009290919082900301818387803b15801561118657600080fd5b600254600090600160a060020a0316331461243b57600080fd5b6014546122b81161244b57600080fd5b61245a60008060008530612978565b601154909150612474908290600160a060020a0316612c4b565b601154600160a060020a03166354279bdd8261248e613402565b306040518463ffffffff1660e060020a0281526004018084815260200183815260200182600160a060020a0316600160a060020a031681526020019350505050600060405180830381600087803b1580156124e857600080fd5b505af11580156124fc573d6000803e3d6000fd5b505060148054600101905550505050565b60606125188261292b565b151561252357600080fd5b600d8054604080516020601f60026000196101006001881615020190951694909404938401819004810282018101909252828152611b0893909290918301828280156125b05780601f10612585576101008083540402835291602001916125b0565b820191906000526020600020905b81548152906001019060200180831161259357829003601f168201915b50505050506125be846134d3565b6135c6565b600254600160a060020a031633146125da57600080fd5b60025460a060020a900460ff16156125f157600080fd5b6125fb3083612c79565b151561260657600080fd5b611ad13082846135fb565b60408051808201909152600781527f4479766572736500000000000000000000000000000000000000000000000000602082015281565b60025460009060a060020a900460ff161561266257600080fd5b60125461267890600160a060020a031683612c79565b151561268357600080fd5b601254604080517f78bd7935000000000000000000000000000000000000000000000000000000008152600481018590529051600160a060020a03909216916378bd7935916024808201926060929091908290030181600087803b1580156126ea57600080fd5b505af11580156126fe573d6000803e3d6000fd5b505050506040513d606081101561271457600080fd5b5051905033600160a060020a0382161461272d57600080fd5b601254604080517f4e8eaa13000000000000000000000000000000000000000000000000000000008152600481018590523360248201529051600160a060020a0390921691634e8eaa139160448082019260009290919082900301818387803b15801561118657600080fd5b601654600160a060020a031681565b600054600160a060020a03163314806127cb5750600154600160a060020a031633145b806127e05750600254600160a060020a031633145b15156127eb57600080fd5b611697600d8383613aca565b601154600160a060020a031681565b600160a060020a039182166000908152600c6020908152604080832093909416825291909152205460ff1690565b600f5481565b60145481565b600254600160a060020a0316331461285757600080fd5b600e55565b60008080831161286b57600080fd5b600780548490811061287957fe5b60009182526020918290206040805161010081018252600290930290910180548352600181015467ffffffffffffffff808216958501959095526801000000000000000081049094169183019190915263ffffffff608060020a84048116606084015260a060020a84048116608084015260c060020a84041660a083015261ffff60e060020a8404811660c084015260f060020a90930490921660e0820152909150612924906130d2565b9392505050565b600090815260086020526040902054600160a060020a0316151590565b60008160a0015163ffffffff16600014158015611b085750506040015167ffffffffffffffff4381169116111590565b600080612983613b48565b600063ffffffff8916891461299757600080fd5b63ffffffff881688146129a957600080fd5b61ffff871687146129b957600080fd5b600287049250600d8361ffff1611156129d157600d92505b505060408051610100810182528581524267ffffffffffffffff90811660208301908152600093830184815263ffffffff8c8116606086019081528c82166080870190815260a0870188815261ffff8a811660c08a019081528f821660e08b01908152600780546001810182559c528a517fa66cc928b5edb82af9bd49922954155ab7b0942694bea4ce44661d9a8736c68860028e029081019190915598517fa66cc928b5edb82af9bd49922954155ab7b0942694bea4ce44661d9a8736c689909901805498519651955194519251915167ffffffffffffffff19909916998b16999099176fffffffffffffffff000000000000000019166801000000000000000096909a16959095029890981773ffffffff000000000000000000000000000000001916608060020a938616939093029290921777ffffffff0000000000000000000000000000000000000000191660a060020a91851691909102177bffffffff000000000000000000000000000000000000000000000000191660c060020a96841696909602959095177fffff0000ffffffffffffffffffffffffffffffffffffffffffffffffffffffff1660e060020a91861691909102177dffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1660f060020a929094169190910292909217905590919081168114612bcf57600080fd5b60608281015160808085015185516040805187815263ffffffff95861660208201529490921684830152938301939093529151600160a060020a038816927f7191c0804172ee8ac080b63e93fd6c2f26bbea256aed023d843c2a9f3dee0d3b928290030190a2612c3f85826136f6565b98975050505050505050565b6000918252600a60205260409091208054600160a060020a031916600160a060020a03909216919091179055565b600090815260086020526040902054600160a060020a0391821691161490565b600080612ca583611ae4565b905080600160a060020a031684600160a060020a03161480612ce0575083600160a060020a0316612cd584610c35565b600160a060020a0316145b80612cf05750612cf08185612806565b949350505050565b81600160a060020a0316612d0b82611ae4565b600160a060020a031614612d1e57600080fd5b6000818152600a6020526040902054600160a060020a031615612d58576000818152600a602052604090208054600160a060020a03191690555b6000818152600b6020526040902054600160a060020a031615611ad1576000908152600b602052604090208054600160a060020a031916905550565b81600160a060020a0316612da782611ae4565b600160a060020a031614612dba57600080fd5b600160a060020a038216600090815260096020526040902054612de490600163ffffffff61374f16565b600160a060020a039092166000908152600960209081526040808320949094559181526008909152208054600160a060020a0319169055565b600081815260086020526040902054600160a060020a031615612e3f57600080fd5b60008181526008602090815260408083208054600160a060020a031916600160a060020a03871690811790915583526009909152902054612e81906001613766565b600160a060020a0390921660009081526009602052604090209190915550565b6000806000600785815481101515612eb557fe5b90600052602060002090600202019150600784815481101515612ed457fe5b906000526020600020906002020190506120bb82868387613101565b600080600783815481101515612f0257fe5b90600052602060002090600202019150600784815481101515612f2157fe5b600091825260209091206002909102016001810180547bffffffff000000000000000000000000000000000000000000000000191660c060020a63ffffffff8716021790559050612f7182613778565b612f7a81613778565b6000848152600b602090815260408083208054600160a060020a031990811690915586845281842080549091169055600f80546001908101909155878452600883529281902054928401548151600160a060020a0390941684529183018790528281018690526801000000000000000090910467ffffffffffffffff166060830152517f0424154dc3e27f052d934e01126bedb53185fe060b7bcf8799972a1c8b7015ff916080908290030190a150505050565b600054600160a060020a0316331461304557600080fd5b60025460a060020a900460ff16151561305d57600080fd5b6002805474ff000000000000000000000000000000000000000019169055565b6000818152600860205260408082205484835290822054600160a060020a039182169116808214806120bb57506000858152600b6020526040902054600160a060020a03908116908316149250505092915050565b60008160a0015163ffffffff166000148015611b085750506040015167ffffffffffffffff4381169116111590565b60008184141561311357506000612cf0565b6001850154608060020a900463ffffffff168214806131425750600185015460a060020a900463ffffffff1682145b1561314f57506000612cf0565b6001830154608060020a900463ffffffff1684148061317e5750600183015460a060020a900463ffffffff1684145b1561318b57506000612cf0565b6001830154608060020a900463ffffffff1615806131b857506001850154608060020a900463ffffffff16155b156131c557506001612cf0565b60018581015490840154608060020a9182900463ffffffff90811692909104161480613210575060018086015490840154608060020a900463ffffffff90811660a060020a90920416145b1561321d57506000612cf0565b6001808601549084015460a060020a900463ffffffff908116608060020a90920416148061326857506001858101549084015460a060020a9182900463ffffffff9081169290910416145b1561327557506000612cf0565b506001949350505050565b60008061329585600160a060020a0316613861565b15156132a457600191506133f9565b6040517f150b7a020000000000000000000000000000000000000000000000000000000081523360048201818152600160a060020a03898116602485015260448401889052608060648501908152875160848601528751918a169463150b7a0294938c938b938b93909160a490910190602085019080838360005b8381101561333757818101518382015260200161331f565b50505050905090810190601f1680156133645780820380516001836020036101000a031916815260200191505b5095505050505050602060405180830381600087803b15801561338657600080fd5b505af115801561339a573d6000803e3d6000fd5b505050506040513d60208110156133b057600080fd5b50517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1981167f150b7a020000000000000000000000000000000000000000000000000000000014925090505b50949350505050565b6000806000601160009054906101000a9004600160a060020a0316600160a060020a031663eac9d94c6040518163ffffffff1660e060020a028152600401602060405180830381600087803b15801561345a57600080fd5b505af115801561346e573d6000803e3d6000fd5b505050506040513d602081101561348457600080fd5b505191506fffffffffffffffffffffffffffffffff821682146134a657600080fd5b6134b38260028104613766565b9050662386f26fc10000811015611b085750662386f26fc1000092915050565b6060600080828185151561351c5760408051808201909152600181527f3000000000000000000000000000000000000000000000000000000000000000602082015294506135bd565b8593505b831561353757600190920191600a84049350613520565b826040519080825280601f01601f191660200182016040528015613565578160200160208202803883390190505b5091505060001982015b85156135b957815160001982019160f860020a6030600a8a06010291849190811061359657fe5b906020010190600160f860020a031916908160001a905350600a8604955061356f565b8194505b50505050919050565b604080516020818101835260008083528351808301855281815284519283019094528152606092612924928692869290613869565b600160a060020a03821660009081526009602052604090205461362590600163ffffffff61376616565b600160a060020a03808416600081815260096020818152604080842096909655868352600881528583208054600160a060020a0319169094179093559287168152919052205461367c90600163ffffffff61374f16565b600160a060020a03808516600081815260096020908152604080832095909555858252600b81528482208054600160a060020a0319908116909155600a9091528482208054909116905592518493928616927fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef91a4505050565b6136ff8161292b565b1561370957600080fd5b6137138282612e1d565b6040518190600160a060020a038416906000907fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef908290a45050565b6000808383111561375f57600080fd5b5050900390565b60008282018381101561292457600080fd5b600654600182015443919060049060e060020a900461ffff16600e811061379b57fe5b600891828204019190066004029054906101000a900463ffffffff1663ffffffff168115156137c657fe5b6001840180546fffffffffffffffff0000000000000000191668010000000000000000939092049390930167ffffffffffffffff16919091021790819055600c60e060020a90910461ffff16101561385e576001818101805461ffff60e060020a8083048216909401169092027fffff0000ffffffffffffffffffffffffffffffffffffffffffffffffffffffff9092169190911790555b50565b6000903b1190565b6060806060806060806060806000808e98508d97508c96508b95508a94508451865188518a518c51010101016040519080825280601f01601f1916602001820160405280156138c2578160200160208202803883390190505b50935083925060009150600090505b885181101561392f5788818151811015156138e857fe5b90602001015160f860020a900460f860020a02838380600101945081518110151561390f57fe5b906020010190600160f860020a031916908160001a9053506001016138d1565b5060005b875181101561399157878181518110151561394a57fe5b90602001015160f860020a900460f860020a02838380600101945081518110151561397157fe5b906020010190600160f860020a031916908160001a905350600101613933565b5060005b86518110156139f35786818151811015156139ac57fe5b90602001015160f860020a900460f860020a0283838060010194508151811015156139d357fe5b906020010190600160f860020a031916908160001a905350600101613995565b5060005b8551811015613a55578581815181101515613a0e57fe5b90602001015160f860020a900460f860020a028383806001019450815181101515613a3557fe5b906020010190600160f860020a031916908160001a9053506001016139f7565b5060005b8451811015613ab7578481815181101515613a7057fe5b90602001015160f860020a900460f860020a028383806001019450815181101515613a9757fe5b906020010190600160f860020a031916908160001a905350600101613a59565b50909d9c50505050505050505050505050565b828054600181600116156101000203166002900490600052602060002090601f016020900481019282601f10613b0b5782800160ff19823516178555613b38565b82800160010185558215613b38579182015b82811115613b38578235825591602001919060010190613b1d565b50613b44929150613b8c565b5090565b6040805161010081018252600080825260208201819052918101829052606081018290526080810182905260a0810182905260c0810182905260e081019190915290565b610c3291905b80821115613b445760008155600101613b925600a165627a7a72305820984728e95ce5f0c01a687d1e7a73daa4abbc56d2875bd49459d0d51c1a2448050029

Swarm Source

bzzr://984728e95ce5f0c01a687d1e7a73daa4abbc56d2875bd49459d0d51c1a244805
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.