Contract 0x2fd039e697acdfe4df74ffeb3c8f5a13d03f3ad5

Contract Overview

Balance:
0.002 Ether
TxHash Block Age From To Value [TxFee]
0x75be0e4c542e9b4c7b46fc34964393d70a0d628f142d5f4532e7d80b5ad13ac840374275 days 4 hrs ago0x098c88d890f6039f40960598861dced632d2c9df IN  0x2fd039e697acdfe4df74ffeb3c8f5a13d03f3ad50.002 Ether0.000069044
0x8358bce77236b2f5dad88b068965d023bdf10a1feafb9c14178127ff9badbd10397636415 days 19 hrs ago0xd6210877d1214b68f805cbbf95a43fefb0e8e9dd IN  0x2fd039e697acdfe4df74ffeb3c8f5a13d03f3ad50 Ether0.000109514
0xdcfc8a90609a64795fb2e065f432e692b4ad177f843d99dad2cd5699f3cc676a397635815 days 19 hrs ago0x098c88d890f6039f40960598861dced632d2c9df IN  0x2fd039e697acdfe4df74ffeb3c8f5a13d03f3ad50.002 Ether0.000069044
0xbb5efb141e0fe0238db64477eaff5db0dc1dadccf8f1961275897b49f347f415395402319 days 16 hrs ago0xd6210877d1214b68f805cbbf95a43fefb0e8e9dd IN  0x2fd039e697acdfe4df74ffeb3c8f5a13d03f3ad50 Ether0.00010922
0x886ccee94bd0eb50cfa601b8b451e1bf4bb92938c68bfbaff99fc799b9faf59b395378119 days 17 hrs ago0x098c88d890f6039f40960598861dced632d2c9df IN  0x2fd039e697acdfe4df74ffeb3c8f5a13d03f3ad50.002 Ether0.00006885
0x6acf33a31c06cfe6a41e1b98eb50589d3654354081336e6feeb90a59b8ec3acd394892520 days 13 hrs ago0xd6210877d1214b68f805cbbf95a43fefb0e8e9dd IN  0x2fd039e697acdfe4df74ffeb3c8f5a13d03f3ad50 Ether0.00010922
0x85d1624cf95a04a030d4e2ab9de32681e04952be9bcb0d482ddf70c39a6d1ed9394880320 days 13 hrs ago0x098c88d890f6039f40960598861dced632d2c9df IN  0x2fd039e697acdfe4df74ffeb3c8f5a13d03f3ad50.002 Ether0.00006885
0xca47c9c5a5c6f14783a40c4382a9de6222892583dd39d2fe3075b35a5cec361f394878220 days 13 hrs ago0xd6210877d1214b68f805cbbf95a43fefb0e8e9dd IN  0x2fd039e697acdfe4df74ffeb3c8f5a13d03f3ad50 Ether0.00010922
0xec13f3a22f8f3435b0bc4e6c6bdafeddfc3740ecd512488df794bf3b8af1934f394827920 days 16 hrs ago0x098c88d890f6039f40960598861dced632d2c9df IN  0x2fd039e697acdfe4df74ffeb3c8f5a13d03f3ad50.002 Ether0.00006875
0x8c3a6ed8922a38a8da8092ef830766038e1a77a42b729d8b484482096196aee6387489633 days 9 hrs ago0x7d64f6b9966d9b0251b931ee243b6d2647e9ab00 IN  0x2fd039e697acdfe4df74ffeb3c8f5a13d03f3ad50 Ether0.000107556
0x6b9ab8360fbcb0f6123a0dd64b1b88833d6b7db558337fd25901c0a22c6e4b45386685134 days 19 hrs ago0x098c88d890f6039f40960598861dced632d2c9df IN  0x2fd039e697acdfe4df74ffeb3c8f5a13d03f3ad50.002 Ether0.00006875
0x3554ea1b8005be4297a3ee2256fcd6c54c7997ebf76632d12843af67948638f2383966439 days 12 hrs ago0xa459110739d5e9b3b88c3eac26a31838a22d83f0 IN  0x2fd039e697acdfe4df74ffeb3c8f5a13d03f3ad50 Ether0.00002667
0x36db2042cad7414212b3f6b9b2d6504f7da327532181bfc3bdd87fa22d4b8616383966339 days 12 hrs ago0xa459110739d5e9b3b88c3eac26a31838a22d83f0 IN  0x2fd039e697acdfe4df74ffeb3c8f5a13d03f3ad50 Ether0.00010922
0xe3cbeacea287bfca44b3a0ba8dff8ce82a51ac31c51d919a3d1dd593cd8be26f383962239 days 12 hrs ago0x098c88d890f6039f40960598861dced632d2c9df IN  0x2fd039e697acdfe4df74ffeb3c8f5a13d03f3ad50.002 Ether0.00006885
0xa938e5c99ca061a46e18abe943f4427de2d9fc31f0ec81b2de0dba36a4a78ccb383961439 days 12 hrs ago0xa459110739d5e9b3b88c3eac26a31838a22d83f0 IN  0x2fd039e697acdfe4df74ffeb3c8f5a13d03f3ad50 Ether0.00010922
0xbc8ef93adf4f152d9c569ae523a590f3b84d2e4dd375040181c171aea03de188383959339 days 12 hrs ago0x098c88d890f6039f40960598861dced632d2c9df IN  0x2fd039e697acdfe4df74ffeb3c8f5a13d03f3ad50.002 Ether0.00006885
0x37a1ac88947897c84fcf3a512cfbe87e4a7278d04bf538dde8d81bf88e503cbd383881739 days 16 hrs ago0xa459110739d5e9b3b88c3eac26a31838a22d83f0 IN  0x2fd039e697acdfe4df74ffeb3c8f5a13d03f3ad50 Ether0.00002667
0x8dd079e7f4362ff1a0443fbf3a162e2ffd5a6267c4eb299c6e7ca42b046458a9383881639 days 16 hrs ago0xa459110739d5e9b3b88c3eac26a31838a22d83f0 IN  0x2fd039e697acdfe4df74ffeb3c8f5a13d03f3ad50 Ether0.00010922
0xa254ce7ba6130cc46adfe7169bd3ca532a32d0df52ce22b284c67f3e7af94f74383875639 days 16 hrs ago0x098c88d890f6039f40960598861dced632d2c9df IN  0x2fd039e697acdfe4df74ffeb3c8f5a13d03f3ad50.002 Ether0.00006885
0xdd993849a054eac989febbfcc3a4a5bcfe5e9f9ea42cd23d9e3df5371c9d2c41383854239 days 17 hrs ago0xa459110739d5e9b3b88c3eac26a31838a22d83f0 IN  0x2fd039e697acdfe4df74ffeb3c8f5a13d03f3ad50 Ether0.00002667
0xd1d8c1cdb26adfa93170317b9408b5fdd291b2c66a1a9705aca30aee1b5f31b0383854139 days 17 hrs ago0xa459110739d5e9b3b88c3eac26a31838a22d83f0 IN  0x2fd039e697acdfe4df74ffeb3c8f5a13d03f3ad50 Ether0.00002667
0x30cdc4c6c8ae8fcd74b0c3ac8d0f882cab77c8194f4aa48e37efdfdfb831cded383854039 days 17 hrs ago0xa459110739d5e9b3b88c3eac26a31838a22d83f0 IN  0x2fd039e697acdfe4df74ffeb3c8f5a13d03f3ad50 Ether0.00010922
0x09433f311bd20d6e96c71164e221f97f1d6c8df9e6d6df0b1fd303a55b2e5298383815439 days 18 hrs ago0x098c88d890f6039f40960598861dced632d2c9df IN  0x2fd039e697acdfe4df74ffeb3c8f5a13d03f3ad50.002 Ether0.00006875
0x14b1dde4eb25430a3055d4ccb3e3b3c7a70991a586ba0f90e98df18b88b00b4c383560340 days 5 hrs ago0x098c88d890f6039f40960598861dced632d2c9df IN  0x2fd039e697acdfe4df74ffeb3c8f5a13d03f3ad50 Ether0.000108625
0xa86851c5fc83a0df3b40f9a2a2c2d6da2c2d258585b06b302cffff94dfab9c98383560140 days 5 hrs ago0x098c88d890f6039f40960598861dced632d2c9df IN  0x2fd039e697acdfe4df74ffeb3c8f5a13d03f3ad50 Ether0.000108625
[ Download CSV Export 

Latest 14 internal transactions Internal Transactions as a result of Contract Execution

Parent TxHash Block Age From To Value
0x8358bce77236b2f5dad88b068965d023bdf10a1feafb9c14178127ff9badbd10397636415 days 19 hrs ago0x2fd039e697acdfe4df74ffeb3c8f5a13d03f3ad50xd6210877d1214b68f805cbbf95a43fefb0e8e9dd0.002 Ether
0xbb5efb141e0fe0238db64477eaff5db0dc1dadccf8f1961275897b49f347f415395402319 days 16 hrs ago0x2fd039e697acdfe4df74ffeb3c8f5a13d03f3ad50xd6210877d1214b68f805cbbf95a43fefb0e8e9dd0.002 Ether
0x6acf33a31c06cfe6a41e1b98eb50589d3654354081336e6feeb90a59b8ec3acd394892520 days 13 hrs ago0x2fd039e697acdfe4df74ffeb3c8f5a13d03f3ad50xd6210877d1214b68f805cbbf95a43fefb0e8e9dd0.002 Ether
0xca47c9c5a5c6f14783a40c4382a9de6222892583dd39d2fe3075b35a5cec361f394878220 days 13 hrs ago0x2fd039e697acdfe4df74ffeb3c8f5a13d03f3ad50xd6210877d1214b68f805cbbf95a43fefb0e8e9dd0.002 Ether
0x8c3a6ed8922a38a8da8092ef830766038e1a77a42b729d8b484482096196aee6387489633 days 9 hrs ago0x2fd039e697acdfe4df74ffeb3c8f5a13d03f3ad50x7d64f6b9966d9b0251b931ee243b6d2647e9ab000.002 Ether
0x36db2042cad7414212b3f6b9b2d6504f7da327532181bfc3bdd87fa22d4b8616383966339 days 12 hrs ago0x2fd039e697acdfe4df74ffeb3c8f5a13d03f3ad50xa459110739d5e9b3b88c3eac26a31838a22d83f00.002 Ether
0xa938e5c99ca061a46e18abe943f4427de2d9fc31f0ec81b2de0dba36a4a78ccb383961439 days 12 hrs ago0x2fd039e697acdfe4df74ffeb3c8f5a13d03f3ad50xa459110739d5e9b3b88c3eac26a31838a22d83f00.002 Ether
0x8dd079e7f4362ff1a0443fbf3a162e2ffd5a6267c4eb299c6e7ca42b046458a9383881639 days 16 hrs ago0x2fd039e697acdfe4df74ffeb3c8f5a13d03f3ad50xa459110739d5e9b3b88c3eac26a31838a22d83f00.002 Ether
0x30cdc4c6c8ae8fcd74b0c3ac8d0f882cab77c8194f4aa48e37efdfdfb831cded383854039 days 17 hrs ago0x2fd039e697acdfe4df74ffeb3c8f5a13d03f3ad50xa459110739d5e9b3b88c3eac26a31838a22d83f00.002 Ether
0xb83acd4e28b45b3740f5d1b2a535a5b09da8b5b19bcd46dbe67b464d328ae4db377211751 days 6 hrs ago0x2fd039e697acdfe4df74ffeb3c8f5a13d03f3ad50x749b2567a646c0df71075121af1abe23139448400 Ether
0xa8f8d073be82e4d81d6a9f24d28d2d39488705b1aa611c74aa922e2c1296034a377211451 days 6 hrs ago0x2fd039e697acdfe4df74ffeb3c8f5a13d03f3ad50x348eb8e17549fd85fe082217ac0ef89dba36df970 Ether
0x967b3e24900aa67f18c845ba2acc9e2b18eef1d097ea4af5f78c6eac253606c0377211251 days 6 hrs ago0x2fd039e697acdfe4df74ffeb3c8f5a13d03f3ad50x91334865f825262e3ed2ab7254398422f69b48090 Ether
0xaf32def0f9d3f5365d34ed78f7f91281f1fd85328bfa468a90e1737199ce8b06377208351 days 6 hrs ago0x348eb8e17549fd85fe082217ac0ef89dba36df970x2fd039e697acdfe4df74ffeb3c8f5a13d03f3ad50 Ether
0x2ecdbebc1a41c41273e4d96d892758b52a182b4a584c387e661e8c13a262c715377208251 days 6 hrs ago0x91334865f825262e3ed2ab7254398422f69b48090x2fd039e697acdfe4df74ffeb3c8f5a13d03f3ad50 Ether
[ Download CSV Export 
Warning: The compiled contract might be susceptible to ExpExponentCleanup (medium/high-severity), EventStructWrongData (very low-severity) Solidity Compiler Bugs.

Contract Source Code Verified (Similar Match)
Note: This contract matches the deployed ByteCode of the Verified Source Code for Contract 0x86eb36fbCDa39dF95B80fc3B4b5aF4f8C7Dc615b

Contract Name:
Core

Compiler Version
v0.4.24+commit.e67f0147

Optimization Enabled:
Yes

Runs (Optimizer):
200

Contract Source Code

pragma solidity 0.4.24;

// File: /home/moncy/projects/planetpegasus/planet-pegasus-smart-contracts/contracts/modules/ERC165.sol

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

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

// File: /home/moncy/projects/planetpegasus/planet-pegasus-smart-contracts/contracts/modules/ERC721Basic.sol

/**
 * @title ERC721 Non-Fungible Token Standard basic interface
 * @dev see https://github.com/ethereum/EIPs/blob/master/EIPS/eip-721.md
 */
contract ERC721Basic is ERC165 {
    event Transfer(
      address indexed _from,
      address indexed _to,
      uint256 indexed _tokenId
    );
    event Approval(
      address indexed _owner,
      address indexed _approved,
      uint256 indexed _tokenId
    );
    event ApprovalForAll(
      address indexed _owner,
      address indexed _operator,
      bool _approved
    );

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

    function approve(address _to, uint256 _tokenId) public;
    function getApproved(uint256 _tokenId) public view returns (address _operator);

    function setApprovalForAll(address _operator, bool _approved) public;
    function isApprovedForAll(address _owner, address _operator) public view returns (bool);

    function transferFrom(address _from, address _to, uint256 _tokenId) public;
    function safeTransferFrom(address _from, address _to, uint256 _tokenId) public;

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

// File: /home/moncy/projects/planetpegasus/planet-pegasus-smart-contracts/contracts/modules/ERC721Enumerable.sol

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

// File: /home/moncy/projects/planetpegasus/planet-pegasus-smart-contracts/contracts/modules/ERC721Metadata.sol

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

// File: /home/moncy/projects/planetpegasus/planet-pegasus-smart-contracts/contracts/modules/ERC721.sol

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

// File: /home/moncy/projects/planetpegasus/planet-pegasus-smart-contracts/contracts/modules/ERC721Receiver.sol

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

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

// File: /home/moncy/projects/planetpegasus/planet-pegasus-smart-contracts/contracts/modules/SafeMath.sol

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

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

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

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

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

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

// File: /home/moncy/projects/planetpegasus/planet-pegasus-smart-contracts/contracts/modules/AddressUtils.sol

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

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

}

// File: /home/moncy/projects/planetpegasus/planet-pegasus-smart-contracts/contracts/modules/SupportsInterfaceWithLookup.sol

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

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

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

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

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

// File: /home/moncy/projects/planetpegasus/planet-pegasus-smart-contracts/contracts/modules/AccessControl.sol

contract AccessControl {

    event ContractUpgrade(address newContract);

    // The addresses of the accounts (or contracts) that can execute actions within each roles.
    address public ceoAddress;
    address public cfoAddress;
    address public cooAddress;
    address public ctoAddress;

    // @dev Keeps track whether the contract is paused. When that is true, most actions are blocked
    bool public paused = false;

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

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

    /// @dev Access modifier for CTO-only functionality
    modifier onlyCTO() {
        require(msg.sender == ctoAddress);
        _;
    }

    modifier onlyCLevel() {
        require(
            msg.sender == cooAddress ||
            msg.sender == ceoAddress ||
            msg.sender == cfoAddress ||
            msg.sender == ctoAddress
        );
        _;
    }

    /// @dev Assigns a new address to act as the CEO. Only available to the current CTO.
    /// @param _newCEO The address of the new CEO
    function setCEO(address _newCEO) external onlyCTO {
        require(_newCEO != address(0));
        ceoAddress = _newCEO;
    }

    /// @dev Assigns a new address to act as the CFO. Only available to the current CTO.
    /// @param _newCFO The address of the new CFO
    function setCFO(address _newCFO) external onlyCTO {
        require(_newCFO != address(0));
        cfoAddress = _newCFO;
    }

    /// @dev Assigns a new address to act as the COO. Only available to the current CTO.
    /// @param _newCOO The address of the new COO
    function setCOO(address _newCOO) external onlyCTO {
        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 and we need to limit 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;
    }
}

// File: /home/moncy/projects/planetpegasus/planet-pegasus-smart-contracts/contracts/modules/ClockAuctionBase.sol

/// @title Auction Core
/// @dev Contains models, variables, and internal methods for the auction.
/// @notice We omit a fallback function to prevent accidental sends to this contract.
contract ClockAuctionBase is ERC721Receiver {

    // Represents an auction on an NFT
    struct Auction {
        // Current owner of NFT
        address seller;
        // Price (in wei) at beginning of auction
        uint128 startingPrice;
        // Price (in wei) at end of auction
        uint128 endingPrice;
        // Duration (in seconds) of auction
        uint64 duration;
        // Time when auction started
        // NOTE: 0 if this auction has been concluded
        uint64 startedAt;
    }

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

    // Cut owner takes on each auction, measured in basis points (1/100 of a percent).
    // Values 0-10,000 map to 0%-100%
    uint256 public ownerCut;

    // Map from token ID to their corresponding auction.
    mapping (uint256 => Auction) tokenIdToAuction;

    event AuctionCreated(uint256 tokenId, uint256 startingPrice, uint256 endingPrice, uint256 duration, uint256 timestamp);
    event AuctionSuccessful(uint256 tokenId, uint256 totalPrice, address winner);
    event AuctionCancelled(uint256 tokenId);

    /// @dev Returns true if the claimant owns the token.
    /// @param _claimant - Address claiming to own the token.
    /// @param _tokenId - ID of token whose ownership to verify.
    function _owns(address _claimant, uint256 _tokenId) internal view returns (bool) {
        return (nonFungibleContract.ownerOf(_tokenId) == _claimant);
    }

    /// @dev Escrows the NFT, assigning ownership to this contract.
    /// Throws if the escrow fails.
    /// @param _owner - Current owner address of token to escrow.
    /// @param _tokenId - ID of token whose approval to verify.
    function _escrow(address _owner, uint256 _tokenId) internal {
        // it will throw if transfer fails
        if(_owner != address(nonFungibleContract)){
            nonFungibleContract.safeTransferFrom(_owner, address(this), _tokenId); // SAFE TRANSFER
        }

    }

    function onERC721Received(address /* _operator */, address /* _from */, uint256 /* _tokenId*/, bytes /* _data */) public returns(bytes4) {
        // require(nonFungibleContract.isApprovedForAll(_from, _operator), "Operator lacks approval from token owner");
        // require(nonFungibleContract.ownerOf(_tokenId) == address(_operator), "Operator is not in possession of token");
        return ERC721_RECEIVED;
    }

    /// @dev Transfers an NFT owned by this contract to another address.
    /// Returns true if the transfer succeeds.
    /// @param _receiver - Address to transfer NFT to.
    /// @param _tokenId - ID of token to transfer.
    function _transfer(address _receiver, uint256 _tokenId, address _seller) internal {
        // it will throw if transfer fails
        // nonFungibleContract.transfer(_receiver, _tokenId);
        if(_seller != address(nonFungibleContract)) {
            nonFungibleContract.safeTransferFrom(address(this), _receiver, _tokenId); // SAFE TRANSFER
        } else {
            nonFungibleContract.safeTransferFrom(address(nonFungibleContract), _receiver, _tokenId);
        }
    }

    /// @dev Adds an auction to the list of open auctions. Also fires the
    ///  AuctionCreated event.
    /// @param _tokenId The ID of the token to be put on auction.
    /// @param _auction Auction to add.
    function _addAuction(uint256 _tokenId, Auction _auction) internal {
        // Require that all auctions have a duration of
        // at least one minute. (Keeps our math from getting hairy!)
        require(_auction.duration >= 1 minutes);

        tokenIdToAuction[_tokenId] = _auction;

        emit AuctionCreated(
            uint256(_tokenId),
            uint256(_auction.startingPrice),
            uint256(_auction.endingPrice),
            uint256(_auction.duration),
            block.timestamp
        );
    }

    /// @dev Cancels an auction unconditionally.
    function _cancelAuction(uint256 _tokenId, address _seller) internal {
        _removeAuction(_tokenId);
        _transfer(_seller, _tokenId, _seller);
        emit AuctionCancelled(_tokenId);
    }

    /// @dev Computes the price and transfers winnings.
    /// Does NOT transfer ownership of token.
    function _bid(uint256 _tokenId, uint256 _bidAmount)
        internal
        returns (uint256)
    {
        // Get a reference to the auction struct
        Auction storage auction = tokenIdToAuction[_tokenId];

        // Explicitly check that this auction is currently live.
        // (Because of how Ethereum mappings work, we can't just count
        // on the lookup above failing. An invalid _tokenId will just
        // return an auction object that is all zeros.)
        require(_isOnAuction(auction));

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

        // Grab a reference to the seller before the auction struct
        // gets deleted.
        address seller = auction.seller;

        // The bid is good! Remove the auction before sending the fees
        // to the sender so we can't have a reentrancy attack.
        _removeAuction(_tokenId);

        // Transfer proceeds to seller (if there are any!)
        if (price > 0) {
            // Calculate the auctioneer's cut.
            // (NOTE: _computeCut() is guaranteed to return a
            // value <= price, so this subtraction can't go negative.)
            uint256 auctioneerCut = _computeCut(price);
            uint256 sellerProceeds = price - auctioneerCut;

            // NOTE: Doing a transfer() in the middle of a complex
            // method like this is generally discouraged because of
            // reentrancy attacks and DoS attacks if the seller is
            // a contract with an invalid fallback function. We explicitly
            // guard against reentrancy attacks by removing the auction
            // before calling transfer(), and the only thing the seller
            // can DoS is the sale of their own asset! (And if it's an
            // accident, they can call cancelAuction(). )
            seller.transfer(sellerProceeds);
        }

        // Calculate any excess funds included with the bid. If the excess
        // is anything worth worrying about, transfer it back to bidder.
        // NOTE: We checked above that the bid amount is greater than or
        // equal to the price so this cannot underflow.
        uint256 bidExcess = _bidAmount - price;

        // Return the funds. Similar to the previous transfer, this is
        // not susceptible to a re-entry attack because the auction is
        // removed before any transfers occur.
        msg.sender.transfer(bidExcess);

        // Tell the world!
        emit AuctionSuccessful(_tokenId, price, msg.sender);

        return price;
    }

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

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

    /// @dev Returns current price of an NFT on auction. Broken into two
    ///  functions (this one, that computes the duration from the auction
    ///  structure, and the other that does the price computation) so we
    ///  can easily test that the price computation works correctly.
    function _currentPrice(Auction storage _auction)
        internal
        view
        returns (uint256)
    {
        uint256 secondsPassed = 0;

        // A bit of insurance against negative values (or wraparound).
        // Probably not necessary (since Ethereum guarnatees that the
        // now variable doesn't ever go backwards).
        if (now > _auction.startedAt) {
            secondsPassed = now - _auction.startedAt;
        }

        return _computeCurrentPrice(
            _auction.startingPrice,
            _auction.endingPrice,
            _auction.duration,
            secondsPassed
        );
    }

    /// @dev Computes the current price of an auction. Factored out
    ///  from _currentPrice so we can run extensive unit tests.
    ///  When testing, make this function public and turn on
    ///  `Current price computation` test suite.
    function _computeCurrentPrice(
        uint256 _startingPrice,
        uint256 _endingPrice,
        uint256 _duration,
        uint256 _secondsPassed
    )
        internal
        pure
        returns (uint256)
    {
        // NOTE: We don't use SafeMath (or similar) in this function because
        //  all of our public functions carefully cap the maximum values for
        //  time (at 64-bits) and currency (at 128-bits). _duration is
        //  also known to be non-zero (see the require() statement in
        //  _addAuction())
        if (_secondsPassed >= _duration) {
            // We've reached the end of the dynamic pricing portion
            // of the auction, just return the end price.
            return _endingPrice;
        } else {
            // Starting price can be higher than ending price (and often is!), so
            // this delta can be negative.
            int256 totalPriceChange = int256(_endingPrice) - int256(_startingPrice);

            // This multiplication can't overflow, _secondsPassed will easily fit within
            // 64-bits, and totalPriceChange will easily fit within 128-bits, their product
            // will always fit within 256-bits.
            int256 currentPriceChange = totalPriceChange * int256(_secondsPassed) / int256(_duration);

            // currentPriceChange can be negative, but if so, will have a magnitude
            // less that _startingPrice. Thus, this result will always end up positive.
            int256 currentPrice = int256(_startingPrice) + currentPriceChange;

            return uint256(currentPrice);
        }
    }

    /// @dev Computes owner's cut of a sale.
    /// @param _price - Sale price of NFT.
    function _computeCut(uint256 _price) internal view returns (uint256) {
        // NOTE: We don't use SafeMath (or similar) in this function because
        //  all of our entry functions carefully cap the maximum values for
        //  currency (at 128-bits), and ownerCut <= 10000 (see the require()
        //  statement in the ClockAuction constructor). The result of this
        //  function is always guaranteed to be <= _price.
        return _price * ownerCut / 10000;
    }

}

// File: /home/moncy/projects/planetpegasus/planet-pegasus-smart-contracts/contracts/modules/Ownable.sol

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

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

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

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

}

// File: /home/moncy/projects/planetpegasus/planet-pegasus-smart-contracts/contracts/modules/Pausable.sol

/**
 * @title Pausable
 * @dev Base contract which allows children to implement an emergency stop mechanism.
 */
contract Pausable is Ownable {
  event Pause();
  event Unpause();

  bool public paused = false;


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

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

  /**
   * @dev called by the owner to pause, triggers stopped state
   */
  function pause() public onlyOwner whenNotPaused returns (bool) {
    paused = true;
    emit Pause();
    return true;
  }

  /**
   * @dev called by the owner to unpause, returns to normal state
   */
  function unpause() public onlyOwner whenPaused returns (bool) {
    paused = false;
    emit Unpause();
    return true;
  }
}

// File: /home/moncy/projects/planetpegasus/planet-pegasus-smart-contracts/contracts/modules/ClockAuction.sol

/// @title Clock auction for non-fungible tokens.
/// @notice We omit a fallback function to prevent accidental sends to this contract.
contract ClockAuction is Pausable, ClockAuctionBase {

    /// @dev The ERC-165 interface signature for ERC-721.
    ///  Ref: https://github.com/ethereum/EIPs/issues/165
    ///  Ref: https://github.com/ethereum/EIPs/issues/721
    // bytes4 constant InterfaceSignature_ERC721 = bytes4(0x9a20483d);
    bytes4 private constant InterfaceId_ERC721 = 0x80ac58cd;

    /// @dev Constructor creates a reference to the NFT ownership contract
    ///  and verifies the owner cut is in the valid range.
    /// @param _nftAddress - address of a deployed contract implementing
    ///  the Nonfungible Interface.
    /// @param _cut - percent cut the owner takes on each auction, must be
    ///  between 0-500 i.e a maximum of 5% comission
    constructor(address _nftAddress, uint256 _cut) public {
        require(_cut <= 500);
        ownerCut = _cut;

        ERC721 candidateContract = ERC721(_nftAddress);
        require(candidateContract.supportsInterface(InterfaceId_ERC721));
        nonFungibleContract = candidateContract;
    }

    function setComission(uint256 _commission) external onlyOwner whenPaused {
        require(_commission <= 500, "Commission may not exceed 5%");
        ownerCut = _commission;
    }

    /// @dev Sets internal reference of NFT ownership to new contract address
    /// @param _nftAddress - address of the new NFT contract
    function setNFTAddress(address _nftAddress) whenPaused onlyOwner public {

        ERC721 candidateContract = ERC721(_nftAddress);
        require(candidateContract.supportsInterface(InterfaceId_ERC721));
        nonFungibleContract = candidateContract;
    }

    /// @dev Remove all Ether from the contract, which is the owner's cuts
    ///  as well as any Ether sent directly to the contract address.
    ///  Always transfers to the NFT contract, but can be called either by
    ///  the owner or 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 token to auction, sender must be owner.
    /// @param _startingPrice - Price of item (in wei) at beginning of auction.
    /// @param _endingPrice - Price of item (in wei) at end of auction.
    /// @param _duration - Length of time to move between starting
    ///  price and ending price (in seconds).
    /// @param _seller - Seller, if not the message sender
    function createAuction(
        uint256 _tokenId,
        uint256 _startingPrice,
        uint256 _endingPrice,
        uint256 _duration,
        address _seller
    )
        external
        whenNotPaused
    {
        // Sanity check that no inputs overflow how many bits we've allocated
        // to store them in the auction struct.
        require(_startingPrice == uint256(uint128(_startingPrice)));
        require(_endingPrice == uint256(uint128(_endingPrice)));
        require(_duration == uint256(uint64(_duration)));

        require(_owns(msg.sender, _tokenId));
        _escrow(msg.sender, _tokenId);
        Auction memory auction = Auction(
            _seller,
            uint128(_startingPrice),
            uint128(_endingPrice),
            uint64(_duration),
            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
    {
        address seller = tokenIdToAuction[_tokenId].seller;
        // _bid will throw if the bid or funds transfer fails
        _bid(_tokenId, msg.value);
        _transfer(msg.sender, _tokenId, seller);
    }

    /// @dev Cancels an auction that hasn't been won yet.
    ///  Returns the NFT to original owner.
    /// @notice This is a state-modifying function that can
    ///  be called while the contract is paused.
    /// @param _tokenId - ID of token on auction
    function cancelAuction(uint256 _tokenId)
        external
    {
        Auction storage auction = tokenIdToAuction[_tokenId];
        require(_isOnAuction(auction));
        address seller = auction.seller;
        require(msg.sender == 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. This should only be used in emergencies.
    /// @param _tokenId - ID of the NFT on auction to cancel.
    function cancelAuctionWhenPaused(uint256 _tokenId)
        whenPaused
        onlyOwner
        external
    {
        Auction storage auction = tokenIdToAuction[_tokenId];
        require(_isOnAuction(auction));
        _cancelAuction(_tokenId, auction.seller);
    }

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

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

}

// File: /home/moncy/projects/planetpegasus/planet-pegasus-smart-contracts/contracts/modules/SiringClockAuction.sol

/// @title Reverse auction modified for siring
/// @notice We omit a fallback function to prevent accidental sends to this contract.
contract SiringClockAuction is ClockAuction {

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

    // 2% comission
    constructor(address _nftAddr) public
        ClockAuction(_nftAddr, 200) {}

    /// @dev Creates and begins a new auction. Since this function is wrapped,
    /// require sender to be Core contract.
    /// @param _tokenId - ID of token to auction, sender must be owner.
    /// @param _startingPrice - Price of item (in wei) at beginning of auction.
    /// @param _endingPrice - Price of item (in wei) at end of auction.
    /// @param _duration - Length of auction (in seconds).
    /// @param _seller - Seller, if not the message sender
    function createAuction(
        uint256 _tokenId,
        uint256 _startingPrice,
        uint256 _endingPrice,
        uint256 _duration,
        address _seller
    )
        external
    {
        // Sanity check that no inputs overflow how many bits we've allocated
        // to store them in the auction struct.
        require(_startingPrice == uint256(uint128(_startingPrice)));
        require(_endingPrice == uint256(uint128(_endingPrice)));
        require(_duration == uint256(uint64(_duration)));

        require(msg.sender == address(nonFungibleContract));
        _escrow(_seller, _tokenId);
        Auction memory auction = Auction(
            _seller,
            uint128(_startingPrice),
            uint128(_endingPrice),
            uint64(_duration),
            uint64(now)
        );
        _addAuction(_tokenId, auction);
    }

    /// @dev Places a bid for siring. Requires the sender
    /// is the Core contract because all bid methods
    /// should be wrapped. Also returns the horsey to the
    /// seller rather than the winner.
    function bid(uint256 _tokenId)
        external
        payable
    {
        require(msg.sender == address(nonFungibleContract));
        address seller = tokenIdToAuction[_tokenId].seller;
        // _bid checks that token ID is valid and will throw if bid fails
        _bid(_tokenId, msg.value);
        // We transfer the horsey back to the seller, the winner will get
        // the offspring
        _transfer(seller, _tokenId, seller); /* INTERNAL TO CLOCKAUCTION */
    }
}

// File: /home/moncy/projects/planetpegasus/planet-pegasus-smart-contracts/contracts/modules/SaleClockAuction.sol

/// @title Clock auction modified for sale of horses
/// @notice We omit a fallback function to prevent accidental sends to this contract.
contract SaleClockAuction is ClockAuction {

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

    // Tracks last 5 sale price of gen0 horse sales
    uint256 public gen0SaleCount;
    uint256[5] public lastGen0SalePrices;

    // 2% comission
    constructor(address _nftAddr) public
    ClockAuction(_nftAddr, 200) {}

    /// @dev Creates and begins a new auction.
    /// @param _tokenId - ID of token to auction, sender must be owner.
    /// @param _startingPrice - Price of item (in wei) at beginning of auction.
    /// @param _endingPrice - Price of item (in wei) at end of auction.
    /// @param _duration - Length of auction (in seconds).
    /// @param _seller - Seller, if not the message sender
    function createAuction(
        uint256 _tokenId,
        uint256 _startingPrice,
        uint256 _endingPrice,
        uint256 _duration,
        address _seller
    )
        external
    {
        // Sanity check that no inputs overflow how many bits we've allocated
        // to store them in the auction struct.
        require(_startingPrice == uint256(uint128(_startingPrice)));
        require(_endingPrice == uint256(uint128(_endingPrice)));
        require(_duration == uint256(uint64(_duration)));

        require(msg.sender == address(nonFungibleContract));
        _escrow(_seller, _tokenId);
        Auction memory auction = Auction(
            _seller,
            uint128(_startingPrice),
            uint128(_endingPrice),
            uint64(_duration),
            uint64(now)
        );
        _addAuction(_tokenId, auction);
    }

    /// @dev Updates lastSalePrice if seller is the nft contract
    /// Otherwise, works the same as default bid method.
    function bid(uint256 _tokenId)
        external
        payable
    {
        // _bid verifies token ID size
        address seller = tokenIdToAuction[_tokenId].seller;
        uint256 price = _bid(_tokenId, msg.value);
        _transfer(msg.sender, _tokenId, seller); /* INTERNAL TO CLOCKAUCTION */

        // If not a gen0 auction, exit
        if (seller == address(nonFungibleContract)) {
            // Track gen0 sale prices
            lastGen0SalePrices[gen0SaleCount % 5] = price;
            gen0SaleCount++;
        }
    }

    // TODO determine selling price strategy
    function averageGen0SalePrice() external view returns (uint256) {
        uint256 sum = 0;
        for (uint256 i = 0; i < 5; i++) {
            sum += lastGen0SalePrices[i];
        }
        return sum / 5;
    }

}

// File: /home/moncy/projects/planetpegasus/planet-pegasus-smart-contracts/contracts/modules/GeneScienceInterface.sol

contract GeneScienceInterface {
    /// @dev simply a boolean to indicate this is the contract we expect to be
    function isGeneScience() public pure returns (bool);

    /// @dev given genes of kitten 1 & 2, return a genetic combination - may have a random factor
    /// @param gene1 gene of mom
    /// @param gene2 gene of dad
    /// @return the genes that are supposed to be passed down the child
    function mixGenes(uint256 gene1, uint256 gene2, uint256 targetBlock) public view returns (uint256);
}

// File: /home/moncy/projects/planetpegasus/planet-pegasus-smart-contracts/contracts/modules/ReentrancyGuard.sol

/**
 * @title Helps contracts guard agains reentrancy attacks.
 * @author Remco Bloemen <[email protected]π.com>
 * @notice If you mark a function `nonReentrant`, you should also
 * mark it `external`.
 */
contract ReentrancyGuard {

    /**
    * @dev We use a single lock for the whole contract.
    */
    bool private reentrancyLock = false;

    /**
    * @dev Prevents a contract from calling itself, directly or indirectly.
    * @notice If you mark a function `nonReentrant`, you should also
    * mark it `external`. Calling one nonReentrant function from
    * another is not supported. Instead, you can implement a
    * `private` function doing the actual work, and a `external`
    * wrapper marked as `nonReentrant`.
    */
    modifier nonReentrant() {
        require(!reentrancyLock);
        reentrancyLock = true;
        _;
        reentrancyLock = false;
    }

}

// File: /home/moncy/projects/planetpegasus/planet-pegasus-smart-contracts/contracts/modules/Base.sol

/// @title Base contract. Holds all common structs, events and base variables.
contract Base is AccessControl, SupportsInterfaceWithLookup, ReentrancyGuard, ERC721 {
    using SafeMath for uint256;
    using AddressUtils for address;    
    /*** EVENTS ***/

    /// @dev The Birth event is fired whenever a new token comes into existence. This obviously
    ///  includes any time a token is created through the giveBirth method, but it is also called
    ///  when a new gen0 token is created.
    event Birth(address owner, uint256 tokenId, uint256 matronId, uint256 sireId, uint256 gene);

    /// @dev Transfer event as defined in current draft of ERC721. Emitted every time a token
    ///  ownership is assigned, including births.
    // event Transfer(address from, address to, uint256 tokenId);

    /*** DATA TYPES ***/

    /// @dev The NFT struct. Every token is represented by a copy.
    struct NFT {
        // The genetic code is packed into a 256-bit word
        uint256 gene;
        // The timestamp from the block when this token came into existence.
        uint64 birthTime; 

        // The minimum timestamp after which this token can engage in breeding
        // activities again. This same timestamp is used for the pregnancy
        // timer (for matrons) as well as the siring cooldown.
        uint64 cooldownEndBlock;

        // The ID of the parents of this token, set to 0 for gen0 tokens.
        uint32 matronId;
        uint32 sireId;

        // Set to the ID of the sire horse for matrons that are pregnant, zero otherwise. 
        uint32 siringWithId;

        // Set to the index in the cooldown array representing the current cooldown for this token
        uint16 cooldownIndex;      

        // The "generation number" of this token.
        // eneration number of all other token is the larger of the two generation
        // numbers of their parents, plus one.
        // (i.e. max(matron.generation, sire.generation) + 1)
        uint16 generation;
    }
    
    
    /*** TO BE MODIFIED***/

    /// @dev A lookup table indicating the cooldown duration after any successful breeding action
    uint32[14] public cooldowns = [
        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),
        uint32(7 days)
    ];

    // An approximation of currently how many seconds are in between blocks.
    uint256 public secondsPerBlock = 15;

    /*** STORAGE ***/

    /// @dev An array containing the Horse struct for all horses in existence. The ID
    ///  of each horse is actually an index into this array. Note that ID 0 is 
    ///  Pegasus, the mythical beast that is the parent of all gen0 horse. A bizarre
    ///  creature that is both matron and sire... to itself! Has an invalid genetic code.
    ///  In other words, horse ID 0 is invalid... 
    NFT[] collection;

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

    /// @dev A mapping from horse IDs to the address that owns them. All tokens have
    ///  some valid owner address, even gen0 tokens are created with a non-zero owner.
    mapping (uint256 => address) internal tokenOwner;

    // @dev A mapping from owner address to count of tokens that address owns.
    //  Used internally inside balanceOf() to resolve ownership count.
    mapping (address => uint256) internal ownedTokensCount;

    /// @dev A mapping from TokenIDs to an address that has been approved to call
    ///  transferFrom(). Each Horse can only have one approved address for transfer
    ///  at any time. A zero value means no approval is outstanding.
    mapping (uint256 => address) public tokenApprovals;

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

    /// @dev A mapping from TokenIDs to an address that has been approved to use
    ///  this token for siring via breedWith(). Each Horse can only have one approved
    ///  address for siring at any time. A zero value means no approval is outstanding.
    mapping (uint256 => address) public sireApprovals;

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

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

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

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

    /**
    * @dev Guarantees msg.sender is owner of the given token
    * @param _tokenId uint256 ID of the token to validate its ownership belongs to msg.sender
    */
    modifier onlyOwnerOf(uint256 _tokenId) {
        require(ownerOf(_tokenId) == msg.sender);
        _;
    } 
    
    /**
    * @dev Checks msg.sender can transfer a token, by being owner, approved, or operator
    * @param _tokenId uint256 ID of the token to validate
    */
    modifier canTransfer(uint256 _tokenId) {
        require(isApprovedOrOwner(msg.sender, _tokenId),"msg.sender is not approved to transfer on behalf of owner");
        // require(_tokenId > 0);
        _;
    }       

    /// @dev The address of the ClockAuction contract that handles sales of tokens. This
    ///  same contract handles both peer-to-peer sales as well as the gen0 sales which are
    ///  initiated every 15 minutes.
    SaleClockAuction public saleAuction;

    /// @dev The address of a custom ClockAuction subclassed contract that handles siring
    ///  auctions. Needs to be separate from saleAuction because the actions taken on success
    ///  after a sales and siring auction are quite different.
    SiringClockAuction public siringAuction;

    // /// @dev Assigns ownership of a specific Token to an address.
    // function _transfer(address _from, address _to, uint256 _tokenId) internal {
    //     // Since the number of tokens is capped to 2^32 we can't overflow this
    //     ownedTokensCount[_to]++;
    //     // transfer ownership
    //     tokenOwner[_tokenId] = _to;
    //     // When creating new horses _from is 0x0, but we can't account that address.
    //     if (_from != address(0)) {
    //         ownedTokensCount[_from]--;
    //         // once the horse is transferred also clear sire allowances
    //         delete sireApprovals[_tokenId];
    //         // clear any previously approved ownership exchange
    //         delete tokenApprovals[_tokenId];
    //     }
    //     // Emit the transfer event.
    //     emit Transfer(_from, _to, _tokenId);
    // }

  /**
   * @dev Returns an URI for a given token ID
   * Throws if the token ID does not exist. May return an empty string.
   * @param _tokenId uint256 ID of the token to query
   */
    function tokenURI(uint256 _tokenId) public view returns (string) {
        require(exists(_tokenId));
        return tokenURIs[_tokenId];
    }

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

    /// @dev An internal method that creates a new horse and stores it. This
    ///  method doesn't do any checking and should only be called when the
    ///  input data is known to be valid. Will generate both a Birth event
    ///  and a Transfer event.
    /// @param _matronId The horsey ID of the matron of this horse (zero for gen0)
    /// @param _sireId The horsey ID of the sire of this horse (zero for gen0)
    /// @param _generation The generation number of this horse, must be computed by caller.
    /// @param _gene The horse's genetic code
    /// @param _owner The inital owner of this horse, must be non-zero (except for Pegasus, ID 0)
    function _createToken(
        uint256 _matronId,
        uint256 _sireId,
        uint256 _generation,
        uint256 _gene,
        address _owner
    )
        internal
        returns (uint)
    {
        // require(_to != address(0));       
        // These requires are not strictly necessary, our calling code should make
        // sure that these conditions are never broken. However! _createToken() is already
        // an expensive call (for storage), and it doesn't hurt to be especially careful
        // to ensure our data structures are always valid.
        require(_matronId == uint256(uint32(_matronId)));
        require(_sireId == uint256(uint32(_sireId)));
        require(_generation == uint256(uint16(_generation)));

        // New horse starts with the same cooldown as parent gen/2
        uint16 cooldownIndex = uint16(_generation / 2);
        if (cooldownIndex > 13) {
            cooldownIndex = 13;
        }

        NFT memory _new = NFT({
            gene: _gene,
            birthTime: uint64(now),
            cooldownEndBlock: 0,
            matronId: uint32(_matronId),
            sireId: uint32(_sireId),
            siringWithId: 0,
            cooldownIndex: cooldownIndex,
            generation: uint16(_generation)
        });
        uint256 newTokenId = collection.push(_new) - 1;

        // It's probably never going to happen, 4 billion horses is A LOT, but
        // let's just be 100% sure we never let this happen.
        require(newTokenId == uint256(uint32(newTokenId)));

        // emit the birth event
        emit Birth(_owner, newTokenId, uint256(_new.matronId), uint256(_new.sireId), _new.gene);

        // This will assign ownership, and also emit the Transfer event as
        // per ERC721 draft
        // _transfer(0, _owner, newTokenId);
        addTokenTo(_owner, newTokenId);
        emit Transfer(address(0), _owner, newTokenId);

        // allTokensIndex[newTokenId] = allTokens.length;
        // allTokens.push(newTokenId);

        return newTokenId;
    }

    // Any C-level can fix how many seconds per blocks are currently observed.
    function setSecondsPerBlock(uint256 secs) external onlyCLevel {
        require(secs < cooldowns[0]);
        secondsPerBlock = secs;
    }
//================================================//    
// }

// contract Ownership is Base /*, ERC721 */ {
//     using SafeMath for uint256;
//     using AddressUtils for address;

//================================================//
    /// @notice Name and symbol of the non fungible token, as defined in ERC721.

    // string public constant name = "ERC721";
    // string public constant symbol = "ERC721";

    // Token name
    string internal name_;

    // Token symbol
    string internal symbol_;    

    // bytes4 constant InterfaceSignature_ERC165 =
    //     bytes4(keccak256('supportsInterface(bytes4)')); ///////in SupportsInterfaceWithLookup.sol
    
    bytes4 private constant InterfaceId_ERC721Exists = 0x4f558e79;
    /*
    * 0x4f558e79 ===
    *   bytes4(keccak256('exists(uint256)'))
    */

    bytes4 private constant ERC721_RECEIVED = 0x150b7a02;    

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

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

    // bytes4 constant InterfaceSignature_ERC721 = ///////DEPRACATED SEE BELOW
    //     bytes4(keccak256('name()')) ^
    //     bytes4(keccak256('symbol()')) ^
    //     bytes4(keccak256('totalSupply()')) ^
    //     bytes4(keccak256('balanceOf(address)')) ^
    //     bytes4(keccak256('ownerOf(uint256)')) ^
    //     bytes4(keccak256('approve(address,uint256)')) ^
    //     bytes4(keccak256('transfer(address,uint256)')) ^
    //     bytes4(keccak256('transferFrom(address,address,uint256)')) ^
    //     bytes4(keccak256('tokensOfOwner(address)')) ^
    //     bytes4(keccak256('tokenMetadata(uint256,string)'));

    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)'))
       */
    /// @notice Introspection interface as per ERC-165 (https://github.com/ethereum/EIPs/issues/165).
    ///  Returns true for any standardized interfaces implemented by this contract. We implement
    ///  ERC-165 (obviously!) and ERC-721.
    // function supportsInterface(bytes4 _interfaceID) external view returns (bool) ///////in SupportsInterfaceWithLookup.sol
    // {
    //     // DEBUG ONLY
    //     //require((InterfaceSignature_ERC165 == 0x01ffc9a7) && (InterfaceSignature_ERC721 == 0x9a20483d));

    //     return ((_interfaceID == InterfaceSignature_ERC165) || (_interfaceID == InterfaceSignature_ERC721));
    // }

    constructor(string _name, string _symbol) public { 
        name_ = _name;
        symbol_ = _symbol;

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

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

  /**
   * @dev Gets the token symbol
   * @return string representing the token symbol
   */
    function symbol() external view returns (string) { 
        return symbol_;
    }
    // Internal utility functions: These functions all assume that their input arguments
    // are valid. We leave it to public methods to sanitize their inputs and follow
    // the required logic.

    /// @dev Checks if a given address is the current owner of a particular Horse.
    /// @param _claimant the address we are validating against.
    /// @param _tokenId horse id, only valid when > 0
    function _owns(address _claimant, uint256 _tokenId) internal view returns (bool) {
        return tokenOwner[_tokenId] == _claimant;
    }

    /// @dev Checks if a given address currently has transferApproval for a particular Horse.
    /// @param _claimant the address we are confirming horse is approved for.
    /// @param _tokenId horse id, only valid when > 0
    function _approvedFor(address _claimant, uint256 _tokenId) internal view returns (bool) {
        return tokenApprovals[_tokenId] == _claimant;
    }

    // /// @dev Marks an address as being approved for transferFrom(), overwriting any previous
    // ///  approval. Setting _approved to address(0) clears all transfer approval.
    // ///  NOTE: _approve() does NOT send the Approval event. This is intentional because
    // ///  _approve() and transferFrom() are used together for putting Horses on auction, and
    // ///  there is no value in spamming the log with Approval events in that case.
    // function _approve(uint256 _tokenId, address _approved) internal {
    //     tokenApprovals[_tokenId] = _approved;
    // }

    // /// @notice Returns the number of Horses owned by a specific address.
    // /// @param _owner The owner address to check.
    // /// @dev Required for ERC-721 compliance
    // function balanceOf(address _owner) public view returns (uint256 count) {
    //     require(_owner != address(0));
    //     return ownedTokensCount[_owner];
    // }

    /**
    * @dev Gets the balance of the specified address
    * @param _owner address to query the balance of
    * @return uint256 representing the amount owned by the passed address
    */
    function balanceOf(address _owner) public view returns (uint256) {
        require(_owner != address(0));
        return ownedTokensCount[_owner];
    }

    ////// DEPRECATED
    // /// @notice Transfers a Horse to another address. If transferring to a smart
    // ///  contract be VERY CAREFUL to ensure that it is aware of ERC-721 or your Horse may be lost forever. Seriously.
    // /// @param _to The address of the recipient, can be a user or contract.
    // /// @param _tokenId The ID of the Horse to transfer.
    // /// @dev Required for ERC-721 compliance.
    // function transfer(
    //     address _to,
    //     uint256 _tokenId
    // )
    //     external
    //     whenNotPaused
    // {
    //     // Safety check to prevent against an unexpected 0x0 default.
    //     require(_to != address(0));
    //     // Disallow transfers to this contract to prevent accidental misuse.
    //     // The contract should never own any horsies (except very briefly
    //     // after a gen0 horse is created and before it goes on auction).
    //     require(_to != address(this));
    //     // Disallow transfers to the auction contracts to prevent accidental
    //     // misuse. Auction contracts should only take ownership of horses
    //     // through the allow + transferFrom flow.
    //     require(_to != address(saleAuction));
    //     require(_to != address(siringAuction));

    //     // You can only send your own horse.
    //     require(_owns(msg.sender, _tokenId));

    //     // Reassign ownership, clear pending approvals, emit Transfer event.
    //     _transfer(msg.sender, _to, _tokenId);
    // }

    // /// @notice Grant another address the right to transfer a specific Horse via
    // ///  transferFrom(). This is the preferred flow for transfering NFTs to contracts.
    // /// @param _to The address to be granted transfer approval. Pass address(0) to
    // ///  clear all approvals.
    // /// @param _tokenId The ID of the Horse that can be transferred if this call succeeds.
    // /// @dev Required for ERC-721 compliance.
    // function approve(
    //     address _to,
    //     uint256 _tokenId
    // )
    //     external
    //     whenNotPaused
    // {
    //     // Only an owner can grant transfer approval.
    //     require(_owns(msg.sender, _tokenId));

    //     // Register the approval (replacing any previous approval).
    //     // _approve(_tokenId, _to);
    //     tokenApprovals[_tokenId] = _to; //_approved;

    //     // Emit approval event.
    //     emit Approval(msg.sender, _to, _tokenId);
    // }

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

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

    /**
    * @dev Gets the approved address for a token ID, or zero if no address set
    * @param _tokenId uint256 ID of the token to query the approval of
    * @return address currently approved for the given token ID
    */
    function getApproved(uint256 _tokenId) public view returns (address) {
        return tokenApprovals[_tokenId];
    }

    /**
    * @dev Sets or unsets the approval of a given operator
    * An operator is allowed to transfer all tokens of the sender on their behalf
    * @param _to operator address to set the approval
    * @param _approved representing the status of the approval to be set
    */
    function setApprovalForAll(address _to, bool _approved) public {
        require(_to != msg.sender);
        operatorApprovals[msg.sender][_to] = _approved;
        emit ApprovalForAll(msg.sender, _to, _approved);
    }    

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

    // /// @notice Transfer a Horse owned by another address, for which the calling address
    // ///  has previously been granted transfer approval by the owner.
    // /// @param _from The address that owns the Horse to be transfered.
    // /// @param _to The address that should take ownership of the Horse. Can be any address,
    // ///  including the caller.
    // /// @param _tokenId The ID of the Horse to be transferred.
    // /// @dev Required for ERC-721 compliance.
    // function transferFrom(
    //     address _from,
    //     address _to,
    //     uint256 _tokenId
    // )
    //     external
    //     whenNotPaused
    // {
    //     // Safety check to prevent against an unexpected 0x0 default.
    //     require(_to != address(0));
    //     // Disallow transfers to this contract to prevent accidental misuse.
    //     // The contract should never own any horses (except very briefly
    //     // after a gen0 horse is created and before it goes on auction).
    //     require(_to != address(this));
    //     // Check for approval and valid ownership
    //     require(_approvedFor(msg.sender, _tokenId));
    //     require(_owns(_from, _tokenId));

    //     // Reassign ownership (also clears pending approvals and emits Transfer event).
    //     _transfer(_from, _to, _tokenId);
    // }

    // /// @notice Returns the total number of Horses currently in existence.
    // /// @dev Required for ERC-721 compliance.
    // function totalSupply() public view returns (uint) {
    //     return collection.length - 1;
    // }

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

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

  /**
   * @dev Internal function to set the token URI for a given token
   * Reverts if the token ID does not exist
   * @param _tokenId uint256 ID of the token to set its URI
   * @param _uri string URI to assign
   */
    function _setTokenURI(uint256 _tokenId, string _uri) internal {
        require(exists(_tokenId));
        tokenURIs[_tokenId] = _uri;
    }

  /**
   * @dev Transfers the ownership of a given token ID to another address
   * Usage of this method is discouraged, use `safeTransferFrom` whenever possible
   * Requires the msg sender to be the owner, approved, or operator
   * @param _from current owner of the token
   * @param _to address to receive the ownership of the given token ID
   * @param _tokenId uint256 ID of the token to be transferred
  */
    function transferFrom(address _from, address _to, uint256 _tokenId) public canTransfer(_tokenId) whenNotPaused {
        require(_from != address(0));
        require(_to != address(0));

        // require(_to != address(saleAuction));
        // require(_to != address(siringAuction));

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

        emit Transfer(_from, _to, _tokenId);
    }

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

  /**
   * @dev Safely transfers the ownership of a given token ID to another address
   * If the target address is a contract, it must implement `onERC721Received`,
   * which is called upon a safe transfer, and return the magic value
   * `bytes4(keccak256("onERC721Received(address,address,uint256,bytes)"))`; otherwise,
   * the transfer is reverted.
   * Requires the msg sender to be the owner, approved, or operator
   * @param _from current owner of the token
   * @param _to address to receive the ownership of the given token ID
   * @param _tokenId uint256 ID of the token to be transferred
   * @param _data bytes data to send along with a safe transfer check
   */
    function safeTransferFrom(address _from, address _to, uint256 _tokenId, bytes _data) public canTransfer(_tokenId) whenNotPaused {
        transferFrom(_from, _to, _tokenId);
        // solium-disable-next-line arg-overflow
        require(checkAndCallSafeTransfer(_from, _to, _tokenId, _data)); // FAILS BEFORE REACHING THIS
    }

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

    // /// @notice Returns the address currently assigned ownership of a given Horse.
    // /// @dev Required for ERC-721 compliance.
    // function ownerOf(uint256 _tokenId)
    //     external
    //     view
    //     returns (address owner)
    // {
    //     owner = tokenOwner[_tokenId];

    //     require(owner != address(0));
    // }

    /**
    * @dev Gets the owner of the specified token ID
    * @param _tokenId uint256 ID of the token to query the owner of
    * @return owner address currently marked as the owner of the given token ID
    */
    function ownerOf(uint256 _tokenId) public view returns (address) {
        address owner = tokenOwner[_tokenId];
        require(owner != address(0));
        return owner;
    }

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

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

    function clearSiringApproval(address _owner, uint256 _tokenId) internal {
        require(ownerOf(_tokenId) == _owner);
        if (sireApprovals[_tokenId] != address(0)) {
            sireApprovals[_tokenId] = address(0);
        }
    }

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

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

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

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

        // tokenOwner[_tokenId] = address(0);
    }

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

        // uint256 length = ownedTokens[_to].length;
        // ownedTokens[_to].push(_tokenId);
        // ownedTokensIndex[_tokenId] = length;
    }

  /**
   * @dev Returns whether the given spender can transfer a given token ID
   * @param _spender address of the spender to query
   * @param _tokenId uint256 ID of the token to be transferred
   * @return bool whether the msg.sender is approved for the given token ID,
   *  is an operator of the owner, or is the owner of the token
   */
    function isApprovedOrOwner(address _spender, uint256 _tokenId) internal view returns (bool) {
        address owner = ownerOf(_tokenId);
        // Disable solium check because of
        // https://github.com/duaraghav8/Solium/issues/175
        // solium-disable-next-line operator-whitespace
        return (
        _spender == owner ||
        getApproved(_tokenId) == _spender ||
        isApprovedForAll(owner, _spender)
        );
    }

    /// @notice Returns a list of all Horse IDs assigned to an address.
    /// @param _owner The owner whose Horses we are interested in.
    /// @dev This method MUST NEVER be called by smart contract code. First, it's fairly
    ///  expensive (it walks the entire Horse array looking for horses belonging to owner),
    ///  but 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 totalTokens = totalSupply();
            uint256 resultIndex = 0;

            // We count on the fact that all horses have IDs starting at 1 and increasing
            // sequentially up to the totalHorses count.
            uint256 tokenId;

            for (tokenId = 1; tokenId <= totalTokens; tokenId++) {
                if (tokenOwner[tokenId] == _owner) {
                    result[resultIndex] = tokenId;
                    resultIndex++;
                }
            }

            return result;
        }
    }
}

