Contract 0x663e4229142a27f00bafb5d087e1e730648314c3

 

TxHash Block Age From To Value [TxFee]
0xeb7da63fce1db16889dbf096b87ac64188c06d26b58dd34c5a639fcbf6cdd25e72156752 days 16 hrs ago0x7d8bf18c7ce84b3e175b339c4ca93aed1dd166f1  IN   0x663e4229142a27f00bafb5d087e1e730648314c30 Ether0.00078798069
0xa17284e2b0a6e46a67f97152d59bb5fc461044607622e648b81c46b29245df8872127473 days 9 hrs ago0x7dec37c03ea5ca2c47ad2509be6abaf8c63cdb39  IN   0x663e4229142a27f00bafb5d087e1e730648314c30 Ether0.00028204371
0xc0a10182b7a529ed1decc56c5519f3a0a7918505a8e5f6d53099d8a912950fe472084844 days 9 hrs ago0x530cf036ed4fa58f7301a9c788c9806624cefd19  IN   0x663e4229142a27f00bafb5d087e1e730648314c30 Ether0.000230805
0x2d3e380a4e13fb24c18293636b7398046ac1b028708088a1d765db2209a429a372084824 days 9 hrs ago0x530cf036ed4fa58f7301a9c788c9806624cefd19  IN   0x663e4229142a27f00bafb5d087e1e730648314c30 Ether0.000779025
0x48c5be49ba877860f87d5ec3006d816b1f8118f9e318b550d9b207529942541b72084784 days 9 hrs ago0x530cf036ed4fa58f7301a9c788c9806624cefd19  IN   0x663e4229142a27f00bafb5d087e1e730648314c30 Ether0.000779025
0xb9087fdf6b85d374e651823246316a09779e03a6e75e1f1ecfdea17e161b3ca872084764 days 9 hrs ago0x530cf036ed4fa58f7301a9c788c9806624cefd19  IN   0x663e4229142a27f00bafb5d087e1e730648314c30 Ether0.000779025
0x43752b3cadd5e8bd029edf3dc8e0d14d46fa1f2946c9f1fc0ad85efc88eb2aeb72019715 days 22 hrs ago0x33849c8a4a9539699ed988b3ca6753bb3a597338  IN   0x663e4229142a27f00bafb5d087e1e730648314c30 Ether0.000230805
0x239d573008e76a3c702ec6c142787c5d0321b73cf33d4ddfc16db64bbe62715572019635 days 22 hrs ago0x33849c8a4a9539699ed988b3ca6753bb3a597338  IN   0x663e4229142a27f00bafb5d087e1e730648314c30 Ether0.000230805
0x2367dc1d99e66d94311df4682577881891ac66451ac16a3213eb7547a9f8914771939907 days 14 hrs ago0xbad858a0cf09f210fcf35cbf83569178879b47f2  IN   0x663e4229142a27f00bafb5d087e1e730648314c30 Ether0.00057159
0x2849031611913a340c404123dc60505a3ec0837b9ec609966deb734f42fbf21371853059 days 8 hrs ago0xde67adf51408acca6bee2abe20dbfff2dddfed33  IN   0x663e4229142a27f00bafb5d087e1e730648314c30 Ether0.000155805
0x7a012743d4af9cb8a2100ca0f693fff8414c7b118b3f116fe988d64105104107717093912 days 7 hrs ago0x55611b747af18e27ba99c251377912fcd96ea656  IN   0x663e4229142a27f00bafb5d087e1e730648314c30 Ether0.0000507771
0xb2d8cfc672551b66e130dc4ad3bf4648812a0b1ea62e02fa60c60ebbd12ada4a717092712 days 7 hrs ago0x55611b747af18e27ba99c251377912fcd96ea656  IN   0x663e4229142a27f00bafb5d087e1e730648314c30 Ether0.0000507771
0xa3d85375ae5a12a91eac100a707ffc773786f72cb9e178fbb75e3d5c84200710716462613 days 13 hrs ago0x6eac7d87a9f2ad5c8c03c79e71b9038468043780  IN   0x663e4229142a27f00bafb5d087e1e730648314c30 Ether0.00046161
0x1baa37acf726e36a6b6559fe5ba3d8b3954387980354ab71677d0d0aac4b8379716039014 days 10 hrs ago0x530cf036ed4fa58f7301a9c788c9806624cefd19  IN   0x663e4229142a27f00bafb5d087e1e730648314c30 Ether0.001892601
0xa9f5eb85f6dbf99f9f02f3aeab3e145ed46ee68da1ac737493b3a46e3e3af281716038614 days 10 hrs ago0x530cf036ed4fa58f7301a9c788c9806624cefd19  IN   0x663e4229142a27f00bafb5d087e1e730648314c30 Ether0.001277601
0x686b2693e220137ccc63781898e42606d670145d6c864d99037c947e331860aa715889714 days 18 hrs ago0xece114137b2e9dbf29712bdc39639eb0b72b41b8  IN   0x663e4229142a27f00bafb5d087e1e730648314c30 Ether0.0006253815
0x6ef005a20741b43f7a8440da6c8a968449f6dab2447964ea4dd6f1f19883608d715418515 days 17 hrs ago0x33849c8a4a9539699ed988b3ca6753bb3a597338  IN   0x663e4229142a27f00bafb5d087e1e730648314c30 Ether0.000488064043
0x26fb602fff9e6986195af861d5d56f319389e808507b8308181f011848eddb90712978220 days 15 hrs ago0x33849c8a4a9539699ed988b3ca6753bb3a597338  IN   0x663e4229142a27f00bafb5d087e1e730648314c30 Ether0.000230805
0xfdee65e68977f7b834b5a87c3e31d316626b674bb71942e21f7356ad867c6256712977420 days 15 hrs ago0x33849c8a4a9539699ed988b3ca6753bb3a597338  IN   0x663e4229142a27f00bafb5d087e1e730648314c30 Ether0.000230805
0xb1a7c92ce44434ba9470b9c6a98e4b7f6b4eb0d8f7e76d919cd5683533b4ffcc712555421 days 11 hrs ago0xde67adf51408acca6bee2abe20dbfff2dddfed33  IN   0x663e4229142a27f00bafb5d087e1e730648314c30 Ether0.000062322
0x45b21f8c312a7afa08e5363cc57c7279844bc0c18a4045a5f28669798874dc63712353821 days 21 hrs ago0x406f4533b2f6209812d7ef9c7d69b8c54217c208  IN   0x663e4229142a27f00bafb5d087e1e730648314c30 Ether0.000369288
0x87c463282d23737c4643f204d0c0cdadf2130f264a40389fdcde59f09876d7c4712352621 days 21 hrs ago0x406f4533b2f6209812d7ef9c7d69b8c54217c208  IN   0x663e4229142a27f00bafb5d087e1e730648314c30 Ether0.000369288
0xd78c16e63d47dad19572fcb2050c4d35955b8bc45792637c923b5988882805ad712348821 days 21 hrs ago0x406f4533b2f6209812d7ef9c7d69b8c54217c208  IN   0x663e4229142a27f00bafb5d087e1e730648314c30 Ether0.000276966
0x9816103368ff1e77a2420a0c6934a352c639a9d46f0fc8cfbf38ada47f9fb695712346521 days 21 hrs ago0x406f4533b2f6209812d7ef9c7d69b8c54217c208  IN   0x663e4229142a27f00bafb5d087e1e730648314c30 Ether0.000155805
0x7cb65df3c9817801ec7ac9c751a2caee09c3af7ae3c71ebf2e67b4a90def7290712345321 days 21 hrs ago0x406f4533b2f6209812d7ef9c7d69b8c54217c208  IN   0x663e4229142a27f00bafb5d087e1e730648314c30 Ether0.000276966
[ Download CSV Export 

Latest 25 Internal Transaction, Click here to view more Internal Transactions as a result of Contract Execution

Parent TxHash Block Age From To Value
0x2a71f57aea0ad98f85fb459cd9f780853128584d9ac94eade8b1ee137db89315677396582 days 4 hrs ago0x663e4229142a27f00bafb5d087e1e730648314c30xf6ec3b28b7daea20fbebd8b85939456e5dd4aab60.002 Ether
0xf6e5b370ad5dfea79e954573365fa283ff8ef1d08eee6abfa1691997a062429f677396082 days 4 hrs ago0x663e4229142a27f00bafb5d087e1e730648314c30xf6ec3b28b7daea20fbebd8b85939456e5dd4aab60.002 Ether
0xa5eb9119aef9127bbc84fb4569f6911448b0b0131cdcbf17bc7c42095d7a021d677396082 days 4 hrs ago0x663e4229142a27f00bafb5d087e1e730648314c30xf6ec3b28b7daea20fbebd8b85939456e5dd4aab60.002 Ether
0x9ad2161c31d37f495bb3564e83a139d33d2e9939fc37560b4fc1d2c0838b388c677395882 days 4 hrs ago0x663e4229142a27f00bafb5d087e1e730648314c30xf6ec3b28b7daea20fbebd8b85939456e5dd4aab60.002 Ether
0xb62135edcea538eca9e721e93100c913eabdb21c8afeab56f5123449513b49f8677395682 days 4 hrs ago0x663e4229142a27f00bafb5d087e1e730648314c30xf6ec3b28b7daea20fbebd8b85939456e5dd4aab60.002 Ether
0x7ace221adb198c3eeef8059ad0254b1b0f2868628aac8ea511a8695f09a5c084677395482 days 4 hrs ago0x663e4229142a27f00bafb5d087e1e730648314c30xf6ec3b28b7daea20fbebd8b85939456e5dd4aab60.002 Ether
0xa329feb46b70bafeead4bb057885c020c3410a1397f769e477bd46f0524718e9677395382 days 4 hrs ago0x663e4229142a27f00bafb5d087e1e730648314c30xf6ec3b28b7daea20fbebd8b85939456e5dd4aab60.002 Ether
0xccbf2c1809f4087d4349f4339ea65faf82eae6a298eaa97bd53ca8f737831108677393782 days 4 hrs ago0x663e4229142a27f00bafb5d087e1e730648314c30xc078f416dd0a7cf2ec2fc5b531d3a31bd9a67b9b3.694066850244548251 Ether
0x6fca0f457b6499968934fe66d2d3d6ebf610050ea8ad050138faed5580cc4e3d677390482 days 4 hrs ago0xbf4b10a3e9aacf7755345de8c9d1a06c184bed7a0x663e4229142a27f00bafb5d087e1e730648314c30.139491769976159485 Ether
0x6fca0f457b6499968934fe66d2d3d6ebf610050ea8ad050138faed5580cc4e3d677390482 days 4 hrs ago0xe84e30aacb41490a1baf1d09416e970f1e6c6a1d0x663e4229142a27f00bafb5d087e1e730648314c33.552793479791578528 Ether
0x753fdffa5374cfb020139261542c8d4925c4860af1514a9da15cfa9c0071cd5d673713188 days 4 hrs ago0x663e4229142a27f00bafb5d087e1e730648314c30xf6ec3b28b7daea20fbebd8b85939456e5dd4aab60.002 Ether
0xb6009426a20a5136d73463bac5e2b52ba7fd8679ad392105c507d0f16bb2fe52673346688 days 19 hrs ago0x663e4229142a27f00bafb5d087e1e730648314c30xf6ec3b28b7daea20fbebd8b85939456e5dd4aab60.002 Ether
0x2fed17957410abf15c4d73a73d0589e74c15aab66542c8be90eb47644b81240c673346688 days 19 hrs ago0x663e4229142a27f00bafb5d087e1e730648314c30xf6ec3b28b7daea20fbebd8b85939456e5dd4aab60.002 Ether
0x545bf18fc47d58633fd0599de08258498addc60b30cb8b0805c356c9894ff868673346388 days 19 hrs ago0x663e4229142a27f00bafb5d087e1e730648314c30xf6ec3b28b7daea20fbebd8b85939456e5dd4aab60.002 Ether
0x2313a776f4da4981bf90a78dd26cf42815e90b9c17322d4bc0e5df5a7d99bcc2673346088 days 19 hrs ago0x663e4229142a27f00bafb5d087e1e730648314c30xf6ec3b28b7daea20fbebd8b85939456e5dd4aab60.002 Ether
0x0df284c33fb407e550472d21da41ba8cbeae767231ddc0aeab1759508ef95a95673345888 days 19 hrs ago0x663e4229142a27f00bafb5d087e1e730648314c30xf6ec3b28b7daea20fbebd8b85939456e5dd4aab60.002 Ether
0x3e2a3f3ca05d84ed0488c0b68422a434d7bb72def7d9fdd745fb487ce4ab32cb673345588 days 19 hrs ago0x663e4229142a27f00bafb5d087e1e730648314c30xf6ec3b28b7daea20fbebd8b85939456e5dd4aab60.002 Ether
0x7e159ce244d958b19f2bf080a7cafd2f47fbdca0d75d1857baab4a5da78e1d7b673345388 days 19 hrs ago0x663e4229142a27f00bafb5d087e1e730648314c30xf6ec3b28b7daea20fbebd8b85939456e5dd4aab60.002 Ether
0xe120c221c8d435dc8276c685343f5d1041144109a473258e13a6d7000f00d619673345388 days 19 hrs ago0x663e4229142a27f00bafb5d087e1e730648314c30xf6ec3b28b7daea20fbebd8b85939456e5dd4aab60.002 Ether
0xb7ff3d6bc1278c4ac69e2d33b387c9b2081b4792b5846ee59a7a1cf1ce06ff91673345188 days 19 hrs ago0x663e4229142a27f00bafb5d087e1e730648314c30xf6ec3b28b7daea20fbebd8b85939456e5dd4aab60.002 Ether
0x06fefee577d29cce3b73ea00f7735a4fcbb14012ab204067955c590b9cef30d1673344988 days 19 hrs ago0x663e4229142a27f00bafb5d087e1e730648314c30xf6ec3b28b7daea20fbebd8b85939456e5dd4aab60.002 Ether
0x11c54610082e1700f0b4a570eddf065e06441637fa4c30aaf6efd77c476f0a0a673344788 days 19 hrs ago0x663e4229142a27f00bafb5d087e1e730648314c30xf6ec3b28b7daea20fbebd8b85939456e5dd4aab60.002 Ether
0x0a9c8389e91f7b341ea132ec401f98e21400a2e0142d7279d2663a30b204ab4c673344788 days 19 hrs ago0x663e4229142a27f00bafb5d087e1e730648314c30xf6ec3b28b7daea20fbebd8b85939456e5dd4aab60.002 Ether
0xa9a50f173cb7d3d54045028c89410d3b489e3cf5e50cb3b98db211c34d51255e673344588 days 19 hrs ago0x663e4229142a27f00bafb5d087e1e730648314c30xf6ec3b28b7daea20fbebd8b85939456e5dd4aab60.002 Ether
0x3c57de5668f0c3bb97989e17d9ad93a8f89cefa2828dadc9daed6e9a1d9f9445673344388 days 19 hrs ago0x663e4229142a27f00bafb5d087e1e730648314c30xf6ec3b28b7daea20fbebd8b85939456e5dd4aab60.002 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 (Exact Match)
Contract Name: PandaCore
Compiler Version: v0.4.24-nightly.2018.4.24+commit.258ae892
Optimization Enabled: Yes
Runs (Optimizer):  200


Contract Source Code
pragma solidity ^0.4.11;


contract ERC20 {
    function totalSupply() constant returns (uint supply);
    function balanceOf( address who ) constant returns (uint value);
    function allowance( address owner, address spender ) constant returns (uint _allowance);

    function transfer( address to, uint value) returns (bool ok);
    function transferFrom( address from, address to, uint value) returns (bool ok);
    function approve( address spender, uint value ) returns (bool ok);

    event Transfer( address indexed from, address indexed to, uint value);
    event Approval( address indexed owner, address indexed spender, uint value);
}
/**
 * @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.
   */
  function Ownable() {
    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) onlyOwner {
    if (newOwner != address(0)) {
      owner = newOwner;
    }
  }

}