// File: /home/moncy/projects/planetpegasus/planet-pegasus-smart-contracts/contracts/modules/Breeding.sol

/// @title A facet of Core that manages NFT siring, gestation, and birth.
contract Breeding is Base {

    /// @dev The Pregnant event is fired when two horses successfully breed and the pregnancy
    ///  timer begins for the matron.
    event Pregnant(address owner, uint256 matronId, uint256 sireId, uint256 matronCooldownEndBlock, uint256 sireCooldownEndBlock);

    /// @notice The minimum payment required to use breedWithAuto(). This fee goes towards
    ///  the gas cost paid by whatever calls giveBirth(), and can be dynamically updated by
    ///  the COO role as the gas price changes.
    uint256 public autoBirthFee = 2 finney;         //0.002 ether

    // Keeps track of number of pregnant horsies.
    uint256 public pregnantTokens;

    uint256 public cooldownEtherRate = 1 finney;   // 0.001 ether

    /// @dev The address of the sibling contract that is used to implement the
    ///  truffle tic combination algorithm.
    GeneScienceInterface public geneScience;

    /// @dev Update the address of the genetic contract, can only be called by the CEO.
    /// @param _address An address of a GeneScience contract instance to be used from this point forward.
    function setGeneScienceAddress(address _address) external onlyCEO {
        GeneScienceInterface candidateContract = GeneScienceInterface(_address);

        // NOTE: verify that a contract is what we expect
        // https://github.com/Lunyr/crowdsale-contracts/blob/cfadd15986c30521d8ba7d5b6f57b4fefcc7ac38/contracts/LunyrToken.sol#L117
        require(candidateContract.isGeneScience());

        // Set the new contract address
        geneScience = candidateContract;
    }

    function setCooldownEtherRate(uint256 _rate) external onlyCTO {
        require(_rate > 0, "Rate may not be zero");
        cooldownEtherRate = _rate;
    }

    /// @dev Checks that a given horse is able to breed. Requires that the
    ///  current cooldown is finished (for sires) and also checks that there is
    ///  no pending pregnancy.
    function _isReadyToBreed(NFT _nft) internal view returns (bool) {
        // In addition to checking the cooldownEndBlock, we also need to check to see if
        // the horse has a pending birth; there can be some period of time between the end
        // of the pregnacy timer and the birth event.
        return (_nft.siringWithId == 0) && (_nft.cooldownEndBlock <= uint64(block.number));
    }

    /// @dev Check if a sire has authorized breeding with this matron. True if both sire
    ///  and matron have the same owner, or if the sire has given siring permission to
    ///  the matron's owner (via approveSiring()).
    function _isSiringPermitted(uint256 _sireId, uint256 _matronId) internal view returns (bool) {
        address matronOwner = tokenOwner[_matronId];
        address sireOwner = tokenOwner[_sireId];

        // Siring is okay if they have same owner, or if the matron's owner was given
        // permission to breed with this sire.
        return (matronOwner == sireOwner || sireApprovals[_sireId] == matronOwner);
    }

    /// @dev Set the cooldownEndTime for the given Horse, based on its current cooldownIndex.
    ///  Also increments the cooldownIndex (unless it has hit the cap).
    /// @param _nft A reference to the NFT in storage which needs its timer started.
    function _triggerCooldown(NFT storage _nft) internal {
        // Compute an estimation of the cooldown time in blocks (based on current cooldownIndex).
        _nft.cooldownEndBlock = uint64((cooldowns[_nft.cooldownIndex]/secondsPerBlock) + block.number);

        // Increment the breeding count, clamping it at 13, which is the length of the
        // cooldowns array. We could check the array size dynamically, but hard-coding
        // this as a constant saves gas. Yay, Solidity!
        if (_nft.cooldownIndex < 13) {
            _nft.cooldownIndex += 1;
        }
    }

    /// @dev Reduce the cooldownEndTime for the given NFT.
    /// @param _id A reference to the NFT in storage which needs its timer started.
    function reduceCooldown(uint256 _id) payable external onlyOwnerOf(_id) nonReentrant {
        NFT storage _nft = collection[_id];

        uint256 reductionCost = _computeCooldownCost(_nft);

        if(reductionCost == 0) {
            revert();
        }

        // uint256 cost = duration * cooldownEtherRate;
        require(msg.value >= reductionCost, "Insufficient payment to reduce current cooldown");

        _nft.cooldownEndBlock = uint64(block.number);
        (msg.sender).transfer(msg.value - reductionCost);
    }

    /// @dev Calculates the cost to reduce current cooldown
    /// @param _id The token ID whose cooldown cost is being queried
    function getCooldownCost(uint256 _id) external view returns(uint256 cost) {
        NFT storage _nft = collection[_id];
        cost = _computeCooldownCost(_nft);
    }

    /// @dev internal method handling cooldown cost computation
    /// @param _nft The token whose cooldown cost is being queried
    function _computeCooldownCost(NFT memory _nft) internal view returns(uint256) {
        // duration is zero for cooldowns less than an hour
        // uint256 duration = ((_nft.cooldownEndBlock - block.number) * secondsPerBlock) / (1 hours);
        // cost is correspondingly zero for cooldowns below an hour
        // cost = duration * cooldownEtherRate;
        // bypass unecessary intermediate variable
        return uint256((((_nft.cooldownEndBlock - block.number) * secondsPerBlock) / (1 hours)) * cooldownEtherRate);
    }

    /// @notice Grants approval to another user to sire with one of your Horses.
    /// @param _addr The address that will be able to sire with your Horse. Set to
    ///  address(0) to clear all siring approvals for this Horse.
    /// @param _sireId A Horse that you own that _addr will now be able to sire with.
    function approveSiring(address _addr, uint256 _sireId)
        external
        whenNotPaused
    {
        require(_owns(msg.sender, _sireId));
        sireApprovals[_sireId] = _addr;
    }

    /// @dev Updates the minimum payment required for calling giveBirthAuto(). Can only
    ///  be called by the COO address. (This fee is used to offset the gas cost incurred
    ///  by the autobirth daemon).
    function setAutoBirthFee(uint256 val) external onlyCOO {
        autoBirthFee = val;
    }

    /// @dev Checks to see if a given Horse is pregnant and (if so) if the gestation
    ///  period has passed.
    function _isReadyToGiveBirth(NFT _matron) private view returns (bool) {
        return (_matron.siringWithId != 0) && (_matron.cooldownEndBlock <= uint64(block.number));
    }

    /// @notice Checks that a given horse is able to breed (i.e. it is not pregnant or
    ///  in the middle of a siring cooldown).
    /// @param _nftId reference the id of the horse, any user can inquire about it
    function isReadyToBreed(uint256 _nftId)
        public
        view
        returns (bool)
    {
        require(_nftId > 0);
        NFT storage token = collection[_nftId];
        return _isReadyToBreed(token);
    }

    /// @dev Checks whether a horsey is currently pregnant.
    /// @param _nftId reference the id of the horse, any user can inquire about it
    function isPregnant(uint256 _nftId)
        public
        view
        returns (bool)
    {
        require(_nftId > 0);
        // A horse is pregnant if and only if this field is set
        return collection[_nftId].siringWithId != 0;
    }

    /// @dev Internal check to see if a given sire and matron are a valid mating pair. DOES NOT
    ///  check ownership permissions (that is up to the caller).
    /// @param _matron A reference to the Horse struct of the potential matron.
    /// @param _matronId The matron's ID.
    /// @param _sire A reference to the Horse struct of the potential sire.
    /// @param _sireId The sire's ID
    function _isValidMatingPair(
        NFT storage _matron,
        uint256 _matronId,
        NFT storage _sire,
        uint256 _sireId
    )
        private
        view
        returns(bool)
    {
        // A Horse can't breed with itself!
        if (_matronId == _sireId) {
            return false;
        }

        // Horses can't breed with their parents.
        if (_matron.matronId == _sireId || _matron.sireId == _sireId) {
            return false;
        }
        if (_sire.matronId == _matronId || _sire.sireId == _matronId) {
            return false;
        }

        // We can short circuit the sibling check (below) if either horse is
        // gen zero (has a matron ID of zero).
        if (_sire.matronId == 0 || _matron.matronId == 0) {
            return true;
        }

        // Horses can't breed with full or half siblings.
        if (_sire.matronId == _matron.matronId || _sire.matronId == _matron.sireId) {
            return false;
        }
        if (_sire.sireId == _matron.matronId || _sire.sireId == _matron.sireId) {
            return false;
        }

        // Everything seems cool! Let's get DTF.
        return true;
    }

    /// @dev Internal check to see if a given sire and matron are a valid mating pair for
    ///  breeding via auction (i.e. skips ownership and siring approval checks).
    function _canBreedWithViaAuction(uint256 _matronId, uint256 _sireId)
        internal
        view
        returns (bool)
    {
        NFT storage matron = collection[_matronId];
        NFT storage sire = collection[_sireId];
        return _isValidMatingPair(matron, _matronId, sire, _sireId);
    }

    /// @notice Checks to see if two horses can breed together, including checks for
    ///  ownership and siring approvals. Does NOT check that both horses are ready for
    ///  breeding (i.e. breedWith could still fail until the cooldowns are finished).
    /// @param _matronId The ID of the proposed matron.
    /// @param _sireId The ID of the proposed sire.
    function canBreedWith(uint256 _matronId, uint256 _sireId)
        external
        view
        returns(bool)
    {
        require(_matronId > 0);
        require(_sireId > 0);
        NFT storage matron = collection[_matronId];
        NFT storage sire = collection[_sireId];
        return _isValidMatingPair(matron, _matronId, sire, _sireId) &&
            _isSiringPermitted(_sireId, _matronId);
    }

    /// @dev Internal utility function to initiate breeding, assumes that all breeding
    ///  requirements have been checked.
    function _breedWith(uint256 _matronId, uint256 _sireId) internal {
        // Grab a reference to the Horses from storage.
        NFT storage sire = collection[_sireId];
        NFT storage matron = collection[_matronId];

        // Mark the matron as pregnant, keeping track of who the sire is.
        matron.siringWithId = uint32(_sireId);

        // Trigger the cooldown for both parents.
        _triggerCooldown(sire);
        _triggerCooldown(matron);

        // Clear siring permission for both parents. This may not be strictly necessary
        // but it's likely to avoid confusion!
        delete sireApprovals[_matronId];
        delete sireApprovals[_sireId];

        // Every time a horse gets pregnant, counter is incremented.
        pregnantTokens++;

        // Emit the pregnancy event.
        emit Pregnant(tokenOwner[_matronId], _matronId, _sireId, matron.cooldownEndBlock, sire.cooldownEndBlock);
    }

    /// @notice Breed a Horse you own (as matron) with a sire that you own, or for which you
    ///  have previously been given Siring approval. Will either make your horse pregnant, or will
    ///  fail entirely. Requires a pre-payment of the fee given out to the first caller of giveBirth()
    /// @param _matronId The ID of the Horse acting as matron (will end up pregnant if successful)
    /// @param _sireId The ID of the Horse acting as sire (will begin its siring cooldown if successful)
    function breedWithAuto(uint256 _matronId, uint256 _sireId)
        external
        payable
        whenNotPaused
    {
        // Checks for payment.
        require(msg.value >= autoBirthFee);

        // Caller must own the matron.
        require(_owns(msg.sender, _matronId));

        // Neither sire nor matron are allowed to be on auction during a normal
        // breeding operation, but we don't need to check that explicitly.
        // For matron: The caller of this function can't be the owner of the matron
        //   because the owner of a Horse on auction is the auction house, and the
        //   auction house will never call breedWith().
        // For sire: Similarly, a sire on auction will be owned by the auction house
        //   and the act of transferring ownership will have cleared any oustanding
        //   siring approval.
        // Thus we don't need to spend gas explicitly checking to see if either horse
        // is on auction.

        // Check that matron and sire are both owned by caller, or that the sire
        // has given siring permission to caller (i.e. matron's owner).
        // Will fail for _sireId = 0
        require(_isSiringPermitted(_sireId, _matronId));

        // Grab a reference to the potential matron
        NFT storage matron = collection[_matronId];

        // Make sure matron isn't pregnant, or in the middle of a siring cooldown
        require(_isReadyToBreed(matron));

        // Grab a reference to the potential sire
        NFT storage sire = collection[_sireId];

        // Make sure sire isn't pregnant, or in the middle of a siring cooldown
        require(_isReadyToBreed(sire));

        // Test that these horses are a valid mating pair.
        require(_isValidMatingPair(
            matron,
            _matronId,
            sire,
            _sireId
        ));

        // All checks passed, horse gets pregnant!
        _breedWith(_matronId, _sireId);
    }

    /// @notice Have a pregnant Horse give birth!
    /// @param _matronId A Horse ready to give birth.
    /// @return The Horse ID of the new horse.
    /// @dev Looks at a given Horse and, if pregnant and if the gestation period has passed,
    ///  combines the genes of the two parents to create a new horse. The new Horse is assigned
    ///  to the current owner of the matron. Upon successful completion, both the matron and the
    ///  new horse will be ready to breed again. Note that anyone can call this function (if they
    ///  are willing to pay the gas!), but the new horse always goes to the mother's owner.

	  /// Update this giveBirth to accept 2nd parameter - _cGene
    function giveBirth(uint256 _matronId, uint256 _cGene)
        external
        whenNotPaused
        returns(uint256)
    {
        // Grab a reference to the matron in storage.
        NFT storage matron = collection[_matronId];

        // Check that the matron is a valid horses.
        require(matron.birthTime != 0);

        // Check that the matron is pregnant, and that its time has come!
        require(_isReadyToGiveBirth(matron));

        // Grab a reference to the sire in storage.
        uint256 sireId = matron.siringWithId;
        NFT storage sire = collection[sireId];

        // Determine the higher generation number of the two parents
        uint16 parentGen = matron.generation;
        if (sire.generation > matron.generation) {
            parentGen = sire.generation;
        }

        // Call the gene mixing operation
        uint256 childGene;
        // (childGene) = geneScience.mixGenes(matron.gene, sire.gene, matron.cooldownEndBlock - 1);

              (childGene) = _cGene;

        // Make the new horse!
        address owner = tokenOwner[_matronId];
        uint256 newTokenId = _createToken(_matronId, matron.siringWithId, parentGen + 1, childGene, owner);

        // Clear the reference to sire from the matron (REQUIRED! Having siringWithId
        // set is what marks a matron as being pregnant.)
        delete matron.siringWithId;

        // Every time a horsey gives birth counter is decremented.
        pregnantTokens--;

        // Send the balance fee to the person who made birth happen.
        msg.sender.transfer(autoBirthFee);

        // return the new horse's ID
        return newTokenId;
    }
}

// File: /home/moncy/projects/planetpegasus/planet-pegasus-smart-contracts/contracts/modules/Auction.sol

/// @title Handles creating auctions for sale and siring of horses.
///  This wrapper of ReverseAuction exists only so that users can create
///  auctions with only one transaction.
contract Auction is Breeding {

    // @notice The auction contract variables are defined in Base to allow
    //  us to refer to them in Ownership to prevent accidental transfers.
    // `saleAuction` refers to the auction for gen0 and p2p sale of horsies.
    // `siringAuction` refers to the auction for siring rights of horsies.

    /// @dev Sets the reference to the sale auction.
    /// @param _address - Address of sale contract.
    function setSaleAuctionAddress(address _address) external onlyCEO {
        SaleClockAuction candidateContract = SaleClockAuction(_address);

        // NOTE: verify that a contract is what we expect 
        // https://github.com/Lunyr/crowdsale-contracts/blob/cfadd15986c30521d8ba7d5b6f57b4fefcc7ac38/contracts/LunyrToken.sol#L117
        require(candidateContract.isSaleClockAuction());

        // Set the new contract address
        saleAuction = candidateContract;
        
        operatorApprovals[address(this)][_address] = true; // approve sale auction
    }

    /// @dev Sets the reference to the siring auction.
    /// @param _address - Address of siring contract.
    function setSiringAuctionAddress(address _address) external onlyCEO {
        SiringClockAuction candidateContract = SiringClockAuction(_address);

        // NOTE: verify that a contract is what we expect 
        // https://github.com/Lunyr/crowdsale-contracts/blob/cfadd15986c30521d8ba7d5b6f57b4fefcc7ac38/contracts/LunyrToken.sol#L117
        require(candidateContract.isSiringClockAuction());

        // Set the new contract address
        siringAuction = candidateContract;
        
        // setApprovalForAll(siringAuction, true); Core will never sire place tokens for siring!
    }

    /// @dev Put an nft up for auction.
    ///  Does some ownership trickery to create auctions in one tx.
    function createSaleAuction(
        uint256 _nftId,
        uint256 _startingPrice,
        uint256 _endingPrice,
        uint256 _duration
    )
        external
        whenNotPaused
    {
        // Auction contract checks input sizes
        // If horse is already on any auction, this will throw
        // because it will be owned by the auction contract.
        require(_owns(msg.sender, _nftId));
        // Ensure the horsey is not pregnant to prevent the auction
        // contract accidentally receiving ownership of the child.
        // NOTE: the horse IS allowed to be in a cooldown.
        require(!isPregnant(_nftId));
        // _approve(_nftId, saleAuction);
        // Sale auction throws if inputs are invalid and clears
        // transfer and sire approval after escrowing the horsey.
        saleAuction.createAuction(
            _nftId,
            _startingPrice,
            _endingPrice,
            _duration,
            msg.sender
        );
    }

    /// @dev Put a horse up for auction to be sire.
    ///  Performs checks to ensure the horse can be sired, then
    ///  delegates to reverse auction.
    function createSiringAuction(
        uint256 _nftId,
        uint256 _startingPrice,
        uint256 _endingPrice,
        uint256 _duration
    )
        external
        whenNotPaused
    {
        // Auction contract checks input sizes
        // If horse is already on any auction, this will throw
        // because it will be owned by the auction contract.
        require(_owns(msg.sender, _nftId));
        require(isReadyToBreed(_nftId));
        // _approve(_nftId, siringAuction);
        // Siring auction throws if inputs are invalid and clears
        // transfer and sire approval after escrowing the horsey.
        siringAuction.createAuction(
            _nftId,
            _startingPrice,
            _endingPrice,
            _duration,
            msg.sender
        );
    }

    /// @dev Completes a siring auction by bidding.
    ///  Immediately breeds the winning matron with the sire on auction.
    /// @param _sireId - ID of the sire on auction.
    /// @param _matronId - ID of the matron owned by the bidder.
    function bidOnSiringAuction(
        uint256 _sireId,
        uint256 _matronId
    )
        external
        payable
        whenNotPaused
    {
        // Auction contract checks input sizes
        require(_owns(msg.sender, _matronId));
        require(isReadyToBreed(_matronId));
        require(_canBreedWithViaAuction(_matronId, _sireId));

        // Define the current price of the auction.
        uint256 currentPrice = siringAuction.getCurrentPrice(_sireId);
        require(msg.value >= currentPrice + autoBirthFee);

        // Siring auction will throw if the bid fails.
        siringAuction.bid.value(msg.value - autoBirthFee)(_sireId);
        _breedWith(uint32(_matronId), uint32(_sireId));
    }

    /// @dev Transfers the balance of the sale auction contract
    /// to the Core contract. We use two-step withdrawal to
    /// prevent two transfer calls in the auction bid function.
    function withdrawAuctionBalances() external onlyCLevel {
        saleAuction.withdrawBalance();
        siringAuction.withdrawBalance();
    }
}