/// @title Interface for contracts conforming to ERC-721: Non-Fungible Tokens
/// @author Dieter Shirley <[email protected]> (https://github.com/dete)
contract ERC721 {
    // Required methods
    function totalSupply() public view returns (uint256 total);
    function balanceOf(address _owner) public view returns (uint256 balance);
    function ownerOf(uint256 _tokenId) external view returns (address owner);
    function approve(address _to, uint256 _tokenId) external;
    function transfer(address _to, uint256 _tokenId) external;
    function transferFrom(address _from, address _to, uint256 _tokenId) external;

    // Events
    event Transfer(address from, address to, uint256 tokenId);
    event Approval(address owner, address approved, uint256 tokenId);

    // Optional
    // function name() public view returns (string name);
    // function symbol() public view returns (string symbol);
    // function tokensOfOwner(address _owner) external view returns (uint256[] tokenIds);
    // function tokenMetadata(uint256 _tokenId, string _preferredTransport) public view returns (string infoUrl);

    // ERC-165 Compatibility (https://github.com/ethereum/EIPs/issues/165)
    function supportsInterface(bytes4 _interfaceID) external view returns (bool);
}

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 genes1 genes of mom
    /// @param genes2 genes of sire
    /// @return the genes that are supposed to be passed down the child
    function mixGenes(uint256[2] genes1, uint256[2] genes2,uint256 g1,uint256 g2, uint256 targetBlock) public returns (uint256[2]);

    function getPureFromGene(uint256[2] gene) public view returns(uint256);

    /// @dev get sex from genes 0: female 1: male
    function getSex(uint256[2] gene) public view returns(uint256);

    /// @dev get wizz type from gene
    function getWizzType(uint256[2] gene) public view returns(uint256);

    function clearWizzType(uint256[2] _gene) public returns(uint256[2]);
}

/// @title A facet of PandaCore that manages special access privileges.
/// @author Axiom Zen (https://www.axiomzen.co)
/// @dev See the PandaCore contract documentation to understand how the various contract facets are arranged.
contract PandaAccessControl {
    // This facet controls access control for CryptoPandas. There are four roles managed here:
    //
    //     - The CEO: The CEO can reassign other roles and change the addresses of our dependent smart
    //         contracts. It is also the only role that can unpause the smart contract. It is initially
    //         set to the address that created the smart contract in the PandaCore constructor.
    //
    //     - The CFO: The CFO can withdraw funds from PandaCore and its auction contracts.
    //
    //     - The COO: The COO can release gen0 pandas to auction, and mint promo cats.
    //
    // It should be noted that these roles are distinct without overlap in their access abilities, the
    // abilities listed for each role above are exhaustive. In particular, while the CEO can assign any
    // address to any role, the CEO address itself doesn't have the ability to act in those roles. This
    // restriction is intentional so that we aren't tempted to use the CEO address frequently out of
    // convenience. The less we use an address, the less likely it is that we somehow compromise the
    // account.

    /// @dev Emited when contract is upgraded - See README.md for updgrade plan
    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;

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

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

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

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

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

        ceoAddress = _newCEO;
    }

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

        cfoAddress = _newCFO;
    }

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

        cooAddress = _newCOO;
    }

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

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

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

    /// @dev Called by any "C-level" role to pause the contract. Used only when
    ///  a bug or exploit is detected 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;
    }
}








/// @title Base contract for CryptoPandas. Holds all common structs, events and base variables.
/// @author Axiom Zen (https://www.axiomzen.co)
/// @dev See the PandaCore contract documentation to understand how the various contract facets are arranged.
contract PandaBase is PandaAccessControl {
    /*** EVENTS ***/

    uint256 public constant GEN0_TOTAL_COUNT = 16200;
    uint256 public gen0CreatedCount;

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

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

    /*** DATA TYPES ***/

    /// @dev The main Panda struct. Every cat in CryptoPandas is represented by a copy
    ///  of this structure, so great care was taken to ensure that it fits neatly into
    ///  exactly two 256-bit words. Note that the order of the members in this structure
    ///  Ref: http://solidity.readthedocs.io/en/develop/miscellaneous.html
    struct Panda {
        // The Panda's genetic code is packed into these 256-bits, the format is
        // sooper-sekret! A cat's genes never change.
        uint256[2] genes;

        // The timestamp from the block when this cat came into existence.
        uint64 birthTime;

        // The minimum timestamp after which this cat 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 panda, set to 0 for gen0 cats.
        // Note that using 32-bit unsigned integers limits us to a "mere"
        // 4 billion cats. This number might seem small until you realize
        // that Ethereum currently has a limit of about 500 million
        // transactions per year! So, this definitely won't be a problem
        // for several years (even as Ethereum learns to scale).
        uint32 matronId;
        uint32 sireId;

        // Set to the ID of the sire cat for matrons that are pregnant,
        // zero otherwise. A non-zero value here is how we know a cat
        // is pregnant. Used to retrieve the genetic material for the new
        // kitten when the birth transpires.
        uint32 siringWithId;

        // Set to the index in the cooldown array (see below) that represents
        // the current cooldown duration for this Panda. This starts at zero
        // for gen0 cats, and is initialized to floor(generation/2) for others.
        // Incremented by one for each successful breeding action, regardless
        // of whether this cat is acting as matron or sire.
        uint16 cooldownIndex;

        // The "generation number" of this cat. Cats minted by the CK contract
        // for sale are called "gen0" and have a generation number of 0. The
        // generation number of all other cats is the larger of the two generation
        // numbers of their parents, plus one.
        // (i.e. max(matron.generation, sire.generation) + 1)
        uint16 generation;
    }

    /*** CONSTANTS ***/

    /// @dev A lookup table indicating the cooldown duration after any successful
    ///  breeding action, called "pregnancy time" for matrons and "siring cooldown"
    ///  for sires. Designed such that the cooldown roughly doubles each time a cat
    ///  is bred, encouraging owners not to just keep breeding the same cat over
    ///  and over again. Caps out at one week (a cat can breed an unbounded number
    ///  of times, and the maximum cooldown is always seven days).
    uint32[9] public cooldowns = [
        uint32(5 minutes),
        uint32(30 minutes),
        uint32(2 hours),
        uint32(4 hours),    
        uint32(8 hours),
        uint32(24 hours),
        uint32(48 hours),
        uint32(72 hours),
        uint32(7 days)
    ];

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

    /*** STORAGE ***/

    /// @dev An array containing the Panda struct for all Pandas in existence. The ID
    ///  of each cat is actually an index into this array. Note that ID 0 is a negacat,
    ///  the unPanda, the mythical beast that is the parent of all gen0 cats. A bizarre
    ///  creature that is both matron and sire... to itself! Has an invalid genetic code.
    ///  In other words, cat ID 0 is invalid... ;-)
    Panda[] pandas;

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

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

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

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

    /// @dev The address of the ClockAuction contract that handles sales of Pandas. 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 The address of the sibling contract that is used to implement the sooper-sekret
    ///  genetic combination algorithm.
    GeneScienceInterface public geneScience;


    SaleClockAuctionERC20 public saleAuctionERC20;


    // wizz panda total
    mapping (uint256 => uint256) public wizzPandaQuota;
    mapping (uint256 => uint256) public wizzPandaCount;

    
    /// wizz panda control
    function getWizzPandaQuotaOf(uint256 _tp) view external returns(uint256) {
        return wizzPandaQuota[_tp];
    }

    function getWizzPandaCountOf(uint256 _tp) view external returns(uint256) {
        return wizzPandaCount[_tp];
    }

    function setTotalWizzPandaOf(uint256 _tp,uint256 _total) external onlyCLevel {
        require (wizzPandaQuota[_tp]==0);
        require (_total==uint256(uint32(_total)));
        wizzPandaQuota[_tp] = _total;
    }

    function getWizzTypeOf(uint256 _id) view external returns(uint256) {
        Panda memory _p = pandas[_id];
        return geneScience.getWizzType(_p.genes);
    }

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

    /// @dev An internal method that creates a new panda 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 panda ID of the matron of this cat (zero for gen0)
    /// @param _sireId The panda ID of the sire of this cat (zero for gen0)
    /// @param _generation The generation number of this cat, must be computed by caller.
    /// @param _genes The panda's genetic code.
    /// @param _owner The inital owner of this cat, must be non-zero (except for the unPanda, ID 0)
    function _createPanda(
        uint256 _matronId,
        uint256 _sireId,
        uint256 _generation,
        uint256[2] _genes,
        address _owner
    )
        internal
        returns (uint)
    {
        // These requires are not strictly necessary, our calling code should make
        // sure that these conditions are never broken. However! _createPanda() 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 panda starts with the same cooldown as parent gen/2
        uint16 cooldownIndex = 0;
        // when contract creation, geneScience ref is null 
        if (pandas.length>0){
            uint16 pureDegree = uint16(geneScience.getPureFromGene(_genes));
            if (pureDegree==0) {
                pureDegree = 1;
            }
            cooldownIndex = 1000/pureDegree;
            if (cooldownIndex%10 < 5){
                cooldownIndex = cooldownIndex/10;
            }else{
                cooldownIndex = cooldownIndex/10 + 1;
            }
            cooldownIndex = cooldownIndex - 1;
            if (cooldownIndex > 8) {
                cooldownIndex = 8;
            }
            uint256 _tp = geneScience.getWizzType(_genes);
            if (_tp>0 && wizzPandaQuota[_tp]<=wizzPandaCount[_tp]) {
                _genes = geneScience.clearWizzType(_genes);
                _tp = 0;
            }
            // gensis panda cooldownIndex should be 24 hours
            if (_tp == 1){
                cooldownIndex = 5;
            }

            // increase wizz counter
            if (_tp>0){
                wizzPandaCount[_tp] = wizzPandaCount[_tp] + 1;
            }
            // all gen0&gen1 except gensis
            if (_generation <= 1 && _tp != 1){
                require(gen0CreatedCount<GEN0_TOTAL_COUNT);
                gen0CreatedCount++;
            }
        }

        Panda memory _panda = Panda({
            genes: _genes,
            birthTime: uint64(now),
            cooldownEndBlock: 0,
            matronId: uint32(_matronId),
            sireId: uint32(_sireId),
            siringWithId: 0,
            cooldownIndex: cooldownIndex,
            generation: uint16(_generation)
        });
        uint256 newKittenId = pandas.push(_panda) - 1;

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

        // emit the birth event
        Birth(
            _owner,
            newKittenId,
            uint256(_panda.matronId),
            uint256(_panda.sireId),
            _panda.genes
        );

        // This will assign ownership, and also emit the Transfer event as
        // per ERC721 draft
        _transfer(0, _owner, newKittenId);
        
        return newKittenId;
    }

    // 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;
    }
}
/// @title The external contract that is responsible for generating metadata for the pandas,
///  it has one function that will return the data as bytes.
contract ERC721Metadata {
    /// @dev Given a token Id, returns a byte array that is supposed to be converted into string.
    function getMetadata(uint256 _tokenId, string) public view returns (bytes32[4] buffer, uint256 count) {
        if (_tokenId == 1) {
            buffer[0] = "Hello World! :D";
            count = 15;
        } else if (_tokenId == 2) {
            buffer[0] = "I would definitely choose a medi";
            buffer[1] = "um length string.";
            count = 49;
        } else if (_tokenId == 3) {
            buffer[0] = "Lorem ipsum dolor sit amet, mi e";
            buffer[1] = "st accumsan dapibus augue lorem,";
            buffer[2] = " tristique vestibulum id, libero";
            buffer[3] = " suscipit varius sapien aliquam.";
            count = 128;
        }
    }
}