// File: /home/moncy/projects/planetpegasus/planet-pegasus-smart-contracts/contracts/modules/Minting.sol

/// @title all functions related to creating horses
contract Minting is Auction {

    // Limits the number of horses the contract owner can ever create.
    uint256 public constant PROMO_CREATION_LIMIT = 5000;
    uint256 public constant GEN0_CREATION_LIMIT = 45000;

    // Constants for gen0 auctions.
    uint256 public constant GEN0_STARTING_PRICE = 10 finney;    //0.01 ether
    uint256 public constant GEN0_AUCTION_DURATION = 1 days;

    // Counts the number of horses the contract owner has created.
    uint256 public promoCreatedCount;
    uint256 public gen0CreatedCount;

    /// @dev we can create promo nfts, up to a limit. Only callable by COO
    /// @param _gene the encoded genes of the nft to be created, any value is accepted
    function createPromoTokenDebugger(uint256 _gene) external onlyCTO returns(uint256 nftId) {
        require(promoCreatedCount < PROMO_CREATION_LIMIT);

        promoCreatedCount++;
        nftId = _createToken(0, 0, 0, _gene, ctoAddress);
    }

    /// @dev we can create promo nfts, up to a limit. Only callable by COO
    /// @param _gene the encoded genes of the nft to be created, any value is accepted
    /// @param _owner the future owner of the created nfts. Default to contract COO
    function createPromoToken(uint256 _gene, address _owner) external onlyCTO returns(uint256 nftId) {
        require(promoCreatedCount < PROMO_CREATION_LIMIT);

        promoCreatedCount++;
        nftId = _createToken(0, 0, 0, _gene, _owner);
    }

    /// @dev Creates a new gen0 horse with the given genes and
    ///  creates an auction for it.
    function createGen0Auction(uint256 _gene) external onlyCTO {
        require(gen0CreatedCount < GEN0_CREATION_LIMIT);
        // require(gasleft() >= 400000, "Insufficient gas");

        uint256 nftId = _createToken(0, 0, 0, _gene, address(this));
    
        saleAuction.createAuction(
            nftId,
            _computeNextGen0Price(),
            0,
            GEN0_AUCTION_DURATION,
            address(this)
        );

        gen0CreatedCount++;
    }

    /// @dev Computes the next gen0 auction starting price, given
    ///  the average of the past 5 prices + 50%.
    function _computeNextGen0Price() internal view returns (uint256) {
        uint256 avePrice = saleAuction.averageGen0SalePrice();

        // Sanity check to ensure we don't overflow arithmetic
        require(avePrice == uint256(uint128(avePrice)));

        uint256 nextPrice = avePrice + (avePrice / 2);

        // We never auction for less than starting price
        if (nextPrice < GEN0_STARTING_PRICE) {
            nextPrice = GEN0_STARTING_PRICE;
        }

        return nextPrice;
    }
}

// File: /home/moncy/projects/planetpegasus/planet-pegasus-smart-contracts/contracts/modules/Modules.sol

// import "./ClockAuction.sol";
// import "./GeneScienceInterface.sol";
// import "./AccessControl.sol"; in Ownership.sol
// import "./Base.sol";
// import "./MiddleWare.sol";
// import "./Ownership.sol";
// import "./ERC721.sol";


contract Modules {}

// File: contracts/Core.sol

contract Core is Minting {

    // This is the main contract. In order to keep our code seperated into logical sections,
    // we've broken it up in two ways. First, we have several seperately-instantiated sibling contracts
    // that handle auctions and our super-top-secret genetic combination algorithm. The auctions are
    // seperate since their logic is somewhat complex and there's always a risk of subtle bugs. By keeping
    // them in their own contracts, we can upgrade them without disrupting the main contract that tracks
    // horsey ownership. The genetic combination algorithm is kept seperate so we can open-source all of
    // the rest of our code without making it _too_ easy for folks to figure out how the genetics work.
    // Don't worry, I'm sure someone will reverse engineer it soon enough!
    //
    // Secondly, we break the core contract into multiple files using inheritence, one for each major
    // facet of functionality of DBC. This allows us to keep related code bundled together while still
    // avoiding a single giant file with everything in it. The breakdown is as follows:
    //
    //      - Base: This is where we define the most fundamental code shared throughout the core
    //             functionality. This includes our main data storage, constants and data types, plus
    //             internal functions for managing these items.
    //
    //      - AccessControl: This contract manages the various addresses and constraints for operations
    //             that can be executed only by specific roles. Namely CEO, CFO and COO.
    //
    //      - Ownership: This provides the methods required for basic non-fungible token
    //             transactions, following the draft ERC-721 spec (https://github.com/ethereum/EIPs/issues/721).
    //
    //      - Breeding: This file contains the methods necessary to breed horses together, including
    //             keeping track of siring offers, and relies on an external genetic combination contract.
    //
    //      - Auction: Here we have the public methods for auctioning or bidding on horses or siring
    //             services. The actual auction functionality is handled in two sibling contracts (one
    //             for sales and one for siring), while auction creation and bidding is mostly mediated
    //             through this facet of the core contract.
    //
    //      - Minting: This final facet contains the functionality we use for creating new gen0 horses.
    //             We can make up to 5000 "promo" horses that can be given away (especially important when
    //             the community is new), and all others can only be created and then immediately put up
    //             for auction via an algorithmically determined starting price. Regardless of how they
    //             are created, there is a hard limit of 50k gen0 horses. After that, it's all up to the
    //             community to breed, breed, breed!

    // Set in case the core contract is broken and an upgrade is required
    address public newContractAddress;

    /// @notice Creates the main smart contract instance.
    constructor() public
        Base("PlanetPegasus", "PEGASUS")
    {

        // Starts paused.
        paused = true;

        // the creator is also the CTO
        ctoAddress = msg.sender;

        // start with the zero nft (ID 0) - so we don't have generation-0 parent issues
        _createToken(0, 0, 0, uint256(-1), address(0));

        // saleAuction = new SaleClockAuction(address(this));
    }

    // function deploySaleAuction() external onlyCTO {
    //     saleAuction = new SaleClockAuction(address(this), ctoAddress);
    //     setApprovalForAll(saleAuction, true);
    // }

    // function deploySiringAuction() external onlyCTO {
    //     siringAuction = new SiringClockAuction(address(this), ctoAddress);
    // }

    /// @dev Used to mark the smart contract as upgraded, in case there is a serious
    ///  breaking bug. This method does nothing but keep track of the new contract and
    ///  emit a message indicating that the new address is set. It's up to clients of this
    ///  contract to update to the new contract address in that case. (This contract will
    ///  be paused indefinitely if such an upgrade takes place.)
    /// @param _v2Address new address
    function setNewAddress(address _v2Address) external onlyCEO whenPaused {
        // See README.md for updgrade plan
        newContractAddress = _v2Address;
        emit ContractUpgrade(_v2Address);
    }

    /// @notice No tipping!
    /// @dev Reject all Ether from being sent here, unless it's from one of the
    ///  two auction contracts. (Hopefully, we can prevent user accidents.)
    function() external payable {
        require(
            msg.sender == address(saleAuction) ||
            msg.sender == address(siringAuction)
        );
    }

    /// @notice Returns all the relevant information about a specific horse.
    /// @param _id The ID of the horse of interest.
    function getNFT(uint256 _id)
        external
        view
        returns (
        bool isGestating,
        bool isReady,
        uint256 cooldownIndex,
        uint256 nextActionAt,
        uint256 siringWithId,
        uint256 birthTime,
        uint256 matronId,
        uint256 sireId,
        uint256 generation,
        uint256 gene
    ) {

        NFT storage _nft = collection[_id];

        // if this variable is 0 then it's not gestating
        isGestating = (_nft.siringWithId != 0);
        isReady = (_nft.cooldownEndBlock <= block.number);
        cooldownIndex = uint256(_nft.cooldownIndex);
        nextActionAt = uint256(_nft.cooldownEndBlock);
        siringWithId = uint256(_nft.siringWithId);
        birthTime = uint256(_nft.birthTime);
        matronId = uint256(_nft.matronId);
        sireId = uint256(_nft.sireId);
        generation = uint256(_nft.generation);
        gene = _nft.gene;
    }

    /// @dev Override unpause so it requires all external contract addresses
    ///  to be set before contract can be unpaused. Also, we can't have
    ///  newContractAddress set either, because then the contract was upgraded.
    /// @notice This is public rather than external so we can call super.unpause
    ///  without using an expensive CALL.
    function unpause() public onlyCEO whenPaused {
        require(saleAuction != address(0));
        require(siringAuction != address(0));
        require(geneScience != address(0));
        require(newContractAddress == address(0));

        // Actually unpause the contract.
        super.unpause();
    }

    // @dev Allows the CFO to capture the balance available to the contract.
    function withdrawBalance() external onlyCFO {
        uint256 balance = address(this).balance;
        // Subtract all the currently pregnant horses we have, plus 1 of margin.
        uint256 subtractFees = (pregnantTokens + 1) * autoBirthFee;

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

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":"_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":true,"inputs":[],"name":"GEN0_STARTING_PRICE","outputs":[{"name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"name":"_address","type":"address"}],"name":"setSiringAuctionAddress","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":"_nftId","type":"uint256"}],"name":"isPregnant","outputs":[{"name":"","type":"bool"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"GEN0_AUCTION_DURATION","outputs":[{"name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"InterfaceId_ERC165","outputs":[{"name":"","type":"bytes4"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"ctoAddress","outputs":[{"name":"","type":"address"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"siringAuction","outputs":[{"name":"","type":"address"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"name":"_from","type":"address"},{"name":"_to","type":"address"},{"name":"_tokenId","type":"uint256"}],"name":"transferFrom","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"name":"_address","type":"address"}],"name":"setGeneScienceAddress","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"name":"_newCEO","type":"address"}],"name":"setCEO","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"name":"_newCOO","type":"address"}],"name":"setCOO","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"name":"_gene","type":"uint256"},{"name":"_owner","type":"address"}],"name":"createPromoToken","outputs":[{"name":"nftId","type":"uint256"}],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"name":"_nftId","type":"uint256"},{"name":"_startingPrice","type":"uint256"},{"name":"_endingPrice","type":"uint256"},{"name":"_duration","type":"uint256"}],"name":"createSaleAuction","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[],"name":"unpause","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"name":"_from","type":"address"},{"name":"_to","type":"address"},{"name":"_tokenId","type":"uint256"}],"name":"safeTransferFrom","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[{"name":"_matronId","type":"uint256"},{"name":"_sireId","type":"uint256"}],"name":"canBreedWith","outputs":[{"name":"","type":"bool"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"name":"_nftId","type":"uint256"},{"name":"_startingPrice","type":"uint256"},{"name":"_endingPrice","type":"uint256"},{"name":"_duration","type":"uint256"}],"name":"createSiringAuction","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"name":"val","type":"uint256"}],"name":"setAutoBirthFee","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"name":"_addr","type":"address"},{"name":"_sireId","type":"uint256"}],"name":"approveSiring","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"name":"_newCFO","type":"address"}],"name":"setCFO","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[{"name":"_tokenId","type":"uint256"}],"name":"exists","outputs":[{"name":"","type":"bool"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"name":"_index","type":"uint256"}],"name":"tokenByIndex","outputs":[{"name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"name":"_gene","type":"uint256"}],"name":"createPromoTokenDebugger","outputs":[{"name":"nftId","type":"uint256"}],"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":"_id","type":"uint256"}],"name":"getNFT","outputs":[{"name":"isGestating","type":"bool"},{"name":"isReady","type":"bool"},{"name":"cooldownIndex","type":"uint256"},{"name":"nextActionAt","type":"uint256"},{"name":"siringWithId","type":"uint256"},{"name":"birthTime","type":"uint256"},{"name":"matronId","type":"uint256"},{"name":"sireId","type":"uint256"},{"name":"generation","type":"uint256"},{"name":"gene","type":"uint256"}],"payable":false,"stateMutability":"view","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":"_tokenId","type":"uint256"}],"name":"ownerOf","outputs":[{"name":"","type":"address"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"GEN0_CREATION_LIMIT","outputs":[{"name":"","type":"uint256"}],"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":false,"inputs":[{"name":"_rate","type":"uint256"}],"name":"setCooldownEtherRate","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[],"name":"secondsPerBlock","outputs":[{"name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"pregnantTokens","outputs":[{"name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"name":"_matronId","type":"uint256"},{"name":"_cGene","type":"uint256"}],"name":"giveBirth","outputs":[{"name":"","type":"uint256"}],"payable":false,"stateMutability":"nonpayable","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":true,"inputs":[{"name":"","type":"uint256"}],"name":"sireApprovals","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":"","type":"uint256"}],"name":"cooldowns","outputs":[{"name":"","type":"uint32"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"name":"_id","type":"uint256"}],"name":"getCooldownCost","outputs":[{"name":"cost","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"name":"_to","type":"address"},{"name":"_approved","type":"bool"}],"name":"setApprovalForAll","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[{"name":"","type":"uint256"}],"name":"tokenApprovals","outputs":[{"name":"","type":"address"}],"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":"autoBirthFee","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":"_gene","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":true,"inputs":[{"name":"_nftId","type":"uint256"}],"name":"isReadyToBreed","outputs":[{"name":"","type":"bool"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"PROMO_CREATION_LIMIT","outputs":[{"name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"saleAuction","outputs":[{"name":"","type":"address"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"name":"_id","type":"uint256"}],"name":"reduceCooldown","outputs":[],"payable":true,"stateMutability":"payable","type":"function"},{"constant":true,"inputs":[],"name":"cooldownEtherRate","outputs":[{"name":"","type":"uint256"}],"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":false,"inputs":[{"name":"_sireId","type":"uint256"},{"name":"_matronId","type":"uint256"}],"name":"bidOnSiringAuction","outputs":[],"payable":true,"stateMutability":"payable","type":"function"},{"constant":true,"inputs":[],"name":"gen0CreatedCount","outputs":[{"name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"geneScience","outputs":[{"name":"","type":"address"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"name":"_matronId","type":"uint256"},{"name":"_sireId","type":"uint256"}],"name":"breedWithAuto","outputs":[],"payable":true,"stateMutability":"payable","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":"matronId","type":"uint256"},{"indexed":false,"name":"sireId","type":"uint256"},{"indexed":false,"name":"matronCooldownEndBlock","type":"uint256"},{"indexed":false,"name":"sireCooldownEndBlock","type":"uint256"}],"name":"Pregnant","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"name":"owner","type":"address"},{"indexed":false,"name":"tokenId","type":"uint256"},{"indexed":false,"name":"matronId","type":"uint256"},{"indexed":false,"name":"sireId","type":"uint256"},{"indexed":false,"name":"gene","type":"uint256"}],"name":"Birth","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"}]

Contract Creation Code

6003805460a060020a60ff02191690556005805460ff19169055610240604052603c6080908152607860a05261012c60c05261025860e05261070861010052610e1061012052611c2061014052613840610160526170806101805261e1006101a052620151806101c0526202a3006101e052620546006102005262093a80610220526200009190600690600e620006ed565b50600f60085566071afd498d000060145566038d7ea4c68000601655348015620000ba57600080fd5b50604080518082018252600d81527f506c616e6574506567617375730000000000000000000000000000000000000060208083019182528351808501909452600784527f5045474153555300000000000000000000000000000000000000000000000000908401528151919291620001359160129162000790565b5080516200014b90601390602084019062000790565b50620001807f01ffc9a700000000000000000000000000000000000000000000000000000000640100000000620002a9810204565b620001b47f780e9d6300000000000000000000000000000000000000000000000000000000640100000000620002a9810204565b620001e87f5b5e139f00000000000000000000000000000000000000000000000000000000640100000000620002a9810204565b6200021c7f80ac58cd00000000000000000000000000000000000000000000000000000000640100000000620002a9810204565b620002507f4f558e7900000000000000000000000000000000000000000000000000000000640100000000620002a9810204565b505060038054600160a060020a031960a060020a60ff021990911674010000000000000000000000000000000000000000171633179055620002a2600080806000198164010000000062000316810204565b5062000899565b7fffffffff000000000000000000000000000000000000000000000000000000008082161415620002d957600080fd5b7fffffffff00000000000000000000000000000000000000000000000000000000166000908152600460205260409020805460ff19166001179055565b6000806200032362000811565b600063ffffffff891689146200033857600080fd5b63ffffffff881688146200034b57600080fd5b61ffff871687146200035c57600080fd5b600287049250600d8361ffff1611156200037557600d92505b505060408051610100810182528581524267ffffffffffffffff90811660208301908152600093830184815263ffffffff8c8116606086019081528c82166080870190815260a0870188815261ffff8a811660c08a019081528f821660e08b01908152600980546001810182559c528a517f6e1540171b6c0c960b71a7020d9f60077f6af931a8bbf590da0223dacf75c7af60028e029081019190915598517f6e1540171b6c0c960b71a7020d9f60077f6af931a8bbf590da0223dacf75c7b0909901805498519651955194519251915167ffffffffffffffff19909916998b1699909917604060020a608060020a0319166801000000000000000096909a169590950298909817608060020a63ffffffff021916700100000000000000000000000000000000938616939093029290921760a060020a63ffffffff02191674010000000000000000000000000000000000000000918516919091021760c060020a63ffffffff0219167801000000000000000000000000000000000000000000000000968416969096029590951760e060020a61ffff0219167c01000000000000000000000000000000000000000000000000000000009186169190910217600160f060020a03167e010000000000000000000000000000000000000000000000000000000000009290941691909102929092179055909190811681146200057d57600080fd5b606080830151608080850151855160408051600160a060020a038c1681526020810188905263ffffffff95861681830152929094169482019490945290810192909252517f0a5311bd2a6608f08a180df2ee7c5946819a649b204b554bb8e39825b2c50ad59181900360a00190a162000600858264010000000062000644810204565b6040518190600160a060020a038716906000907fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef908290a498975050505050505050565b6000818152600a6020526040902054600160a060020a0316156200066757600080fd5b6000818152600a602090815260408083208054600160a060020a031916600160a060020a0387169081179091558352600b909152902054620006b9906001640100000000620006d98102620037961704565b600160a060020a039092166000908152600b602052604090209190915550565b81810182811015620006e757fe5b92915050565b6002830191839082156200077e5791602002820160005b838211156200074a57835183826101000a81548163ffffffff021916908363ffffffff160217905550926020019260040160208160030104928301926001030262000704565b80156200077c5782816101000a81549063ffffffff02191690556004016020816003010492830192600103026200074a565b505b506200078c92915062000855565b5090565b828054600181600116156101000203166002900490600052602060002090601f016020900481019282601f10620007d357805160ff191683800117855562000803565b8280016001018555821562000803579182015b8281111562000803578251825591602001919060010190620007e6565b506200078c9291506200087c565b6040805161010081018252600080825260208201819052918101829052606081018290526080810182905260a0810182905260c0810182905260e081019190915290565b6200087991905b808211156200078c57805463ffffffff191681556001016200085c565b90565b6200087991905b808211156200078c576000815560010162000883565b61390480620008a96000396000f3006080604052600436106103135763ffffffff60e060020a60003504166301ffc9a781146103435780630519ce791461037957806305e45546146103aa57806306fdde03146103d1578063081812fc1461045b578063095ea7b3146104735780630a0f8168146104975780630e583df0146104ac57806314001f4c146104c157806318160ddd146104e25780631940a936146104f757806319c2f2011461050f57806319fa8f50146105245780631f5136601461055657806321717ebf1461056b57806323b872dd1461058057806324e7a38a146105aa57806327d7874c146105cb5780632ba73c15146105ec578063314cd12c1461060d5780633d7d3f5a146106315780633f4ba83a1461065257806342842e0e1461066757806346d22c70146106915780634ad8c938146106ac5780634b85fd55146106cd5780634dfff04f146106e55780634e0a3379146107095780634f558e791461072a5780634f6ccce714610742578063541d26f91461075a5780635663896e14610772578063576f7ea71461078a5780635c975abb146107f45780635fd8c710146108095780636352211e1461081e578063680eba27146108365780636af04a571461084b5780636fbde40d1461086057806370a082311461088157806371587988146108a2578063769fbf19146108c35780637a7d4937146108db5780637a81dc0c146108f05780637b422184146109055780638456cb59146109205780638462151c1461093557806391876e57146109a657806391c4b6de146109bb57806395d89b41146109d35780639d6fac6f146109e85780639d754c8014610a19578063a22cb46514610a31578063acdeb5b914610a57578063b047fb5014610a6f578063b0c35c0514610a84578063b88d4fde14610a99578063c3bea9af14610b08578063c87b56dd14610b20578063d3e6f49f14610b38578063defb958414610b50578063e6cbe35114610b65578063e8891de814610b7a578063e91a507a14610b85578063e985e9c514610b9a578063ed60ade614610bc1578063f1ca941014610bcf578063f2b47d5214610be4578063f7d8c88314610bf9575b601054600160a060020a03163314806103365750601154600160a060020a031633145b151561034157600080fd5b005b34801561034f57600080fd5b50610365600160e060020a031960043516610c07565b604080519115158252519081900360200190f35b34801561038557600080fd5b5061038e610c26565b60408051600160a060020a039092168252519081900360200190f35b3480156103b657600080fd5b506103bf610c35565b60408051918252519081900360200190f35b3480156103dd57600080fd5b506103e6610c3b565b6040805160208082528351818301528351919283929083019185019080838360005b83811015610420578181015183820152602001610408565b50505050905090810190601f16801561044d5780820380516001836020036101000a031916815260200191505b509250505060405180910390f35b34801561046757600080fd5b5061038e600435610cd1565b34801561047f57600080fd5b50610341600160a060020a0360043516602435610cec565b3480156104a357600080fd5b5061038e610dad565b3480156104b857600080fd5b506103bf610dbc565b3480156104cd57600080fd5b50610341600160a060020a0360043516610dc7565b3480156104ee57600080fd5b506103bf610e91565b34801561050357600080fd5b50610365600435610e97565b34801561051b57600080fd5b506103bf610edc565b34801561053057600080fd5b50610539610ee3565b60408051600160e060020a03199092168252519081900360200190f35b34801561056257600080fd5b5061038e610f07565b34801561057757600080fd5b5061038e610f16565b34801561058c57600080fd5b50610341600160a060020a0360043581169060243516604435610f25565b3480156105b657600080fd5b50610341600160a060020a0360043516611052565b3480156105d757600080fd5b50610341600160a060020a036004351661111c565b3480156105f857600080fd5b50610341600160a060020a036004351661116a565b34801561061957600080fd5b506103bf600435600160a060020a03602435166111b8565b34801561063d57600080fd5b50610341600435602435604435606435611200565b34801561065e57600080fd5b506103416112de565b34801561067357600080fd5b50610341600160a060020a0360043581169060243516604435611389565b34801561069d57600080fd5b50610365600435602435611449565b3480156106b857600080fd5b506103416004356024356044356064356114c9565b3480156106d957600080fd5b5061034160043561158a565b3480156106f157600080fd5b50610341600160a060020a03600435166024356115bd565b34801561071557600080fd5b50610341600160a060020a0360043516611617565b34801561073657600080fd5b50610365600435611665565b34801561074e57600080fd5b506103bf600435611682565b34801561076657600080fd5b506103bf60043561169b565b34801561077e57600080fd5b506103416004356116f2565b34801561079657600080fd5b506107a2600435611763565b604080519a15158b5298151560208b0152898901979097526060890195909552608088019390935260a087019190915260c086015260e085015261010084015261012083015251908190036101400190f35b34801561080057600080fd5b506103656118c4565b34801561081557600080fd5b506103416118d4565b34801561082a57600080fd5b5061038e600435611961565b34801561084257600080fd5b506103bf611985565b34801561085757600080fd5b5061038e61198b565b34801561086c57600080fd5b50610341600160a060020a036004351661199a565b34801561088d57600080fd5b506103bf600160a060020a0360043516611a88565b3480156108ae57600080fd5b50610341600160a060020a0360043516611abb565b3480156108cf57600080fd5b50610341600435611b55565b3480156108e757600080fd5b506103bf611bc9565b3480156108fc57600080fd5b506103bf611bcf565b34801561091157600080fd5b506103bf600435602435611bd5565b34801561092c57600080fd5b50610341611dfd565b34801561094157600080fd5b50610956600160a060020a0360043516611e92565b60408051602080825283518183015283519192839290830191858101910280838360005b8381101561099257818101518382015260200161097a565b505050509050019250505060405180910390f35b3480156109b257600080fd5b50610341611f64565b3480156109c757600080fd5b5061038e60043561208e565b3480156109df57600080fd5b506103e66120a9565b3480156109f457600080fd5b50610a0060043561210a565b6040805163ffffffff9092168252519081900360200190f35b348015610a2557600080fd5b506103bf600435612137565b348015610a3d57600080fd5b50610341600160a060020a036004351660243515156121f4565b348015610a6357600080fd5b5061038e600435612278565b348015610a7b57600080fd5b5061038e612293565b348015610a9057600080fd5b506103bf6122a2565b348015610aa557600080fd5b50604080516020601f60643560048181013592830184900484028501840190955281845261034194600160a060020a0381358116956024803590921695604435953695608494019181908401838280828437509497506122a89650505050505050565b348015610b1457600080fd5b5061034160043561236f565b348015610b2c57600080fd5b506103e6600435612442565b348015610b4457600080fd5b506103656004356124f7565b348015610b5c57600080fd5b506103bf6125bf565b348015610b7157600080fd5b5061038e6125c5565b6103416004356125d4565b348015610b9157600080fd5b506103bf6127cb565b348015610ba657600080fd5b50610365600160a060020a03600435811690602435166127d1565b6103416004356024356127ff565b348015610bdb57600080fd5b506103bf612999565b348015610bf057600080fd5b5061038e61299f565b6103416004356024356129ae565b600160e060020a03191660009081526004602052604090205460ff1690565b600154600160a060020a031681565b60185481565b60128054604080516020601f6002600019610100600188161502019095169490940493840181900481028201810190925282815260609390929091830182828015610cc75780601f10610c9c57610100808354040283529160200191610cc7565b820191906000526020600020905b815481529060010190602001808311610caa57829003601f168201915b5050505050905090565b6000908152600c6020526040902054600160a060020a031690565b60035460009060a060020a900460ff1615610d0657600080fd5b610d0f82611961565b9050600160a060020a038381169082161415610d2a57600080fd5b33600160a060020a0382161480610d465750610d4681336127d1565b1515610d5157600080fd5b6000828152600c60205260408082208054600160a060020a031916600160a060020a0387811691821790925591518593918516917f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b92591a4505050565b600054600160a060020a031681565b662386f26fc1000081565b60008054600160a060020a0316331480610deb5750600354600160a060020a031633145b1515610df657600080fd5b81905080600160a060020a03166376190f8f6040518163ffffffff1660e060020a028152600401602060405180830381600087803b158015610e3757600080fd5b505af1158015610e4b573d6000803e3d6000fd5b505050506040513d6020811015610e6157600080fd5b50511515610e6e57600080fd5b60118054600160a060020a031916600160a060020a039290921691909117905550565b60095490565b6000808211610ea557600080fd5b6009805483908110610eb357fe5b600091825260209091206002909102016001015460c060020a900463ffffffff16151592915050565b6201518081565b7f01ffc9a70000000000000000000000000000000000000000000000000000000081565b600354600160a060020a031681565b601154600160a060020a031681565b80610f303382612bac565b1515610fac576040805160e560020a62461bcd02815260206004820152603960248201527f6d73672e73656e646572206973206e6f7420617070726f76656420746f20747260448201527f616e73666572206f6e20626568616c66206f66206f776e657200000000000000606482015290519081900360840190fd5b60035460a060020a900460ff1615610fc357600080fd5b600160a060020a0384161515610fd857600080fd5b600160a060020a0383161515610fed57600080fd5b610ff78483612c0b565b6110018483612ca7565b61100b8383612d30565b8183600160a060020a031685600160a060020a03167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef60405160405180910390a450505050565b60008054600160a060020a03163314806110765750600354600160a060020a031633145b151561108157600080fd5b81905080600160a060020a03166354c15b826040518163ffffffff1660e060020a028152600401602060405180830381600087803b1580156110c257600080fd5b505af11580156110d6573d6000803e3d6000fd5b505050506040513d60208110156110ec57600080fd5b505115156110f957600080fd5b60178054600160a060020a031916600160a060020a039290921691909117905550565b600354600160a060020a0316331461113357600080fd5b600160a060020a038116151561114857600080fd5b60008054600160a060020a031916600160a060020a0392909216919091179055565b600354600160a060020a0316331461118157600080fd5b600160a060020a038116151561119657600080fd5b60028054600160a060020a031916600160a060020a0392909216919091179055565b600354600090600160a060020a031633146111d257600080fd5b601854611388116111e257600080fd5b6018805460010190556111f9600080808686612db4565b9392505050565b60035460a060020a900460ff161561121757600080fd5b61122133856130c7565b151561122c57600080fd5b61123584610e97565b1561123f57600080fd5b601054604080517f27ebe40a000000000000000000000000000000000000000000000000000000008152600481018790526024810186905260448101859052606481018490523360848201529051600160a060020a03909216916327ebe40a9160a48082019260009290919082900301818387803b1580156112c057600080fd5b505af11580156112d4573d6000803e3d6000fd5b5050505050505050565b600054600160a060020a03163314806113015750600354600160a060020a031633145b151561130c57600080fd5b60035460a060020a900460ff16151561132457600080fd5b601054600160a060020a0316151561133b57600080fd5b601154600160a060020a0316151561135257600080fd5b601754600160a060020a0316151561136957600080fd5b601a54600160a060020a03161561137f57600080fd5b6113876130e7565b565b806113943382612bac565b1515611410576040805160e560020a62461bcd02815260206004820152603960248201527f6d73672e73656e646572206973206e6f7420617070726f76656420746f20747260448201527f616e73666572206f6e20626568616c66206f66206f776e657200000000000000606482015290519081900360840190fd5b60035460a060020a900460ff161561142757600080fd5b61144384848460206040519081016040528060008152506122a8565b50505050565b6000808080851161145957600080fd5b6000841161146657600080fd5b600980548690811061147457fe5b9060005260206000209060020201915060098481548110151561149357fe5b906000526020600020906002020190506114af8286838761314d565b80156114c057506114c084866132cc565b95945050505050565b60035460a060020a900460ff16156114e057600080fd5b6114ea33856130c7565b15156114f557600080fd5b6114fe846124f7565b151561150957600080fd5b601154604080517f27ebe40a000000000000000000000000000000000000000000000000000000008152600481018790526024810186905260448101859052606481018490523360848201529051600160a060020a03909216916327ebe40a9160a48082019260009290919082900301818387803b1580156112c057600080fd5b600154600160a060020a03163314806115ad5750600354600160a060020a031633145b15156115b857600080fd5b601455565b60035460a060020a900460ff16156115d457600080fd5b6115de33826130c7565b15156115e957600080fd5b6000908152600e602052604090208054600160a060020a031916600160a060020a0392909216919091179055565b600354600160a060020a0316331461162e57600080fd5b600160a060020a038116151561164357600080fd5b60018054600160a060020a031916600160a060020a0392909216919091179055565b6000908152600a6020526040902054600160a060020a0316151590565b600061168c610e91565b821061169757600080fd5b5090565b600354600090600160a060020a031633146116b557600080fd5b601854611388116116c557600080fd5b6018805460010190556003546116ec90600090819081908690600160a060020a0316612db4565b92915050565b600254600160a060020a03163314806117155750600054600160a060020a031633145b8061172a5750600154600160a060020a031633145b8061173f5750600354600160a060020a031633145b151561174a57600080fd5b60065463ffffffff16811061175e57600080fd5b600855565b600080600080600080600080600080600060098c81548110151561178357fe5b906000526020600020906002020190508060010160189054906101000a900463ffffffff1663ffffffff16600014159a50438160010160089054906101000a900467ffffffffffffffff1667ffffffffffffffff161115995080600101601c9054906101000a900461ffff1661ffff1698508060010160089054906101000a900467ffffffffffffffff1667ffffffffffffffff1697508060010160189054906101000a900463ffffffff1663ffffffff1696508060010160009054906101000a900467ffffffffffffffff1667ffffffffffffffff1695508060010160109054906101000a900463ffffffff1663ffffffff1694508060010160149054906101000a900463ffffffff1663ffffffff16935080600101601e9054906101000a900461ffff1661ffff16925080600001549150509193959799509193959799565b60035460a060020a900460ff1681565b6001546000908190600160a060020a03163314806118fc5750600354600160a060020a031633145b151561190757600080fd5b50506014546015543031916001909101028082111561195d57600154604051600160a060020a039091169082840380156108fc02916000818181858888f1935050505015801561195b573d6000803e3d6000fd5b505b5050565b6000818152600a6020526040812054600160a060020a03168015156116ec57600080fd5b61afc881565b601a54600160a060020a031681565b60008054600160a060020a03163314806119be5750600354600160a060020a031633145b15156119c957600080fd5b81905080600160a060020a03166385b861886040518163ffffffff1660e060020a028152600401602060405180830381600087803b158015611a0a57600080fd5b505af1158015611a1e573d6000803e3d6000fd5b505050506040513d6020811015611a3457600080fd5b50511515611a4157600080fd5b60108054600160a060020a031916600160a060020a03928316179055306000908152600d60209081526040808320949093168252929092529020805460ff19166001179055565b6000600160a060020a0382161515611a9f57600080fd5b50600160a060020a03166000908152600b602052604090205490565b600054600160a060020a0316331480611ade5750600354600160a060020a031633145b1515611ae957600080fd5b60035460a060020a900460ff161515611b0157600080fd5b601a8054600160a060020a038316600160a060020a0319909116811790915560408051918252517f450db8da6efbe9c22f2347f7c2021231df1fc58d3ae9a2fa75d39fa4461993059181900360200190a150565b600354600160a060020a03163314611b6c57600080fd5b60008111611bc4576040805160e560020a62461bcd02815260206004820152601460248201527f52617465206d6179206e6f74206265207a65726f000000000000000000000000604482015290519081900360640190fd5b601655565b60085481565b60155481565b600080600080600080600080600360149054906101000a900460ff16151515611bfd57600080fd5b600980548b908110611c0b57fe5b60009182526020909120600290910201600181015490975067ffffffffffffffff161515611c3857600080fd5b604080516101008101825288548152600189015467ffffffffffffffff8082166020840152680100000000000000008204169282019290925263ffffffff608060020a83048116606083015260a060020a83048116608083015260c060020a83041660a082015261ffff60e060020a8304811660c083015260f060020a90920490911660e0820152611cc990613321565b1515611cd457600080fd5b60018701546009805460c060020a90920463ffffffff1697509087908110611cf857fe5b600091825260209091206001808a015460029093029091019081015490965061ffff60f060020a928390048116965091900416841015611d4557600185015460f060020a900461ffff1693505b60008a8152600a60205260409020546001888101548b9550600160a060020a039092169350611d8c918c9160c060020a90910463ffffffff1690870161ffff168686612db4565b6001880180547bffffffff0000000000000000000000000000000000000000000000001916905560158054600019019055601454604051919250339181156108fc0291906000818181858888f19350505050158015611def573d6000803e3d6000fd5b509998505050505050505050565b600254600160a060020a0316331480611e205750600054600160a060020a031633145b80611e355750600154600160a060020a031633145b80611e4a5750600354600160a060020a031633145b1515611e5557600080fd5b60035460a060020a900460ff1615611e6c57600080fd5b6003805474ff0000000000000000000000000000000000000000191660a060020a179055565b6060600060606000806000611ea687611a88565b9450841515611ec5576040805160008152602081019091529550611f5a565b84604051908082528060200260200182016040528015611eef578160200160208202803883390190505b509350611efa610e91565b925060009150600190505b828111611f56576000818152600a6020526040902054600160a060020a0388811691161415611f4e57808483815181101515611f3d57fe5b602090810290910101526001909101905b600101611f05565b8395505b5050505050919050565b600254600160a060020a0316331480611f875750600054600160a060020a031633145b80611f9c5750600154600160a060020a031633145b80611fb15750600354600160a060020a031633145b1515611fbc57600080fd5b601060009054906101000a9004600160a060020a0316600160a060020a0316635fd8c7106040518163ffffffff1660e060020a028152600401600060405180830381600087803b15801561200f57600080fd5b505af1158015612023573d6000803e3d6000fd5b50505050601160009054906101000a9004600160a060020a0316600160a060020a0316635fd8c7106040518163ffffffff1660e060020a028152600401600060405180830381600087803b15801561207a57600080fd5b505af1158015611443573d6000803e3d6000fd5b600e60205260009081526040902054600160a060020a031681565b60138054604080516020601f6002600019610100600188161502019095169490940493840181900481028201810190925282815260609390929091830182828015610cc75780601f10610c9c57610100808354040283529160200191610cc7565b600681600e811061211757fe5b60089182820401919006600402915054906101000a900463ffffffff1681565b60008060098381548110151561214957fe5b60009182526020918290206040805161010081018252600290930290910180548352600181015467ffffffffffffffff808216958501959095526801000000000000000081049094169183019190915263ffffffff608060020a84048116606084015260a060020a84048116608084015260c060020a84041660a083015261ffff60e060020a8404811660c084015260f060020a90930490921660e08201529091506111f990613351565b600160a060020a03821633141561220a57600080fd5b336000818152600d60209081526040808320600160a060020a03871680855290835292819020805460ff1916861515908117909155815190815290519293927f17307eab39ab6107e8899845ad3d59bd9653f200f220920489ca2b5937696c31929181900390910190a35050565b600c60205260009081526040902054600160a060020a031681565b600254600160a060020a031681565b60145481565b816122b33382612bac565b151561232f576040805160e560020a62461bcd02815260206004820152603960248201527f6d73672e73656e646572206973206e6f7420617070726f76656420746f20747260448201527f616e73666572206f6e20626568616c66206f66206f776e657200000000000000606482015290519081900360840190fd5b60035460a060020a900460ff161561234657600080fd5b612351858585610f25565b61235d8585858561337f565b151561236857600080fd5b5050505050565b600354600090600160a060020a0316331461238957600080fd5b60195461afc81161239957600080fd5b6123a860008060008530612db4565b601054909150600160a060020a03166327ebe40a826123c56134ec565b6040805160e060020a63ffffffff861602815260048101939093526024830191909152600060448301819052620151806064840152306084840152905160a48084019382900301818387803b15801561241d57600080fd5b505af1158015612431573d6000803e3d6000fd5b505060198054600101905550505050565b606061244d82611665565b151561245857600080fd5b6000828152600f602090815260409182902080548351601f6002600019610100600186161502019093169290920491820184900484028101840190945280845290918301828280156124eb5780601f106124c0576101008083540402835291602001916124eb565b820191906000526020600020905b8154815290600101906020018083116124ce57829003601f168201915b50505050509050919050565b60008080831161250657600080fd5b600980548490811061251457fe5b60009182526020918290206040805161010081018252600290930290910180548352600181015467ffffffffffffffff808216958501959095526801000000000000000081049094169183019190915263ffffffff608060020a84048116606084015260a060020a84048116608084015260c060020a84041660a083015261ffff60e060020a8404811660c084015260f060020a90930490921660e08201529091506111f9906135b5565b61138881565b601054600160a060020a031681565b60008082336125e282611961565b600160a060020a0316146125f557600080fd5b60055460ff161561260557600080fd5b6005805460ff19166001179055600980548590811061262057fe5b60009182526020918290206040805161010081018252600290930290910180548352600181015467ffffffffffffffff808216958501959095526801000000000000000081049094169183019190915263ffffffff608060020a84048116606084015260a060020a84048116608084015260c060020a84041660a083015261ffff60e060020a8404811660c084015260f060020a90930490921660e08201529093506126cb90613351565b91508115156126d957600080fd5b34821115612757576040805160e560020a62461bcd02815260206004820152602f60248201527f496e73756666696369656e74207061796d656e7420746f20726564756365206360448201527f757272656e7420636f6f6c646f776e0000000000000000000000000000000000606482015290519081900360840190fd5b60018301805467ffffffffffffffff431668010000000000000000026fffffffffffffffff00000000000000001990911617905560405133903484900380156108fc02916000818181858888f193505050501580156127ba573d6000803e3d6000fd5b50506005805460ff19169055505050565b60165481565b600160a060020a039182166000908152600d6020908152604080832093909416825291909152205460ff1690565b60035460009060a060020a900460ff161561281957600080fd5b61282333836130c7565b151561282e57600080fd5b612837826124f7565b151561284257600080fd5b61284c82846135e4565b151561285757600080fd5b601154604080517fc55d0f56000000000000000000000000000000000000000000000000000000008152600481018690529051600160a060020a039092169163c55d0f56916024808201926020929091908290030181600087803b1580156128be57600080fd5b505af11580156128d2573d6000803e3d6000fd5b505050506040513d60208110156128e857600080fd5b505160145490915081013410156128fe57600080fd5b601154601454604080517f454a2ab3000000000000000000000000000000000000000000000000000000008152600481018790529051600160a060020a039093169263454a2ab39234039160248082019260009290919082900301818588803b15801561296a57600080fd5b505af115801561297e573d6000803e3d6000fd5b505050505061195b8263ffffffff168463ffffffff16613633565b60195481565b601754600160a060020a031681565b600354600090819060a060020a900460ff16156129ca57600080fd5b6014543410156129d957600080fd5b6129e333856130c7565b15156129ee57600080fd5b6129f883856132cc565b1515612a0357600080fd5b6009805485908110612a1157fe5b60009182526020918290206040805161010081018252600290930290910180548352600181015467ffffffffffffffff808216958501959095526801000000000000000081049094169183019190915263ffffffff608060020a84048116606084015260a060020a84048116608084015260c060020a84041660a083015261ffff60e060020a8404811660c084015260f060020a90930490921660e0820152909250612abc906135b5565b1515612ac757600080fd5b6009805484908110612ad557fe5b60009182526020918290206040805161010081018252600290930290910180548352600181015467ffffffffffffffff808216958501959095526801000000000000000081049094169183019190915263ffffffff608060020a84048116606084015260a060020a84048116608084015260c060020a84041660a083015261ffff60e060020a8404811660c084015260f060020a90930490921660e0820152909150612b80906135b5565b1515612b8b57600080fd5b612b978285838661314d565b1515612ba257600080fd5b6114438484613633565b600080612bb883611961565b905080600160a060020a031684600160a060020a03161480612bf3575083600160a060020a0316612be884610cd1565b600160a060020a0316145b80612c035750612c0381856127d1565b949350505050565b81600160a060020a0316612c1e82611961565b600160a060020a031614612c3157600080fd5b6000818152600c6020526040902054600160a060020a031615612c6b576000818152600c602052604090208054600160a060020a03191690555b6000818152600e6020526040902054600160a060020a03161561195d576000908152600e602052604090208054600160a060020a031916905550565b81600160a060020a0316612cba82611961565b600160a060020a031614612ccd57600080fd5b600160a060020a0382166000908152600b6020526040902054612cf790600163ffffffff61378416565b600160a060020a039092166000908152600b6020908152604080832094909455918152600a909152208054600160a060020a0319169055565b6000818152600a6020526040902054600160a060020a031615612d5257600080fd5b6000818152600a602090815260408083208054600160a060020a031916600160a060020a0387169081179091558352600b909152902054612d94906001613796565b600160a060020a039092166000908152600b602052604090209190915550565b600080612dbf613894565b600063ffffffff89168914612dd357600080fd5b63ffffffff88168814612de557600080fd5b61ffff87168714612df557600080fd5b600287049250600d8361ffff161115612e0d57600d92505b505060408051610100810182528581524267ffffffffffffffff90811660208301908152600093830184815263ffffffff8c8116606086019081528c82166080870190815260a0870188815261ffff8a811660c08a019081528f821660e08b01908152600980546001810182559c528a517f6e1540171b6c0c960b71a7020d9f60077f6af931a8bbf590da0223dacf75c7af60028e029081019190915598517f6e1540171b6c0c960b71a7020d9f60077f6af931a8bbf590da0223dacf75c7b0909901805498519651955194519251915167ffffffffffffffff19909916998b16999099176fffffffffffffffff000000000000000019166801000000000000000096909a16959095029890981773ffffffff000000000000000000000000000000001916608060020a938616939093029290921777ffffffff0000000000000000000000000000000000000000191660a060020a91851691909102177bffffffff000000000000000000000000000000000000000000000000191660c060020a96841696909602959095177fffff0000ffffffffffffffffffffffffffffffffffffffffffffffffffffffff1660e060020a91861691909102177dffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1660f060020a92909416919091029290921790559091908116811461300b57600080fd5b606080830151608080850151855160408051600160a060020a038c1681526020810188905263ffffffff95861681830152929094169482019490945290810192909252517f0a5311bd2a6608f08a180df2ee7c5946819a649b204b554bb8e39825b2c50ad59181900360a00190a16130838582612d30565b6040518190600160a060020a038716906000907fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef908290a498975050505050505050565b6000908152600a6020526040902054600160a060020a0391821691161490565b600054600160a060020a031633148061310a5750600354600160a060020a031633145b151561311557600080fd5b60035460a060020a900460ff16151561312d57600080fd5b6003805474ff000000000000000000000000000000000000000019169055565b60008184141561315f57506000612c03565b6001850154608060020a900463ffffffff1682148061318e5750600185015460a060020a900463ffffffff1682145b1561319b57506000612c03565b6001830154608060020a900463ffffffff168414806131ca5750600183015460a060020a900463ffffffff1684145b156131d757506000612c03565b6001830154608060020a900463ffffffff16158061320457506001850154608060020a900463ffffffff16155b1561321157506001612c03565b60018581015490840154608060020a9182900463ffffffff9081169290910416148061325c575060018086015490840154608060020a900463ffffffff90811660a060020a90920416145b1561326957506000612c03565b6001808601549084015460a060020a900463ffffffff908116608060020a9092041614806132b457506001858101549084015460a060020a9182900463ffffffff9081169290910416145b156132c157506000612c03565b506001949350505050565b6000818152600a60205260408082205484835290822054600160a060020a039182169116808214806114c057506000858152600e6020526040902054600160a060020a03908116908316149250505092915050565b60008160a0015163ffffffff166000141580156116ec5750506040015167ffffffffffffffff4381169116111590565b6000601654610e1060085443856040015167ffffffffffffffff16030281151561337757fe5b040292915050565b60008061339485600160a060020a03166137a3565b15156133a357600191506134e3565b6040517f150b7a020000000000000000000000000000000000000000000000000000000081523360048201818152600160a060020a03898116602485015260448401889052608060648501908152875160848601528751918a169463150b7a0294938c938b938b93909160a490910190602085019080838360005b8381101561343657818101518382015260200161341e565b50505050905090810190601f1680156134635780820380516001836020036101000a031916815260200191505b5095505050505050602060405180830381600087803b15801561348557600080fd5b505af1158015613499573d6000803e3d6000fd5b505050506040513d60208110156134af57600080fd5b5051600160e060020a031981167f150b7a020000000000000000000000000000000000000000000000000000000014925090505b50949350505050565b6000806000601060009054906101000a9004600160a060020a0316600160a060020a031663eac9d94c6040518163ffffffff1660e060020a028152600401602060405180830381600087803b15801561354457600080fd5b505af1158015613558573d6000803e3d6000fd5b505050506040513d602081101561356e57600080fd5b505191506fffffffffffffffffffffffffffffffff8216821461359057600080fd5b50600281048101662386f26fc100008110156116ec5750662386f26fc1000092915050565b60008160a0015163ffffffff1660001480156116ec5750506040015167ffffffffffffffff4381169116111590565b60008060006009858154811015156135f857fe5b9060005260206000209060020201915060098481548110151561361757fe5b906000526020600020906002020190506114c08286838761314d565b60008060098381548110151561364557fe5b9060005260206000209060020201915060098481548110151561366457fe5b600091825260209091206002909102016001810180547bffffffff000000000000000000000000000000000000000000000000191660c060020a63ffffffff87160217905590506136b4826137ab565b6136bd816137ab565b6000848152600e602090815260408083208054600160a060020a031990811690915586845281842080549091169055601580546001908101909155878452600a8352928190205484840154938601548251600160a060020a0392909216825292810188905280820187905267ffffffffffffffff68010000000000000000948590048116606083015293909204909216608082015290517f92f88a5b0e68184d6eaf466894625052095288be7d39de2429081c769956be1e9181900360a00190a150505050565b60008282111561379057fe5b50900390565b818101828110156116ec57fe5b6000903b1190565b600854600182015443919060069060e060020a900461ffff16600e81106137ce57fe5b600891828204019190066004029054906101000a900463ffffffff1663ffffffff168115156137f957fe5b6001840180546fffffffffffffffff0000000000000000191668010000000000000000939092049390930167ffffffffffffffff16919091021790819055600d60e060020a90910461ffff161015613891576001818101805461ffff60e060020a8083048216909401169092027fffff0000ffffffffffffffffffffffffffffffffffffffffffffffffffffffff9092169190911790555b50565b6040805161010081018252600080825260208201819052918101829052606081018290526080810182905260a0810182905260c0810182905260e0810191909152905600a165627a7a723058200610fbc9f04af40597bd94b22ecdf8ae6f7f86492e39ce6395b566d10131a3070029

Swarm Source

bzzr://0610fbc9f04af40597bd94b22ecdf8ae6f7f86492e39ce6395b566d10131a307
Block Age Transaction Difficulty GasUsed Reward
Block Age Uncle Number Difficulty GasUsed Reward