/// @title The facet of the CryptoPandas core contract that manages ownership, ERC-721 (draft) compliant.
/// @author Axiom Zen (https://www.axiomzen.co)
/// @dev Ref: https://github.com/ethereum/EIPs/issues/721
///  See the PandaCore contract documentation to understand how the various contract facets are arranged.
contract PandaOwnership is PandaBase, ERC721 {

    /// @notice Name and symbol of the non fungible token, as defined in ERC721.
    string public constant name = "PandaEarth";
    string public constant symbol = "PE";

    bytes4 constant InterfaceSignature_ERC165 =
        bytes4(keccak256('supportsInterface(bytes4)'));

    bytes4 constant InterfaceSignature_ERC721 =
        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)'));

    /// @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)
    {
        // DEBUG ONLY
        //require((InterfaceSignature_ERC165 == 0x01ffc9a7) && (InterfaceSignature_ERC721 == 0x9a20483d));

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

    // 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 Panda.
    /// @param _claimant the address we are validating against.
    /// @param _tokenId kitten id, only valid when > 0
    function _owns(address _claimant, uint256 _tokenId) internal view returns (bool) {
        return pandaIndexToOwner[_tokenId] == _claimant;
    }

    /// @dev Checks if a given address currently has transferApproval for a particular Panda.
    /// @param _claimant the address we are confirming kitten is approved for.
    /// @param _tokenId kitten id, only valid when > 0
    function _approvedFor(address _claimant, uint256 _tokenId) internal view returns (bool) {
        return pandaIndexToApproved[_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 Pandas on auction, and
    ///  there is no value in spamming the log with Approval events in that case.
    function _approve(uint256 _tokenId, address _approved) internal {
        pandaIndexToApproved[_tokenId] = _approved;
    }

    /// @notice Returns the number of Pandas 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) {
        return ownershipTokenCount[_owner];
    }

    /// @notice Transfers a Panda to another address. If transferring to a smart
    ///  contract be VERY CAREFUL to ensure that it is aware of ERC-721 (or
    ///  CryptoPandas specifically) or your Panda may be lost forever. Seriously.
    /// @param _to The address of the recipient, can be a user or contract.
    /// @param _tokenId The ID of the Panda 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 pandas (except very briefly
        // after a gen0 cat 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 pandas
        // through the allow + transferFrom flow.
        require(_to != address(saleAuction));
        require(_to != address(siringAuction));

        // You can only send your own cat.
        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 Panda 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 Panda 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);

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

    /// @notice Transfer a Panda 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 Panda to be transfered.
    /// @param _to The address that should take ownership of the Panda. Can be any address,
    ///  including the caller.
    /// @param _tokenId The ID of the Panda 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 pandas (except very briefly
        // after a gen0 cat 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 Pandas currently in existence.
    /// @dev Required for ERC-721 compliance.
    function totalSupply() public view returns (uint) {
        return pandas.length - 1;
    }

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

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

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

            // We count on the fact that all cats have IDs starting at 1 and increasing
            // sequentially up to the totalCat count.
            uint256 catId;

            for (catId = 1; catId <= totalCats; catId++) {
                if (pandaIndexToOwner[catId] == _owner) {
                    result[resultIndex] = catId;
                    resultIndex++;
                }
            }

            return result;
        }
    }

    /// @dev Adapted from memcpy() by @arachnid (Nick Johnson <[email protected]>)
    ///  This method is licenced under the Apache License.
    ///  Ref: https://github.com/Arachnid/solidity-stringutils/blob/2f6ca9accb48ae14c66f1437ec50ed19a0616f78/strings.sol
    function _memcpy(uint _dest, uint _src, uint _len) private view {
        // Copy word-length chunks while possible
        for(; _len >= 32; _len -= 32) {
            assembly {
                mstore(_dest, mload(_src))
            }
            _dest += 32;
            _src += 32;
        }

        // Copy remaining bytes
        uint256 mask = 256 ** (32 - _len) - 1;
        assembly {
            let srcpart := and(mload(_src), not(mask))
            let destpart := and(mload(_dest), mask)
            mstore(_dest, or(destpart, srcpart))
        }
    }

    /// @dev Adapted from toString(slice) by @arachnid (Nick Johnson <[email protected]>)
    ///  This method is licenced under the Apache License.
    ///  Ref: https://github.com/Arachnid/solidity-stringutils/blob/2f6ca9accb48ae14c66f1437ec50ed19a0616f78/strings.sol
    function _toString(bytes32[4] _rawBytes, uint256 _stringLength) private view returns (string) {
        var outputString = new string(_stringLength);
        uint256 outputPtr;
        uint256 bytesPtr;

        assembly {
            outputPtr := add(outputString, 32)
            bytesPtr := _rawBytes
        }

        _memcpy(outputPtr, bytesPtr, _stringLength);

        return outputString;
    }

}




/// @title A facet of PandaCore that manages Panda siring, gestation, and birth.
/// @author Axiom Zen (https://www.axiomzen.co)
/// @dev See the PandaCore contract documentation to understand how the various contract facets are arranged.
contract PandaBreeding is PandaOwnership {

    uint256 public constant GENSIS_TOTAL_COUNT = 100;

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

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

    // Keeps track of number of pregnant pandas.
    uint256 public pregnantPandas;

    mapping(uint256 => address) childOwner;


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

    /// @dev Checks that a given kitten is able to breed. Requires that the
    ///  current cooldown is finished (for sires) and also checks that there is
    ///  no pending pregnancy.
    function _isReadyToBreed(Panda _kit) internal view returns(bool) {
        // In addition to checking the cooldownEndBlock, we also need to check to see if
        // the cat has a pending birth; there can be some period of time between the end
        // of the pregnacy timer and the birth event.
        return (_kit.siringWithId == 0) && (_kit.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 = pandaIndexToOwner[_matronId];
        address sireOwner = pandaIndexToOwner[_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 || sireAllowedToAddress[_sireId] == matronOwner);
    }

    /// @dev Set the cooldownEndTime for the given Panda, based on its current cooldownIndex.
    ///  Also increments the cooldownIndex (unless it has hit the cap).
    /// @param _kitten A reference to the Panda in storage which needs its timer started.
    function _triggerCooldown(Panda storage _kitten) internal {
        // Compute an estimation of the cooldown time in blocks (based on current cooldownIndex).
        _kitten.cooldownEndBlock = uint64((cooldowns[_kitten.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 (_kitten.cooldownIndex < 8 && geneScience.getWizzType(_kitten.genes) != 1) {
            _kitten.cooldownIndex += 1;
        }
    }

    /// @notice Grants approval to another user to sire with one of your Pandas.
    /// @param _addr The address that will be able to sire with your Panda. Set to
    ///  address(0) to clear all siring approvals for this Panda.
    /// @param _sireId A Panda 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));
        sireAllowedToAddress[_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 Panda is pregnant and (if so) if the gestation
    ///  period has passed.
    function _isReadyToGiveBirth(Panda _matron) private view returns(bool) {
        return (_matron.siringWithId != 0) && (_matron.cooldownEndBlock <= uint64(block.number));
    }

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

    /// @dev Checks whether a panda is currently pregnant.
    /// @param _pandaId reference the id of the kitten, any user can inquire about it
    function isPregnant(uint256 _pandaId)
    public
    view
    returns(bool) {
        require(_pandaId > 0);
        // A panda is pregnant if and only if this field is set
        return pandas[_pandaId].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 Panda struct of the potential matron.
    /// @param _matronId The matron's ID.
    /// @param _sire A reference to the Panda struct of the potential sire.
    /// @param _sireId The sire's ID
    function _isValidMatingPair(
        Panda storage _matron,
        uint256 _matronId,
        Panda storage _sire,
        uint256 _sireId
    )
    private
    view
    returns(bool) {
        // A Panda can't breed with itself!
        if (_matronId == _sireId) {
            return false;
        }

        // Pandas 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 cat is
        // gen zero (has a matron ID of zero).
        if (_sire.matronId == 0 || _matron.matronId == 0) {
            return true;
        }

        // Pandas 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;
        }

        // male should get breed with female
        if (geneScience.getSex(_matron.genes) + geneScience.getSex(_sire.genes) != 1) {
            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) {
        Panda storage matron = pandas[_matronId];
        Panda storage sire = pandas[_sireId];
        return _isValidMatingPair(matron, _matronId, sire, _sireId);
    }

    /// @notice Checks to see if two cats can breed together, including checks for
    ///  ownership and siring approvals. Does NOT check that both cats are ready for
    ///  breeding (i.e. breedWith could still fail until the cooldowns are finished).
    ///  TODO: Shouldn't this check pregnancy and cooldowns?!?
    /// @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);
        Panda storage matron = pandas[_matronId];
        Panda storage sire = pandas[_sireId];
        return _isValidMatingPair(matron, _matronId, sire, _sireId) &&
            _isSiringPermitted(_sireId, _matronId);
    }

    function _exchangeMatronSireId(uint256 _matronId, uint256 _sireId) internal returns(uint256, uint256) {
        if (geneScience.getSex(pandas[_matronId].genes) == 1) {
            return (_sireId, _matronId);
        } else {
            return (_matronId, _sireId);
        }
    }

    /// @dev Internal utility function to initiate breeding, assumes that all breeding
    ///  requirements have been checked.
    function _breedWith(uint256 _matronId, uint256 _sireId, address _owner) internal {
        // make id point real gender
        (_matronId, _sireId) = _exchangeMatronSireId(_matronId, _sireId);
        // Grab a reference to the Pandas from storage.
        Panda storage sire = pandas[_sireId];
        Panda storage matron = pandas[_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 sireAllowedToAddress[_matronId];
        delete sireAllowedToAddress[_sireId];

        // Every time a panda gets pregnant, counter is incremented.
        pregnantPandas++;

        childOwner[_matronId] = _owner;

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

    /// @notice Breed a Panda you own (as matron) with a sire that you own, or for which you
    ///  have previously been given Siring approval. Will either make your cat 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 Panda acting as matron (will end up pregnant if successful)
    /// @param _sireId The ID of the Panda 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 Panda 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 cat
        // 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
        Panda storage matron = pandas[_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
        Panda storage sire = pandas[_sireId];

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

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

        // All checks passed, panda gets pregnant!
        _breedWith(_matronId, _sireId, msg.sender);
    }

    /// @notice Have a pregnant Panda give birth!
    /// @param _matronId A Panda ready to give birth.
    /// @return The Panda ID of the new kitten.
    /// @dev Looks at a given Panda and, if pregnant and if the gestation period has passed,
    ///  combines the genes of the two parents to create a new kitten. The new Panda is assigned
    ///  to the current owner of the matron. Upon successful completion, both the matron and the
    ///  new kitten will be ready to breed again. Note that anyone can call this function (if they
    ///  are willing to pay the gas!), but the new kitten always goes to the mother's owner.
    function giveBirth(uint256 _matronId, uint256[2] _childGenes, uint256[2] _factors)
    external
    whenNotPaused
    onlyCLevel
    returns(uint256) {
        // Grab a reference to the matron in storage.
        Panda storage matron = pandas[_matronId];

        // Check that the matron is a valid cat.
        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;
        Panda storage sire = pandas[sireId];

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

        // Call the sooper-sekret gene mixing operation.
        //uint256[2] memory childGenes = geneScience.mixGenes(matron.genes, sire.genes,matron.generation,sire.generation, matron.cooldownEndBlock - 1);
        uint256[2] memory childGenes = _childGenes;

        uint256 kittenId = 0;

        // birth failed
        uint256 probability = (geneScience.getPureFromGene(matron.genes) + geneScience.getPureFromGene(sire.genes)) / 2 + _factors[0];
        if (probability >= (parentGen + 1) * _factors[1]) {
            probability = probability - (parentGen + 1) * _factors[1];
        } else {
            probability = 0;
        }
        if (parentGen == 0 && gen0CreatedCount == GEN0_TOTAL_COUNT) {
            probability = 0;
        }
        if (uint256(keccak256(block.blockhash(block.number - 2), now)) % 100 < probability) {
            // Make the new kitten!
            address owner = childOwner[_matronId];
            kittenId = _createPanda(_matronId, matron.siringWithId, parentGen + 1, childGenes, owner);
        } else {
            Abortion(pandaIndexToOwner[_matronId], _matronId, sireId);
        }
        // Make the new kitten!
        //address owner = pandaIndexToOwner[_matronId];
        //address owner = childOwner[_matronId];
        //uint256 kittenId = _createPanda(_matronId, matron.siringWithId, parentGen + 1, childGenes, 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 panda gives birth counter is decremented.
        pregnantPandas--;

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

        delete childOwner[_matronId];

        // return the new kitten's ID
        return kittenId;
    }
}





/// @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 {

    // 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;
        // is this auction for gen0 panda
        uint64 isGen0;
    }

    // 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);
    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
        nonFungibleContract.transferFrom(_owner, this, _tokenId);
    }

    /// @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) internal {
        // it will throw if transfer fails
        nonFungibleContract.transfer(_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;

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

    /// @dev Cancels an auction unconditionally.
    function _cancelAuction(uint256 _tokenId, address _seller) internal {
        _removeAuction(_tokenId);
        _transfer(_seller, _tokenId);
        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!
        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;
    }

}




/**
 * @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() onlyOwner whenNotPaused returns (bool) {
    paused = true;
    Pause();
    return true;
  }

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


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

    /// @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-10,000.
    function ClockAuction(address _nftAddress, uint256 _cut) public {
        require(_cut <= 10000);
        ownerCut = _cut;

        ERC721 candidateContract = ERC721(_nftAddress);
        require(candidateContract.supportsInterface(InterfaceSignature_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
        );
        // We are using this boolean method to make sure that even if one fails it will still work
        bool res = nftAddress.send(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),
            0
        );
        _addAuction(_tokenId, auction);
    }

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

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

}




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

    // Delegate constructor
    function SiringClockAuction(address _nftAddr, uint256 _cut) public
        ClockAuction(_nftAddr, _cut) {}

    /// @dev Creates and begins a new auction. Since this function is wrapped,
    /// require sender to be PandaCore 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),
            0
        );
        _addAuction(_tokenId, auction);
    }

    /// @dev Places a bid for siring. Requires the sender
    /// is the PandaCore contract because all bid methods
    /// should be wrapped. Also returns the panda 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 panda back to the seller, the winner will get
        // the offspring
        _transfer(seller, _tokenId);
    }

}




/// @title Clock auction modified for sale of pandas
/// @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 panda sales
    uint256 public gen0SaleCount;
    uint256[5] public lastGen0SalePrices;
    uint256 public constant SurpriseValue = 10 finney;

    uint256[] CommonPanda;
    uint256[] RarePanda;
    uint256   CommonPandaIndex;
    uint256   RarePandaIndex;

    // Delegate constructor
    function SaleClockAuction(address _nftAddr, uint256 _cut) public
        ClockAuction(_nftAddr, _cut) {
            CommonPandaIndex = 1;
            RarePandaIndex   = 1;
    }

    /// @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),
            0
        );
        _addAuction(_tokenId, auction);
    }

    function createGen0Auction(
        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),
            1
        );
        _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
        uint64 isGen0 = tokenIdToAuction[_tokenId].isGen0;
        uint256 price = _bid(_tokenId, msg.value);
        _transfer(msg.sender, _tokenId);

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

    function createPanda(uint256 _tokenId,uint256 _type)
        external
    {
        require(msg.sender == address(nonFungibleContract));
        if (_type == 0) {
            CommonPanda.push(_tokenId);
        }else {
            RarePanda.push(_tokenId);
        }
    }

    function surprisePanda()
        external
        payable
    {
        bytes32 bHash = keccak256(block.blockhash(block.number),block.blockhash(block.number-1));
        uint256 PandaIndex;
        if (bHash[25] > 0xC8) {
            require(uint256(RarePanda.length) >= RarePandaIndex);
            PandaIndex = RarePandaIndex;
            RarePandaIndex ++;

        } else{
            require(uint256(CommonPanda.length) >= CommonPandaIndex);
            PandaIndex = CommonPandaIndex;
            CommonPandaIndex ++;
        }
        _transfer(msg.sender,PandaIndex);
    }

    function packageCount() external view returns(uint256 common,uint256 surprise) {
        common   = CommonPanda.length + 1 - CommonPandaIndex;
        surprise = RarePanda.length + 1 - RarePandaIndex;
    }

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

}



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


    event AuctionERC20Created(uint256 tokenId, uint256 startingPrice, uint256 endingPrice, uint256 duration, address erc20Contract);

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

    mapping (uint256 => address) public tokenIdToErc20Address;

    mapping (address => uint256) public erc20ContractsSwitcher;

    mapping (address => uint256) public balances;
    
    // Delegate constructor
    function SaleClockAuctionERC20(address _nftAddr, uint256 _cut) public
        ClockAuction(_nftAddr, _cut) {}

    function erc20ContractSwitch(address _erc20address, uint256 _onoff) external{
        require (msg.sender == address(nonFungibleContract));

        require (_erc20address != address(0));

        erc20ContractsSwitcher[_erc20address] = _onoff;
    }
    /// @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,
        address _erc20Address,
        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));

        require (erc20ContractsSwitcher[_erc20Address] > 0);
        
        _escrow(_seller, _tokenId);
        Auction memory auction = Auction(
            _seller,
            uint128(_startingPrice),
            uint128(_endingPrice),
            uint64(_duration),
            uint64(now),
            0
        );
        _addAuctionERC20(_tokenId, auction, _erc20Address);
        tokenIdToErc20Address[_tokenId] = _erc20Address;
    }

    /// @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 _addAuctionERC20(uint256 _tokenId, Auction _auction, address _erc20address) 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;

        AuctionERC20Created(
            uint256(_tokenId),
            uint256(_auction.startingPrice),
            uint256(_auction.endingPrice),
            uint256(_auction.duration),
            _erc20address
        );
    }   

    function bid(uint256 _tokenId)
        external
        payable{
            // do nothing
    }

    /// @dev Updates lastSalePrice if seller is the nft contract
    /// Otherwise, works the same as default bid method.
    function bidERC20(uint256 _tokenId,uint256 _amount)
        external
    {
        // _bid verifies token ID size
        address seller = tokenIdToAuction[_tokenId].seller;
        address _erc20address = tokenIdToErc20Address[_tokenId];
        require (_erc20address != address(0));
        uint256 price = _bidERC20(_erc20address,msg.sender,_tokenId, _amount);
        _transfer(msg.sender, _tokenId);
        delete tokenIdToErc20Address[_tokenId];
    }

    function cancelAuction(uint256 _tokenId)
        external
    {
        Auction storage auction = tokenIdToAuction[_tokenId];
        require(_isOnAuction(auction));
        address seller = auction.seller;
        require(msg.sender == seller);
        _cancelAuction(_tokenId, seller);
        delete tokenIdToErc20Address[_tokenId];
    }

    function withdrawERC20Balance(address _erc20Address, address _to) external returns(bool res)  {
        require (balances[_erc20Address] > 0);
        require(msg.sender == address(nonFungibleContract));
        ERC20(_erc20Address).transfer(_to, balances[_erc20Address]);
    }
    
    /// @dev Computes the price and transfers winnings.
    /// Does NOT transfer ownership of token.
    function _bidERC20(address _erc20Address,address _buyerAddress, 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));


        require (_erc20Address != address(0) && _erc20Address == tokenIdToErc20Address[_tokenId]);
        

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

            // Send Erc20 Token to seller should call Erc20 contract
            // Reference to contract
            require(ERC20(_erc20Address).transferFrom(_buyerAddress,seller,sellerProceeds));
            if (auctioneerCut > 0){
                require(ERC20(_erc20Address).transferFrom(_buyerAddress,address(this),auctioneerCut));
                balances[_erc20Address] += auctioneerCut;
            }
        }

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

        return price;
    }
}


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

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

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

    function setSaleAuctionERC20Address(address _address) external onlyCEO {
        SaleClockAuctionERC20 candidateContract = SaleClockAuctionERC20(_address);

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

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

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

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

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

    function switchSaleAuctionERC20For(address _erc20address, uint256 _onoff) external onlyCOO{
        saleAuctionERC20.erc20ContractSwitch(_erc20address,_onoff);
    }


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

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


    function withdrawERC20Balance(address _erc20Address, address _to) external onlyCLevel {
        require(saleAuctionERC20 != address(0));
        saleAuctionERC20.withdrawERC20Balance(_erc20Address,_to);
    }    
}





/// @title all functions related to creating kittens
contract PandaMinting is PandaAuction {

    // Limits the number of cats 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 = 100 finney;
    uint256 public constant GEN0_AUCTION_DURATION = 1 days;
    uint256 public constant OPEN_PACKAGE_PRICE = 10 finney;


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


    /// @dev we can create promo kittens, up to a limit. Only callable by COO
    /// @param _genes the encoded genes of the kitten to be created, any value is accepted
    /// @param _owner the future owner of the created kittens. Default to contract COO
    function createWizzPanda(uint256[2] _genes, uint256 _generation, address _owner) external onlyCOO {
        address pandaOwner = _owner;
        if (pandaOwner == address(0)) {
            pandaOwner = cooAddress;
        }

        _createPanda(0, 0, _generation, _genes, pandaOwner);
    }

    /// @dev create pandaWithGenes
    /// @param _genes panda genes
    /// @param _type  0 common 1 rare
    function createPanda(uint256[2] _genes,uint256 _generation,uint256 _type)
        external
        payable
        onlyCOO
        whenNotPaused
    {
        require(msg.value >= OPEN_PACKAGE_PRICE);
        uint256 kittenId = _createPanda(0, 0, _generation, _genes, saleAuction);
        saleAuction.createPanda(kittenId,_type);
    }

    //function buyPandaERC20(address _erc20Address, address _buyerAddress, uint256 _pandaID, uint256 _amount)
    //external
    //onlyCOO
    //whenNotPaused {
    //    saleAuctionERC20.bid(_erc20Address, _buyerAddress, _pandaID, _amount);
    //}

    /// @dev Creates a new gen0 panda with the given genes and
    ///  creates an auction for it.
    //function createGen0Auction(uint256[2] _genes) external onlyCOO {
    //    require(gen0CreatedCount < GEN0_CREATION_LIMIT);
    //
    //    uint256 pandaId = _createPanda(0, 0, 0, _genes, address(this));
    //    _approve(pandaId, saleAuction);
    //
    //    saleAuction.createAuction(
    //        pandaId,
    //        _computeNextGen0Price(),
    //        0,
    //        GEN0_AUCTION_DURATION,
    //        address(this)
    //    );
    //
    //    gen0CreatedCount++;
    //}

    function createGen0Auction(uint256 _pandaId) external onlyCOO {
        require(_owns(msg.sender, _pandaId));
        //require(pandas[_pandaId].generation==1);

        _approve(_pandaId, saleAuction);

        saleAuction.createGen0Auction(
            _pandaId,
            _computeNextGen0Price(),
            0,
            GEN0_AUCTION_DURATION,
            msg.sender
        );
    }

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



/// @title CryptoPandas: Collectible, breedable, and oh-so-adorable cats on the Ethereum blockchain.
/// @author Axiom Zen (https://www.axiomzen.co)
/// @dev The main CryptoPandas contract, keeps track of kittens so they don't wander around and get lost.
contract PandaCore is PandaMinting {

    // This is the main CryptoPandas 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
    // panda 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 CK. 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:
    //
    //      - PandaBase: 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.
    //
    //      - PandaAccessControl: This contract manages the various addresses and constraints for operations
    //             that can be executed only by specific roles. Namely CEO, CFO and COO.
    //
    //      - PandaOwnership: This provides the methods required for basic non-fungible token
    //             transactions, following the draft ERC-721 spec (https://github.com/ethereum/EIPs/issues/721).
    //
    //      - PandaBreeding: This file contains the methods necessary to breed cats together, including
    //             keeping track of siring offers, and relies on an external genetic combination contract.
    //
    //      - PandaAuctions: Here we have the public methods for auctioning or bidding on cats 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.
    //
    //      - PandaMinting: This final facet contains the functionality we use for creating new gen0 cats.
    //             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 cats. 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 CryptoPandas smart contract instance.
    function PandaCore() public {
        // Starts paused.
        paused = true;

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

        // the creator of the contract is also the initial COO
        cooAddress = msg.sender;

        // move these code to init(), so we not excceed gas limit
        //uint256[2] memory _genes = [uint256(-1),uint256(-1)];

        //wizzPandaQuota[1] = 100;

        //_createPanda(0, 0, 0, _genes, address(0));
    }

    /// init contract
    function init() external onlyCEO whenPaused {
        // make sure init() only run once
        require(pandas.length == 0);
        // start with the mythical kitten 0 - so we don't have generation-0 parent issues
        uint256[2] memory _genes = [uint256(-1),uint256(-1)];

        wizzPandaQuota[1] = 100;
       _createPanda(0, 0, 0, _genes, address(0));
    }

    /// @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;
        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 panda.
    /// @param _id The ID of the panda of interest.
    function getPanda(uint256 _id)
        external
        view
        returns (
        bool isGestating,
        bool isReady,
        uint256 cooldownIndex,
        uint256 nextActionAt,
        uint256 siringWithId,
        uint256 birthTime,
        uint256 matronId,
        uint256 sireId,
        uint256 generation,
        uint256[2] genes
    ) {
        Panda storage kit = pandas[_id];

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

    /// @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 = this.balance;
        // Subtract all the currently pregnant kittens we have, plus 1 of margin.
        uint256 subtractFees = (pregnantPandas + 1) * autoBirthFee;

        if (balance > subtractFees) {
            cfoAddress.send(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":"name","outputs":[{"name":"","type":"string"}],"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":true,"inputs":[{"name":"_id","type":"uint256"}],"name":"getPanda","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":"genes","type":"uint256[2]"}],"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":"GEN0_TOTAL_COUNT","outputs":[{"name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"totalSupply","outputs":[{"name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"name":"_pandaId","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":false,"inputs":[{"name":"_erc20Address","type":"address"},{"name":"_to","type":"address"}],"name":"withdrawERC20Balance","outputs":[],"payable":false,"stateMutability":"nonpayable","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":"_pandaId","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":true,"inputs":[{"name":"","type":"uint256"}],"name":"sireAllowedToAddress","outputs":[{"name":"","type":"address"}],"payable":false,"stateMutability":"view","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":"_pandaId","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":"_id","type":"uint256"}],"name":"getWizzTypeOf","outputs":[{"name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"name":"_genes","type":"uint256[2]"},{"name":"_generation","type":"uint256"},{"name":"_owner","type":"address"}],"name":"createWizzPanda","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"name":"secs","type":"uint256"}],"name":"setSecondsPerBlock","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[],"name":"paused","outputs":[{"name":"","type":"bool"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[],"name":"withdrawBalance","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[{"name":"_tokenId","type":"uint256"}],"name":"ownerOf","outputs":[{"name":"owner","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":"count","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"name":"_v2Address","type":"address"}],"name":"setNewAddress","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[{"name":"","type":"uint256"}],"name":"wizzPandaQuota","outputs":[{"name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"name":"","type":"uint256"}],"name":"wizzPandaCount","outputs":[{"name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"name":"","type":"uint256"}],"name":"pandaIndexToOwner","outputs":[{"name":"","type":"address"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"secondsPerBlock","outputs":[{"name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"name":"_pandaId","type":"uint256"},{"name":"_erc20address","type":"address"},{"name":"_startingPrice","type":"uint256"},{"name":"_endingPrice","type":"uint256"},{"name":"_duration","type":"uint256"}],"name":"createSaleAuctionERC20","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[{"name":"_tp","type":"uint256"}],"name":"getWizzPandaQuotaOf","outputs":[{"name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[],"name":"pause","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[{"name":"_owner","type":"address"}],"name":"tokensOfOwner","outputs":[{"name":"ownerTokens","type":"uint256[]"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"saleAuctionERC20","outputs":[{"name":"","type":"address"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[],"name":"withdrawAuctionBalances","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"name":"_genes","type":"uint256[2]"},{"name":"_generation","type":"uint256"},{"name":"_type","type":"uint256"}],"name":"createPanda","outputs":[],"payable":true,"stateMutability":"payable","type":"function"},{"constant":true,"inputs":[],"name":"symbol","outputs":[{"name":"","type":"string"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"name":"_address","type":"address"}],"name":"setSaleAuctionERC20Address","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"name":"_erc20address","type":"address"},{"name":"_onoff","type":"uint256"}],"name":"switchSaleAuctionERC20For","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[{"name":"","type":"uint256"}],"name":"cooldowns","outputs":[{"name":"","type":"uint32"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"name":"_to","type":"address"},{"name":"_tokenId","type":"uint256"}],"name":"transfer","outputs":[],"payable":false,"stateMutability":"nonpayable","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":"_tp","type":"uint256"},{"name":"_total","type":"uint256"}],"name":"setTotalWizzPandaOf","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[{"name":"","type":"uint256"}],"name":"pandaIndexToApproved","outputs":[{"name":"","type":"address"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"name":"_pandaId","type":"uint256"}],"name":"createGen0Auction","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[],"name":"GENSIS_TOTAL_COUNT","outputs":[{"name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"name":"_pandaId","type":"uint256"}],"name":"isReadyToBreed","outputs":[{"name":"","type":"bool"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[],"name":"init","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[],"name":"saleAuction","outputs":[{"name":"","type":"address"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"OPEN_PACKAGE_PRICE","outputs":[{"name":"","type":"uint256"}],"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":"_childGenes","type":"uint256[2]"},{"name":"_factors","type":"uint256[2]"}],"name":"giveBirth","outputs":[{"name":"","type":"uint256"}],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[{"name":"_tp","type":"uint256"}],"name":"getWizzPandaCountOf","outputs":[{"name":"","type":"uint256"}],"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"},{"constant":true,"inputs":[],"name":"pregnantPandas","outputs":[{"name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"inputs":[],"payable":false,"stateMutability":"nonpayable","type":"constructor"},{"payable":true,"stateMutability":"payable","type":"fallback"},{"anonymous":false,"inputs":[{"indexed":false,"name":"owner","type":"address"},{"indexed":false,"name":"matronId","type":"uint256"},{"indexed":false,"name":"sireId","type":"uint256"},{"indexed":false,"name":"cooldownEndBlock","type":"uint256"}],"name":"Pregnant","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"name":"owner","type":"address"},{"indexed":false,"name":"matronId","type":"uint256"},{"indexed":false,"name":"sireId","type":"uint256"}],"name":"Abortion","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"name":"from","type":"address"},{"indexed":false,"name":"to","type":"address"},{"indexed":false,"name":"tokenId","type":"uint256"}],"name":"Transfer","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"name":"owner","type":"address"},{"indexed":false,"name":"approved","type":"address"},{"indexed":false,"name":"tokenId","type":"uint256"}],"name":"Approval","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"name":"owner","type":"address"},{"indexed":false,"name":"pandaId","type":"uint256"},{"indexed":false,"name":"matronId","type":"uint256"},{"indexed":false,"name":"sireId","type":"uint256"},{"indexed":false,"name":"genes","type":"uint256[2]"}],"name":"Birth","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"name":"newContract","type":"address"}],"name":"ContractUpgrade","type":"event"}]

Contract Creation Code
6002805460a060020a60ff02191690556101a060405261012c608090815261070860a052611c2060c05261384060e0526170806101005262015180610120526202a300610140526203f4806101605262093a806101805262000066906004906009620000d0565b50600f60065566071afd498d00006012553480156200008457600080fd5b506002805460008054600160a060020a03199081163390811790925560a060020a60ff02199092167401000000000000000000000000000000000000000017919091161790556200019a565b600283019183908215620001615791602002820160005b838211156200012d57835183826101000a81548163ffffffff021916908363ffffffff1602179055509260200192600401602081600301049283019260010302620000e7565b80156200015f5782816101000a81549063ffffffff02191690556004016020816003010492830192600103026200012d565b505b506200016f92915062000173565b5090565b6200019791905b808211156200016f57805463ffffffff191681556001016200017a565b90565b6141da80620001aa6000396000f30060806040526004361061031e5763ffffffff60e060020a60003504166301ffc9a7811461034e5780630519ce791461039957806306fdde03146103ca578063095ea7b3146104545780630a0f8168146104785780630e583df01461048d5780631327fbe5146104b457806314001f4c1461054e57806316b648981461056f57806318160ddd146105845780631940a9361461059957806319c2f201146105b15780631c338644146105c657806321717ebf146105ed57806323b872dd1461060257806324e7a38a1461062c57806327d7874c1461064d5780632ba73c151461066e5780633d7d3f5a1461068f5780633f4ba83a146106b057806346116e6f146106c557806346d22c70146106dd5780634ad8c938146106f85780634b85fd55146107195780634dfff04f146107315780634e0a3379146107555780634e61efc51461077657806353a01f681461078e5780635663896e146107b45780635c975abb146107cc5780635fd8c710146107e15780636352211e146107f6578063680eba271461080e5780636af04a57146108235780636fbde40d1461083857806370a0823114610859578063715879881461087a5780637420d16c1461089b57806374ea167f146108b3578063756d77fc146108cb5780637a7d4937146108e35780637d16bef7146108f8578063818438ca146109255780638456cb591461093d5780638462151c1461095257806388524780146109c357806391876e57146109d85780639505b2a7146109ed57806395d89b41146109fd5780639b96f3ed14610a125780639cca68e214610a335780639d6fac6f14610a57578063a9059cbb14610a88578063b047fb5014610aac578063b0c35c0514610ac1578063b380beac14610ad6578063c212445214610af1578063c3bea9af14610b09578063d0774f7414610b21578063d3e6f49f14610b36578063e1c7392a14610b4e578063e6cbe35114610b63578063e8b4c9d714610b78578063ed60ade614610b8d578063f1ca941014610b9b578063f2b47d5214610bb0578063f374694714610bc5578063f3817b2314610be1578063f7d8c88314610bf9578063ffa40a4c14610c07575b600c54600160a060020a03163314806103415750600d54600160a060020a031633145b151561034c57600080fd5b005b34801561035a57600080fd5b506103857bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1960043516610c1c565b604080519115158252519081900360200190f35b3480156103a557600080fd5b506103ae610eaf565b60408051600160a060020a039092168252519081900360200190f35b3480156103d657600080fd5b506103df610ebe565b6040805160208082528351818301528351919283929083019185019080838360005b83811015610419578181015183820152602001610401565b50505050905090810190601f1680156104465780820380516001836020036101000a031916815260200191505b509250505060405180910390f35b34801561046057600080fd5b5061034c600160a060020a0360043516602435610ef5565b34801561048457600080fd5b506103ae610f77565b34801561049957600080fd5b506104a2610f86565b60408051918252519081900360200190f35b3480156104c057600080fd5b506104cc600435610f92565b604051808b1515151581526020018a15151515815260200189815260200188815260200187815260200186815260200185815260200184815260200183815260200182600260200280838360005b8381101561053257818101518382015260200161051a565b505050509050019a505050505050505050505060405180910390f35b34801561055a57600080fd5b5061034c600160a060020a0360043516611135565b34801561057b57600080fd5b506104a26111e8565b34801561059057600080fd5b506104a26111ee565b3480156105a557600080fd5b506103856004356111f9565b3480156105bd57600080fd5b506104a261123e565b3480156105d257600080fd5b5061034c600160a060020a0360043581169060243516611245565b3480156105f957600080fd5b506103ae61133f565b34801561060e57600080fd5b5061034c600160a060020a036004358116906024351660443561134e565b34801561063857600080fd5b5061034c600160a060020a03600435166113ca565b34801561065957600080fd5b5061034c600160a060020a036004351661147d565b34801561067a57600080fd5b5061034c600160a060020a03600435166114cb565b34801561069b57600080fd5b5061034c600435602435604435606435611519565b3480156106bc57600080fd5b5061034c61160e565b3480156106d157600080fd5b506103ae6004356116a2565b3480156106e957600080fd5b506103856004356024356116bd565b34801561070457600080fd5b5061034c60043560243560443560643561173d565b34801561072557600080fd5b5061034c600435611815565b34801561073d57600080fd5b5061034c600160a060020a0360043516602435611831565b34801561076157600080fd5b5061034c600160a060020a036004351661188b565b34801561078257600080fd5b506104a26004356118d9565b34801561079a57600080fd5b5061034c6004604435600160a060020a0360643516611a79565b3480156107c057600080fd5b5061034c600435611aec565b3480156107d857600080fd5b50610385611b48565b3480156107ed57600080fd5b5061034c611b58565b34801561080257600080fd5b506103ae600435611bbc565b34801561081a57600080fd5b506104a2611be0565b34801561082f57600080fd5b506103ae611be6565b34801561084457600080fd5b5061034c600160a060020a0360043516611bf5565b34801561086557600080fd5b506104a2600160a060020a0360043516611ca8565b34801561088657600080fd5b5061034c600160a060020a0360043516611cc3565b3480156108a757600080fd5b506104a2600435611d46565b3480156108bf57600080fd5b506104a2600435611d58565b3480156108d757600080fd5b506103ae600435611d6a565b3480156108ef57600080fd5b506104a2611d85565b34801561090457600080fd5b5061034c600435600160a060020a0360243516604435606435608435611d8b565b34801561093157600080fd5b506104a2600435611e89565b34801561094957600080fd5b5061034c611e9b565b34801561095e57600080fd5b50610973600160a060020a0360043516611f1b565b60408051602080825283518183015283519192839290830191858101910280838360005b838110156109af578181015183820152602001610997565b505050509050019250505060405180910390f35b3480156109cf57600080fd5b506103ae611fed565b3480156109e457600080fd5b5061034c611ffc565b61034c6004604435606435612111565b348015610a0957600080fd5b506103df612203565b348015610a1e57600080fd5b5061034c600160a060020a036004351661223a565b348015610a3f57600080fd5b5061034c600160a060020a03600435166024356122ed565b348015610a6357600080fd5b50610a6f60043561238e565b6040805163ffffffff9092168252519081900360200190f35b348015610a9457600080fd5b5061034c600160a060020a03600435166024356123bb565b348015610ab857600080fd5b506103ae612453565b348015610acd57600080fd5b506104a2612462565b348015610ae257600080fd5b5061034c600435602435612468565b348015610afd57600080fd5b506103ae6004356124e8565b348015610b1557600080fd5b5061034c600435612503565b348015610b2d57600080fd5b506104a26125cc565b348015610b4257600080fd5b506103856004356125d1565b348015610b5a57600080fd5b5061034c6126c3565b348015610b6f57600080fd5b506103ae61275e565b348015610b8457600080fd5b506104a261276d565b61034c600435602435612778565b348015610ba757600080fd5b506104a2612913565b348015610bbc57600080fd5b506103ae612919565b348015610bd157600080fd5b506104a260043560246064612928565b348015610bed57600080fd5b506104a2600435612e39565b61034c600435602435612e4b565b348015610c1357600080fd5b506104a261308e565b604080517f737570706f727473496e74657266616365286279746573342900000000000000815290519081900360190190206000907bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1983811691161480610ea75750604080517f746f6b656e4d657461646174612875696e743235362c737472696e67290000008152815190819003601d0181207f746f6b656e734f664f776e657228616464726573732900000000000000000000825282519182900360160182207f7472616e7366657246726f6d28616464726573732c616464726573732c75696e83527f7432353629000000000000000000000000000000000000000000000000000000602084015283519283900360250183207f7472616e7366657228616464726573732c75696e743235362900000000000000845284519384900360190184207f617070726f766528616464726573732c75696e74323536290000000000000000855285519485900360180185207f6f776e65724f662875696e743235362900000000000000000000000000000000865286519586900360100186207f62616c616e63654f662861646472657373290000000000000000000000000000875287519687900360120187207f746f74616c537570706c792829000000000000000000000000000000000000008852885197889003600d0188207f73796d626f6c2829000000000000000000000000000000000000000000000000895289519889900360080189207f6e616d65282900000000000000000000000000000000000000000000000000008a529951988990036006019098207bffffffffffffffffffffffffffffffffffffffffffffffffffffffff198c811691909a189098181818181818181891909116145b90505b919050565b600154600160a060020a031681565b60408051808201909152600a81527f50616e6461456172746800000000000000000000000000000000000000000000602082015281565b60025460a060020a900460ff1615610f0c57600080fd5b610f163382613094565b1515610f2157600080fd5b610f2b81836130b4565b60408051338152600160a060020a038416602082015280820183905290517f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b9259181900360600190a15050565b600054600160a060020a031681565b67016345785d8a000081565b6000806000806000806000806000610fa86140ef565b600060078c815481101515610fb957fe5b906000526020600020906003020190508060020160189054906101000a900463ffffffff1663ffffffff16600014159a50438160020160089054906101000a900467ffffffffffffffff1667ffffffffffffffff161115995080600201601c9054906101000a900461ffff1661ffff1698508060020160089054906101000a900467ffffffffffffffff1667ffffffffffffffff1697508060020160189054906101000a900463ffffffff1663ffffffff1696508060020160009054906101000a900467ffffffffffffffff1667ffffffffffffffff1695508060020160109054906101000a900463ffffffff1663ffffffff1694508060020160149054906101000a900463ffffffff1663ffffffff16935080600201601e9054906101000a900461ffff1661ffff16925080600001600280602002604051908101604052809291908260028015611120576020028201915b81548152602001906001019080831161110c575b50505050509150509193959799509193959799565b60008054600160a060020a0316331461114d57600080fd5b81905080600160a060020a03166376190f8f6040518163ffffffff1660e060020a028152600401602060405180830381600087803b15801561118e57600080fd5b505af11580156111a2573d6000803e3d6000fd5b505050506040513d60208110156111b857600080fd5b505115156111c557600080fd5b600d8054600160a060020a031916600160a060020a039290921691909117905550565b613f4881565b600754600019015b90565b600080821161120757600080fd5b600780548390811061121557fe5b600091825260209091206003909102016002015460c060020a900463ffffffff16151592915050565b6201518081565b600254600160a060020a03163314806112685750600054600160a060020a031633145b8061127d5750600154600160a060020a031633145b151561128857600080fd5b600f54600160a060020a0316151561129f57600080fd5b600f54604080517f1c338644000000000000000000000000000000000000000000000000000000008152600160a060020a038581166004830152848116602483015291519190921691631c3386449160448083019260209291908290030181600087803b15801561130f57600080fd5b505af1158015611323573d6000803e3d6000fd5b505050506040513d602081101561133957600080fd5b50505050565b600d54600160a060020a031681565b60025460a060020a900460ff161561136557600080fd5b600160a060020a038216151561137a57600080fd5b600160a060020a03821630141561139057600080fd5b61139a33826130e2565b15156113a557600080fd5b6113af8382613094565b15156113ba57600080fd5b6113c5838383613102565b505050565b60008054600160a060020a031633146113e257600080fd5b81905080600160a060020a03166354c15b826040518163ffffffff1660e060020a028152600401602060405180830381600087803b15801561142357600080fd5b505af1158015611437573d6000803e3d6000fd5b505050506040513d602081101561144d57600080fd5b5051151561145a57600080fd5b600e8054600160a060020a031916600160a060020a039290921691909117905550565b600054600160a060020a0316331461149457600080fd5b600160a060020a03811615156114a957600080fd5b60008054600160a060020a031916600160a060020a0392909216919091179055565b600054600160a060020a031633146114e257600080fd5b600160a060020a03811615156114f757600080fd5b60028054600160a060020a031916600160a060020a0392909216919091179055565b60025460a060020a900460ff161561153057600080fd5b61153a3385613094565b151561154557600080fd5b61154e846111f9565b1561155857600080fd5b600c5461156f908590600160a060020a03166130b4565b600c54604080517f27ebe40a000000000000000000000000000000000000000000000000000000008152600481018790526024810186905260448101859052606481018490523360848201529051600160a060020a03909216916327ebe40a9160a48082019260009290919082900301818387803b1580156115f057600080fd5b505af1158015611604573d6000803e3d6000fd5b5050505050505050565b600054600160a060020a0316331461162557600080fd5b60025460a060020a900460ff16151561163d57600080fd5b600c54600160a060020a0316151561165457600080fd5b600d54600160a060020a0316151561166b57600080fd5b600e54600160a060020a0316151561168257600080fd5b601554600160a060020a03161561169857600080fd5b6116a06131e4565b565b600b60205260009081526040902054600160a060020a031681565b600080808085116116cd57600080fd5b600084116116da57600080fd5b60078054869081106116e857fe5b9060005260206000209060030201915060078481548110151561170757fe5b9060005260206000209060030201905061172382868387613233565b80156117345750611734848661350f565b95945050505050565b60025460a060020a900460ff161561175457600080fd5b61175e3385613094565b151561176957600080fd5b611772846125d1565b151561177d57600080fd5b600d54611794908590600160a060020a03166130b4565b600d54604080517f27ebe40a000000000000000000000000000000000000000000000000000000008152600481018790526024810186905260448101859052606481018490523360848201529051600160a060020a03909216916327ebe40a9160a48082019260009290919082900301818387803b1580156115f057600080fd5b600254600160a060020a0316331461182c57600080fd5b601255565b60025460a060020a900460ff161561184857600080fd5b6118523382613094565b151561185d57600080fd5b6000908152600b602052604090208054600160a060020a031916600160a060020a0392909216919091179055565b600054600160a060020a031633146118a257600080fd5b600160a060020a03811615156118b757600080fd5b60018054600160a060020a031916600160a060020a0392909216919091179055565b60006118e361410a565b60078054849081106118f157fe5b6000918252602090912060408051610140810190915291600302018161010081018260028282826020028201915b81548152602001906001019080831161191f5750505091835250506002919091015467ffffffffffffffff80821660208401526801000000000000000082041660408084019190915263ffffffff608060020a83048116606085015260a060020a83048116608085015260c060020a83041660a084015261ffff60e060020a8304811660c085015260f060020a90920490911660e090920191909152600e54825182517f7c59f828000000000000000000000000000000000000000000000000000000008152939450600160a060020a0390911692637c59f828926004909101908190839080838360005b83811015611a22578181015183820152602001611a0a565b50505050905001915050602060405180830381600087803b158015611a4657600080fd5b505af1158015611a5a573d6000803e3d6000fd5b505050506040513d6020811015611a7057600080fd5b50519392505050565b600254600090600160a060020a03163314611a9357600080fd5b5080600160a060020a0381161515611ab35750600254600160a060020a03165b611ae5600080858760028060200260405190810160405280929190826002602002808284375089935061356492505050565b5050505050565b600254600160a060020a0316331480611b0f5750600054600160a060020a031633145b80611b245750600154600160a060020a031633145b1515611b2f57600080fd5b60045463ffffffff168110611b4357600080fd5b600655565b60025460a060020a900460ff1681565b6001546000908190600160a060020a03163314611b7457600080fd5b505060125460135430319160019091010280821115611bb857600154604051600160a060020a039091169082840380156108fc02916000818181858888f150505050505b5050565b600081815260086020526040902054600160a060020a0316801515610eaa57600080fd5b61afc881565b601554600160a060020a031681565b60008054600160a060020a03163314611c0d57600080fd5b81905080600160a060020a03166385b861886040518163ffffffff1660e060020a028152600401602060405180830381600087803b158015611c4e57600080fd5b505af1158015611c62573d6000803e3d6000fd5b505050506040513d6020811015611c7857600080fd5b50511515611c8557600080fd5b600c8054600160a060020a031916600160a060020a039290921691909117905550565b600160a060020a031660009081526009602052604090205490565b600054600160a060020a03163314611cda57600080fd5b60025460a060020a900460ff161515611cf257600080fd5b60158054600160a060020a038316600160a060020a0319909116811790915560408051918252517f450db8da6efbe9c22f2347f7c2021231df1fc58d3ae9a2fa75d39fa4461993059181900360200190a150565b60106020526000908152604090205481565b60116020526000908152604090205481565b600860205260009081526040902054600160a060020a031681565b60065481565b60025460a060020a900460ff1615611da257600080fd5b611dac3386613094565b1515611db757600080fd5b611dc0856111f9565b15611dca57600080fd5b600f54611de1908690600160a060020a03166130b4565b600f54604080517fc82531a300000000000000000000000000000000000000000000000000000000815260048101889052600160a060020a0387811660248301526044820187905260648201869052608482018590523360a48301529151919092169163c82531a39160c480830192600092919082900301818387803b158015611e6a57600080fd5b505af1158015611e7e573d6000803e3d6000fd5b505050505050505050565b60009081526010602052604090205490565b600254600160a060020a0316331480611ebe5750600054600160a060020a031633145b80611ed35750600154600160a060020a031633145b1515611ede57600080fd5b60025460a060020a900460ff1615611ef557600080fd5b6002805474ff0000000000000000000000000000000000000000191660a060020a179055565b6060600060606000806000611f2f87611ca8565b9450841515611f4e576040805160008152602081019091529550611fe3565b84604051908082528060200260200182016040528015611f78578160200160208202803883390190505b509350611f836111ee565b925060009150600190505b828111611fdf57600081815260086020526040902054600160a060020a0388811691161415611fd757808483815181101515611fc657fe5b602090810290910101526001909101905b600101611f8e565b8395505b5050505050919050565b600f54600160a060020a031681565b600254600160a060020a031633148061201f5750600054600160a060020a031633145b806120345750600154600160a060020a031633145b151561203f57600080fd5b600c60009054906101000a9004600160a060020a0316600160a060020a0316635fd8c7106040518163ffffffff1660e060020a028152600401600060405180830381600087803b15801561209257600080fd5b505af11580156120a6573d6000803e3d6000fd5b50505050600d60009054906101000a9004600160a060020a0316600160a060020a0316635fd8c7106040518163ffffffff1660e060020a028152600401600060405180830381600087803b1580156120fd57600080fd5b505af1158015611339573d6000803e3d6000fd5b600254600090600160a060020a0316331461212b57600080fd5b60025460a060020a900460ff161561214257600080fd5b662386f26fc1000034101561215657600080fd5b612193600080858760028060200260405190810160405280929190826002602002808284375050600c54600160a060020a03169250613564915050565b600c54604080517f4257793500000000000000000000000000000000000000000000000000000000815260048101849052602481018690529051929350600160a060020a039091169163425779359160448082019260009290919082900301818387803b1580156115f057600080fd5b60408051808201909152600281527f5045000000000000000000000000000000000000000000000000000000000000602082015281565b60008054600160a060020a0316331461225257600080fd5b81905080600160a060020a031663791fc59d6040518163ffffffff1660e060020a028152600401602060405180830381600087803b15801561229357600080fd5b505af11580156122a7573d6000803e3d6000fd5b505050506040513d60208110156122bd57600080fd5b505115156122ca57600080fd5b600f8054600160a060020a031916600160a060020a039290921691909117905550565b600254600160a060020a0316331461230457600080fd5b600f54604080517fc69ec779000000000000000000000000000000000000000000000000000000008152600160a060020a038581166004830152602482018590529151919092169163c69ec77991604480830192600092919082900301818387803b15801561237257600080fd5b505af1158015612386573d6000803e3d6000fd5b505050505050565b6004816009811061239b57fe5b60089182820401919006600402915054906101000a900463ffffffff1681565b60025460a060020a900460ff16156123d257600080fd5b600160a060020a03821615156123e757600080fd5b600160a060020a0382163014156123fd57600080fd5b600c54600160a060020a038381169116141561241857600080fd5b600d54600160a060020a038381169116141561243357600080fd5b61243d3382613094565b151561244857600080fd5b611bb8338383613102565b600254600160a060020a031681565b60125481565b600254600160a060020a031633148061248b5750600054600160a060020a031633145b806124a05750600154600160a060020a031633145b15156124ab57600080fd5b600082815260106020526040902054156124c457600080fd5b63ffffffff811681146124d657600080fd5b60009182526010602052604090912055565b600a60205260009081526040902054600160a060020a031681565b600254600160a060020a0316331461251a57600080fd5b6125243382613094565b151561252f57600080fd5b600c54612546908290600160a060020a03166130b4565b600c54600160a060020a031663f40e28f282612560613ba7565b6040805160e060020a63ffffffff861602815260048101939093526024830191909152600060448301819052620151806064840152336084840152905160a48084019382900301818387803b1580156125b857600080fd5b505af1158015611ae5573d6000803e3d6000fd5b606481565b6000808083116125e057600080fd5b60078054849081106125ee57fe5b6000918252602090912060408051610140810190915260039092020191506126bc90828161010081018260028282826020028201915b8154815260200190600101908083116126245750505091835250506002919091015467ffffffffffffffff808216602084015268010000000000000000820416604083015263ffffffff608060020a82048116606084015260a060020a82048116608084015260c060020a82041660a083015261ffff60e060020a8204811660c084015260f060020a9091041660e090910152613c73565b9392505050565b6126cb6140ef565b600054600160a060020a031633146126e257600080fd5b60025460a060020a900460ff1615156126fa57600080fd5b6007541561270757600080fd5b506040805180820190915260001980825260208083019190915260016000908152601090915260647f8c6065603763fec3f5742441d3833f3f43b982453612d76adb39a885e3006b5f55611bb89080808481613564565b600c54600160a060020a031681565b662386f26fc1000081565b60025460009060a060020a900460ff161561279257600080fd5b61279c3383613094565b15156127a757600080fd5b6127b0826125d1565b15156127bb57600080fd5b6127c58284613ca2565b15156127d057600080fd5b600d54604080517fc55d0f56000000000000000000000000000000000000000000000000000000008152600481018690529051600160a060020a039092169163c55d0f56916024808201926020929091908290030181600087803b15801561283757600080fd5b505af115801561284b573d6000803e3d6000fd5b505050506040513d602081101561286157600080fd5b5051601254909150810134101561287757600080fd5b600d54601254604080517f454a2ab3000000000000000000000000000000000000000000000000000000008152600481018790529051600160a060020a039093169263454a2ab39234039160248082019260009290919082900301818588803b1580156128e357600080fd5b505af11580156128f7573d6000803e3d6000fd5b50505050506113c58263ffffffff168463ffffffff1633613cf1565b60035481565b600e54600160a060020a031681565b60008060008060006129386140ef565b6002546000908190819060a060020a900460ff161561295657600080fd5b600254600160a060020a03163314806129795750600054600160a060020a031633145b8061298e5750600154600160a060020a031633145b151561299957600080fd5b600780548d9081106129a757fe5b60009182526020909120600390910201600281015490985067ffffffffffffffff1615156129d457600080fd5b604080516101408101909152612a9090898161010081018260028282826020028201915b8154815260200190600101908083116129f85750505091835250506002919091015467ffffffffffffffff808216602084015268010000000000000000820416604083015263ffffffff608060020a82048116606084015260a060020a82048116608084015260c060020a82041660a083015261ffff60e060020a8204811660c084015260f060020a9091041660e090910152613e54565b1515612a9b57600080fd5b60028801546007805460c060020a90920463ffffffff1698509088908110612abf57fe5b600091825260209091206002808b015460039093029091019081015490975061ffff60f060020a928390048116975091900416851015612b0c57600286015460f060020a900461ffff1694505b604080518082018252908c90600290839083908082843750939750600096508d9350869250612b39915050565b600e546040517fdc1279d4000000000000000000000000000000000000000000000000000000008152602092909202929092013591600291600160a060020a039091169063dc1279d4908a90600481019060440182825b815481526020019060010190808311612b90575050915050602060405180830381600087803b158015612bc257600080fd5b505af1158015612bd6573d6000803e3d6000fd5b505050506040513d6020811015612bec57600080fd5b5051600e546040517fdc1279d4000000000000000000000000000000000000000000000000000000008152600160a060020a039091169063dc1279d4908d90600481019060440182825b815481526020019060010190808311612c36575050915050602060405180830381600087803b158015612c6857600080fd5b505af1158015612c7c573d6000803e3d6000fd5b505050506040513d6020811015612c9257600080fd5b505101811515612c9e57fe5b0401915061ffff600186011660208b0135028210612ccd5761ffff600186011660208b01350290910390612cd2565b600091505b61ffff8516158015612ce75750613f48600354145b15612cf157600091505b60408051600119430140815242602082015281519081900390910190208290606490061015612d64575060008b8152601460205260409020546002880154600160a060020a0390911690612d5d908d9060c060020a900463ffffffff166001880161ffff168785613564565b9250612dbf565b60008c815260086020908152604091829020548251600160a060020a0390911681529081018e905280820189905290517f8943505fa15e1a07c5635ef3ab3e573cc070f95356c7aeda969e039a702fa2829181900360600190a15b6002880180547bffffffff0000000000000000000000000000000000000000000000001916905560138054600019019055601254604051339180156108fc02916000818181858888f150505060009d8e5250506014602052505060409099208054600160a060020a03191690555096979650505050505050565b60009081526011602052604090205490565b600254600090819060a060020a900460ff1615612e6757600080fd5b601254341015612e7657600080fd5b612e803385613094565b1515612e8b57600080fd5b612e95838561350f565b1515612ea057600080fd5b6007805485908110612eae57fe5b600091825260209091206040805161014081019091526003909202019250612f7b90838161010081018260028282826020028201918154815260200190600101908083116126245750505091835250506002919091015467ffffffffffffffff808216602084015268010000000000000000820416604083015263ffffffff608060020a82048116606084015260a060020a82048116608084015260c060020a82041660a083015261ffff60e060020a8204811660c084015260f060020a9091041660e090910152613c73565b1515612f8657600080fd5b6007805484908110612f9457fe5b60009182526020909120604080516101408101909152600390920201915061306190828161010081018260028282826020028201918154815260200190600101908083116126245750505091835250506002919091015467ffffffffffffffff808216602084015268010000000000000000820416604083015263ffffffff608060020a82048116606084015260a060020a82048116608084015260c060020a82041660a083015261ffff60e060020a8204811660c084015260f060020a9091041660e090910152613c73565b151561306c57600080fd5b61307882858386613233565b151561308357600080fd5b611339848433613cf1565b60135481565b600090815260086020526040902054600160a060020a0391821691161490565b6000918252600a60205260409091208054600160a060020a031916600160a060020a03909216919091179055565b6000908152600a6020526040902054600160a060020a0391821691161490565b600160a060020a03808316600081815260096020908152604080832080546001019055858352600890915290208054600160a060020a031916909117905583161561319557600160a060020a03831660009081526009602090815260408083208054600019019055838352600b82528083208054600160a060020a0319908116909155600a909252909120805490911690555b60408051600160a060020a0380861682528416602082015280820183905290517fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef9181900360600190a1505050565b600054600160a060020a031633146131fb57600080fd5b60025460a060020a900460ff16151561321357600080fd5b6002805474ff000000000000000000000000000000000000000019169055565b60008184141561324557506000613507565b6002850154608060020a900463ffffffff168214806132745750600285015460a060020a900463ffffffff1682145b1561328157506000613507565b6002830154608060020a900463ffffffff168414806132b05750600283015460a060020a900463ffffffff1684145b156132bd57506000613507565b6002830154608060020a900463ffffffff1615806132ea57506002850154608060020a900463ffffffff16155b156132f757506001613507565b60028581015490840154608060020a9182900463ffffffff90811692909104161480613342575060028086015490840154608060020a900463ffffffff90811660a060020a90920416145b1561334f57506000613507565b6002808601549084015460a060020a900463ffffffff908116608060020a90920416148061339a57506002858101549084015460a060020a9182900463ffffffff9081169290910416145b156133a757506000613507565b600e546040517fe6898a7d000000000000000000000000000000000000000000000000000000008152600160a060020a039091169063e6898a7d908590600481019060440182825b8154815260200190600101908083116133ef575050915050602060405180830381600087803b15801561342157600080fd5b505af1158015613435573d6000803e3d6000fd5b505050506040513d602081101561344b57600080fd5b5051600e546040517fe6898a7d000000000000000000000000000000000000000000000000000000008152600160a060020a039091169063e6898a7d908890600481019060440182825b815481526020019060010190808311613495575050915050602060405180830381600087803b1580156134c757600080fd5b505af11580156134db573d6000803e3d6000fd5b505050506040513d60208110156134f157600080fd5b50510160011461350357506000613507565b5060015b949350505050565b6000818152600860205260408082205484835290822054600160a060020a0391821691168082148061173457506000858152600b6020526040902054600160a060020a03908116908316149250505092915050565b60008060008061357261410a565b600063ffffffff8b168b1461358657600080fd5b63ffffffff8a168a1461359857600080fd5b61ffff891689146135a857600080fd5b600754600095508510156138e357600e54604080517fdc1279d4000000000000000000000000000000000000000000000000000000008152600160a060020a039092169163dc1279d4918b91600401908190839080838360005b8381101561361a578181015183820152602001613602565b50505050905001915050602060405180830381600087803b15801561363e57600080fd5b505af1158015613652573d6000803e3d6000fd5b505050506040513d602081101561366857600080fd5b5051935061ffff8416151561367c57600193505b8361ffff166103e881151561368d57fe5b0494506005600a61ffff87160661ffff1610156136b357600a61ffff86160494506136c1565b600a61ffff86160460010194505b60018503945060088561ffff1611156136d957600894505b600e54604080517f7c59f828000000000000000000000000000000000000000000000000000000008152600160a060020a0390921691637c59f828918b91600401908190839080838360005b8381101561373d578181015183820152602001613725565b50505050905001915050602060405180830381600087803b15801561376157600080fd5b505af1158015613775573d6000803e3d6000fd5b505050506040513d602081101561378b57600080fd5b505192506000831180156137b8575060008381526011602090815260408083205460109092529091205411155b1561388557600e54604080517f3010b5cd000000000000000000000000000000000000000000000000000000008152600160a060020a0390921691633010b5cd918b91600401908190839080838360005b83811015613821578181015183820152602001613809565b505050509050019150506040805180830381600087803b15801561384457600080fd5b505af1158015613858573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250604081101561387d57600080fd5b509750600092505b826001141561389357600594505b60008311156138b2576000838152601160205260409020805460010190555b600189111580156138c4575082600114155b156138e357600354613f48116138d957600080fd5b6003805460010190555b604080516101008101825289815267ffffffffffffffff42166020820152600091810182905263ffffffff808e1660608301528c16608082015260a0810182905261ffff80881660c08301528b1660e0820152600780546001818101808455929094528251929550909185916003027fa66cc928b5edb82af9bd49922954155ab7b0942694bea4ce44661d9a8736c68801906139829082906002614156565b506020820151600291909101805460408401516060850151608086015160a087015160c088015160e09098015167ffffffffffffffff1990951667ffffffffffffffff978816176fffffffffffffffff000000000000000019166801000000000000000097909416969096029290921773ffffffff000000000000000000000000000000001916608060020a63ffffffff928316021777ffffffff0000000000000000000000000000000000000000191660a060020a92821692909202919091177bffffffff000000000000000000000000000000000000000000000000191660c060020a94821694909402939093177fffff0000ffffffffffffffffffffffffffffffffffffffffffffffffffffffff1660e060020a61ffff95861602177dffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1660f060020a949091169390930292909217909155919003915081168114613ae757600080fd5b7f1f5e6c92c06029950ba2a0b8fdd9cdcb864a6d651f543bad22feaed8459483488782846060015163ffffffff16856080015163ffffffff1686600001516040518086600160a060020a0316600160a060020a0316815260200185815260200184815260200183815260200182600260200280838360005b83811015613b77578181015183820152602001613b5f565b505050509050019550505050505060405180910390a1613b9960008883613102565b9a9950505050505050505050565b6000806000600c60009054906101000a9004600160a060020a0316600160a060020a031663eac9d94c6040518163ffffffff1660e060020a028152600401602060405180830381600087803b158015613bff57600080fd5b505af1158015613c13573d6000803e3d6000fd5b505050506040513d6020811015613c2957600080fd5b505191506fffffffffffffffffffffffffffffffff82168214613c4b57600080fd5b5060028104810167016345785d8a0000811015613c6d575067016345785d8a00005b92915050565b60008160a0015163ffffffff166000148015610ea75750506040015167ffffffffffffffff4381169116111590565b6000806000600785815481101515613cb657fe5b90600052602060002090600302019150600784815481101515613cd557fe5b9060005260206000209060030201905061173482868387613233565b600080613cfe8585613e84565b600780549297509095509085908110613d1357fe5b90600052602060002090600302019150600785815481101515613d3257fe5b600091825260209091206003909102016002810180547bffffffff000000000000000000000000000000000000000000000000191660c060020a63ffffffff8816021790559050613d8282613f58565b613d8b81613f58565b6000858152600b602090815260408083208054600160a060020a0319908116909155878452818420805482169055601380546001019055888452601483528184208054600160a060020a03898116919093161790556008835292819020546002850154825191909416815291820188905281810187905267ffffffffffffffff6801000000000000000090930492909216606082015290517f241ea03ca20251805084d27d4440371c34a0b85ff108f6bb5611248f73818b809181900360800190a15050505050565b60008160a0015163ffffffff16600014158015610ea75750506040015167ffffffffffffffff4381169116111590565b600e54600780546000928392600160a060020a039091169163e6898a7d919087908110613ead57fe5b6000918252602090912060405163ffffffff841660e060020a02815260039092020190600481019060440182825b815481526020019060010190808311613edb575050915050602060405180830381600087803b158015613f0d57600080fd5b505af1158015613f21573d6000803e3d6000fd5b505050506040513d6020811015613f3757600080fd5b505160011415613f4b575081905082613f51565b50829050815b9250929050565b600654600282015443919060049060e060020a900461ffff1660098110613f7b57fe5b600891828204019190066004029054906101000a900463ffffffff1663ffffffff16811515613fa657fe5b6002840180546fffffffffffffffff0000000000000000191668010000000000000000939092049390930167ffffffffffffffff16919091021790819055600860e060020a90910461ffff161080156140a55750600e546040517f7c59f828000000000000000000000000000000000000000000000000000000008152600160a060020a0390911690637c59f828908390600481019060440182825b815481526020019060010190808311614042575050915050602060405180830381600087803b15801561407457600080fd5b505af1158015614088573d6000803e3d6000fd5b505050506040513d602081101561409e57600080fd5b5051600114155b156140ec5760028101805461ffff60e060020a8083048216600101909116027fffff0000ffffffffffffffffffffffffffffffffffffffffffffffffffffffff9091161790555b50565b60408051808201825290600290829080388339509192915050565b6101206040519081016040528061411f6140ef565b815260006020820181905260408201819052606082018190526080820181905260a0820181905260c0820181905260e09091015290565b8260028101928215614184579160200282015b82811115614184578251825591602001919060010190614169565b50614190929150614194565b5090565b6111f691905b80821115614190576000815560010161419a5600a165627a7a72305820a30a7053507c9b39a0463df909dc600a42eefcadd3eb02f841c44b53676246140029


   Swarm Source:
bzzr://a30a7053507c9b39a0463df909dc600a42eefcadd3eb02f841c44b5367624614
Block Age transaction Difficulty GasUsed Reward
Block Age Uncle Number Difficulty GasUsed Reward
Make sure to use the "Vote Down" button for any spammy posts, and the "Vote Up" for interesting conversations.