ETH Price: $3,665.61 (+1.80%)

Contract

0x31Cf2697d3117eFaB5f5493796C94aEF362c56Ad
 

Overview

ETH Balance

0.002 ETH

Eth Value

$7.33 (@ $3,665.61/ETH)

Token Holdings

Multichain Info

No addresses found
Age:24H
Reset Filter

Transaction Hash
Method
Block
From
To

There are no matching entries

Update your filters to view other transactions

Latest 9 internal transactions

Advanced mode:
Parent Transaction Hash Block From To
71133002019-01-23 10:04:182138 days ago1548237858
0x31Cf2697...F362c56Ad
0.002 ETH
71119182019-01-23 3:22:402138 days ago1548213760
0x31Cf2697...F362c56Ad
0.002 ETH
71038162019-01-21 12:58:552140 days ago1548075535
0x31Cf2697...F362c56Ad
0.002 ETH
70873962019-01-18 13:42:282143 days ago1547818948
0x31Cf2697...F362c56Ad
0.002 ETH
70861462019-01-18 8:17:092143 days ago1547799429
0x31Cf2697...F362c56Ad
0.002 ETH
70857492019-01-18 6:37:152143 days ago1547793435
0x31Cf2697...F362c56Ad
0.002 ETH
70853552019-01-18 4:56:482143 days ago1547787408
0x31Cf2697...F362c56Ad
0.002 ETH
70852152019-01-18 4:14:092143 days ago1547784849
0x31Cf2697...F362c56Ad
0.002 ETH
70521312019-01-12 6:16:122149 days ago1547273772
0x31Cf2697...F362c56Ad
0.002 ETH
Loading...
Loading

Contract Source Code Verified (Exact Match)

Contract Name:
PonyCore

Compiler Version
v0.4.24+commit.e67f0147

Optimization Enabled:
Yes with 200 runs

Other Settings:
default evmVersion

Contract Source Code (Solidity)

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

pragma solidity ^0.4.23;


/**
 * @title SafeMath
 * @dev Math operations with safety checks that throw on error
 */
library SafeMath {
    int256 constant private INT256_MIN = -2**255;

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

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

        return c;
    }

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

        require(!(a == -1 && b == INT256_MIN)); // This is the only case of overflow not detected by the check below

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

        return c;
    }

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

        return c;
    }

    /**
    * @dev Integer division of two signed integers truncating the quotient, reverts on division by zero.
    */
    function div(int256 a, int256 b) internal pure returns (int256) {
        require(b != 0); // Solidity only automatically asserts when dividing by 0
        require(!(b == -1 && a == INT256_MIN)); // This is the only case of overflow

        int256 c = a / b;

        return c;
    }

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

        return c;
    }

    /**
    * @dev Subtracts two signed integers, reverts on overflow.
    */
    function sub(int256 a, int256 b) internal pure returns (int256) {
        int256 c = a - b;
        require((b >= 0 && c <= a) || (b < 0 && c > a));

        return c;
    }

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

        return c;
    }

    /**
    * @dev Adds two signed integers, reverts on overflow.
    */
    function add(int256 a, int256 b) internal pure returns (int256) {
        int256 c = a + b;
        require((b >= 0 && c >= a) || (b < 0 && c < a));

        return c;
    }

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

/// @title Interface for contracts conforming to ERC-721: Non-Fungible Tokens
interface ERC721 {
    // Required methods
    function totalSupply() external view returns (uint256 total);

    function balanceOf(address _owner) external 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);
}

/// @title SEKRETOOOO
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 pony 1 & 2, return a genetic combination - may have a random factor
    /// @param genes1 genes of mom
    /// @param genes2 genes of dad
    /// @return the genes that are supposed to be passed down the child
    function mixGenes(uint256 genes1, uint256 genes2, uint256 targetBlock) public returns (uint256);

    // calculate the cooldown of child pony
    function processCooldown(uint16 childGen, uint256 targetBlock) public returns (uint16);

    // calculate the result for upgrading pony
    function upgradePonyResult(uint8 unicornation, uint256 targetBlock) public returns (bool);
    
    function setMatingSeason(bool _isMatingSeason) public returns (bool);
}



/// @title Interface for contracts conforming to ERC-20
interface ERC20 {
    //core ERC20 functions
    function transfer(address _to, uint _value) external returns (bool success);

    function balanceOf(address who) external view returns (uint256);

    function allowance(address owner, address spender) external view returns (uint256);

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

    function transferPreSigned(bytes _signature, address _to, uint256 _value, uint256 _fee, uint256 _nonce) external returns (bool);

    function recoverSigner(bytes _signature, address _to, uint256 _value, uint256 _fee, uint256 _nonce) external view returns (address);
}

/**
 * @title Signature verifier
 * @dev To verify C level actions
 */
contract SignatureVerifier {

    function splitSignature(bytes sig)
    internal
    pure
    returns (uint8, bytes32, bytes32)
    {
        require(sig.length == 65);

        bytes32 r;
        bytes32 s;
        uint8 v;

        assembly {
        // first 32 bytes, after the length prefix
            r := mload(add(sig, 32))
        // second 32 bytes
            s := mload(add(sig, 64))
        // final byte (first byte of the next 32 bytes)
            v := byte(0, mload(add(sig, 96)))
        }
        return (v, r, s);
    }

    function recover(bytes32 hash, bytes sig) public pure returns (address) {
        bytes32 r;
        bytes32 s;
        uint8 v;
        //Check the signature length
        if (sig.length != 65) {
            return (address(0));
        }
        // Divide the signature in r, s and v variables
        (v, r, s) = splitSignature(sig);
        // Version of signature should be 27 or 28, but 0 and 1 are also possible versions
        if (v < 27) {
            v += 27;
        }
        // If the version is correct return the signer address
        if (v != 27 && v != 28) {
            return (address(0));
        } else {
            bytes memory prefix = "\x19Ethereum Signed Message:\n32";
            bytes32 prefixedHash = keccak256(abi.encodePacked(prefix, hash));
            return ecrecover(prefixedHash, v, r, s);
        }
    }
}

/**
 * @title A DEKLA token access control
 * @author DEKLA (https://www.dekla.io)
 * @dev The Dekla token has 3 C level address to manage.
 * They can execute special actions but it need to be approved by another C level address.
 */
contract AccessControl is SignatureVerifier {
    using SafeMath for uint256;

    // C level address that can execute special actions.
    address public ceoAddress;
    address public cfoAddress;
    address public cooAddress;
    address public systemAddress;
    uint256 public CLevelTxCount_ = 0;
    mapping(address => uint256) nonces;

    // @dev C level transaction must be approved with another C level address
    modifier onlyCLevel() {
        require(
            msg.sender == cooAddress ||
            msg.sender == ceoAddress ||
            msg.sender == cfoAddress
        );
        _;
    }


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

    // @dev return true if transaction already signed by a C Level address
    // @param _message The string to be verify
    function signedByCLevel(
        bytes32 _message,
        bytes _sig
    )
    internal
    view
    onlyCLevel
    returns (bool)
    {
        address signer = recover(_message, _sig);
        require(signer != msg.sender);
        return (
        signer == cooAddress ||
        signer == ceoAddress ||
        signer == cfoAddress
        );
    }

    // @dev return true if transaction already signed by a C Level address
    // @param _message The string to be verify
    // @param _sig the signature from signing the _message with system key
    function signedBySystem(
        bytes32 _message,
        bytes _sig
    )
    internal
    view
    returns (bool)
    {
        address signer = recover(_message, _sig);
        require(signer != msg.sender);
        return (
        signer == systemAddress
        );
    }

    /**
     * @notice Hash (keccak256) of the payload used by setCEO
     * @param _newCEO address The address of the new CEO
     * @param _nonce uint256 setCEO transaction number.
     */
    function getCEOHashing(address _newCEO, uint256 _nonce) public pure returns (bytes32) {
        return keccak256(abi.encodePacked(bytes4(0x486A0E94), _newCEO, _nonce));
    }

    // @dev Assigns a new address to act as the CEO. The C level transaction, must verify.
    // @param _newCEO The address of the new CEO
    // @param _sig the signature from signing the _message with CEO key
    function setCEO(
        address _newCEO,
        bytes _sig
    ) external onlyCLevel {
        require(
            _newCEO != address(0) &&
            _newCEO != cfoAddress &&
            _newCEO != cooAddress
        );

        bytes32 hashedTx = getCEOHashing(_newCEO, nonces[msg.sender]);
        require(signedByCLevel(hashedTx, _sig));
        nonces[msg.sender]++;

        ceoAddress = _newCEO;
        CLevelTxCount_++;
    }

    /**
     * @notice Hash (keccak256) of the payload used by setCFO
     * @param _newCFO address The address of the new CFO
     * @param _nonce uint256 setCFO transaction number.
     */
    function getCFOHashing(address _newCFO, uint256 _nonce) public pure returns (bytes32) {
        return keccak256(abi.encodePacked(bytes4(0x486A0E95), _newCFO, _nonce));
    }

    // @dev Assigns a new address to act as the CFO. The C level transaction, must verify.
    // @param _newCFO The address of the new CFO
    function setCFO(
        address _newCFO,
        bytes _sig
    ) external onlyCLevel {
        require(
            _newCFO != address(0) &&
            _newCFO != ceoAddress &&
            _newCFO != cooAddress
        );

        bytes32 hashedTx = getCFOHashing(_newCFO, nonces[msg.sender]);
        require(signedByCLevel(hashedTx, _sig));
        nonces[msg.sender]++;

        cfoAddress = _newCFO;
        CLevelTxCount_++;
    }

    /**
     * @notice Hash (keccak256) of the payload used by setCOO
     * @param _newCOO address The address of the new COO
     * @param _nonce uint256 setCO transaction number.
     */
    function getCOOHashing(address _newCOO, uint256 _nonce) public pure returns (bytes32) {
        return keccak256(abi.encodePacked(bytes4(0x486A0E96), _newCOO, _nonce));
    }

    // @dev Assigns a new address to act as the COO. The C level transaction, must verify.
    // @param _newCOO The address of the new COO, _sig signature used to verify COO address
    // @param _sig the signature from signing the _newCOO with 1 of the C-level key
    function setCOO(
        address _newCOO,
        bytes _sig
    ) external onlyCLevel {
        require(
            _newCOO != address(0) &&
            _newCOO != ceoAddress &&
            _newCOO != cfoAddress
        );

        bytes32 hashedTx = getCOOHashing(_newCOO, nonces[msg.sender]);
        require(signedByCLevel(hashedTx, _sig));
        nonces[msg.sender]++;

        cooAddress = _newCOO;
        CLevelTxCount_++;
    }

    function getNonces(address _sender) public view returns (uint256) {
        return nonces[_sender];
    }
}


/// @title A facet of PonyCore that manages special access privileges.
contract PonyAccessControl is AccessControl {
    /// @dev Emited when contract is upgraded - See README.md for updgrade plan
    event ContractUpgrade(address newContract);


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


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


/// @dev See the PonyCore contract documentation to understand how the various contract facets are arranged.
contract PonyBase is PonyAccessControl {
    /*** EVENTS ***/

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

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

    /*** DATA TYPES ***/

    /// @dev The main Pony struct. Every pony in MyEtherPonies 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
    ///  is important because of the byte-packing rules used by Ethereum.
    ///  Ref: http://solidity.readthedocs.io/en/develop/miscellaneous.html
    struct Pony {
        // The Pony's genetic code is packed into these 256-bits, the format is
        // sooper-sekret! A pony's genes never change.
        uint256 genes;

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

        // The minimum timestamp after which this pony 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 Pony, set to 0 for gen0 ponies.
        // Note that using 32-bit unsigned integers limits us to a "mere"
        // 4 billion ponies. 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 pony for matrons that are pregnant,
        // zero otherwise. A non-zero value here is how we know a pony
        // is pregnant. Used to retrieve the genetic material for the new
        // pony when the birth transpires.
        uint32 matingWithId;

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

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

        uint16 txCount;

        uint8 unicornation;


    }

    /*** 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 pony
    ///  is bred, encouraging owners not to just keep breeding the same pony over
    ///  and over again. Caps out at one week (a pony can breed an unbounded number
    ///  of times, and the maximum cooldown is always seven days).
    uint32[10] public cooldowns = [
    uint32(1 minutes),
    uint32(5 minutes),
    uint32(30 minutes),
    uint32(1 hours),
    uint32(4 hours),
    uint32(8 hours),
    uint32(1 days),
    uint32(2 days),
    uint32(4 days),
    uint32(7 days)
    ];

    uint8[5] public incubators = [
    uint8(5),
    uint8(10),
    uint8(15),
    uint8(20),
    uint8(25)
    ];

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

    /*** STORAGE ***/

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

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

    // @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 PonyIDs to an address that has been approved to call
    ///  transferFrom(). Each Pony can only have one approved address for transfer
    ///  at any time. A zero value means no approval is outstanding.
    mapping(uint256 => address) public ponyIndexToApproved;

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

    mapping(address => bool) public hasIncubator;

    /// @dev The address of the ClockAuction contract that handles sales of Ponies. 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;


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

    /// @dev An internal method that creates a new Pony 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 Pony ID of the matron of this pony (zero for gen0)
    /// @param _sireId The Pony ID of the sire of this pony (zero for gen0)
    /// @param _generation The generation number of this pony, must be computed by caller.
    /// @param _genes The Pony's genetic code.
    /// @param _owner The inital owner of this pony, must be non-zero (except for the unPony, ID 0)
    function _createPony(
        uint256 _matronId,
        uint256 _sireId,
        uint256 _generation,
        uint256 _genes,
        address _owner,
        uint16 _cooldownIndex
    )
    internal
    returns (uint)
    {
        // These requires are not strictly necessary, our calling code should make
        // sure that these conditions are never broken. However! _createPony() 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)));


        Pony memory _pony = Pony({
            genes : _genes,
            birthTime : uint64(now),
            cooldownEndBlock : 0,
            matronId : uint32(_matronId),
            sireId : uint32(_sireId),
            matingWithId : 0,
            cooldownIndex : _cooldownIndex,
            generation : uint16(_generation),
            unicornation : 0,
            txCount : 0
            });
        uint256 newPonyId = ponies.push(_pony) - 1;

        require(newPonyId == uint256(uint32(newPonyId)));

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

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

        return newPonyId;
    }

    // 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 facet of the EtherPonies core contract that manages ownership, ERC-721 (draft) compliant.
/// @author Dekla (https://www.dekla.io)
/// @dev Ref: https://github.com/ethereum/EIPs/issues/721
///  See the PonyCore contract documentation to understand how the various contract facets are arranged.
contract PonyOwnership is PonyBase, ERC721 {

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

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

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

    /// @notice Returns the number of Ponies 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 Pony to another address. If transferring to a smart
    ///  contract be VERY CAREFUL to ensure that it is aware of ERC-721 (or
    ///  EtherPonies specifically) or your Pony may be lost forever. Seriously.
    /// @param _to The address of the recipient, can be a user or contract.
    /// @param _tokenId The ID of the Pony 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 ponies (except very briefly
        // after a gen0 pony is created and before it goes on auction).
        require(_to != address(this));


        // You can only send your own pony.
        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 Pony 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 Pony 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.
        emit Approval(msg.sender, _to, _tokenId);
    }

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

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

    }

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

            // We count on the fact that all ponies have IDs starting at 1 and increasing
            // sequentially up to the totalPony count.
            uint256 ponyId;

            for (ponyId = 1; ponyId <= totalPonies; ponyId++) {
                if (ponyIndexToOwner[ponyId] == _owner) {
                    result[resultIndex] = ponyId;
                    resultIndex++;
                }
            }

            return result;
        }
    }

    function transferPreSignedHashing(
        address _token,
        address _to,
        uint256 _id,
        uint256 _nonce
    )
    public
    pure
    returns (bytes32)
    {
        return keccak256(abi.encodePacked(bytes4(0x486A0E97), _token, _to, _id, _nonce));
    }

    function transferPreSigned(
        bytes _signature,
        address _to,
        uint256 _id,
        uint256 _nonce
    )
    public
    {
        require(_to != address(0));
        // require(signatures[_signature] == false);
        bytes32 hashedTx = transferPreSignedHashing(address(this), _to, _id, _nonce);
        address from = recover(hashedTx, _signature);
        require(from != address(0));
        require(_to != address(this));

        // You can only send your own pony.
        require(_owns(from, _id));
        nonces[from]++;
        // Reassign ownership, clear pending approvals, emit Transfer event.
        _transfer(from, _to, _id);
    }

    function approvePreSignedHashing(
        address _token,
        address _spender,
        uint256 _tokenId,
        uint256 _nonce
    )
    public
    pure
    returns (bytes32)
    {
        return keccak256(abi.encodePacked(_token, _spender, _tokenId, _nonce));
    }

    function approvePreSigned(
        bytes _signature,
        address _spender,
        uint256 _tokenId,
        uint256 _nonce
    )
    public
    returns (bool)
    {
        require(_spender != address(0));
        // require(signatures[_signature] == false);
        bytes32 hashedTx = approvePreSignedHashing(address(this), _spender, _tokenId, _nonce);
        address from = recover(hashedTx, _signature);
        require(from != address(0));

        // Only an owner can grant transfer approval.
        require(_owns(from, _tokenId));

        nonces[from]++;
        // Register the approval (replacing any previous approval).
        _approve(_tokenId, _spender);

        // Emit approval event.
        emit Approval(from, _spender, _tokenId);
        return true;
    }
}



/// @title A facet of PonyCore that manages Pony siring, gestation, and birth.
/// @author Dekla (https://www.dekla.io)
/// @dev See the PonyCore contract documentation to understand how the various contract facets are arranged.
contract PonyBreeding is PonyOwnership {

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

    /// @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 Ponies.
    uint256 public pregnantPonies;

    /// @dev The address of the sibling contract that is used to implement the sooper-sekret
    ///  genetic combination algorithm.
    GeneScienceInterface public geneScience;

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

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

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

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

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

    function _triggerPregnant(Pony storage _pony, uint8 _incubator) internal {
        // Compute an estimation of the cooldown time in blocks (based on current cooldownIndex).

        if (_incubator > 0) {
            uint64 initialCooldown = uint64(cooldowns[_pony.cooldownIndex] / secondsPerBlock);
            _pony.cooldownEndBlock = uint64((initialCooldown - (initialCooldown * incubators[_incubator] / 100)) + block.number);

        } else {
            _pony.cooldownEndBlock = uint64((cooldowns[_pony.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 (_pony.cooldownIndex < 13) {
            _pony.cooldownIndex += 1;
        }
    }

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

    /// @notice Checks that a given pony is able to breed (i.e. it is not pregnant or
    ///  in the middle of a siring cooldown).
    /// @param _ponyId reference the id of the pony, any user can inquire about it
    function isReadyToMate(uint256 _ponyId)
    public
    view
    returns (bool)
    {
        require(_ponyId > 0);
        Pony storage pon = ponies[_ponyId];
        return _isReadyToMate(pon);
    }

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

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

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

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

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

    /// @notice Checks to see if two ponies can breed together, including checks for
    ///  ownership and siring approvals. Does NOT check that both ponies 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 canMateWith(uint256 _matronId, uint256 _sireId)
    external
    view
    returns (bool)
    {
        require(_matronId > 0);
        require(_sireId > 0);
        Pony storage matron = ponies[_matronId];
        Pony storage sire = ponies[_sireId];
        return _isValidMatingPair(matron, _matronId, sire, _sireId) &&
        _isMatingPermitted(_sireId, _matronId);
    }

    /// @dev Internal utility function to initiate breeding, assumes that all breeding
    ///  requirements have been checked.
    function _mateWith(uint256 _matronId, uint256 _sireId, uint8 _incubator) internal {
        // Grab a reference to the Ponies from storage.
        Pony storage sire = ponies[_sireId];
        Pony storage matron = ponies[_matronId];

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

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

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

        // Every time a Pony gets pregnant, counter is incremented.
        pregnantPonies++;

        // Emit the pregnancy event.

        emit Pregnant(ponyIndexToOwner[_matronId], _matronId, _sireId, matron.cooldownEndBlock);
    }

    function getIncubatorHashing(
        address _sender,
        uint8 _incubator,
        uint256 txCount
    )
    public
    pure
    returns (bytes32)
    {
        return keccak256(abi.encodePacked(bytes4(0x486A0E98), _sender, _incubator, txCount));
    }

    /// @notice Breed a Pony you own (as matron) with a sire that you own, or for which you
    ///  have previously been given Siring approval. Will either make your pony 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 Pony acting as matron (will end up pregnant if successful)
    /// @param _sireId The ID of the Pony acting as sire (will begin its siring cooldown if successful)
    function mateWithAuto(uint256 _matronId, uint256 _sireId, uint8 _incubator, bytes _sig)
    external
    payable
    whenNotPaused
    {
        // Checks for payment.
        require(msg.value >= autoBirthFee);

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

        require(_isMatingPermitted(_sireId, _matronId));

        // Grab a reference to the potential matron
        Pony storage matron = ponies[_matronId];

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

        // Grab a reference to the potential sire
        Pony storage sire = ponies[_sireId];

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

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

        if (_incubator == 0 && hasIncubator[msg.sender]) {
            _mateWith(_matronId, _sireId, _incubator);
        } else {
            bytes32 hashedTx = getIncubatorHashing(msg.sender, _incubator, nonces[msg.sender]);
            require(signedBySystem(hashedTx, _sig));
            nonces[msg.sender]++;

            // All checks passed, Pony gets pregnant!
            if (!hasIncubator[msg.sender]) {
                hasIncubator[msg.sender] = true;
            }
            _mateWith(_matronId, _sireId, _incubator);
        }
    }

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

        // Check that the matron is a valid pony.
        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.matingWithId;
        Pony storage sire = ponies[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 childGenes = geneScience.mixGenes(matron.genes, sire.genes, matron.cooldownEndBlock - 1);
        // New Pony starts with the same cooldown as parent gen/20
        uint16 cooldownIndex = geneScience.processCooldown(parentGen + 1, block.number);
        if (cooldownIndex > 13) {
            cooldownIndex = 13;
        }
        // Make the new pony!
        address owner = ponyIndexToOwner[_matronId];
        uint256 ponyId = _createPony(_matronId, matron.matingWithId, parentGen + 1, childGenes, owner, cooldownIndex);

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

        // Every time a Pony gives birth counter is decremented.
        pregnantPonies--;

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

        // return the new pony's ID
        return ponyId;
    }
    
    function  setMatingSeason(bool _isMatingSeason) external onlyCLevel {
        geneScience.setMatingSeason(_isMatingSeason);
    }
}


/// @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;
        uint256 price;
        bool allowPayDekla;
    }

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

    ERC20 public tokens;

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

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

    event AuctionCreated(uint256 tokenId);
    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 {

        tokenIdToAuction[_tokenId] = _auction;

        emit AuctionCreated(
            uint256(_tokenId)
        );
    }


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

        require(!auction.allowPayDekla);
        // 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 = auction.price;
        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;

            seller.transfer(sellerProceeds);
        }

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

        return price;
    }

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

        require(auction.allowPayDekla);
        // 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 = auction.price;
        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;

            tokens.transfer(seller, sellerProceeds);
        }
        // Tell the world!
        emit AuctionSuccessful(_tokenId, price, msg.sender);

        return price;
    }


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

    /// @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 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 AccessControl{
    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() onlyCEO whenNotPaused public returns (bool) {
        paused = true;
        emit Pause();
        return true;
    }

    /**
     * @dev called by the owner to unpause, returns to normal state
     */
    function unpause() onlyCEO whenPaused public returns (bool) {
        paused = false;
        emit 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.
    constructor(address _nftAddress, address _tokenAddress) public {
        ERC721 candidateContract = ERC721(_nftAddress);
        require(candidateContract.supportsInterface(InterfaceSignature_ERC721));
        tokens = ERC20(_tokenAddress);
        nonFungibleContract = candidateContract;
    }


    /// @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];
        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
    onlyCEO
    external
    {
        Auction storage auction = tokenIdToAuction[_tokenId];
        _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 price,
        bool allowPayDekla

    ) {
        Auction storage auction = tokenIdToAuction[_tokenId];
        return (
        auction.seller,
        auction.price,
        auction.allowPayDekla
        );
    }

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

}


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

    uint256 public prizeCut = 100;

    uint256 public tokenDiscount = 100;

    address prizeAddress;

    // Delegate constructor
    constructor(address _nftAddr, address _tokenAddress, address _prizeAddress) public
    ClockAuction(_nftAddr, _tokenAddress) {
        prizeAddress = _prizeAddress;
    }

    /// @dev Creates and begins a new auction. Since this function is wrapped,
    /// require sender to be PonyCore contract.
    /// @param _tokenId - ID of token to auction, sender must be owner.
    /// @param _seller - Seller, if not the message sender
    function createEthAuction(
        uint256 _tokenId,
        address _seller,
        uint256 _price
    )
    external
    {

        require(msg.sender == address(nonFungibleContract));
        require(_price > 0);
        _escrow(_seller, _tokenId);
        Auction memory auction = Auction(
            _seller,
            _price,
            false
        );
        _addAuction(_tokenId, auction);
    }

    /// @dev Creates and begins a new auction. Since this function is wrapped,
    /// require sender to be PonyCore contract.
    /// @param _tokenId - ID of token to auction, sender must be owner.
    /// @param _seller - Seller, if not the message sender
    function createDklAuction(
        uint256 _tokenId,
        address _seller,
        uint256 _price
    )
    external
    {

        require(msg.sender == address(nonFungibleContract));
        require(_price > 0);
        _escrow(_seller, _tokenId);
        Auction memory auction = Auction(
            _seller,
            _price,
            true
        );
        _addAuction(_tokenId, auction);
    }

    /// @dev Places a bid for siring. Requires the sender
    /// is the PonyCore contract because all bid methods
    /// should be wrapped. Also returns the pony to the
    /// seller rather than the winner.
    function bidEth(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
        _bidEth(_tokenId, msg.value);
        // We transfer the pony back to the seller, the winner will get
        // the offspring

        uint256 prizeAmount = (msg.value * prizeCut) / 10000;
        prizeAddress.transfer(prizeAmount);

        _transfer(seller, _tokenId);
    }


    function bidDkl(uint256 _tokenId,
        uint256 _price,
        uint256 _fee,
        bytes _signature,
        uint256 _nonce)
    external
    whenNotPaused
    {
        address seller = tokenIdToAuction[_tokenId].seller;
        tokens.transferPreSigned(_signature, address(this), _price, _fee, _nonce);
        // _bid will throw if the bid or funds transfer fails
        _bidDkl(_tokenId, _price);
        tokens.transfer(msg.sender, _fee);
        address spender = tokens.recoverSigner(_signature, address(this), _price, _fee, _nonce);
        uint256 discountAmount = (_price * tokenDiscount) / 10000;
        uint256 prizeAmount = (_price * prizeCut) / 10000;
        tokens.transfer(prizeAddress, prizeAmount);
        tokens.transfer(spender, discountAmount);
        _transfer(seller, _tokenId);
    }

    function setCut(uint256 _prizeCut, uint256 _tokenDiscount)
    external
    {
        require(msg.sender == address(nonFungibleContract));
        require(_prizeCut + _tokenDiscount < ownerCut);

        prizeCut = _prizeCut;
        tokenDiscount = _tokenDiscount;
    }

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

        nftAddress.transfer(address(this).balance);
    }

    function withdrawDklBalance() external {
        address nftAddress = address(nonFungibleContract);

        require(
            msg.sender == nftAddress
        );

        tokens.transfer(nftAddress, tokens.balanceOf(this));
    }
}





/// @title Clock auction modified for sale of Ponies
/// @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;

    uint256 public prizeCut = 100;

    uint256 public tokenDiscount = 100;

    address prizeAddress;

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

    // Delegate constructor
    constructor(address _nftAddr, address _token, address _prizeAddress) public
    ClockAuction(_nftAddr, _token) {
        prizeAddress = _prizeAddress;
    }

    /// @dev Creates and begins a new auction.
    /// @param _tokenId - ID of token to auction, sender must be owner.
    /// @param _seller - Seller, if not the message sender
    function createEthAuction(
        uint256 _tokenId,
        address _seller,
        uint256 _price
    )
    external
    {

        require(msg.sender == address(nonFungibleContract));
        _escrow(_seller, _tokenId);
        Auction memory auction = Auction(
            _seller,
            _price,
            false
        );
        _addAuction(_tokenId, auction);
    }

    /// @dev Creates and begins a new auction.
    /// @param _tokenId - ID of token to auction, sender must be owner.
    /// @param _seller - Seller, if not the message sender
    function createDklAuction(
        uint256 _tokenId,
        address _seller,
        uint256 _price
    )
    external
    {

        require(msg.sender == address(nonFungibleContract));
        _escrow(_seller, _tokenId);
        Auction memory auction = Auction(
            _seller,
            _price,
            true
        );
        _addAuction(_tokenId, auction);
    }


    function bidEth(uint256 _tokenId)
    external
    payable
    whenNotPaused
    {
        // _bid will throw if the bid or funds transfer fails
        _bidEth(_tokenId, msg.value);
        uint256 prizeAmount = (msg.value * prizeCut) / 10000;
        prizeAddress.transfer(prizeAmount);
        _transfer(msg.sender, _tokenId);
    }


    function bidDkl(uint256 _tokenId,
        uint256 _price,
        uint256 _fee,
        bytes _signature,
        uint256 _nonce)
    external
    whenNotPaused
    {
        address buyer = tokens.recoverSigner(_signature, address(this), _price, _fee, _nonce);
        tokens.transferPreSigned(_signature, address(this), _price, _fee, _nonce);
        // _bid will throw if the bid or funds transfer fails
        _bidDkl(_tokenId, _price);
        uint256 prizeAmount = (_price * prizeCut) / 10000;
        uint256 discountAmount = (_price * tokenDiscount) / 10000;
        tokens.transfer(buyer, discountAmount);
        tokens.transfer(prizeAddress, prizeAmount);
        _transfer(buyer, _tokenId);
    }

    function setCut(uint256 _prizeCut, uint256 _tokenDiscount)
    external
    {
        require(msg.sender == address(nonFungibleContract));
        require(_prizeCut + _tokenDiscount < ownerCut);

        prizeCut = _prizeCut;
        tokenDiscount = _tokenDiscount;
    }

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

        nftAddress.transfer(address(this).balance);
    }

    function withdrawDklBalance() external {
        address nftAddress = address(nonFungibleContract);

        require(
            msg.sender == nftAddress
        );

        tokens.transfer(nftAddress, tokens.balanceOf(this));
    }
}


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

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

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

    /// @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 Sets the reference to the bidding auction.
    /// @param _address - Address of bidding contract.
    function setBiddingAuctionAddress(address _address) external onlyCEO {
        BiddingClockAuction candidateContract = BiddingClockAuction(_address);

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

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


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


    /// @dev Put a Pony up for auction.
    ///  Does some ownership trickery to create auctions in one tx.
    function delegateDklSaleAuction(
        uint256 _tokenId,
        uint256 _price,
        bytes _ponySig,
        uint256 _nonce
    )
    external
    whenNotPaused
    {
        bytes32 hashedTx = approvePreSignedHashing(address(this), saleAuction, _tokenId, _nonce);
        address from = recover(hashedTx, _ponySig);
        // Auction contract checks input sizes
        // If Pony is already on any auction, this will throw
        // because it will be owned by the auction contract.
        require(_owns(from, _tokenId));
        // Ensure the Pony is not pregnant to prevent the auction
        // contract accidentally receiving ownership of the child.
        // NOTE: the Pony IS allowed to be in a cooldown.
        require(!isPregnant(_tokenId));
        approvePreSigned(_ponySig, saleAuction, _tokenId, _nonce);
        // Sale auction throws if inputs are invalid and clears
        // transfer and sire approval after escrowing the Pony.
        saleAuction.createDklAuction(
            _tokenId,
            from,
            _price
        );
    }


    /// @dev Put a Pony up for auction.
    ///  Does some ownership trickery to create auctions in one tx.
    function delegateDklSiringAuction(
        uint256 _tokenId,
        uint256 _price,
        bytes _ponySig,
        uint256 _nonce
    )
    external
    whenNotPaused
    {
        bytes32 hashedTx = approvePreSignedHashing(address(this), siringAuction, _tokenId, _nonce);
        address from = recover(hashedTx, _ponySig);
        // Auction contract checks input sizes
        // If Pony is already on any auction, this will throw
        // because it will be owned by the auction contract.
        require(_owns(from, _tokenId));
        // Ensure the Pony is not pregnant to prevent the auction
        // contract accidentally receiving ownership of the child.
        // NOTE: the Pony IS allowed to be in a cooldown.
        require(!isPregnant(_tokenId));
        approvePreSigned(_ponySig, siringAuction, _tokenId, _nonce);
        // Sale auction throws if inputs are invalid and clears
        // transfer and sire approval after escrowing the Pony.
        siringAuction.createDklAuction(
            _tokenId,
            from,
            _price
        );
    }

    /// @dev Put a Pony up for auction.
    ///  Does some ownership trickery to create auctions in one tx.
    function delegateDklBidAuction(
        uint256 _tokenId,
        uint256 _price,
        bytes _ponySig,
        uint256 _nonce,
        uint16 _durationIndex
    )
    external
    whenNotPaused
    {
        bytes32 hashedTx = approvePreSignedHashing(address(this), biddingAuction, _tokenId, _nonce);
        address from = recover(hashedTx, _ponySig);
        // Auction contract checks input sizes
        // If Pony is already on any auction, this will throw
        // because it will be owned by the auction contract.
        require(_owns(from, _tokenId));
        // Ensure the Pony is not pregnant to prevent the auction
        // contract accidentally receiving ownership of the child.
        // NOTE: the Pony IS allowed to be in a cooldown.
        require(!isPregnant(_tokenId));
        approvePreSigned(_ponySig, biddingAuction, _tokenId, _nonce);
        // Sale auction throws if inputs are invalid and clears
        // transfer and sire approval after escrowing the Pony.
        biddingAuction.createDklAuction(_tokenId, from, _durationIndex, _price);
    }


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

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

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

    function createEthBidAuction(
        uint256 _ponyId,
        uint256 _price,
        uint16 _durationIndex
    ) external whenNotPaused {
        require(_owns(msg.sender, _ponyId));
        _approve(_ponyId, biddingAuction);
        biddingAuction.createETHAuction(_ponyId, msg.sender, _durationIndex, _price);
    }

    function createDeklaBidAuction(
        uint256 _ponyId,
        uint256 _price,
        uint16 _durationIndex
    ) external whenNotPaused {
        require(_owns(msg.sender, _ponyId));
        _approve(_ponyId, biddingAuction);
        biddingAuction.createDklAuction(_ponyId, msg.sender, _durationIndex, _price);
    }

    /// @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 bidOnEthSiringAuction(
        uint256 _sireId,
        uint256 _matronId,
        uint8 _incubator,
        bytes _sig
    )
    external
    payable
    whenNotPaused
    {
        // Auction contract checks input sizes
        require(_owns(msg.sender, _matronId));
        require(isReadyToMate(_matronId));
        require(canMateWithViaAuction(_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.bidEth.value(msg.value - autoBirthFee)(_sireId);
        if (_incubator == 0 && hasIncubator[msg.sender]) {
            _mateWith(_matronId, _sireId, _incubator);
        } else {
            bytes32 hashedTx = getIncubatorHashing(msg.sender, _incubator, nonces[msg.sender]);
            require(signedBySystem(hashedTx, _sig));
            nonces[msg.sender]++;

            // All checks passed, Pony gets pregnant!
            if (!hasIncubator[msg.sender]) {
                hasIncubator[msg.sender] = true;
            }
            _mateWith(_matronId, _sireId, _incubator);
        }
    }

    /// @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 bidOnDklSiringAuction(
        uint256 _sireId,
        uint256 _matronId,
        uint8 _incubator,
        bytes _incubatorSig,
        uint256 _price,
        uint256 _fee,
        bytes _delegateSig,
        uint256 _nonce

    )
    external
    payable
    whenNotPaused
    {
        // Auction contract checks input sizes
        require(_owns(msg.sender, _matronId));
        require(isReadyToMate(_matronId));
        require(canMateWithViaAuction(_matronId, _sireId));

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

        // Siring auction will throw if the bid fails.
        siringAuction.bidDkl(_sireId, _price, _fee, _delegateSig, _nonce);
        if (_incubator == 0 && hasIncubator[msg.sender]) {
            _mateWith(_matronId, _sireId, _incubator);
        } else {
            bytes32 hashedTx = getIncubatorHashing(msg.sender, _incubator, nonces[msg.sender]);
            require(signedBySystem(hashedTx, _incubatorSig));
            nonces[msg.sender]++;

            // All checks passed, Pony gets pregnant!
            if (!hasIncubator[msg.sender]) {
                hasIncubator[msg.sender] = true;
            }
            _mateWith(_matronId, _sireId, _incubator);
        }
    }

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

    function withdrawAuctionDklBalance() external onlyCLevel {
        saleAuction.withdrawDklBalance();
        siringAuction.withdrawDklBalance();
        biddingAuction.withdrawDklBalance();
    }


    function setBiddingRate(uint256 _prizeCut, uint256 _tokenDiscount) external onlyCLevel {
        biddingAuction.setCut(_prizeCut, _tokenDiscount);
    }

    function setSaleRate(uint256 _prizeCut, uint256 _tokenDiscount) external onlyCLevel {
        saleAuction.setCut(_prizeCut, _tokenDiscount);
    }

    function setSiringRate(uint256 _prizeCut, uint256 _tokenDiscount) external onlyCLevel {
        siringAuction.setCut(_prizeCut, _tokenDiscount);
    }
}

/// @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 BiddingAuctionBase {
    // An approximation of currently how many seconds are in between blocks.
    uint256 public secondsPerBlock = 15;

    // Represents an auction on an NFT
    struct Auction {
        // Current owner of NFT
        address seller;
        // Duration (in seconds) of auction
        uint16 durationIndex;
        // Time when auction started
        // NOTE: 0 if this auction has been concluded
        uint64 startedAt;

        uint64 auctionEndBlock;
        // Price (in wei) at beginning of auction
        uint256 startingPrice;

        bool allowPayDekla;
    }

    uint32[4] public auctionDuration = [
    //production
     uint32(2 days),
     uint32(3 days),
     uint32(4 days),
     uint32(5 days)
    ];

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


    uint256 public ownerCut = 500;

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

    event AuctionCreated(uint256 tokenId);
    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 {

        tokenIdToAuction[_tokenId] = _auction;

        emit AuctionCreated(
            uint256(_tokenId)
        );
    }

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


    /// @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 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 Clock auction for non-fungible tokens.
/// @notice We omit a fallback function to prevent accidental sends to this contract.
contract BiddingAuction is Pausable, BiddingAuctionBase {
    /// @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.
    constructor(address _nftAddress) public {

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

    function cancelAuctionHashing(
        uint256 _tokenId,
        uint64 _endblock
    )
    public
    pure
    returns (bytes32)
    {
        return keccak256(abi.encodePacked(bytes4(0x486A0E9E), _tokenId, _endblock));
    }

    /// @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,
        bytes _sig
    )
    external
    {
        Auction storage auction = tokenIdToAuction[_tokenId];
        address seller = auction.seller;
        uint64 endblock = auction.auctionEndBlock;
        require(msg.sender == seller);
        require(endblock < block.number);

        bytes32 hashedTx = cancelAuctionHashing(_tokenId, endblock);
        require(signedBySystem(hashedTx, _sig));

        _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
    onlyCLevel
    external
    {
        Auction storage auction = tokenIdToAuction[_tokenId];
        _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,
        uint64 startedAt,
        uint16 durationIndex,
        uint64 auctionEndBlock,
        uint256 startingPrice,
        bool allowPayDekla
    ) {
        Auction storage auction = tokenIdToAuction[_tokenId];
        return (
        auction.seller,
        auction.startedAt,
        auction.durationIndex,
        auction.auctionEndBlock,
        auction.startingPrice,
        auction.allowPayDekla
        );
    }

    function setSecondsPerBlock(uint256 secs) external onlyCEO {
        secondsPerBlock = secs;
    }

}


contract BiddingWallet is AccessControl {

    //user balances is stored in this balances map and could be withdraw by owner at anytime
    mapping(address => uint) public EthBalances;

    mapping(address => uint) public DeklaBalances;

    ERC20 public tokens;

    //the limit of deposit and withdraw the minimum amount you can deposit is 0.05 eth
    //you also have to have at least 0.05 eth
    uint public EthLimit = 50000000000000000;
    uint public DeklaLimit = 100;

    uint256 public totalEthDeposit;
    uint256 public totalDklDeposit;

    event withdrawSuccess(address receiver, uint amount);
    event cancelPendingWithdrawSuccess(address sender);

    function getNonces(address _address) public view returns (uint256) {
        return nonces[_address];
    }

    function setSystemAddress(address _systemAddress, address _tokenAddress) internal {
        systemAddress = _systemAddress;
        tokens = ERC20(_tokenAddress);
    }

    //user will be assign an equivalent amount of bidding credit to bid
    function depositETH() payable external {
        require(msg.value >= EthLimit);
        EthBalances[msg.sender] = EthBalances[msg.sender] + msg.value;
        totalEthDeposit = totalEthDeposit + msg.value;
    }

    function depositDekla(
        uint256 _amount,
        uint256 _fee,
        bytes _signature,
        uint256 _nonce)
    external {
        address sender = tokens.recoverSigner(_signature, address(this), _amount, _fee, _nonce);
        tokens.transferPreSigned(_signature, address(this), _amount, _fee, _nonce);
        DeklaBalances[sender] = DeklaBalances[sender] + _amount;
        totalDklDeposit = totalDklDeposit + _amount;
    }


    function withdrawAmountHashing(uint256 _amount, uint256 _nonce) public pure returns (bytes32) {
        return keccak256(abi.encodePacked(bytes4(0x486A0E9B), _amount, _nonce));
    }

    // Withdraw all available eth back to user wallet, need co-verify
    function withdrawEth(
        uint256 _amount,
        bytes _sig
    ) external {
        require(EthBalances[msg.sender] >= _amount);

        bytes32 hashedTx = withdrawAmountHashing(_amount, nonces[msg.sender]);
        require(signedBySystem(hashedTx, _sig));

        EthBalances[msg.sender] = EthBalances[msg.sender] - _amount;
        totalEthDeposit = totalEthDeposit - _amount;
        msg.sender.transfer(_amount);

        nonces[msg.sender]++;
        emit withdrawSuccess(msg.sender, _amount);
    }

    // Withdraw all available dekla back to user wallet, need co-verify
    function withdrawDekla(
        uint256 _amount,
        bytes _sig
    ) external {
        require(DeklaBalances[msg.sender] >= _amount);

        bytes32 hashedTx = withdrawAmountHashing(_amount, nonces[msg.sender]);
        require(signedBySystem(hashedTx, _sig));

        DeklaBalances[msg.sender] = DeklaBalances[msg.sender] - _amount;
        totalDklDeposit = totalDklDeposit - _amount;
        tokens.transfer(msg.sender, _amount);

        nonces[msg.sender]++;
        emit withdrawSuccess(msg.sender, _amount);
    }


    event valueLogger(uint256 value);
    //bidding success tranfer eth to seller wallet
    function winBidEth(
        address winner,
        address seller,
        uint256 sellerProceeds,
        uint256 auctioneerCut
    ) internal {
        require(EthBalances[winner] >= sellerProceeds + auctioneerCut);
        seller.transfer(sellerProceeds);
        EthBalances[winner] = EthBalances[winner] - (sellerProceeds + auctioneerCut);
    }

    //bidding success tranfer eth to seller wallet
    function winBidDekla(
        address winner,
        address seller,
        uint256 sellerProceeds,
        uint256 auctioneerCut
    ) internal {
        require(DeklaBalances[winner] >= sellerProceeds + auctioneerCut);
        tokens.transfer(seller, sellerProceeds);
        DeklaBalances[winner] = DeklaBalances[winner] - (sellerProceeds + auctioneerCut);
    }

    function() public {
        revert();
    }
}


/// @title Reverse auction modified for siring
/// @notice We omit a fallback function to prevent accidental sends to this contract.
contract BiddingClockAuction is BiddingAuction, BiddingWallet {

    address public prizeAddress;

    uint256 public prizeCut = 100;

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

    modifier onlySystem() {
        require(msg.sender == systemAddress);
        _;
    }

    // Delegate constructor
    constructor(
        address _nftAddr,
        address _tokenAddress,
        address _prizeAddress,
        address _systemAddress,
        address _ceoAddress,
        address _cfoAddress,
        address _cooAddress)
    public
    BiddingAuction(_nftAddr) {
        // validate address
        require(_systemAddress != address(0));
        require(_tokenAddress != address(0));
        require(_ceoAddress != address(0));
        require(_cooAddress != address(0));
        require(_cfoAddress != address(0));
        require(_prizeAddress != address(0));

        setSystemAddress(_systemAddress, _tokenAddress);

        ceoAddress = _ceoAddress;
        cooAddress = _cooAddress;
        cfoAddress = _cfoAddress;
        prizeAddress = _prizeAddress;
    }


    /// @dev Creates and begins a new auction. Since this function is wrapped,
    /// require sender to be PonyCore contract.
    function createETHAuction(
        uint256 _tokenId,
        address _seller,
        uint16 _durationIndex,
        uint256 _startingPrice
    )
    external
    {
        require(msg.sender == address(nonFungibleContract));
        _escrow(_seller, _tokenId);
        uint64 auctionEndBlock = uint64((auctionDuration[_durationIndex] / secondsPerBlock) + block.number);
        Auction memory auction = Auction(
            _seller,
            _durationIndex,
            uint64(now),
            auctionEndBlock,
            _startingPrice,
            false
        );
        _addAuction(_tokenId, auction);
    }

    function setCut(uint256 _prizeCut, uint256 _tokenDiscount)
    external
    {
        require(msg.sender == address(nonFungibleContract));
        require(_prizeCut + _tokenDiscount < ownerCut);

        prizeCut = _prizeCut;
        tokenDiscount = _tokenDiscount;
    }

    /// @dev Creates and begins a new auction. Since this function is wrapped,
    /// require sender to be PonyCore contract.
    function createDklAuction(
        uint256 _tokenId,
        address _seller,
        uint16 _durationIndex,
        uint256 _startingPrice
    )
    external

    {
        require(msg.sender == address(nonFungibleContract));
        _escrow(_seller, _tokenId);
        uint64 auctionEndBlock = uint64((auctionDuration[_durationIndex] / secondsPerBlock) + block.number);
        Auction memory auction = Auction(
            _seller,
            _durationIndex,
            uint64(now),
            auctionEndBlock,
            _startingPrice,
            true
        );
        _addAuction(_tokenId, auction);
    }

    function getNonces(address _address) public view returns (uint256) {
        return nonces[_address];
    }

    function auctionEndHashing(uint _amount, uint256 _tokenId) public pure returns (bytes32) {
        return keccak256(abi.encodePacked(bytes4(0x486A0F0E), _tokenId, _amount));
    }

    function auctionEthEnd(address _winner, uint _amount, uint256 _tokenId, bytes _sig) public onlySystem {
        bytes32 hashedTx = auctionEndHashing(_amount, _tokenId);
        require(recover(hashedTx, _sig) == _winner);
        Auction storage auction = tokenIdToAuction[_tokenId];
        uint64 endblock = auction.auctionEndBlock;
        require(endblock < block.number);
        require(!auction.allowPayDekla);
        uint256 prize = _amount * prizeCut / 10000;
        uint256 auctioneerCut = _computeCut(_amount) - prize;
        uint256 sellerProceeds = _amount - auctioneerCut;
        winBidEth(_winner, auction.seller, sellerProceeds, auctioneerCut);
        prizeAddress.transfer(prize);
        _removeAuction(_tokenId);
        _transfer(_winner, _tokenId);
        emit AuctionSuccessful(_tokenId, _amount, _winner);
    }

    function auctionDeklaEnd(address _winner, uint _amount, uint256 _tokenId, bytes _sig) public onlySystem {
        bytes32 hashedTx = auctionEndHashing(_amount, _tokenId);
        require(recover(hashedTx, _sig) == _winner);
        Auction storage auction = tokenIdToAuction[_tokenId];
        uint64 endblock = auction.auctionEndBlock;
        require(endblock < block.number);
        require(auction.allowPayDekla);
        uint256 prize = _amount * prizeCut / 10000;
        uint256 discountAmount = _amount * tokenDiscount / 10000;
        uint256 auctioneerCut = _computeCut(_amount) - discountAmount - prizeCut;
        uint256 sellerProceeds = _amount - auctioneerCut;
        winBidDekla(_winner, auction.seller, sellerProceeds, auctioneerCut);
        tokens.transfer(prizeAddress, prize);
        tokens.transfer(_winner, discountAmount);
        _removeAuction(_tokenId);
        _transfer(_winner, _tokenId);
        emit AuctionSuccessful(_tokenId, _amount, _winner);
    }

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

        nftAddress.transfer(address(this).balance - totalEthDeposit);
    }

    function withdrawDklBalance() external {
        address nftAddress = address(nonFungibleContract);

        require(
            msg.sender == nftAddress
        );
        tokens.transfer(nftAddress, tokens.balanceOf(this) - totalDklDeposit);
    }
}

/// @title all functions related to creating ponies
contract PonyMinting is PonyAuction {

    // Limits the number of ponies the contract owner can ever create.
    uint256 public constant PROMO_CREATION_LIMIT = 50;
    uint256 public constant GEN0_CREATION_LIMIT = 4950;


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

    /// @dev we can create promo ponies, up to a limit. Only callable by COO
    /// @param _genes the encoded genes of the pony to be created, any value is accepted
    /// @param _owner the future owner of the created ponies. Default to contract COO
    function createPromoPony(uint256 _genes, address _owner) external onlyCOO {
        address ponyOwner = _owner;
        if (ponyOwner == address(0)) {
            ponyOwner = cooAddress;
        }
        require(promoCreatedCount < PROMO_CREATION_LIMIT);

        promoCreatedCount++;
        _createPony(0, 0, 0, _genes, ponyOwner, 0);
    }

    /// @dev Creates a new gen0 Pony with the given genes and
    ///  creates an auction for it.
    function createGen0(uint256 _genes, uint256 _price, uint16 _durationIndex, bool _saleDKL ) external onlyCOO {
        require(gen0CreatedCount < GEN0_CREATION_LIMIT);

        uint256 ponyId = _createPony(0, 0, 0, _genes, ceoAddress, 0);

        _approve(ponyId, biddingAuction);

        if(_saleDKL) {
            biddingAuction.createDklAuction(ponyId, ceoAddress, _durationIndex, _price);
        } else {
            biddingAuction.createETHAuction(ponyId, ceoAddress, _durationIndex, _price);
        }
        gen0CreatedCount++;
    }

}


contract PonyUpgrade is PonyMinting {
    event PonyUpgraded(uint256 upgradedPony, uint256 tributePony, uint8 unicornation);

    function upgradePonyHashing(uint256 _upgradeId, uint256 _txCount) public pure returns (bytes32) {
        return keccak256(abi.encodePacked(bytes4(0x486A0E9D), _upgradeId, _txCount));
    }

    function upgradePony(uint256 _upgradeId, uint256 _tributeId, bytes _sig)
    external
    whenNotPaused
    {
        require(_owns(msg.sender, _upgradeId));
        require(_upgradeId != _tributeId);

        Pony storage upPony = ponies[_upgradeId];

        bytes32 hashedTx = upgradePonyHashing(_upgradeId, upPony.txCount);
        require(signedBySystem(hashedTx, _sig));

        upPony.txCount += 1;
        if (upPony.unicornation == 0) {
            if (geneScience.upgradePonyResult(upPony.unicornation, block.number)) {
                upPony.unicornation += 1;
                emit PonyUpgraded(_upgradeId, _tributeId, upPony.unicornation);
            }
        }
        else if (upPony.unicornation > 0) {
            require(_owns(msg.sender, _tributeId));

            if (geneScience.upgradePonyResult(upPony.unicornation, block.number)) {
                upPony.unicornation += 1;
                _transfer(msg.sender, address(0), _tributeId);
                emit PonyUpgraded(_upgradeId, _tributeId, upPony.unicornation);
            } else if (upPony.unicornation == 2) {
                upPony.unicornation += 1;
                _transfer(msg.sender, address(0), _tributeId);
                emit PonyUpgraded(_upgradeId, _tributeId, upPony.unicornation);
            }
        }
    }
}

/// @title EtherPonies: Collectible, breedable, and oh-so-adorable ponies on the Ethereum blockchain.
/// @author Dekla (https://www.dekla.io)
/// @dev The main EtherPonies contract, keeps track of ponies so they don't wander around and get lost.
contract PonyCore is PonyUpgrade {

    event WithdrawEthBalanceSuccessful(address sender, uint256 amount);
    event WithdrawDeklaBalanceSuccessful(address sender, uint256 amount);

    // This is the main MyEtherPonies 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
    // Pony 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:
    //
    //      - PonyBase: 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.
    //
    //      - PonyAccessControl: This contract manages the various addresses and constraints for operations
    //             that can be executed only by specific roles. Namely CEO, CFO and COO.
    //
    //      - PonyOwnership: This provides the methods required for basic non-fungible token
    //             transactions, following the draft ERC-721 spec (https://github.com/ethereum/EIPs/issues/721).
    //
    //      - PonyBreeding: This file contains the methods necessary to breed ponies together, including
    //             keeping track of siring offers, and relies on an external genetic combination contract.
    //
    //      - PonyAuctions: Here we have the public methods for auctioning or bidding on ponies 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.
    //
    //      - PonyMinting: This final facet contains the functionality we use for creating new gen0 ponies.
    //             We can make up to 5000 "promo" ponies that can be given away (especially important when
    //             the community is new), and all others can only be created and then immediately put up
    //             for auction via an algorithmically determined starting price. Regardless of how they
    //             are created, there is a hard limit of 50k gen0 ponies. 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;

    // ERC20 basic token contract being held
    ERC20 public token;

    /// @notice Creates the main EtherPonies smart contract instance.
    constructor(
        address _ceoAddress,
        address _cfoAddress,
        address _cooAddress,
        address _systemAddress,
        address _tokenAddress
    ) public {
        // validate address
        require(_ceoAddress != address(0));
        require(_cooAddress != address(0));
        require(_cfoAddress != address(0));
        require(_systemAddress != address(0));
        require(_tokenAddress != address(0));

        // Starts paused.
        paused = true;

        // the creator of the contract is the initial CEO
        ceoAddress = _ceoAddress;
        cfoAddress = _cfoAddress;
        cooAddress = _cooAddress;
        systemAddress = _systemAddress;
        token = ERC20(_tokenAddress);

        // start with the mythical pony 0 - so we don't have generation-0 parent issues
        _createPony(0, 0, 0, uint256(- 1), address(0), 0);
    }

    //check that the token is set
    modifier validToken() {
        require(token != address(0));
        _;
    }

    function getTokenAddressHashing(address _token, uint256 _nonce) public pure returns (bytes32) {
        return keccak256(abi.encodePacked(bytes4(0x486A1216), _token, _nonce));
    }

    function setTokenAddress(address _token, bytes _sig) external onlyCLevel {
        bytes32 hashedTx = getTokenAddressHashing(_token, nonces[msg.sender]);
        require(signedByCLevel(hashedTx, _sig));
        nonces[msg.sender]++;

        token = ERC20(_token);
    }

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

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

    /// @notice Returns all the relevant information about a specific Pony.
    /// @param _id The ID of the Pony of interest.
    function getPony(uint256 _id)
    external
    view
    returns (
        bool isGestating,
        bool isReady,
        uint256 cooldownIndex,
        uint256 nextActionAt,
        uint256 siringWithId,
        uint256 birthTime,
        uint256 matronId,
        uint256 sireId,
        uint256 generation,
        uint256 genes,
        uint16 upgradeIndex,
        uint8 unicornation
    ) {
        Pony storage pon = ponies[_id];

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

    /// @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(geneScience != address(0));
        require(newContractAddress == address(0));

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

    function withdrawBalanceHashing(address _address, uint256 _nonce) public pure returns (bytes32) {
        return keccak256(abi.encodePacked(bytes4(0x486A1217), _address, _nonce));
    }

    function withdrawEthBalance(address _withdrawWallet, bytes _sig) external onlyCLevel {
        bytes32 hashedTx = withdrawBalanceHashing(_withdrawWallet, nonces[msg.sender]);
        require(signedByCLevel(hashedTx, _sig));

        uint256 balance = address(this).balance;

        // Subtract all the currently pregnant ponies we have, plus 1 of margin.
        uint256 subtractFees = (pregnantPonies + 1) * autoBirthFee;
        require(balance > 0);
        require(balance > subtractFees);

        nonces[msg.sender]++;
        _withdrawWallet.transfer(balance - subtractFees);
        emit WithdrawEthBalanceSuccessful(_withdrawWallet, balance - subtractFees);
    }


    function withdrawDeklaBalance(address _withdrawWallet, bytes _sig) external validToken onlyCLevel {
        bytes32 hashedTx = withdrawBalanceHashing(_withdrawWallet, nonces[msg.sender]);
        require(signedByCLevel(hashedTx, _sig));

        uint256 balance = token.balanceOf(this);
        require(balance > 0);

        nonces[msg.sender]++;
        token.transfer(_withdrawWallet, balance);
        emit WithdrawDeklaBalanceSuccessful(_withdrawWallet, balance);
    }
}

Contract Security Audit

Contract ABI

[{"constant":true,"inputs":[{"name":"_interfaceID","type":"bytes4"}],"name":"supportsInterface","outputs":[{"name":"","type":"bool"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"cfoAddress","outputs":[{"name":"","type":"address"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"promoCreatedCount","outputs":[{"name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"name","outputs":[{"name":"","type":"string"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"name":"_ponyId","type":"uint256"},{"name":"_price","type":"uint256"},{"name":"_durationIndex","type":"uint16"}],"name":"createDeklaBidAuction","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"name":"_to","type":"address"},{"name":"_tokenId","type":"uint256"}],"name":"approve","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[],"name":"ceoAddress","outputs":[{"name":"","type":"address"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"name":"_address","type":"address"}],"name":"setBiddingAuctionAddress","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"name":"_newCFO","type":"address"},{"name":"_sig","type":"bytes"}],"name":"setCFO","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[{"name":"_newCFO","type":"address"},{"name":"_nonce","type":"uint256"}],"name":"getCFOHashing","outputs":[{"name":"","type":"bytes32"}],"payable":false,"stateMutability":"pure","type":"function"},{"constant":false,"inputs":[{"name":"_address","type":"address"}],"name":"setSiringAuctionAddress","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[],"name":"totalSupply","outputs":[{"name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"name":"hash","type":"bytes32"},{"name":"sig","type":"bytes"}],"name":"recover","outputs":[{"name":"","type":"address"}],"payable":false,"stateMutability":"pure","type":"function"},{"constant":true,"inputs":[{"name":"_ponyId","type":"uint256"}],"name":"isPregnant","outputs":[{"name":"","type":"bool"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"name":"_sireId","type":"uint256"},{"name":"_matronId","type":"uint256"},{"name":"_incubator","type":"uint8"},{"name":"_incubatorSig","type":"bytes"},{"name":"_price","type":"uint256"},{"name":"_fee","type":"uint256"},{"name":"_delegateSig","type":"bytes"},{"name":"_nonce","type":"uint256"}],"name":"bidOnDklSiringAuction","outputs":[],"payable":true,"stateMutability":"payable","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":"_genes","type":"uint256"},{"name":"_price","type":"uint256"},{"name":"_durationIndex","type":"uint16"},{"name":"_saleDKL","type":"bool"}],"name":"createGen0","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[],"name":"pregnantPonies","outputs":[{"name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"biddingAuction","outputs":[{"name":"","type":"address"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"name":"_signature","type":"bytes"},{"name":"_to","type":"address"},{"name":"_id","type":"uint256"},{"name":"_nonce","type":"uint256"}],"name":"transferPreSigned","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[{"name":"","type":"address"}],"name":"hasIncubator","outputs":[{"name":"","type":"bool"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"name":"_id","type":"uint256"}],"name":"getPony","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"},{"name":"upgradeIndex","type":"uint16"},{"name":"unicornation","type":"uint8"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"name":"_newCOO","type":"address"},{"name":"_sig","type":"bytes"}],"name":"setCOO","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"name":"_prizeCut","type":"uint256"},{"name":"_tokenDiscount","type":"uint256"}],"name":"setSiringRate","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[],"name":"unpause","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"name":"_token","type":"address"},{"name":"_sig","type":"bytes"}],"name":"setTokenAddress","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"name":"_prizeCut","type":"uint256"},{"name":"_tokenDiscount","type":"uint256"}],"name":"setBiddingRate","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"name":"val","type":"uint256"}],"name":"setAutoBirthFee","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[{"name":"","type":"uint256"}],"name":"matingAllowedToAddress","outputs":[{"name":"","type":"address"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"name":"_signature","type":"bytes"},{"name":"_spender","type":"address"},{"name":"_tokenId","type":"uint256"},{"name":"_nonce","type":"uint256"}],"name":"approvePreSigned","outputs":[{"name":"","type":"bool"}],"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":true,"inputs":[{"name":"_newCEO","type":"address"},{"name":"_nonce","type":"uint256"}],"name":"getCEOHashing","outputs":[{"name":"","type":"bytes32"}],"payable":false,"stateMutability":"pure","type":"function"},{"constant":false,"inputs":[{"name":"_sireId","type":"uint256"},{"name":"_matronId","type":"uint256"},{"name":"_incubator","type":"uint8"},{"name":"_sig","type":"bytes"}],"name":"bidOnEthSiringAuction","outputs":[],"payable":true,"stateMutability":"payable","type":"function"},{"constant":true,"inputs":[{"name":"_sender","type":"address"}],"name":"getNonces","outputs":[{"name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"CLevelTxCount_","outputs":[{"name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"name":"secs","type":"uint256"}],"name":"setSecondsPerBlock","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[{"name":"","type":"uint256"}],"name":"ponyIndexToApproved","outputs":[{"name":"","type":"address"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"name":"_token","type":"address"},{"name":"_to","type":"address"},{"name":"_id","type":"uint256"},{"name":"_nonce","type":"uint256"}],"name":"transferPreSignedHashing","outputs":[{"name":"","type":"bytes32"}],"payable":false,"stateMutability":"pure","type":"function"},{"constant":false,"inputs":[{"name":"_isMatingSeason","type":"bool"}],"name":"setMatingSeason","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[],"name":"paused","outputs":[{"name":"","type":"bool"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"name":"_token","type":"address"},{"name":"_spender","type":"address"},{"name":"_tokenId","type":"uint256"},{"name":"_nonce","type":"uint256"}],"name":"approvePreSignedHashing","outputs":[{"name":"","type":"bytes32"}],"payable":false,"stateMutability":"pure","type":"function"},{"constant":true,"inputs":[{"name":"_tokenId","type":"uint256"}],"name":"ownerOf","outputs":[{"name":"owner","type":"address"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"name":"_PonyId","type":"uint256"},{"name":"_price","type":"uint256"}],"name":"createEthSaleAuction","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[],"name":"withdrawAuctionDklBalance","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"name":"_matronId","type":"uint256"},{"name":"_sireId","type":"uint256"},{"name":"_incubator","type":"uint8"},{"name":"_sig","type":"bytes"}],"name":"mateWithAuto","outputs":[],"payable":true,"stateMutability":"payable","type":"function"},{"constant":true,"inputs":[],"name":"GEN0_CREATION_LIMIT","outputs":[{"name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"name":"_PonyId","type":"uint256"},{"name":"_price","type":"uint256"}],"name":"createEthSiringAuction","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[{"name":"_sender","type":"address"},{"name":"_incubator","type":"uint8"},{"name":"txCount","type":"uint256"}],"name":"getIncubatorHashing","outputs":[{"name":"","type":"bytes32"}],"payable":false,"stateMutability":"pure","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":"_newCOO","type":"address"},{"name":"_nonce","type":"uint256"}],"name":"getCOOHashing","outputs":[{"name":"","type":"bytes32"}],"payable":false,"stateMutability":"pure","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":false,"inputs":[{"name":"_genes","type":"uint256"},{"name":"_owner","type":"address"}],"name":"createPromoPony","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"name":"_tokenId","type":"uint256"},{"name":"_price","type":"uint256"},{"name":"_ponySig","type":"bytes"},{"name":"_nonce","type":"uint256"}],"name":"delegateDklSiringAuction","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[],"name":"secondsPerBlock","outputs":[{"name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"name":"_withdrawWallet","type":"address"},{"name":"_sig","type":"bytes"}],"name":"withdrawEthBalance","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[],"name":"pause","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[{"name":"_owner","type":"address"}],"name":"tokensOfOwner","outputs":[{"name":"ownerTokens","type":"uint256[]"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"name":"_PonyId","type":"uint256"},{"name":"_price","type":"uint256"}],"name":"createDklSiringAuction","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[{"name":"_address","type":"address"},{"name":"_nonce","type":"uint256"}],"name":"withdrawBalanceHashing","outputs":[{"name":"","type":"bytes32"}],"payable":false,"stateMutability":"pure","type":"function"},{"constant":false,"inputs":[{"name":"_matronId","type":"uint256"}],"name":"giveBirth","outputs":[{"name":"","type":"uint256"}],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[{"name":"_ponyId","type":"uint256"}],"name":"isReadyToMate","outputs":[{"name":"","type":"bool"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[],"name":"withdrawAuctionBalances","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[],"name":"symbol","outputs":[{"name":"","type":"string"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"name":"","type":"uint256"}],"name":"ponyIndexToOwner","outputs":[{"name":"","type":"address"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"name":"","type":"uint256"}],"name":"cooldowns","outputs":[{"name":"","type":"uint32"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"name":"_prizeCut","type":"uint256"},{"name":"_tokenDiscount","type":"uint256"}],"name":"setSaleRate","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[{"name":"_matronId","type":"uint256"},{"name":"_sireId","type":"uint256"}],"name":"canMateWith","outputs":[{"name":"","type":"bool"}],"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":"_token","type":"address"},{"name":"_nonce","type":"uint256"}],"name":"getTokenAddressHashing","outputs":[{"name":"","type":"bytes32"}],"payable":false,"stateMutability":"pure","type":"function"},{"constant":false,"inputs":[{"name":"_PonyId","type":"uint256"},{"name":"_price","type":"uint256"}],"name":"createDklSaleAuction","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"name":"_tokenId","type":"uint256"},{"name":"_price","type":"uint256"},{"name":"_ponySig","type":"bytes"},{"name":"_nonce","type":"uint256"}],"name":"delegateDklSaleAuction","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":"_upgradeId","type":"uint256"},{"name":"_tributeId","type":"uint256"},{"name":"_sig","type":"bytes"}],"name":"upgradePony","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[{"name":"_matronId","type":"uint256"},{"name":"_sireId","type":"uint256"}],"name":"canMateWithViaAuction","outputs":[{"name":"","type":"bool"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"name":"_tokenId","type":"uint256"},{"name":"_price","type":"uint256"},{"name":"_ponySig","type":"bytes"},{"name":"_nonce","type":"uint256"},{"name":"_durationIndex","type":"uint16"}],"name":"delegateDklBidAuction","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[],"name":"systemAddress","outputs":[{"name":"","type":"address"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"name":"_withdrawWallet","type":"address"},{"name":"_sig","type":"bytes"}],"name":"withdrawDeklaBalance","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"name":"_newCEO","type":"address"},{"name":"_sig","type":"bytes"}],"name":"setCEO","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[],"name":"PROMO_CREATION_LIMIT","outputs":[{"name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"saleAuction","outputs":[{"name":"","type":"address"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"name":"_ponyId","type":"uint256"},{"name":"_price","type":"uint256"},{"name":"_durationIndex","type":"uint16"}],"name":"createEthBidAuction","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[{"name":"_upgradeId","type":"uint256"},{"name":"_txCount","type":"uint256"}],"name":"upgradePonyHashing","outputs":[{"name":"","type":"bytes32"}],"payable":false,"stateMutability":"pure","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":true,"inputs":[{"name":"","type":"uint256"}],"name":"incubators","outputs":[{"name":"","type":"uint8"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"token","outputs":[{"name":"","type":"address"}],"payable":false,"stateMutability":"view","type":"function"},{"inputs":[{"name":"_ceoAddress","type":"address"},{"name":"_cfoAddress","type":"address"},{"name":"_cooAddress","type":"address"},{"name":"_systemAddress","type":"address"},{"name":"_tokenAddress","type":"address"}],"payable":false,"stateMutability":"nonpayable","type":"constructor"},{"payable":true,"stateMutability":"payable","type":"fallback"},{"anonymous":false,"inputs":[{"indexed":false,"name":"sender","type":"address"},{"indexed":false,"name":"amount","type":"uint256"}],"name":"WithdrawEthBalanceSuccessful","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"name":"sender","type":"address"},{"indexed":false,"name":"amount","type":"uint256"}],"name":"WithdrawDeklaBalanceSuccessful","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"name":"upgradedPony","type":"uint256"},{"indexed":false,"name":"tributePony","type":"uint256"},{"indexed":false,"name":"unicornation","type":"uint8"}],"name":"PonyUpgraded","type":"event"},{"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":"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":"ponyId","type":"uint256"},{"indexed":false,"name":"matronId","type":"uint256"},{"indexed":false,"name":"sireId","type":"uint256"},{"indexed":false,"name":"genes","type":"uint256"}],"name":"Birth","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"name":"newContract","type":"address"}],"name":"ContractUpgrade","type":"event"}]

60006004556006805460ff191690556101c0604052603c608090815261012c60a05261070860c052610e1060e052613840610100526170806101205262015180610140526202a30061016052620546006101805262093a806101a0526200006b90600790600a620005d7565b506040805160a0810182526005808252600a6020830152600f928201929092526014606082015260196080820152620000a891600991906200067a565b50600f600a5566071afd498d0000601455348015620000c657600080fd5b5060405160a080620066688339810160409081528151602083015191830151606084015160809094015191939091600160a060020a03851615156200010a57600080fd5b600160a060020a03831615156200012057600080fd5b600160a060020a03841615156200013657600080fd5b600160a060020a03821615156200014c57600080fd5b600160a060020a03811615156200016257600080fd5b6006805460ff1916600190811790915560008054600160a060020a03808916600160a060020a03199283161783558354888216908316179093556002805487851690831617905560038054868516908316179055601a80549385169390911692909217909155620001e39080806000198180640100000000620001ef810204565b505050505050620007ac565b6000620001fb62000710565b600063ffffffff891689146200021057600080fd5b63ffffffff881688146200022357600080fd5b61ffff871687146200023457600080fd5b61014060405190810160405280878152602001426001604060020a0316815260200160006001604060020a031681526020018a63ffffffff1681526020018963ffffffff168152602001600063ffffffff1681526020018561ffff1681526020018861ffff168152602001600061ffff168152602001600060ff1681525091506001600b83908060018154018082558091505090600182039060005260206000209060030201600090919290919091506000820151816000015560208201518160010160006101000a8154816001604060020a0302191690836001604060020a0316021790555060408201518160010160086101000a8154816001604060020a0302191690836001604060020a0316021790555060608201518160010160106101000a81548163ffffffff021916908363ffffffff16021790555060808201518160010160146101000a81548163ffffffff021916908363ffffffff16021790555060a08201518160010160186101000a81548163ffffffff021916908363ffffffff16021790555060c082015181600101601c6101000a81548161ffff021916908361ffff16021790555060e082015181600101601e6101000a81548161ffff021916908361ffff1602179055506101008201518160020160006101000a81548161ffff021916908361ffff1602179055506101208201518160020160026101000a81548160ff021916908360ff16021790555050500390508063ffffffff16811415156200046357600080fd5b606080830151608080850151855160408051600160a060020a038c1681526020810188905263ffffffff95861681830152929094169482019490945290810192909252517f0a5311bd2a6608f08a180df2ee7c5946819a649b204b554bb8e39825b2c50ad59181900360a00190a1620004e860008683640100000000620004f4810204565b98975050505050505050565b600160a060020a038083166000818152600d6020908152604080832080546001019055858352600c90915290208054600160a060020a03191690911790558316156200058857600160a060020a0383166000908152600d602090815260408083208054600019019055838352600f82528083208054600160a060020a0319908116909155600e909252909120805490911690555b60408051600160a060020a0380861682528416602082015280820183905290517fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef9181900360600190a1505050565b600283019183908215620006685791602002820160005b838211156200063457835183826101000a81548163ffffffff021916908363ffffffff1602179055509260200192600401602081600301049283019260010302620005ee565b8015620006665782816101000a81549063ffffffff021916905560040160208160030104928301926001030262000634565b505b506200067692915062000764565b5090565b600183019183908215620007025791602002820160005b83821115620006d157835183826101000a81548160ff021916908360ff160217905550926020019260010160208160000104928301926001030262000691565b8015620007005782816101000a81549060ff0219169055600101602081600001049283019260010302620006d1565b505b50620006769291506200078b565b6040805161014081018252600080825260208201819052918101829052606081018290526080810182905260a0810182905260c0810182905260e08101829052610100810182905261012081019190915290565b6200078891905b808211156200067657805463ffffffff191681556001016200076b565b90565b6200078891905b808211156200067657805460ff1916815560010162000792565b615eac80620007bc6000396000f3006080604052600436106104055763ffffffff60e060020a60003504166301ffc9a781146104075780630519ce791461045257806305e455461461048357806306fdde03146104aa57806308ec651f14610534578063095ea7b3146105565780630a0f81681461057a5780630a7782e91461058f5780630bf2c50d146105b05780630ee85800146105dd57806314001f4c1461060157806318160ddd1461062257806319045a25146106375780631940a936146106955780631c0acbd5146106ad57806321717ebf146106e657806323b872dd146106fb57806324e7a38a146107255780632fd95a6f14610746578063304b01901461076d578063313424b61461078257806333d764a2146107975780633618ef6d1461080557806336917dfa1461082657806336c4db09146108a65780633c771309146108d35780633f4ba83a146108ee5780634b16304f146109035780634b6a8604146109305780634b85fd551461094b5780634ba081cf146109635780634c167a6e1461097b5780634dfff04f146109e95780634eaef8a214610a0d5780635041742a14610a315780635124ae9514610a5357806355381f0014610a745780635663896e14610a8957806359d71a2414610aa15780635c4b4c1214610ab95780635c80b44814610ae65780635c975abb14610b005780635dac48bb14610b155780636352211e14610b42578063656d309114610b5a578063664d862914610b7557806366a6cf1a14610b8a578063680eba2714610bac5780636973cf5814610bc15780636a23e30814610bdc5780636af04a5714610c065780636fbde40d14610c1b5780637039368614610c3c57806370a0823114610c605780637158798814610c8157806375776fa414610ca257806375a5ba8014610cc65780637a7d493714610cf15780638165913d14610d065780638456cb5914610d335780638462151c14610d4857806384a429a014610db95780638760d65d14610dd457806388c2a0bf14610df857806389eb313a14610e1057806391876e5714610e2857806395d89b4114610e3d5780639892a87114610e525780639d6fac6f14610e6a5780639dbfe1b814610e9b578063a2dd9dd314610eb6578063a9059cbb14610ed1578063abcb7fce14610ef5578063abd05acd14610f19578063abd936ab14610f34578063b047fb5014610f5f578063b0c35c0514610f74578063c56b2dc214610f89578063c7d9630414610fb1578063d15b95b414610fcc578063d3e848f114610ffe578063d831b71414611013578063d9194fcb14611040578063defb95841461106d578063e6cbe35114611082578063e928ad4714611097578063f12acca2146110b9578063f1ca9410146110d4578063f2b47d52146110e9578063f89309f2146110fe578063fc0c546a1461112c575b005b34801561041357600080fd5b5061043e7bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1960043516611141565b604080519115158252519081900360200190f35b34801561045e57600080fd5b506104676113d2565b60408051600160a060020a039092168252519081900360200190f35b34801561048f57600080fd5b506104986113e1565b60408051918252519081900360200190f35b3480156104b657600080fd5b506104bf6113e7565b6040805160208082528351818301528351919283929083019185019080838360005b838110156104f95781810151838201526020016104e1565b50505050905090810190601f1680156105265780820380516001836020036101000a031916815260200191505b509250505060405180910390f35b34801561054057600080fd5b5061040560043560243561ffff6044351661141e565b34801561056257600080fd5b50610405600160a060020a03600435166024356114f4565b34801561058657600080fd5b5061046761156f565b34801561059b57600080fd5b50610405600160a060020a036004351661157e565b3480156105bc57600080fd5b5061040560048035600160a060020a03169060248035908101910135611631565b3480156105e957600080fd5b50610498600160a060020a0360043516602435611769565b34801561060d57600080fd5b50610405600160a060020a0360043516611829565b34801561062e57600080fd5b506104986118dc565b34801561064357600080fd5b5060408051602060046024803582810135601f81018590048502860185019096528585526104679583359536956044949193909101919081908401838280828437509497506118e69650505050505050565b3480156106a157600080fd5b5061043e600435611ab1565b6104056004803590602480359160ff60443516916064358082019290810135916084359160a4359160c43590810191013560e435611af6565b3480156106f257600080fd5b50610467611da3565b34801561070757600080fd5b50610405600160a060020a0360043581169060243516604435611db2565b34801561073157600080fd5b50610405600160a060020a0360043516611e27565b34801561075257600080fd5b5061040560043560243561ffff604435166064351515611eda565b34801561077957600080fd5b50610498612088565b34801561078e57600080fd5b5061046761208e565b3480156107a357600080fd5b506040805160206004803580820135601f810184900484028501840190955284845261040594369492936024939284019190819084018382808284375094975050508335600160a060020a03169450505060208201359160400135905061209d565b34801561081157600080fd5b5061043e600160a060020a0360043516612141565b34801561083257600080fd5b5061083e600435612156565b604080519c15158d529a151560208d01528b8b019990995260608b019790975260808a019590955260a089019390935260c088019190915260e087015261010086015261012085015261ffff1661014084015260ff1661016083015251908190036101800190f35b3480156108b257600080fd5b5061040560048035600160a060020a031690602480359081019101356122e5565b3480156108df57600080fd5b50610405600435602435612420565b3480156108fa57600080fd5b506104056124e4565b34801561090f57600080fd5b5061040560048035600160a060020a03169060248035908101910135612543565b34801561093c57600080fd5b50610405600435602435612626565b34801561095757600080fd5b506104056004356126d6565b34801561096f57600080fd5b506104676004356126f2565b34801561098757600080fd5b506040805160206004803580820135601f810184900484028501840190955284845261043e94369492936024939284019190819084018382808284375094975050508335600160a060020a03169450505060208201359160400135905061270d565b3480156109f557600080fd5b50610405600160a060020a03600435166024356127ea565b348015610a1957600080fd5b50610498600160a060020a036004351660243561283d565b6104056004803590602480359160ff60443516916064359081019101356128c9565b348015610a5f57600080fd5b50610498600160a060020a0360043516612b32565b348015610a8057600080fd5b50610498612b4d565b348015610a9557600080fd5b50610405600435612b53565b348015610aad57600080fd5b50610467600435612baf565b348015610ac557600080fd5b50610498600160a060020a0360043581169060243516604435606435612bca565b348015610af257600080fd5b506104056004351515612ca0565b348015610b0c57600080fd5b5061043e612d75565b348015610b2157600080fd5b50610498600160a060020a0360043581169060243516604435606435612d7e565b348015610b4e57600080fd5b50610467600435612e16565b348015610b6657600080fd5b50610405600435602435612e31565b348015610b8157600080fd5b50610405612ef3565b6104056004803590602480359160ff6044351691606435908101910135613079565b348015610bb857600080fd5b5061049861339a565b348015610bcd57600080fd5b506104056004356024356133a0565b348015610be857600080fd5b50610498600160a060020a036004351660ff60243516604435613463565b348015610c1257600080fd5b5061046761354f565b348015610c2757600080fd5b50610405600160a060020a036004351661355e565b348015610c4857600080fd5b50610498600160a060020a0360043516602435613611565b348015610c6c57600080fd5b50610498600160a060020a036004351661369d565b348015610c8d57600080fd5b50610405600160a060020a03600435166136b8565b348015610cae57600080fd5b50610405600435600160a060020a0360243516613734565b348015610cd257600080fd5b5061040560048035906024803591604435918201910135606435613795565b348015610cfd57600080fd5b506104986138f4565b348015610d1257600080fd5b5061040560048035600160a060020a031690602480359081019101356138fa565b348015610d3f57600080fd5b50610405613a6a565b348015610d5457600080fd5b50610d69600160a060020a0360043516613acc565b60408051602080825283518183015283519192839290830191858101910280838360005b83811015610da5578181015183820152602001610d8d565b505050509050019250505060405180910390f35b348015610dc557600080fd5b50610405600435602435613b9e565b348015610de057600080fd5b50610498600160a060020a0360043516602435613c4b565b348015610e0457600080fd5b50610498600435613cd7565b348015610e1c57600080fd5b5061043e60043561409a565b348015610e3457600080fd5b50610405614189565b348015610e4957600080fd5b506104bf6142f5565b348015610e5e57600080fd5b5061046760043561432c565b348015610e7657600080fd5b50610e82600435614347565b6040805163ffffffff9092168252519081900360200190f35b348015610ea757600080fd5b50610405600435602435614374565b348015610ec257600080fd5b5061043e600435602435614424565b348015610edd57600080fd5b50610405600160a060020a03600435166024356144a4565b348015610f0157600080fd5b50610498600160a060020a0360043516602435614503565b348015610f2557600080fd5b5061040560043560243561458f565b348015610f4057600080fd5b506104056004803590602480359160443591820191013560643561463b565b348015610f6b57600080fd5b50610467614779565b348015610f8057600080fd5b50610498614788565b348015610f9557600080fd5b506104056004803590602480359160443591820191013561478e565b348015610fbd57600080fd5b5061043e600435602435614b78565b348015610fd857600080fd5b506104056004803590602480359160443591820191013560643561ffff60843516614bc7565b34801561100a57600080fd5b50610467614d39565b34801561101f57600080fd5b5061040560048035600160a060020a03169060248035908101910135614d48565b34801561104c57600080fd5b5061040560048035600160a060020a03169060248035908101910135614fa6565b34801561107957600080fd5b506104986150de565b34801561108e57600080fd5b506104676150e3565b3480156110a357600080fd5b5061040560043560243561ffff604435166150f2565b3480156110c557600080fd5b506104986004356024356151ab565b3480156110e057600080fd5b50610498615229565b3480156110f557600080fd5b5061046761522f565b34801561110a57600080fd5b5061111660043561523e565b6040805160ff9092168252519081900360200190f35b34801561113857600080fd5b50610467615265565b604080517f737570706f727473496e74657266616365286279746573342900000000000000815290519081900360190190206000907bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19838116911614806113cc5750604080517f746f6b656e4d657461646174612875696e743235362c737472696e67290000008152815190819003601d0181207f746f6b656e734f664f776e657228616464726573732900000000000000000000825282519182900360160182207f7472616e7366657246726f6d28616464726573732c616464726573732c75696e83527f7432353629000000000000000000000000000000000000000000000000000000602084015283519283900360250183207f7472616e7366657228616464726573732c75696e743235362900000000000000845284519384900360190184207f617070726f766528616464726573732c75696e74323536290000000000000000855285519485900360180185207f6f776e65724f662875696e743235362900000000000000000000000000000000865286519586900360100186207f62616c616e63654f662861646472657373290000000000000000000000000000875287519687900360120187207f746f74616c537570706c792829000000000000000000000000000000000000008852885197889003600d0188207f73796d626f6c2829000000000000000000000000000000000000000000000000895289519889900360080189207f6e616d65282900000000000000000000000000000000000000000000000000008a529951988990036006019098207bffffffffffffffffffffffffffffffffffffffffffffffffffffffff198c811691909a189098181818181818181891909116145b92915050565b600154600160a060020a031681565b60175481565b60408051808201909152600b81527f4574686572506f6e696573000000000000000000000000000000000000000000602082015281565b60065460ff161561142e57600080fd5b6114383384615274565b151561144357600080fd5b60135461145a908490600160a060020a0316615294565b601354604080517ff444c1360000000000000000000000000000000000000000000000000000000081526004810186905233602482015261ffff84166044820152606481018590529051600160a060020a039092169163f444c1369160848082019260009290919082900301818387803b1580156114d757600080fd5b505af11580156114eb573d6000803e3d6000fd5b50505050505050565b60065460ff161561150457600080fd5b61150e3382615274565b151561151957600080fd5b6115238183615294565b60408051338152600160a060020a038416602082015280820183905290517f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b9259181900360600190a15050565b600054600160a060020a031681565b60008054600160a060020a0316331461159657600080fd5b81905080600160a060020a03166358be0f5c6040518163ffffffff1660e060020a028152600401602060405180830381600087803b1580156115d757600080fd5b505af11580156115eb573d6000803e3d6000fd5b505050506040513d602081101561160157600080fd5b5051151561160e57600080fd5b60138054600160a060020a031916600160a060020a039290921691909117905550565b600254600090600160a060020a03163314806116575750600054600160a060020a031633145b8061166c5750600154600160a060020a031633145b151561167757600080fd5b600160a060020a0384161580159061169d5750600054600160a060020a03858116911614155b80156116b75750600254600160a060020a03858116911614155b15156116c257600080fd5b336000908152600560205260409020546116dd908590611769565b90506117198184848080601f016020809104026020016040519081016040528093929190818152602001838380828437506152c2945050505050565b151561172457600080fd5b5050336000908152600560205260409020805460019081019091558054600160a060020a031916600160a060020a039390931692909217825550600480549091019055565b604080517f486a0e9500000000000000000000000000000000000000000000000000000000602080830191909152606060020a600160a060020a0386160260248301526038808301859052835180840390910181526058909201928390528151600093918291908401908083835b602083106117f65780518252601f1990920191602091820191016117d7565b5181516020939093036101000a600019018019909116921691909117905260405192018290039091209695505050505050565b60008054600160a060020a0316331461184157600080fd5b81905080600160a060020a03166376190f8f6040518163ffffffff1660e060020a028152600401602060405180830381600087803b15801561188257600080fd5b505af1158015611896573d6000803e3d6000fd5b505050506040513d60208110156118ac57600080fd5b505115156118b957600080fd5b60128054600160a060020a031916600160a060020a039290921691909117905550565b600b546000190190565b60008060008060606000865160411415156119045760009550611aa6565b61190d87615373565b90965094509250601b60ff8416101561192757601b830192505b8260ff16601b1415801561193f57508260ff16601c14155b1561194d5760009550611aa6565b6040805190810160405280601c81526020017f19457468657265756d205369676e6564204d6573736167653a0a333200000000815250915081886040516020018083805190602001908083835b602083106119b95780518252601f19909201916020918201910161199a565b51815160209384036101000a600019018019909216911617905292019384525060408051808503815293820190819052835193945092839250908401908083835b60208310611a195780518252601f1990920191602091820191016119fa565b51815160209384036101000a600019018019909216911617905260408051929094018290038220600080845283830180875282905260ff8b1684870152606084018d9052608084018c905294519097506001965060a080840196509194601f19820194509281900390910191865af1158015611a99573d6000803e3d6000fd5b5050506020604051035195505b505050505092915050565b6000808211611abf57600080fd5b600b805483908110611acd57fe5b600091825260209091206003909102016001015460c060020a900463ffffffff16151592915050565b600654600090819060ff1615611b0b57600080fd5b611b15338c615274565b1515611b2057600080fd5b611b298b61409a565b1515611b3457600080fd5b611b3e8b8d614b78565b1515611b4957600080fd5b601254604080517fc55d0f56000000000000000000000000000000000000000000000000000000008152600481018f90529051600160a060020a039092169163c55d0f56916024808201926020929091908290030181600087803b158015611bb057600080fd5b505af1158015611bc4573d6000803e3d6000fd5b505050506040513d6020811015611bda57600080fd5b5051601454909250341015611bee57600080fd5b81871015611bfb57600080fd5b601260009054906101000a9004600160a060020a0316600160a060020a031663d64dc79f8d89898989896040518763ffffffff1660e060020a028152600401808781526020018681526020018581526020018060200183815260200182810382528585828181526020019250808284378201915050975050505050505050600060405180830381600087803b158015611c9357600080fd5b505af1158015611ca7573d6000803e3d6000fd5b505050508960ff166000148015611ccd57503360009081526010602052604090205460ff165b15611ce257611cdd8b8d8c6153ac565b611d95565b33600081815260056020526040902054611cfe91908c90613463565b9050611d3a818a8a8080601f016020809104026020016040519081016040528093929190818152602001838380828437506154ec945050505050565b1515611d4557600080fd5b33600090815260056020908152604080832080546001019055601090915290205460ff161515611d8a57336000908152601060205260409020805460ff191660011790555b611d958b8d8c6153ac565b505050505050505050505050565b601254600160a060020a031681565b60065460ff1615611dc257600080fd5b600160a060020a0382161515611dd757600080fd5b600160a060020a038216301415611ded57600080fd5b611df73382615529565b1515611e0257600080fd5b611e0c8382615274565b1515611e1757600080fd5b611e22838383615549565b505050565b60008054600160a060020a03163314611e3f57600080fd5b81905080600160a060020a03166354c15b826040518163ffffffff1660e060020a028152600401602060405180830381600087803b158015611e8057600080fd5b505af1158015611e94573d6000803e3d6000fd5b505050506040513d6020811015611eaa57600080fd5b50511515611eb757600080fd5b60168054600160a060020a031916600160a060020a039290921691909117905550565b600254600090600160a060020a03163314611ef457600080fd5b60185461135611611f0457600080fd5b60008054611f229190819081908990600160a060020a03168261562b565b601354909150611f3c908290600160a060020a0316615294565b8115611fdf5760135460008054604080517ff444c13600000000000000000000000000000000000000000000000000000000815260048101869052600160a060020a03928316602482015261ffff88166044820152606481018990529051919093169263f444c13692608480830193919282900301818387803b158015611fc257600080fd5b505af1158015611fd6573d6000803e3d6000fd5b50505050612078565b60135460008054604080517f855c95f100000000000000000000000000000000000000000000000000000000815260048101869052600160a060020a03928316602482015261ffff88166044820152606481018990529051919093169263855c95f192608480830193919282900301818387803b15801561205f57600080fd5b505af1158015612073573d6000803e3d6000fd5b505050505b5050601880546001019055505050565b60155481565b601354600160a060020a031681565b600080600160a060020a03851615156120b557600080fd5b6120c130868686612bca565b91506120cd82876118e6565b9050600160a060020a03811615156120e457600080fd5b600160a060020a0385163014156120fa57600080fd5b6121048185615274565b151561210f57600080fd5b600160a060020a038116600090815260056020526040902080546001019055612139818686615549565b505050505050565b60106020526000908152604090205460ff1681565b6000806000806000806000806000806000806000600b8e81548110151561217957fe5b906000526020600020906003020190508060010160189054906101000a900463ffffffff1663ffffffff16600014159c50438160010160089054906101000a900467ffffffffffffffff1667ffffffffffffffff1611159b5080600101601c9054906101000a900461ffff1661ffff169a508060010160089054906101000a900467ffffffffffffffff1667ffffffffffffffff1699508060010160189054906101000a900463ffffffff1663ffffffff1698508060010160009054906101000a900467ffffffffffffffff1667ffffffffffffffff1697508060010160109054906101000a900463ffffffff1663ffffffff1696508060010160149054906101000a900463ffffffff1663ffffffff16955080600101601e9054906101000a900461ffff1661ffff169450806000015493508060020160009054906101000a900461ffff1692508060020160029054906101000a900460ff1691505091939597999b5091939597999b565b600254600090600160a060020a031633148061230b5750600054600160a060020a031633145b806123205750600154600160a060020a031633145b151561232b57600080fd5b600160a060020a038416158015906123515750600054600160a060020a03858116911614155b801561236b5750600154600160a060020a03858116911614155b151561237657600080fd5b33600090815260056020526040902054612391908590613611565b90506123cd8184848080601f016020809104026020016040519081016040528093929190818152602001838380828437506152c2945050505050565b15156123d857600080fd5b50503360009081526005602052604090208054600190810190915560028054600160a060020a031916600160a060020a03949094169390931790925550600480549091019055565b600254600160a060020a03163314806124435750600054600160a060020a031633145b806124585750600154600160a060020a031633145b151561246357600080fd5b601254604080517fa4f0d9b100000000000000000000000000000000000000000000000000000000815260048101859052602481018490529051600160a060020a039092169163a4f0d9b19160448082019260009290919082900301818387803b1580156124d057600080fd5b505af1158015612139573d6000803e3d6000fd5b600054600160a060020a031633146124fb57600080fd5b60065460ff16151561250c57600080fd5b601654600160a060020a0316151561252357600080fd5b601954600160a060020a03161561253957600080fd5b612541615925565b565b600254600090600160a060020a03163314806125695750600054600160a060020a031633145b8061257e5750600154600160a060020a031633145b151561258957600080fd5b336000908152600560205260409020546125a4908590614503565b90506125e08184848080601f016020809104026020016040519081016040528093929190818152602001838380828437506152c2945050505050565b15156125eb57600080fd5b50503360009081526005602052604090208054600101905550601a8054600160a060020a031916600160a060020a0392909216919091179055565b600254600160a060020a03163314806126495750600054600160a060020a031633145b8061265e5750600154600160a060020a031633145b151561266957600080fd5b601354604080517fa4f0d9b100000000000000000000000000000000000000000000000000000000815260048101859052602481018490529051600160a060020a039092169163a4f0d9b19160448082019260009290919082900301818387803b1580156124d057600080fd5b600254600160a060020a031633146126ed57600080fd5b601455565b600f60205260009081526040902054600160a060020a031681565b60008080600160a060020a038616151561272657600080fd5b61273230878787612d7e565b915061273e82886118e6565b9050600160a060020a038116151561275557600080fd5b61275f8186615274565b151561276a57600080fd5b600160a060020a0381166000908152600560205260409020805460010190556127938587615294565b60408051600160a060020a0380841682528816602082015280820187905290517f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b9259181900360600190a15060019695505050505050565b60065460ff16156127fa57600080fd5b6128043382615274565b151561280f57600080fd5b6000908152600f602052604090208054600160a060020a031916600160a060020a0392909216919091179055565b604080517f486a0e9400000000000000000000000000000000000000000000000000000000602080830191909152606060020a600160a060020a038616026024830152603880830185905283518084039091018152605890920192839052815160009391829190840190808383602083106117f65780518252601f1990920191602091820191016117d7565b600654600090819060ff16156128de57600080fd5b6128e83387615274565b15156128f357600080fd5b6128fc8661409a565b151561290757600080fd5b6129118688614b78565b151561291c57600080fd5b601254604080517fc55d0f56000000000000000000000000000000000000000000000000000000008152600481018a90529051600160a060020a039092169163c55d0f56916024808201926020929091908290030181600087803b15801561298357600080fd5b505af1158015612997573d6000803e3d6000fd5b505050506040513d60208110156129ad57600080fd5b505160145490925082013410156129c357600080fd5b601254601454604080517f55c623c6000000000000000000000000000000000000000000000000000000008152600481018b90529051600160a060020a03909316926355c623c69234039160248082019260009290919082900301818588803b158015612a2f57600080fd5b505af1158015612a43573d6000803e3d6000fd5b50505050508460ff166000148015612a6a57503360009081526010602052604090205460ff165b15612a7f57612a7a8688876153ac565b6114eb565b33600081815260056020526040902054612a9b91908790613463565b9050612ad78185858080601f016020809104026020016040519081016040528093929190818152602001838380828437506154ec945050505050565b1515612ae257600080fd5b33600090815260056020908152604080832080546001019055601090915290205460ff161515612b2757336000908152601060205260409020805460ff191660011790555b6114eb8688876153ac565b600160a060020a031660009081526005602052604090205490565b60045481565b600254600160a060020a0316331480612b765750600054600160a060020a031633145b80612b8b5750600154600160a060020a031633145b1515612b9657600080fd5b60075463ffffffff168110612baa57600080fd5b600a55565b600e60205260009081526040902054600160a060020a031681565b604080517f486a0e9700000000000000000000000000000000000000000000000000000000602080830191909152606060020a600160a060020a03808916820260248501528716026038830152604c8201859052606c80830185905283518084039091018152608c909201928390528151600093918291908401908083835b60208310612c685780518252601f199092019160209182019101612c49565b6001836020036101000a038019825116818451168082178552505050505050905001915050604051809103902090505b949350505050565b600254600160a060020a0316331480612cc35750600054600160a060020a031633145b80612cd85750600154600160a060020a031633145b1515612ce357600080fd5b601654604080517f5c80b44800000000000000000000000000000000000000000000000000000000815283151560048201529051600160a060020a0390921691635c80b448916024808201926020929091908290030181600087803b158015612d4b57600080fd5b505af1158015612d5f573d6000803e3d6000fd5b505050506040513d6020811015611e2257600080fd5b60065460ff1681565b6000848484846040516020018085600160a060020a0316600160a060020a0316606060020a02815260140184600160a060020a0316600160a060020a0316606060020a02815260140183815260200182815260200194505050505060405160208183030381529060405260405180828051906020019080838360208310612c685780518252601f199092019160209182019101612c49565b6000908152600c6020526040902054600160a060020a031690565b60065460ff1615612e4157600080fd5b612e4b3383615274565b1515612e5657600080fd5b612e5f82611ab1565b15612e6957600080fd5b601154612e80908390600160a060020a0316615294565b601154604080517f3cc1429c00000000000000000000000000000000000000000000000000000000815260048101859052336024820152604481018490529051600160a060020a0390921691633cc1429c9160648082019260009290919082900301818387803b1580156124d057600080fd5b600254600160a060020a0316331480612f165750600054600160a060020a031633145b80612f2b5750600154600160a060020a031633145b1515612f3657600080fd5b601160009054906101000a9004600160a060020a0316600160a060020a0316632c9d69896040518163ffffffff1660e060020a028152600401600060405180830381600087803b158015612f8957600080fd5b505af1158015612f9d573d6000803e3d6000fd5b50505050601260009054906101000a9004600160a060020a0316600160a060020a0316632c9d69896040518163ffffffff1660e060020a028152600401600060405180830381600087803b158015612ff457600080fd5b505af1158015613008573d6000803e3d6000fd5b50505050601360009054906101000a9004600160a060020a0316600160a060020a0316632c9d69896040518163ffffffff1660e060020a028152600401600060405180830381600087803b15801561305f57600080fd5b505af1158015613073573d6000803e3d6000fd5b50505050565b6006546000908190819060ff161561309057600080fd5b60145434101561309f57600080fd5b6130a93389615274565b15156130b457600080fd5b6130be8789615959565b15156130c957600080fd5b600b8054899081106130d757fe5b60009182526020918290206040805161014081018252600390930290910180548352600181015467ffffffffffffffff808216958501959095526801000000000000000081049094169183019190915263ffffffff608060020a84048116606084015260a060020a84048116608084015260c060020a84041660a083015261ffff60e060020a8404811660c084015260f060020a909304831660e0830152600281015492831661010083015260ff62010000909304929092166101208201529093506131a2906159ae565b15156131ad57600080fd5b600b8054889081106131bb57fe5b60009182526020918290206040805161014081018252600390930290910180548352600181015467ffffffffffffffff808216958501959095526801000000000000000081049094169183019190915263ffffffff608060020a84048116606084015260a060020a84048116608084015260c060020a84041660a083015261ffff60e060020a8404811660c084015260f060020a909304831660e0830152600281015492831661010083015260ff6201000090930492909216610120820152909250613286906159ae565b151561329157600080fd5b61329d8389848a6159dd565b15156132a857600080fd5b60ff86161580156132c857503360009081526010602052604090205460ff165b156132dd576132d88888886153ac565b613390565b336000818152600560205260409020546132f991908890613463565b90506133358186868080601f016020809104026020016040519081016040528093929190818152602001838380828437506154ec945050505050565b151561334057600080fd5b33600090815260056020908152604080832080546001019055601090915290205460ff16151561338557336000908152601060205260409020805460ff191660011790555b6133908888886153ac565b5050505050505050565b61135681565b60065460ff16156133b057600080fd5b6133ba3383615274565b15156133c557600080fd5b6133ce8261409a565b15156133d957600080fd5b6012546133f0908390600160a060020a0316615294565b601254604080517f3cc1429c00000000000000000000000000000000000000000000000000000000815260048101859052336024820152604481018490529051600160a060020a0390921691633cc1429c9160648082019260009290919082900301818387803b1580156124d057600080fd5b604080517f486a0e9800000000000000000000000000000000000000000000000000000000602080830191909152606060020a600160a060020a0387160260248301527f010000000000000000000000000000000000000000000000000000000000000060ff86160260388301526039808301859052835180840390910181526059909201928390528151600093918291908401908083835b6020831061351b5780518252601f1990920191602091820191016134fc565b5181516020939093036101000a60001901801990911692169190911790526040519201829003909120979650505050505050565b601954600160a060020a031681565b60008054600160a060020a0316331461357657600080fd5b81905080600160a060020a03166385b861886040518163ffffffff1660e060020a028152600401602060405180830381600087803b1580156135b757600080fd5b505af11580156135cb573d6000803e3d6000fd5b505050506040513d60208110156135e157600080fd5b505115156135ee57600080fd5b60118054600160a060020a031916600160a060020a039290921691909117905550565b604080517f486a0e9600000000000000000000000000000000000000000000000000000000602080830191909152606060020a600160a060020a038616026024830152603880830185905283518084039091018152605890920192839052815160009391829190840190808383602083106117f65780518252601f1990920191602091820191016117d7565b600160a060020a03166000908152600d602052604090205490565b600054600160a060020a031633146136cf57600080fd5b60065460ff1615156136e057600080fd5b60198054600160a060020a038316600160a060020a0319909116811790915560408051918252517f450db8da6efbe9c22f2347f7c2021231df1fc58d3ae9a2fa75d39fa4461993059181900360200190a150565b600254600090600160a060020a0316331461374e57600080fd5b5080600160a060020a038116151561376e5750600254600160a060020a03165b60175460321161377d57600080fd5b6017805460010190556130736000808086858261562b565b600654600090819060ff16156137aa57600080fd5b6012546137c3903090600160a060020a03168986612d7e565b91506137ff8286868080601f016020809104026020016040519081016040528093929190818152602001838380828437506118e6945050505050565b905061380b8188615274565b151561381657600080fd5b61381f87611ab1565b1561382957600080fd5b61387385858080601f0160208091040260200160405190810160405280939291908181526020018383808284375050601254600160a060020a031693508c925088915061270d9050565b506012546040805160e160020a63784b82b3028152600481018a9052600160a060020a038481166024830152604482018a90529151919092169163f097056691606480830192600092919082900301818387803b1580156138d357600080fd5b505af11580156138e7573d6000803e3d6000fd5b5050505050505050505050565b600a5481565b60025460009081908190600160a060020a03163314806139245750600054600160a060020a031633145b806139395750600154600160a060020a031633145b151561394457600080fd5b3360009081526005602052604090205461395f908790613c4b565b925061399b8386868080601f016020809104026020016040519081016040528093929190818152602001838380828437506152c2945050505050565b15156139a657600080fd5b5050601454601554303191600190910102600082116139c457600080fd5b8082116139d057600080fd5b336000908152600560205260408082208054600101905551600160a060020a0388169183850380156108fc02929091818181858888f19350505050158015613a1c573d6000803e3d6000fd5b5060408051600160a060020a0388168152828403602082015281517ff6663f3a481158d6f283c86728a24ad396cc25b1727313f59164456209eaba39929181900390910190a1505050505050565b600254600160a060020a0316331480613a8d5750600054600160a060020a031633145b80613aa25750600154600160a060020a031633145b1515613aad57600080fd5b60065460ff1615613abd57600080fd5b6006805460ff19166001179055565b6060600060606000806000613ae08761369d565b9450841515613aff576040805160008152602081019091529550613b94565b84604051908082528060200260200182016040528015613b29578160200160208202803883390190505b509350613b346118dc565b925060009150600190505b828111613b90576000818152600c6020526040902054600160a060020a0388811691161415613b8857808483815181101515613b7757fe5b602090810290910101526001909101905b600101613b3f565b8395505b5050505050919050565b60065460ff1615613bae57600080fd5b613bb83383615274565b1515613bc357600080fd5b613bcc8261409a565b1515613bd757600080fd5b601254613bee908390600160a060020a0316615294565b6012546040805160e160020a63784b82b302815260048101859052336024820152604481018490529051600160a060020a039092169163f09705669160648082019260009290919082900301818387803b1580156124d057600080fd5b604080517f486a121700000000000000000000000000000000000000000000000000000000602080830191909152606060020a600160a060020a038616026024830152603880830185905283518084039091018152605890920192839052815160009391829190840190808383602083106117f65780518252601f1990920191602091820191016117d7565b6000806000806000806000806000600660009054906101000a900460ff16151515613d0157600080fd5b600b80548b908110613d0f57fe5b60009182526020909120600390910201600181015490985067ffffffffffffffff161515613d3c57600080fd5b60408051610140810182528954815260018a015467ffffffffffffffff80821660208401526801000000000000000082041692820192909252608060020a820463ffffffff908116606083015260a060020a83048116608083015260c060020a83041660a082015260e060020a820461ffff90811660c083015260f060020a909204821660e082015260028a01549182166101008201526201000090910460ff16610120820152613dec90615b5c565b1515613df757600080fd5b6001880154600b805460c060020a90920463ffffffff1698509088908110613e1b57fe5b600091825260209091206001808b015460039093029091019081015490975061ffff60f060020a928390048116975091900416851015613e6857600186015460f060020a900461ffff1694505b6016548854875460018b0154604080517f0d9f5aed0000000000000000000000000000000000000000000000000000000081526004810194909452602484019290925260001967ffffffffffffffff6801000000000000000090920482160116604483015251600160a060020a0390921691630d9f5aed916064808201926020929091908290030181600087803b158015613f0257600080fd5b505af1158015613f16573d6000803e3d6000fd5b505050506040513d6020811015613f2c57600080fd5b5051601654604080517f798b3ecf00000000000000000000000000000000000000000000000000000000815261ffff60018a011660048201524360248201529051929650600160a060020a039091169163798b3ecf916044808201926020929091908290030181600087803b158015613fa457600080fd5b505af1158015613fb8573d6000803e3d6000fd5b505050506040513d6020811015613fce57600080fd5b50519250600d61ffff84161115613fe457600d92505b60008a8152600c6020526040902054600189810154600160a060020a039092169350614029918c9160c060020a90910463ffffffff1690880161ffff1687868861562b565b6001890180547bffffffff0000000000000000000000000000000000000000000000001916905560158054600019019055601454604051919250339181156108fc0291906000818181858888f1935050505015801561408c573d6000803e3d6000fd5b509998505050505050505050565b6000808083116140a957600080fd5b600b8054849081106140b757fe5b60009182526020918290206040805161014081018252600390930290910180548352600181015467ffffffffffffffff808216958501959095526801000000000000000081049094169183019190915263ffffffff608060020a84048116606084015260a060020a84048116608084015260c060020a84041660a083015261ffff60e060020a8404811660c084015260f060020a909304831660e0830152600281015492831661010083015260ff6201000090930492909216610120820152909150614182906159ae565b9392505050565b600254600160a060020a03163314806141ac5750600054600160a060020a031633145b806141c15750600154600160a060020a031633145b15156141cc57600080fd5b601160009054906101000a9004600160a060020a0316600160a060020a0316635fd8c7106040518163ffffffff1660e060020a028152600401600060405180830381600087803b15801561421f57600080fd5b505af1158015614233573d6000803e3d6000fd5b50505050601260009054906101000a9004600160a060020a0316600160a060020a0316635fd8c7106040518163ffffffff1660e060020a028152600401600060405180830381600087803b15801561428a57600080fd5b505af115801561429e573d6000803e3d6000fd5b50505050601360009054906101000a9004600160a060020a0316600160a060020a0316635fd8c7106040518163ffffffff1660e060020a028152600401600060405180830381600087803b15801561305f57600080fd5b60408051808201909152600281527f4550000000000000000000000000000000000000000000000000000000000000602082015281565b600c60205260009081526040902054600160a060020a031681565b600781600a811061435457fe5b60089182820401919006600402915054906101000a900463ffffffff1681565b600254600160a060020a03163314806143975750600054600160a060020a031633145b806143ac5750600154600160a060020a031633145b15156143b757600080fd5b601154604080517fa4f0d9b100000000000000000000000000000000000000000000000000000000815260048101859052602481018490529051600160a060020a039092169163a4f0d9b19160448082019260009290919082900301818387803b1580156124d057600080fd5b6000808080851161443457600080fd5b6000841161444157600080fd5b600b80548690811061444f57fe5b90600052602060002090600302019150600b8481548110151561446e57fe5b9060005260206000209060030201905061448a828683876159dd565b801561449b575061449b8486615959565b95945050505050565b60065460ff16156144b457600080fd5b600160a060020a03821615156144c957600080fd5b600160a060020a0382163014156144df57600080fd5b6144e93382615274565b15156144f457600080fd5b6144ff338383615549565b5050565b604080517f486a121600000000000000000000000000000000000000000000000000000000602080830191909152606060020a600160a060020a038616026024830152603880830185905283518084039091018152605890920192839052815160009391829190840190808383602083106117f65780518252601f1990920191602091820191016117d7565b60065460ff161561459f57600080fd5b6145a93383615274565b15156145b457600080fd5b6145bd82611ab1565b156145c757600080fd5b6011546145de908390600160a060020a0316615294565b6011546040805160e160020a63784b82b302815260048101859052336024820152604481018490529051600160a060020a039092169163f09705669160648082019260009290919082900301818387803b1580156124d057600080fd5b600654600090819060ff161561465057600080fd5b601154614669903090600160a060020a03168986612d7e565b91506146a58286868080601f016020809104026020016040519081016040528093929190818152602001838380828437506118e6945050505050565b90506146b18188615274565b15156146bc57600080fd5b6146c587611ab1565b156146cf57600080fd5b61471985858080601f0160208091040260200160405190810160405280939291908181526020018383808284375050601154600160a060020a031693508c925088915061270d9050565b506011546040805160e160020a63784b82b3028152600481018a9052600160a060020a038481166024830152604482018a90529151919092169163f097056691606480830192600092919082900301818387803b1580156138d357600080fd5b600254600160a060020a031681565b60145481565b600654600090819060ff16156147a357600080fd5b6147ad3387615274565b15156147b857600080fd5b858514156147c557600080fd5b600b8054879081106147d357fe5b6000918252602090912060039091020160028101549092506147fa90879061ffff166151ab565b90506148368185858080601f016020809104026020016040519081016040528093929190818152602001838380828437506154ec945050505050565b151561484157600080fd5b60028201805461ffff8082166001011661ffff19909116179081905560ff62010000909104161515614988576016546002830154604080517fd84391650000000000000000000000000000000000000000000000000000000081526201000090920460ff16600483015243602483015251600160a060020a039092169163d8439165916044808201926020929091908290030181600087803b1580156148e657600080fd5b505af11580156148fa573d6000803e3d6000fd5b505050506040513d602081101561491057600080fd5b5051156149835760028201805460ff6201000080830482166001018216810262ff0000199093169290921792839055604080518a8152602081018a905292909304168183015290517f9c3d8a5e222c3d2e6294b2d6c81634dd021ddf882e85a12a86d10a3273113ef59181900360600190a15b612139565b600282015460006201000090910460ff161115612139576149a93386615274565b15156149b457600080fd5b6016546002830154604080517fd84391650000000000000000000000000000000000000000000000000000000081526201000090920460ff16600483015243602483015251600160a060020a039092169163d8439165916044808201926020929091908290030181600087803b158015614a2d57600080fd5b505af1158015614a41573d6000803e3d6000fd5b505050506040513d6020811015614a5757600080fd5b505115614adf5760028201805460ff6201000080830482166001019091160262ff000019909116179055614a8d33600087615549565b600282015460408051888152602081018890526201000090920460ff1682820152517f9c3d8a5e222c3d2e6294b2d6c81634dd021ddf882e85a12a86d10a3273113ef5916060908290030190a1612139565b60028281015462010000900460ff1614156121395760028201805460ff6201000080830482166001019091160262ff000019909116179055614b2333600087615549565b600282015460408051888152602081018890526201000090920460ff1682820152517f9c3d8a5e222c3d2e6294b2d6c81634dd021ddf882e85a12a86d10a3273113ef5916060908290030190a1505050505050565b6000806000600b85815481101515614b8c57fe5b90600052602060002090600302019150600b84815481101515614bab57fe5b9060005260206000209060030201905061449b828683876159dd565b600654600090819060ff1615614bdc57600080fd5b601354614bf5903090600160a060020a03168a87612d7e565b9150614c318287878080601f016020809104026020016040519081016040528093929190818152602001838380828437506118e6945050505050565b9050614c3d8189615274565b1515614c4857600080fd5b614c5188611ab1565b15614c5b57600080fd5b614ca586868080601f0160208091040260200160405190810160405280939291908181526020018383808284375050601354600160a060020a031693508d925089915061270d9050565b50601354604080517ff444c136000000000000000000000000000000000000000000000000000000008152600481018b9052600160a060020a03848116602483015261ffff87166044830152606482018b90529151919092169163f444c13691608480830192600092919082900301818387803b158015614d2557600080fd5b505af1158015611d95573d6000803e3d6000fd5b600354600160a060020a031681565b601a546000908190600160a060020a03161515614d6457600080fd5b600254600160a060020a0316331480614d875750600054600160a060020a031633145b80614d9c5750600154600160a060020a031633145b1515614da757600080fd5b33600090815260056020526040902054614dc2908690613c4b565b9150614dfe8285858080601f016020809104026020016040519081016040528093929190818152602001838380828437506152c2945050505050565b1515614e0957600080fd5b601a54604080517f70a082310000000000000000000000000000000000000000000000000000000081523060048201529051600160a060020a03909216916370a08231916024808201926020929091908290030181600087803b158015614e6f57600080fd5b505af1158015614e83573d6000803e3d6000fd5b505050506040513d6020811015614e9957600080fd5b5051905060008111614eaa57600080fd5b33600090815260056020908152604080832080546001019055601a5481517fa9059cbb000000000000000000000000000000000000000000000000000000008152600160a060020a038a81166004830152602482018790529251919092169363a9059cbb93604480850194919392918390030190829087803b158015614f2f57600080fd5b505af1158015614f43573d6000803e3d6000fd5b505050506040513d6020811015614f5957600080fd5b505060408051600160a060020a03871681526020810183905281517fcde0786b7d75316f133e800fb41120f51ed4307805bf4581a1d6ce38b9d2be67929181900390910190a15050505050565b600254600090600160a060020a0316331480614fcc5750600054600160a060020a031633145b80614fe15750600154600160a060020a031633145b1515614fec57600080fd5b600160a060020a038416158015906150125750600154600160a060020a03858116911614155b801561502c5750600254600160a060020a03858116911614155b151561503757600080fd5b3360009081526005602052604090205461505290859061283d565b905061508e8184848080601f016020809104026020016040519081016040528093929190818152602001838380828437506152c2945050505050565b151561509957600080fd5b5050336000908152600560205260408120805460019081019091558154600160a060020a031916600160a060020a039490941693909317905550600480549091019055565b603281565b601154600160a060020a031681565b60065460ff161561510257600080fd5b61510c3384615274565b151561511757600080fd5b60135461512e908490600160a060020a0316615294565b601354604080517f855c95f10000000000000000000000000000000000000000000000000000000081526004810186905233602482015261ffff84166044820152606481018590529051600160a060020a039092169163855c95f19160848082019260009290919082900301818387803b1580156114d757600080fd5b604080517f486a0e9d0000000000000000000000000000000000000000000000000000000060208083019190915260248201859052604480830185905283518084039091018152606490920192839052815160009391829190840190808383602083106117f65780518252601f1990920191602091820191016117d7565b60185481565b601654600160a060020a031681565b6009816005811061524b57fe5b60209182820401919006915054906101000a900460ff1681565b601a54600160a060020a031681565b6000908152600c6020526040902054600160a060020a0391821691161490565b6000918252600e60205260409091208054600160a060020a031916600160a060020a03909216919091179055565b6002546000908190600160a060020a03163314806152ea5750600054600160a060020a031633145b806152ff5750600154600160a060020a031633145b151561530a57600080fd5b61531484846118e6565b9050600160a060020a03811633141561532c57600080fd5b600254600160a060020a03828116911614806153555750600054600160a060020a038281169116145b80612c985750600154600160a060020a039081169116149392505050565b6000806000806000808651604114151561538c57600080fd5b505050506020830151604084015160609094015160001a94909392509050565b600080600b848154811015156153be57fe5b90600052602060002090600302019150600b858154811015156153dd57fe5b600091825260209091206003909102016001810180547bffffffff000000000000000000000000000000000000000000000000191660c060020a63ffffffff881602179055905061542d82615b8c565b6154378184615c74565b6000858152600f602090815260408083208054600160a060020a031990811690915587845281842080549091169055601580546001908101909155888452600c83529281902054928401548151600160a060020a0390941684529183018890528281018790526801000000000000000090910467ffffffffffffffff166060830152517f241ea03ca20251805084d27d4440371c34a0b85ff108f6bb5611248f73818b80916080908290030190a15050505050565b6000806154f984846118e6565b9050600160a060020a03811633141561551157600080fd5b600354600160a060020a039081169116149392505050565b6000908152600e6020526040902054600160a060020a0391821691161490565b600160a060020a038083166000818152600d6020908152604080832080546001019055858352600c90915290208054600160a060020a03191690911790558316156155dc57600160a060020a0383166000908152600d602090815260408083208054600019019055838352600f82528083208054600160a060020a0319908116909155600e909252909120805490911690555b60408051600160a060020a0380861682528416602082015280820183905290517fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef9181900360600190a1505050565b6000615635615e2c565b600063ffffffff8916891461564957600080fd5b63ffffffff8816881461565b57600080fd5b61ffff8716871461566b57600080fd5b610140604051908101604052808781526020014267ffffffffffffffff168152602001600067ffffffffffffffff1681526020018a63ffffffff1681526020018963ffffffff168152602001600063ffffffff1681526020018561ffff1681526020018861ffff168152602001600061ffff168152602001600060ff1681525091506001600b83908060018154018082558091505090600182039060005260206000209060030201600090919290919091506000820151816000015560208201518160010160006101000a81548167ffffffffffffffff021916908367ffffffffffffffff16021790555060408201518160010160086101000a81548167ffffffffffffffff021916908367ffffffffffffffff16021790555060608201518160010160106101000a81548163ffffffff021916908363ffffffff16021790555060808201518160010160146101000a81548163ffffffff021916908363ffffffff16021790555060a08201518160010160186101000a81548163ffffffff021916908363ffffffff16021790555060c082015181600101601c6101000a81548161ffff021916908361ffff16021790555060e082015181600101601e6101000a81548161ffff021916908361ffff1602179055506101008201518160020160006101000a81548161ffff021916908361ffff1602179055506101208201518160020160026101000a81548160ff021916908360ff16021790555050500390508063ffffffff168114151561589f57600080fd5b606080830151608080850151855160408051600160a060020a038c1681526020810188905263ffffffff95861681830152929094169482019490945290810192909252517f0a5311bd2a6608f08a180df2ee7c5946819a649b204b554bb8e39825b2c50ad59181900360a00190a161591960008683615549565b98975050505050505050565b600054600160a060020a0316331461593c57600080fd5b60065460ff16151561594d57600080fd5b6006805460ff19169055565b6000818152600c60205260408082205484835290822054600160a060020a0391821691168082148061449b57506000858152600f6020526040902054600160a060020a03908116908316149250505092915050565b60008160a0015163ffffffff1660001480156113cc5750506040015167ffffffffffffffff4381169116111590565b6000818414156159ef57506000612c98565b6001850154608060020a900463ffffffff16821480615a1e5750600185015460a060020a900463ffffffff1682145b15615a2b57506000612c98565b6001830154608060020a900463ffffffff16841480615a5a5750600183015460a060020a900463ffffffff1684145b15615a6757506000612c98565b6001830154608060020a900463ffffffff161580615a9457506001850154608060020a900463ffffffff16155b15615aa157506001612c98565b60018581015490840154608060020a9182900463ffffffff90811692909104161480615aec575060018086015490840154608060020a900463ffffffff90811660a060020a90920416145b15615af957506000612c98565b6001808601549084015460a060020a900463ffffffff908116608060020a909204161480615b4457506001858101549084015460a060020a9182900463ffffffff9081169290910416145b15615b5157506000612c98565b506001949350505050565b60008160a0015163ffffffff166000141580156113cc5750506040015167ffffffffffffffff4381169116111590565b600a80546001830154439260079160e060020a900461ffff16908110615bae57fe5b600891828204019190066004029054906101000a900463ffffffff1663ffffffff16811515615bd957fe5b6001840180546fffffffffffffffff0000000000000000191668010000000000000000939092049390930167ffffffffffffffff16919091021790819055600d60e060020a90910461ffff161015615c71576001818101805461ffff60e060020a8083048216909401169092027fffff0000ffffffffffffffffffffffffffffffffffffffffffffffffffffffff9092169190911790555b50565b6000808260ff161115615d4f57600a80546001850154909160079160e060020a900461ffff16908110615ca357fe5b600891828204019190066004029054906101000a900463ffffffff1663ffffffff16811515615cce57fe5b049050436064600960ff851660058110615ce457fe5b602091828204019190069054906101000a900460ff1660ff16830267ffffffffffffffff16811515615d1257fe5b04820367ffffffffffffffff16018360010160086101000a81548167ffffffffffffffff021916908367ffffffffffffffff160217905550615dc9565b600a80546001850154439260079160e060020a900461ffff16908110615d7157fe5b600891828204019190066004029054906101000a900463ffffffff1663ffffffff16811515615d9c57fe5b04018360010160086101000a81548167ffffffffffffffff021916908367ffffffffffffffff1602179055505b6001830154600d60e060020a90910461ffff161015611e22576001838101805461ffff60e060020a8083048216909401169092027fffff0000ffffffffffffffffffffffffffffffffffffffffffffffffffffffff909216919091179055505050565b6040805161014081018252600080825260208201819052918101829052606081018290526080810182905260a0810182905260c0810182905260e081018290526101008101829052610120810191909152905600a165627a7a723058204323d9b9c7dbfbae8c1c79260dbe7e723a4c4f6ac76370ae01a35d30e8c343ba00290000000000000000000000007aeaf9c8a62caf79c60b0eeb1e57eaefc140a5ca0000000000000000000000005425a1ca8b650ccfe0620fd10fe6e3dc46f0211d000000000000000000000000d75c77816c83537a6bb97819398fc2694e2e1478000000000000000000000000315fb673a6fa8720cf0341795faad602061d1267000000000000000000000000a98e0024db4a1720a301f464c4dabf685e34d078

Deployed Bytecode

0x6080604052600436106104055763ffffffff60e060020a60003504166301ffc9a781146104075780630519ce791461045257806305e455461461048357806306fdde03146104aa57806308ec651f14610534578063095ea7b3146105565780630a0f81681461057a5780630a7782e91461058f5780630bf2c50d146105b05780630ee85800146105dd57806314001f4c1461060157806318160ddd1461062257806319045a25146106375780631940a936146106955780631c0acbd5146106ad57806321717ebf146106e657806323b872dd146106fb57806324e7a38a146107255780632fd95a6f14610746578063304b01901461076d578063313424b61461078257806333d764a2146107975780633618ef6d1461080557806336917dfa1461082657806336c4db09146108a65780633c771309146108d35780633f4ba83a146108ee5780634b16304f146109035780634b6a8604146109305780634b85fd551461094b5780634ba081cf146109635780634c167a6e1461097b5780634dfff04f146109e95780634eaef8a214610a0d5780635041742a14610a315780635124ae9514610a5357806355381f0014610a745780635663896e14610a8957806359d71a2414610aa15780635c4b4c1214610ab95780635c80b44814610ae65780635c975abb14610b005780635dac48bb14610b155780636352211e14610b42578063656d309114610b5a578063664d862914610b7557806366a6cf1a14610b8a578063680eba2714610bac5780636973cf5814610bc15780636a23e30814610bdc5780636af04a5714610c065780636fbde40d14610c1b5780637039368614610c3c57806370a0823114610c605780637158798814610c8157806375776fa414610ca257806375a5ba8014610cc65780637a7d493714610cf15780638165913d14610d065780638456cb5914610d335780638462151c14610d4857806384a429a014610db95780638760d65d14610dd457806388c2a0bf14610df857806389eb313a14610e1057806391876e5714610e2857806395d89b4114610e3d5780639892a87114610e525780639d6fac6f14610e6a5780639dbfe1b814610e9b578063a2dd9dd314610eb6578063a9059cbb14610ed1578063abcb7fce14610ef5578063abd05acd14610f19578063abd936ab14610f34578063b047fb5014610f5f578063b0c35c0514610f74578063c56b2dc214610f89578063c7d9630414610fb1578063d15b95b414610fcc578063d3e848f114610ffe578063d831b71414611013578063d9194fcb14611040578063defb95841461106d578063e6cbe35114611082578063e928ad4714611097578063f12acca2146110b9578063f1ca9410146110d4578063f2b47d52146110e9578063f89309f2146110fe578063fc0c546a1461112c575b005b34801561041357600080fd5b5061043e7bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1960043516611141565b604080519115158252519081900360200190f35b34801561045e57600080fd5b506104676113d2565b60408051600160a060020a039092168252519081900360200190f35b34801561048f57600080fd5b506104986113e1565b60408051918252519081900360200190f35b3480156104b657600080fd5b506104bf6113e7565b6040805160208082528351818301528351919283929083019185019080838360005b838110156104f95781810151838201526020016104e1565b50505050905090810190601f1680156105265780820380516001836020036101000a031916815260200191505b509250505060405180910390f35b34801561054057600080fd5b5061040560043560243561ffff6044351661141e565b34801561056257600080fd5b50610405600160a060020a03600435166024356114f4565b34801561058657600080fd5b5061046761156f565b34801561059b57600080fd5b50610405600160a060020a036004351661157e565b3480156105bc57600080fd5b5061040560048035600160a060020a03169060248035908101910135611631565b3480156105e957600080fd5b50610498600160a060020a0360043516602435611769565b34801561060d57600080fd5b50610405600160a060020a0360043516611829565b34801561062e57600080fd5b506104986118dc565b34801561064357600080fd5b5060408051602060046024803582810135601f81018590048502860185019096528585526104679583359536956044949193909101919081908401838280828437509497506118e69650505050505050565b3480156106a157600080fd5b5061043e600435611ab1565b6104056004803590602480359160ff60443516916064358082019290810135916084359160a4359160c43590810191013560e435611af6565b3480156106f257600080fd5b50610467611da3565b34801561070757600080fd5b50610405600160a060020a0360043581169060243516604435611db2565b34801561073157600080fd5b50610405600160a060020a0360043516611e27565b34801561075257600080fd5b5061040560043560243561ffff604435166064351515611eda565b34801561077957600080fd5b50610498612088565b34801561078e57600080fd5b5061046761208e565b3480156107a357600080fd5b506040805160206004803580820135601f810184900484028501840190955284845261040594369492936024939284019190819084018382808284375094975050508335600160a060020a03169450505060208201359160400135905061209d565b34801561081157600080fd5b5061043e600160a060020a0360043516612141565b34801561083257600080fd5b5061083e600435612156565b604080519c15158d529a151560208d01528b8b019990995260608b019790975260808a019590955260a089019390935260c088019190915260e087015261010086015261012085015261ffff1661014084015260ff1661016083015251908190036101800190f35b3480156108b257600080fd5b5061040560048035600160a060020a031690602480359081019101356122e5565b3480156108df57600080fd5b50610405600435602435612420565b3480156108fa57600080fd5b506104056124e4565b34801561090f57600080fd5b5061040560048035600160a060020a03169060248035908101910135612543565b34801561093c57600080fd5b50610405600435602435612626565b34801561095757600080fd5b506104056004356126d6565b34801561096f57600080fd5b506104676004356126f2565b34801561098757600080fd5b506040805160206004803580820135601f810184900484028501840190955284845261043e94369492936024939284019190819084018382808284375094975050508335600160a060020a03169450505060208201359160400135905061270d565b3480156109f557600080fd5b50610405600160a060020a03600435166024356127ea565b348015610a1957600080fd5b50610498600160a060020a036004351660243561283d565b6104056004803590602480359160ff60443516916064359081019101356128c9565b348015610a5f57600080fd5b50610498600160a060020a0360043516612b32565b348015610a8057600080fd5b50610498612b4d565b348015610a9557600080fd5b50610405600435612b53565b348015610aad57600080fd5b50610467600435612baf565b348015610ac557600080fd5b50610498600160a060020a0360043581169060243516604435606435612bca565b348015610af257600080fd5b506104056004351515612ca0565b348015610b0c57600080fd5b5061043e612d75565b348015610b2157600080fd5b50610498600160a060020a0360043581169060243516604435606435612d7e565b348015610b4e57600080fd5b50610467600435612e16565b348015610b6657600080fd5b50610405600435602435612e31565b348015610b8157600080fd5b50610405612ef3565b6104056004803590602480359160ff6044351691606435908101910135613079565b348015610bb857600080fd5b5061049861339a565b348015610bcd57600080fd5b506104056004356024356133a0565b348015610be857600080fd5b50610498600160a060020a036004351660ff60243516604435613463565b348015610c1257600080fd5b5061046761354f565b348015610c2757600080fd5b50610405600160a060020a036004351661355e565b348015610c4857600080fd5b50610498600160a060020a0360043516602435613611565b348015610c6c57600080fd5b50610498600160a060020a036004351661369d565b348015610c8d57600080fd5b50610405600160a060020a03600435166136b8565b348015610cae57600080fd5b50610405600435600160a060020a0360243516613734565b348015610cd257600080fd5b5061040560048035906024803591604435918201910135606435613795565b348015610cfd57600080fd5b506104986138f4565b348015610d1257600080fd5b5061040560048035600160a060020a031690602480359081019101356138fa565b348015610d3f57600080fd5b50610405613a6a565b348015610d5457600080fd5b50610d69600160a060020a0360043516613acc565b60408051602080825283518183015283519192839290830191858101910280838360005b83811015610da5578181015183820152602001610d8d565b505050509050019250505060405180910390f35b348015610dc557600080fd5b50610405600435602435613b9e565b348015610de057600080fd5b50610498600160a060020a0360043516602435613c4b565b348015610e0457600080fd5b50610498600435613cd7565b348015610e1c57600080fd5b5061043e60043561409a565b348015610e3457600080fd5b50610405614189565b348015610e4957600080fd5b506104bf6142f5565b348015610e5e57600080fd5b5061046760043561432c565b348015610e7657600080fd5b50610e82600435614347565b6040805163ffffffff9092168252519081900360200190f35b348015610ea757600080fd5b50610405600435602435614374565b348015610ec257600080fd5b5061043e600435602435614424565b348015610edd57600080fd5b50610405600160a060020a03600435166024356144a4565b348015610f0157600080fd5b50610498600160a060020a0360043516602435614503565b348015610f2557600080fd5b5061040560043560243561458f565b348015610f4057600080fd5b506104056004803590602480359160443591820191013560643561463b565b348015610f6b57600080fd5b50610467614779565b348015610f8057600080fd5b50610498614788565b348015610f9557600080fd5b506104056004803590602480359160443591820191013561478e565b348015610fbd57600080fd5b5061043e600435602435614b78565b348015610fd857600080fd5b506104056004803590602480359160443591820191013560643561ffff60843516614bc7565b34801561100a57600080fd5b50610467614d39565b34801561101f57600080fd5b5061040560048035600160a060020a03169060248035908101910135614d48565b34801561104c57600080fd5b5061040560048035600160a060020a03169060248035908101910135614fa6565b34801561107957600080fd5b506104986150de565b34801561108e57600080fd5b506104676150e3565b3480156110a357600080fd5b5061040560043560243561ffff604435166150f2565b3480156110c557600080fd5b506104986004356024356151ab565b3480156110e057600080fd5b50610498615229565b3480156110f557600080fd5b5061046761522f565b34801561110a57600080fd5b5061111660043561523e565b6040805160ff9092168252519081900360200190f35b34801561113857600080fd5b50610467615265565b604080517f737570706f727473496e74657266616365286279746573342900000000000000815290519081900360190190206000907bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19838116911614806113cc5750604080517f746f6b656e4d657461646174612875696e743235362c737472696e67290000008152815190819003601d0181207f746f6b656e734f664f776e657228616464726573732900000000000000000000825282519182900360160182207f7472616e7366657246726f6d28616464726573732c616464726573732c75696e83527f7432353629000000000000000000000000000000000000000000000000000000602084015283519283900360250183207f7472616e7366657228616464726573732c75696e743235362900000000000000845284519384900360190184207f617070726f766528616464726573732c75696e74323536290000000000000000855285519485900360180185207f6f776e65724f662875696e743235362900000000000000000000000000000000865286519586900360100186207f62616c616e63654f662861646472657373290000000000000000000000000000875287519687900360120187207f746f74616c537570706c792829000000000000000000000000000000000000008852885197889003600d0188207f73796d626f6c2829000000000000000000000000000000000000000000000000895289519889900360080189207f6e616d65282900000000000000000000000000000000000000000000000000008a529951988990036006019098207bffffffffffffffffffffffffffffffffffffffffffffffffffffffff198c811691909a189098181818181818181891909116145b92915050565b600154600160a060020a031681565b60175481565b60408051808201909152600b81527f4574686572506f6e696573000000000000000000000000000000000000000000602082015281565b60065460ff161561142e57600080fd5b6114383384615274565b151561144357600080fd5b60135461145a908490600160a060020a0316615294565b601354604080517ff444c1360000000000000000000000000000000000000000000000000000000081526004810186905233602482015261ffff84166044820152606481018590529051600160a060020a039092169163f444c1369160848082019260009290919082900301818387803b1580156114d757600080fd5b505af11580156114eb573d6000803e3d6000fd5b50505050505050565b60065460ff161561150457600080fd5b61150e3382615274565b151561151957600080fd5b6115238183615294565b60408051338152600160a060020a038416602082015280820183905290517f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b9259181900360600190a15050565b600054600160a060020a031681565b60008054600160a060020a0316331461159657600080fd5b81905080600160a060020a03166358be0f5c6040518163ffffffff1660e060020a028152600401602060405180830381600087803b1580156115d757600080fd5b505af11580156115eb573d6000803e3d6000fd5b505050506040513d602081101561160157600080fd5b5051151561160e57600080fd5b60138054600160a060020a031916600160a060020a039290921691909117905550565b600254600090600160a060020a03163314806116575750600054600160a060020a031633145b8061166c5750600154600160a060020a031633145b151561167757600080fd5b600160a060020a0384161580159061169d5750600054600160a060020a03858116911614155b80156116b75750600254600160a060020a03858116911614155b15156116c257600080fd5b336000908152600560205260409020546116dd908590611769565b90506117198184848080601f016020809104026020016040519081016040528093929190818152602001838380828437506152c2945050505050565b151561172457600080fd5b5050336000908152600560205260409020805460019081019091558054600160a060020a031916600160a060020a039390931692909217825550600480549091019055565b604080517f486a0e9500000000000000000000000000000000000000000000000000000000602080830191909152606060020a600160a060020a0386160260248301526038808301859052835180840390910181526058909201928390528151600093918291908401908083835b602083106117f65780518252601f1990920191602091820191016117d7565b5181516020939093036101000a600019018019909116921691909117905260405192018290039091209695505050505050565b60008054600160a060020a0316331461184157600080fd5b81905080600160a060020a03166376190f8f6040518163ffffffff1660e060020a028152600401602060405180830381600087803b15801561188257600080fd5b505af1158015611896573d6000803e3d6000fd5b505050506040513d60208110156118ac57600080fd5b505115156118b957600080fd5b60128054600160a060020a031916600160a060020a039290921691909117905550565b600b546000190190565b60008060008060606000865160411415156119045760009550611aa6565b61190d87615373565b90965094509250601b60ff8416101561192757601b830192505b8260ff16601b1415801561193f57508260ff16601c14155b1561194d5760009550611aa6565b6040805190810160405280601c81526020017f19457468657265756d205369676e6564204d6573736167653a0a333200000000815250915081886040516020018083805190602001908083835b602083106119b95780518252601f19909201916020918201910161199a565b51815160209384036101000a600019018019909216911617905292019384525060408051808503815293820190819052835193945092839250908401908083835b60208310611a195780518252601f1990920191602091820191016119fa565b51815160209384036101000a600019018019909216911617905260408051929094018290038220600080845283830180875282905260ff8b1684870152606084018d9052608084018c905294519097506001965060a080840196509194601f19820194509281900390910191865af1158015611a99573d6000803e3d6000fd5b5050506020604051035195505b505050505092915050565b6000808211611abf57600080fd5b600b805483908110611acd57fe5b600091825260209091206003909102016001015460c060020a900463ffffffff16151592915050565b600654600090819060ff1615611b0b57600080fd5b611b15338c615274565b1515611b2057600080fd5b611b298b61409a565b1515611b3457600080fd5b611b3e8b8d614b78565b1515611b4957600080fd5b601254604080517fc55d0f56000000000000000000000000000000000000000000000000000000008152600481018f90529051600160a060020a039092169163c55d0f56916024808201926020929091908290030181600087803b158015611bb057600080fd5b505af1158015611bc4573d6000803e3d6000fd5b505050506040513d6020811015611bda57600080fd5b5051601454909250341015611bee57600080fd5b81871015611bfb57600080fd5b601260009054906101000a9004600160a060020a0316600160a060020a031663d64dc79f8d89898989896040518763ffffffff1660e060020a028152600401808781526020018681526020018581526020018060200183815260200182810382528585828181526020019250808284378201915050975050505050505050600060405180830381600087803b158015611c9357600080fd5b505af1158015611ca7573d6000803e3d6000fd5b505050508960ff166000148015611ccd57503360009081526010602052604090205460ff165b15611ce257611cdd8b8d8c6153ac565b611d95565b33600081815260056020526040902054611cfe91908c90613463565b9050611d3a818a8a8080601f016020809104026020016040519081016040528093929190818152602001838380828437506154ec945050505050565b1515611d4557600080fd5b33600090815260056020908152604080832080546001019055601090915290205460ff161515611d8a57336000908152601060205260409020805460ff191660011790555b611d958b8d8c6153ac565b505050505050505050505050565b601254600160a060020a031681565b60065460ff1615611dc257600080fd5b600160a060020a0382161515611dd757600080fd5b600160a060020a038216301415611ded57600080fd5b611df73382615529565b1515611e0257600080fd5b611e0c8382615274565b1515611e1757600080fd5b611e22838383615549565b505050565b60008054600160a060020a03163314611e3f57600080fd5b81905080600160a060020a03166354c15b826040518163ffffffff1660e060020a028152600401602060405180830381600087803b158015611e8057600080fd5b505af1158015611e94573d6000803e3d6000fd5b505050506040513d6020811015611eaa57600080fd5b50511515611eb757600080fd5b60168054600160a060020a031916600160a060020a039290921691909117905550565b600254600090600160a060020a03163314611ef457600080fd5b60185461135611611f0457600080fd5b60008054611f229190819081908990600160a060020a03168261562b565b601354909150611f3c908290600160a060020a0316615294565b8115611fdf5760135460008054604080517ff444c13600000000000000000000000000000000000000000000000000000000815260048101869052600160a060020a03928316602482015261ffff88166044820152606481018990529051919093169263f444c13692608480830193919282900301818387803b158015611fc257600080fd5b505af1158015611fd6573d6000803e3d6000fd5b50505050612078565b60135460008054604080517f855c95f100000000000000000000000000000000000000000000000000000000815260048101869052600160a060020a03928316602482015261ffff88166044820152606481018990529051919093169263855c95f192608480830193919282900301818387803b15801561205f57600080fd5b505af1158015612073573d6000803e3d6000fd5b505050505b5050601880546001019055505050565b60155481565b601354600160a060020a031681565b600080600160a060020a03851615156120b557600080fd5b6120c130868686612bca565b91506120cd82876118e6565b9050600160a060020a03811615156120e457600080fd5b600160a060020a0385163014156120fa57600080fd5b6121048185615274565b151561210f57600080fd5b600160a060020a038116600090815260056020526040902080546001019055612139818686615549565b505050505050565b60106020526000908152604090205460ff1681565b6000806000806000806000806000806000806000600b8e81548110151561217957fe5b906000526020600020906003020190508060010160189054906101000a900463ffffffff1663ffffffff16600014159c50438160010160089054906101000a900467ffffffffffffffff1667ffffffffffffffff1611159b5080600101601c9054906101000a900461ffff1661ffff169a508060010160089054906101000a900467ffffffffffffffff1667ffffffffffffffff1699508060010160189054906101000a900463ffffffff1663ffffffff1698508060010160009054906101000a900467ffffffffffffffff1667ffffffffffffffff1697508060010160109054906101000a900463ffffffff1663ffffffff1696508060010160149054906101000a900463ffffffff1663ffffffff16955080600101601e9054906101000a900461ffff1661ffff169450806000015493508060020160009054906101000a900461ffff1692508060020160029054906101000a900460ff1691505091939597999b5091939597999b565b600254600090600160a060020a031633148061230b5750600054600160a060020a031633145b806123205750600154600160a060020a031633145b151561232b57600080fd5b600160a060020a038416158015906123515750600054600160a060020a03858116911614155b801561236b5750600154600160a060020a03858116911614155b151561237657600080fd5b33600090815260056020526040902054612391908590613611565b90506123cd8184848080601f016020809104026020016040519081016040528093929190818152602001838380828437506152c2945050505050565b15156123d857600080fd5b50503360009081526005602052604090208054600190810190915560028054600160a060020a031916600160a060020a03949094169390931790925550600480549091019055565b600254600160a060020a03163314806124435750600054600160a060020a031633145b806124585750600154600160a060020a031633145b151561246357600080fd5b601254604080517fa4f0d9b100000000000000000000000000000000000000000000000000000000815260048101859052602481018490529051600160a060020a039092169163a4f0d9b19160448082019260009290919082900301818387803b1580156124d057600080fd5b505af1158015612139573d6000803e3d6000fd5b600054600160a060020a031633146124fb57600080fd5b60065460ff16151561250c57600080fd5b601654600160a060020a0316151561252357600080fd5b601954600160a060020a03161561253957600080fd5b612541615925565b565b600254600090600160a060020a03163314806125695750600054600160a060020a031633145b8061257e5750600154600160a060020a031633145b151561258957600080fd5b336000908152600560205260409020546125a4908590614503565b90506125e08184848080601f016020809104026020016040519081016040528093929190818152602001838380828437506152c2945050505050565b15156125eb57600080fd5b50503360009081526005602052604090208054600101905550601a8054600160a060020a031916600160a060020a0392909216919091179055565b600254600160a060020a03163314806126495750600054600160a060020a031633145b8061265e5750600154600160a060020a031633145b151561266957600080fd5b601354604080517fa4f0d9b100000000000000000000000000000000000000000000000000000000815260048101859052602481018490529051600160a060020a039092169163a4f0d9b19160448082019260009290919082900301818387803b1580156124d057600080fd5b600254600160a060020a031633146126ed57600080fd5b601455565b600f60205260009081526040902054600160a060020a031681565b60008080600160a060020a038616151561272657600080fd5b61273230878787612d7e565b915061273e82886118e6565b9050600160a060020a038116151561275557600080fd5b61275f8186615274565b151561276a57600080fd5b600160a060020a0381166000908152600560205260409020805460010190556127938587615294565b60408051600160a060020a0380841682528816602082015280820187905290517f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b9259181900360600190a15060019695505050505050565b60065460ff16156127fa57600080fd5b6128043382615274565b151561280f57600080fd5b6000908152600f602052604090208054600160a060020a031916600160a060020a0392909216919091179055565b604080517f486a0e9400000000000000000000000000000000000000000000000000000000602080830191909152606060020a600160a060020a038616026024830152603880830185905283518084039091018152605890920192839052815160009391829190840190808383602083106117f65780518252601f1990920191602091820191016117d7565b600654600090819060ff16156128de57600080fd5b6128e83387615274565b15156128f357600080fd5b6128fc8661409a565b151561290757600080fd5b6129118688614b78565b151561291c57600080fd5b601254604080517fc55d0f56000000000000000000000000000000000000000000000000000000008152600481018a90529051600160a060020a039092169163c55d0f56916024808201926020929091908290030181600087803b15801561298357600080fd5b505af1158015612997573d6000803e3d6000fd5b505050506040513d60208110156129ad57600080fd5b505160145490925082013410156129c357600080fd5b601254601454604080517f55c623c6000000000000000000000000000000000000000000000000000000008152600481018b90529051600160a060020a03909316926355c623c69234039160248082019260009290919082900301818588803b158015612a2f57600080fd5b505af1158015612a43573d6000803e3d6000fd5b50505050508460ff166000148015612a6a57503360009081526010602052604090205460ff165b15612a7f57612a7a8688876153ac565b6114eb565b33600081815260056020526040902054612a9b91908790613463565b9050612ad78185858080601f016020809104026020016040519081016040528093929190818152602001838380828437506154ec945050505050565b1515612ae257600080fd5b33600090815260056020908152604080832080546001019055601090915290205460ff161515612b2757336000908152601060205260409020805460ff191660011790555b6114eb8688876153ac565b600160a060020a031660009081526005602052604090205490565b60045481565b600254600160a060020a0316331480612b765750600054600160a060020a031633145b80612b8b5750600154600160a060020a031633145b1515612b9657600080fd5b60075463ffffffff168110612baa57600080fd5b600a55565b600e60205260009081526040902054600160a060020a031681565b604080517f486a0e9700000000000000000000000000000000000000000000000000000000602080830191909152606060020a600160a060020a03808916820260248501528716026038830152604c8201859052606c80830185905283518084039091018152608c909201928390528151600093918291908401908083835b60208310612c685780518252601f199092019160209182019101612c49565b6001836020036101000a038019825116818451168082178552505050505050905001915050604051809103902090505b949350505050565b600254600160a060020a0316331480612cc35750600054600160a060020a031633145b80612cd85750600154600160a060020a031633145b1515612ce357600080fd5b601654604080517f5c80b44800000000000000000000000000000000000000000000000000000000815283151560048201529051600160a060020a0390921691635c80b448916024808201926020929091908290030181600087803b158015612d4b57600080fd5b505af1158015612d5f573d6000803e3d6000fd5b505050506040513d6020811015611e2257600080fd5b60065460ff1681565b6000848484846040516020018085600160a060020a0316600160a060020a0316606060020a02815260140184600160a060020a0316600160a060020a0316606060020a02815260140183815260200182815260200194505050505060405160208183030381529060405260405180828051906020019080838360208310612c685780518252601f199092019160209182019101612c49565b6000908152600c6020526040902054600160a060020a031690565b60065460ff1615612e4157600080fd5b612e4b3383615274565b1515612e5657600080fd5b612e5f82611ab1565b15612e6957600080fd5b601154612e80908390600160a060020a0316615294565b601154604080517f3cc1429c00000000000000000000000000000000000000000000000000000000815260048101859052336024820152604481018490529051600160a060020a0390921691633cc1429c9160648082019260009290919082900301818387803b1580156124d057600080fd5b600254600160a060020a0316331480612f165750600054600160a060020a031633145b80612f2b5750600154600160a060020a031633145b1515612f3657600080fd5b601160009054906101000a9004600160a060020a0316600160a060020a0316632c9d69896040518163ffffffff1660e060020a028152600401600060405180830381600087803b158015612f8957600080fd5b505af1158015612f9d573d6000803e3d6000fd5b50505050601260009054906101000a9004600160a060020a0316600160a060020a0316632c9d69896040518163ffffffff1660e060020a028152600401600060405180830381600087803b158015612ff457600080fd5b505af1158015613008573d6000803e3d6000fd5b50505050601360009054906101000a9004600160a060020a0316600160a060020a0316632c9d69896040518163ffffffff1660e060020a028152600401600060405180830381600087803b15801561305f57600080fd5b505af1158015613073573d6000803e3d6000fd5b50505050565b6006546000908190819060ff161561309057600080fd5b60145434101561309f57600080fd5b6130a93389615274565b15156130b457600080fd5b6130be8789615959565b15156130c957600080fd5b600b8054899081106130d757fe5b60009182526020918290206040805161014081018252600390930290910180548352600181015467ffffffffffffffff808216958501959095526801000000000000000081049094169183019190915263ffffffff608060020a84048116606084015260a060020a84048116608084015260c060020a84041660a083015261ffff60e060020a8404811660c084015260f060020a909304831660e0830152600281015492831661010083015260ff62010000909304929092166101208201529093506131a2906159ae565b15156131ad57600080fd5b600b8054889081106131bb57fe5b60009182526020918290206040805161014081018252600390930290910180548352600181015467ffffffffffffffff808216958501959095526801000000000000000081049094169183019190915263ffffffff608060020a84048116606084015260a060020a84048116608084015260c060020a84041660a083015261ffff60e060020a8404811660c084015260f060020a909304831660e0830152600281015492831661010083015260ff6201000090930492909216610120820152909250613286906159ae565b151561329157600080fd5b61329d8389848a6159dd565b15156132a857600080fd5b60ff86161580156132c857503360009081526010602052604090205460ff165b156132dd576132d88888886153ac565b613390565b336000818152600560205260409020546132f991908890613463565b90506133358186868080601f016020809104026020016040519081016040528093929190818152602001838380828437506154ec945050505050565b151561334057600080fd5b33600090815260056020908152604080832080546001019055601090915290205460ff16151561338557336000908152601060205260409020805460ff191660011790555b6133908888886153ac565b5050505050505050565b61135681565b60065460ff16156133b057600080fd5b6133ba3383615274565b15156133c557600080fd5b6133ce8261409a565b15156133d957600080fd5b6012546133f0908390600160a060020a0316615294565b601254604080517f3cc1429c00000000000000000000000000000000000000000000000000000000815260048101859052336024820152604481018490529051600160a060020a0390921691633cc1429c9160648082019260009290919082900301818387803b1580156124d057600080fd5b604080517f486a0e9800000000000000000000000000000000000000000000000000000000602080830191909152606060020a600160a060020a0387160260248301527f010000000000000000000000000000000000000000000000000000000000000060ff86160260388301526039808301859052835180840390910181526059909201928390528151600093918291908401908083835b6020831061351b5780518252601f1990920191602091820191016134fc565b5181516020939093036101000a60001901801990911692169190911790526040519201829003909120979650505050505050565b601954600160a060020a031681565b60008054600160a060020a0316331461357657600080fd5b81905080600160a060020a03166385b861886040518163ffffffff1660e060020a028152600401602060405180830381600087803b1580156135b757600080fd5b505af11580156135cb573d6000803e3d6000fd5b505050506040513d60208110156135e157600080fd5b505115156135ee57600080fd5b60118054600160a060020a031916600160a060020a039290921691909117905550565b604080517f486a0e9600000000000000000000000000000000000000000000000000000000602080830191909152606060020a600160a060020a038616026024830152603880830185905283518084039091018152605890920192839052815160009391829190840190808383602083106117f65780518252601f1990920191602091820191016117d7565b600160a060020a03166000908152600d602052604090205490565b600054600160a060020a031633146136cf57600080fd5b60065460ff1615156136e057600080fd5b60198054600160a060020a038316600160a060020a0319909116811790915560408051918252517f450db8da6efbe9c22f2347f7c2021231df1fc58d3ae9a2fa75d39fa4461993059181900360200190a150565b600254600090600160a060020a0316331461374e57600080fd5b5080600160a060020a038116151561376e5750600254600160a060020a03165b60175460321161377d57600080fd5b6017805460010190556130736000808086858261562b565b600654600090819060ff16156137aa57600080fd5b6012546137c3903090600160a060020a03168986612d7e565b91506137ff8286868080601f016020809104026020016040519081016040528093929190818152602001838380828437506118e6945050505050565b905061380b8188615274565b151561381657600080fd5b61381f87611ab1565b1561382957600080fd5b61387385858080601f0160208091040260200160405190810160405280939291908181526020018383808284375050601254600160a060020a031693508c925088915061270d9050565b506012546040805160e160020a63784b82b3028152600481018a9052600160a060020a038481166024830152604482018a90529151919092169163f097056691606480830192600092919082900301818387803b1580156138d357600080fd5b505af11580156138e7573d6000803e3d6000fd5b5050505050505050505050565b600a5481565b60025460009081908190600160a060020a03163314806139245750600054600160a060020a031633145b806139395750600154600160a060020a031633145b151561394457600080fd5b3360009081526005602052604090205461395f908790613c4b565b925061399b8386868080601f016020809104026020016040519081016040528093929190818152602001838380828437506152c2945050505050565b15156139a657600080fd5b5050601454601554303191600190910102600082116139c457600080fd5b8082116139d057600080fd5b336000908152600560205260408082208054600101905551600160a060020a0388169183850380156108fc02929091818181858888f19350505050158015613a1c573d6000803e3d6000fd5b5060408051600160a060020a0388168152828403602082015281517ff6663f3a481158d6f283c86728a24ad396cc25b1727313f59164456209eaba39929181900390910190a1505050505050565b600254600160a060020a0316331480613a8d5750600054600160a060020a031633145b80613aa25750600154600160a060020a031633145b1515613aad57600080fd5b60065460ff1615613abd57600080fd5b6006805460ff19166001179055565b6060600060606000806000613ae08761369d565b9450841515613aff576040805160008152602081019091529550613b94565b84604051908082528060200260200182016040528015613b29578160200160208202803883390190505b509350613b346118dc565b925060009150600190505b828111613b90576000818152600c6020526040902054600160a060020a0388811691161415613b8857808483815181101515613b7757fe5b602090810290910101526001909101905b600101613b3f565b8395505b5050505050919050565b60065460ff1615613bae57600080fd5b613bb83383615274565b1515613bc357600080fd5b613bcc8261409a565b1515613bd757600080fd5b601254613bee908390600160a060020a0316615294565b6012546040805160e160020a63784b82b302815260048101859052336024820152604481018490529051600160a060020a039092169163f09705669160648082019260009290919082900301818387803b1580156124d057600080fd5b604080517f486a121700000000000000000000000000000000000000000000000000000000602080830191909152606060020a600160a060020a038616026024830152603880830185905283518084039091018152605890920192839052815160009391829190840190808383602083106117f65780518252601f1990920191602091820191016117d7565b6000806000806000806000806000600660009054906101000a900460ff16151515613d0157600080fd5b600b80548b908110613d0f57fe5b60009182526020909120600390910201600181015490985067ffffffffffffffff161515613d3c57600080fd5b60408051610140810182528954815260018a015467ffffffffffffffff80821660208401526801000000000000000082041692820192909252608060020a820463ffffffff908116606083015260a060020a83048116608083015260c060020a83041660a082015260e060020a820461ffff90811660c083015260f060020a909204821660e082015260028a01549182166101008201526201000090910460ff16610120820152613dec90615b5c565b1515613df757600080fd5b6001880154600b805460c060020a90920463ffffffff1698509088908110613e1b57fe5b600091825260209091206001808b015460039093029091019081015490975061ffff60f060020a928390048116975091900416851015613e6857600186015460f060020a900461ffff1694505b6016548854875460018b0154604080517f0d9f5aed0000000000000000000000000000000000000000000000000000000081526004810194909452602484019290925260001967ffffffffffffffff6801000000000000000090920482160116604483015251600160a060020a0390921691630d9f5aed916064808201926020929091908290030181600087803b158015613f0257600080fd5b505af1158015613f16573d6000803e3d6000fd5b505050506040513d6020811015613f2c57600080fd5b5051601654604080517f798b3ecf00000000000000000000000000000000000000000000000000000000815261ffff60018a011660048201524360248201529051929650600160a060020a039091169163798b3ecf916044808201926020929091908290030181600087803b158015613fa457600080fd5b505af1158015613fb8573d6000803e3d6000fd5b505050506040513d6020811015613fce57600080fd5b50519250600d61ffff84161115613fe457600d92505b60008a8152600c6020526040902054600189810154600160a060020a039092169350614029918c9160c060020a90910463ffffffff1690880161ffff1687868861562b565b6001890180547bffffffff0000000000000000000000000000000000000000000000001916905560158054600019019055601454604051919250339181156108fc0291906000818181858888f1935050505015801561408c573d6000803e3d6000fd5b509998505050505050505050565b6000808083116140a957600080fd5b600b8054849081106140b757fe5b60009182526020918290206040805161014081018252600390930290910180548352600181015467ffffffffffffffff808216958501959095526801000000000000000081049094169183019190915263ffffffff608060020a84048116606084015260a060020a84048116608084015260c060020a84041660a083015261ffff60e060020a8404811660c084015260f060020a909304831660e0830152600281015492831661010083015260ff6201000090930492909216610120820152909150614182906159ae565b9392505050565b600254600160a060020a03163314806141ac5750600054600160a060020a031633145b806141c15750600154600160a060020a031633145b15156141cc57600080fd5b601160009054906101000a9004600160a060020a0316600160a060020a0316635fd8c7106040518163ffffffff1660e060020a028152600401600060405180830381600087803b15801561421f57600080fd5b505af1158015614233573d6000803e3d6000fd5b50505050601260009054906101000a9004600160a060020a0316600160a060020a0316635fd8c7106040518163ffffffff1660e060020a028152600401600060405180830381600087803b15801561428a57600080fd5b505af115801561429e573d6000803e3d6000fd5b50505050601360009054906101000a9004600160a060020a0316600160a060020a0316635fd8c7106040518163ffffffff1660e060020a028152600401600060405180830381600087803b15801561305f57600080fd5b60408051808201909152600281527f4550000000000000000000000000000000000000000000000000000000000000602082015281565b600c60205260009081526040902054600160a060020a031681565b600781600a811061435457fe5b60089182820401919006600402915054906101000a900463ffffffff1681565b600254600160a060020a03163314806143975750600054600160a060020a031633145b806143ac5750600154600160a060020a031633145b15156143b757600080fd5b601154604080517fa4f0d9b100000000000000000000000000000000000000000000000000000000815260048101859052602481018490529051600160a060020a039092169163a4f0d9b19160448082019260009290919082900301818387803b1580156124d057600080fd5b6000808080851161443457600080fd5b6000841161444157600080fd5b600b80548690811061444f57fe5b90600052602060002090600302019150600b8481548110151561446e57fe5b9060005260206000209060030201905061448a828683876159dd565b801561449b575061449b8486615959565b95945050505050565b60065460ff16156144b457600080fd5b600160a060020a03821615156144c957600080fd5b600160a060020a0382163014156144df57600080fd5b6144e93382615274565b15156144f457600080fd5b6144ff338383615549565b5050565b604080517f486a121600000000000000000000000000000000000000000000000000000000602080830191909152606060020a600160a060020a038616026024830152603880830185905283518084039091018152605890920192839052815160009391829190840190808383602083106117f65780518252601f1990920191602091820191016117d7565b60065460ff161561459f57600080fd5b6145a93383615274565b15156145b457600080fd5b6145bd82611ab1565b156145c757600080fd5b6011546145de908390600160a060020a0316615294565b6011546040805160e160020a63784b82b302815260048101859052336024820152604481018490529051600160a060020a039092169163f09705669160648082019260009290919082900301818387803b1580156124d057600080fd5b600654600090819060ff161561465057600080fd5b601154614669903090600160a060020a03168986612d7e565b91506146a58286868080601f016020809104026020016040519081016040528093929190818152602001838380828437506118e6945050505050565b90506146b18188615274565b15156146bc57600080fd5b6146c587611ab1565b156146cf57600080fd5b61471985858080601f0160208091040260200160405190810160405280939291908181526020018383808284375050601154600160a060020a031693508c925088915061270d9050565b506011546040805160e160020a63784b82b3028152600481018a9052600160a060020a038481166024830152604482018a90529151919092169163f097056691606480830192600092919082900301818387803b1580156138d357600080fd5b600254600160a060020a031681565b60145481565b600654600090819060ff16156147a357600080fd5b6147ad3387615274565b15156147b857600080fd5b858514156147c557600080fd5b600b8054879081106147d357fe5b6000918252602090912060039091020160028101549092506147fa90879061ffff166151ab565b90506148368185858080601f016020809104026020016040519081016040528093929190818152602001838380828437506154ec945050505050565b151561484157600080fd5b60028201805461ffff8082166001011661ffff19909116179081905560ff62010000909104161515614988576016546002830154604080517fd84391650000000000000000000000000000000000000000000000000000000081526201000090920460ff16600483015243602483015251600160a060020a039092169163d8439165916044808201926020929091908290030181600087803b1580156148e657600080fd5b505af11580156148fa573d6000803e3d6000fd5b505050506040513d602081101561491057600080fd5b5051156149835760028201805460ff6201000080830482166001018216810262ff0000199093169290921792839055604080518a8152602081018a905292909304168183015290517f9c3d8a5e222c3d2e6294b2d6c81634dd021ddf882e85a12a86d10a3273113ef59181900360600190a15b612139565b600282015460006201000090910460ff161115612139576149a93386615274565b15156149b457600080fd5b6016546002830154604080517fd84391650000000000000000000000000000000000000000000000000000000081526201000090920460ff16600483015243602483015251600160a060020a039092169163d8439165916044808201926020929091908290030181600087803b158015614a2d57600080fd5b505af1158015614a41573d6000803e3d6000fd5b505050506040513d6020811015614a5757600080fd5b505115614adf5760028201805460ff6201000080830482166001019091160262ff000019909116179055614a8d33600087615549565b600282015460408051888152602081018890526201000090920460ff1682820152517f9c3d8a5e222c3d2e6294b2d6c81634dd021ddf882e85a12a86d10a3273113ef5916060908290030190a1612139565b60028281015462010000900460ff1614156121395760028201805460ff6201000080830482166001019091160262ff000019909116179055614b2333600087615549565b600282015460408051888152602081018890526201000090920460ff1682820152517f9c3d8a5e222c3d2e6294b2d6c81634dd021ddf882e85a12a86d10a3273113ef5916060908290030190a1505050505050565b6000806000600b85815481101515614b8c57fe5b90600052602060002090600302019150600b84815481101515614bab57fe5b9060005260206000209060030201905061449b828683876159dd565b600654600090819060ff1615614bdc57600080fd5b601354614bf5903090600160a060020a03168a87612d7e565b9150614c318287878080601f016020809104026020016040519081016040528093929190818152602001838380828437506118e6945050505050565b9050614c3d8189615274565b1515614c4857600080fd5b614c5188611ab1565b15614c5b57600080fd5b614ca586868080601f0160208091040260200160405190810160405280939291908181526020018383808284375050601354600160a060020a031693508d925089915061270d9050565b50601354604080517ff444c136000000000000000000000000000000000000000000000000000000008152600481018b9052600160a060020a03848116602483015261ffff87166044830152606482018b90529151919092169163f444c13691608480830192600092919082900301818387803b158015614d2557600080fd5b505af1158015611d95573d6000803e3d6000fd5b600354600160a060020a031681565b601a546000908190600160a060020a03161515614d6457600080fd5b600254600160a060020a0316331480614d875750600054600160a060020a031633145b80614d9c5750600154600160a060020a031633145b1515614da757600080fd5b33600090815260056020526040902054614dc2908690613c4b565b9150614dfe8285858080601f016020809104026020016040519081016040528093929190818152602001838380828437506152c2945050505050565b1515614e0957600080fd5b601a54604080517f70a082310000000000000000000000000000000000000000000000000000000081523060048201529051600160a060020a03909216916370a08231916024808201926020929091908290030181600087803b158015614e6f57600080fd5b505af1158015614e83573d6000803e3d6000fd5b505050506040513d6020811015614e9957600080fd5b5051905060008111614eaa57600080fd5b33600090815260056020908152604080832080546001019055601a5481517fa9059cbb000000000000000000000000000000000000000000000000000000008152600160a060020a038a81166004830152602482018790529251919092169363a9059cbb93604480850194919392918390030190829087803b158015614f2f57600080fd5b505af1158015614f43573d6000803e3d6000fd5b505050506040513d6020811015614f5957600080fd5b505060408051600160a060020a03871681526020810183905281517fcde0786b7d75316f133e800fb41120f51ed4307805bf4581a1d6ce38b9d2be67929181900390910190a15050505050565b600254600090600160a060020a0316331480614fcc5750600054600160a060020a031633145b80614fe15750600154600160a060020a031633145b1515614fec57600080fd5b600160a060020a038416158015906150125750600154600160a060020a03858116911614155b801561502c5750600254600160a060020a03858116911614155b151561503757600080fd5b3360009081526005602052604090205461505290859061283d565b905061508e8184848080601f016020809104026020016040519081016040528093929190818152602001838380828437506152c2945050505050565b151561509957600080fd5b5050336000908152600560205260408120805460019081019091558154600160a060020a031916600160a060020a039490941693909317905550600480549091019055565b603281565b601154600160a060020a031681565b60065460ff161561510257600080fd5b61510c3384615274565b151561511757600080fd5b60135461512e908490600160a060020a0316615294565b601354604080517f855c95f10000000000000000000000000000000000000000000000000000000081526004810186905233602482015261ffff84166044820152606481018590529051600160a060020a039092169163855c95f19160848082019260009290919082900301818387803b1580156114d757600080fd5b604080517f486a0e9d0000000000000000000000000000000000000000000000000000000060208083019190915260248201859052604480830185905283518084039091018152606490920192839052815160009391829190840190808383602083106117f65780518252601f1990920191602091820191016117d7565b60185481565b601654600160a060020a031681565b6009816005811061524b57fe5b60209182820401919006915054906101000a900460ff1681565b601a54600160a060020a031681565b6000908152600c6020526040902054600160a060020a0391821691161490565b6000918252600e60205260409091208054600160a060020a031916600160a060020a03909216919091179055565b6002546000908190600160a060020a03163314806152ea5750600054600160a060020a031633145b806152ff5750600154600160a060020a031633145b151561530a57600080fd5b61531484846118e6565b9050600160a060020a03811633141561532c57600080fd5b600254600160a060020a03828116911614806153555750600054600160a060020a038281169116145b80612c985750600154600160a060020a039081169116149392505050565b6000806000806000808651604114151561538c57600080fd5b505050506020830151604084015160609094015160001a94909392509050565b600080600b848154811015156153be57fe5b90600052602060002090600302019150600b858154811015156153dd57fe5b600091825260209091206003909102016001810180547bffffffff000000000000000000000000000000000000000000000000191660c060020a63ffffffff881602179055905061542d82615b8c565b6154378184615c74565b6000858152600f602090815260408083208054600160a060020a031990811690915587845281842080549091169055601580546001908101909155888452600c83529281902054928401548151600160a060020a0390941684529183018890528281018790526801000000000000000090910467ffffffffffffffff166060830152517f241ea03ca20251805084d27d4440371c34a0b85ff108f6bb5611248f73818b80916080908290030190a15050505050565b6000806154f984846118e6565b9050600160a060020a03811633141561551157600080fd5b600354600160a060020a039081169116149392505050565b6000908152600e6020526040902054600160a060020a0391821691161490565b600160a060020a038083166000818152600d6020908152604080832080546001019055858352600c90915290208054600160a060020a03191690911790558316156155dc57600160a060020a0383166000908152600d602090815260408083208054600019019055838352600f82528083208054600160a060020a0319908116909155600e909252909120805490911690555b60408051600160a060020a0380861682528416602082015280820183905290517fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef9181900360600190a1505050565b6000615635615e2c565b600063ffffffff8916891461564957600080fd5b63ffffffff8816881461565b57600080fd5b61ffff8716871461566b57600080fd5b610140604051908101604052808781526020014267ffffffffffffffff168152602001600067ffffffffffffffff1681526020018a63ffffffff1681526020018963ffffffff168152602001600063ffffffff1681526020018561ffff1681526020018861ffff168152602001600061ffff168152602001600060ff1681525091506001600b83908060018154018082558091505090600182039060005260206000209060030201600090919290919091506000820151816000015560208201518160010160006101000a81548167ffffffffffffffff021916908367ffffffffffffffff16021790555060408201518160010160086101000a81548167ffffffffffffffff021916908367ffffffffffffffff16021790555060608201518160010160106101000a81548163ffffffff021916908363ffffffff16021790555060808201518160010160146101000a81548163ffffffff021916908363ffffffff16021790555060a08201518160010160186101000a81548163ffffffff021916908363ffffffff16021790555060c082015181600101601c6101000a81548161ffff021916908361ffff16021790555060e082015181600101601e6101000a81548161ffff021916908361ffff1602179055506101008201518160020160006101000a81548161ffff021916908361ffff1602179055506101208201518160020160026101000a81548160ff021916908360ff16021790555050500390508063ffffffff168114151561589f57600080fd5b606080830151608080850151855160408051600160a060020a038c1681526020810188905263ffffffff95861681830152929094169482019490945290810192909252517f0a5311bd2a6608f08a180df2ee7c5946819a649b204b554bb8e39825b2c50ad59181900360a00190a161591960008683615549565b98975050505050505050565b600054600160a060020a0316331461593c57600080fd5b60065460ff16151561594d57600080fd5b6006805460ff19169055565b6000818152600c60205260408082205484835290822054600160a060020a0391821691168082148061449b57506000858152600f6020526040902054600160a060020a03908116908316149250505092915050565b60008160a0015163ffffffff1660001480156113cc5750506040015167ffffffffffffffff4381169116111590565b6000818414156159ef57506000612c98565b6001850154608060020a900463ffffffff16821480615a1e5750600185015460a060020a900463ffffffff1682145b15615a2b57506000612c98565b6001830154608060020a900463ffffffff16841480615a5a5750600183015460a060020a900463ffffffff1684145b15615a6757506000612c98565b6001830154608060020a900463ffffffff161580615a9457506001850154608060020a900463ffffffff16155b15615aa157506001612c98565b60018581015490840154608060020a9182900463ffffffff90811692909104161480615aec575060018086015490840154608060020a900463ffffffff90811660a060020a90920416145b15615af957506000612c98565b6001808601549084015460a060020a900463ffffffff908116608060020a909204161480615b4457506001858101549084015460a060020a9182900463ffffffff9081169290910416145b15615b5157506000612c98565b506001949350505050565b60008160a0015163ffffffff166000141580156113cc5750506040015167ffffffffffffffff4381169116111590565b600a80546001830154439260079160e060020a900461ffff16908110615bae57fe5b600891828204019190066004029054906101000a900463ffffffff1663ffffffff16811515615bd957fe5b6001840180546fffffffffffffffff0000000000000000191668010000000000000000939092049390930167ffffffffffffffff16919091021790819055600d60e060020a90910461ffff161015615c71576001818101805461ffff60e060020a8083048216909401169092027fffff0000ffffffffffffffffffffffffffffffffffffffffffffffffffffffff9092169190911790555b50565b6000808260ff161115615d4f57600a80546001850154909160079160e060020a900461ffff16908110615ca357fe5b600891828204019190066004029054906101000a900463ffffffff1663ffffffff16811515615cce57fe5b049050436064600960ff851660058110615ce457fe5b602091828204019190069054906101000a900460ff1660ff16830267ffffffffffffffff16811515615d1257fe5b04820367ffffffffffffffff16018360010160086101000a81548167ffffffffffffffff021916908367ffffffffffffffff160217905550615dc9565b600a80546001850154439260079160e060020a900461ffff16908110615d7157fe5b600891828204019190066004029054906101000a900463ffffffff1663ffffffff16811515615d9c57fe5b04018360010160086101000a81548167ffffffffffffffff021916908367ffffffffffffffff1602179055505b6001830154600d60e060020a90910461ffff161015611e22576001838101805461ffff60e060020a8083048216909401169092027fffff0000ffffffffffffffffffffffffffffffffffffffffffffffffffffffff909216919091179055505050565b6040805161014081018252600080825260208201819052918101829052606081018290526080810182905260a0810182905260c0810182905260e081018290526101008101829052610120810191909152905600a165627a7a723058204323d9b9c7dbfbae8c1c79260dbe7e723a4c4f6ac76370ae01a35d30e8c343ba0029

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

0000000000000000000000007aeaf9c8a62caf79c60b0eeb1e57eaefc140a5ca0000000000000000000000005425a1ca8b650ccfe0620fd10fe6e3dc46f0211d000000000000000000000000d75c77816c83537a6bb97819398fc2694e2e1478000000000000000000000000315fb673a6fa8720cf0341795faad602061d1267000000000000000000000000a98e0024db4a1720a301f464c4dabf685e34d078

-----Decoded View---------------
Arg [0] : _ceoAddress (address): 0x7AEAf9C8A62caf79C60B0EEB1e57EAefC140a5Ca
Arg [1] : _cfoAddress (address): 0x5425A1cA8b650CcfE0620fd10Fe6E3dC46f0211D
Arg [2] : _cooAddress (address): 0xD75C77816C83537A6bb97819398fc2694e2E1478
Arg [3] : _systemAddress (address): 0x315fB673a6Fa8720Cf0341795faAD602061D1267
Arg [4] : _tokenAddress (address): 0xa98e0024dB4A1720a301F464c4dabf685E34D078

-----Encoded View---------------
5 Constructor Arguments found :
Arg [0] : 0000000000000000000000007aeaf9c8a62caf79c60b0eeb1e57eaefc140a5ca
Arg [1] : 0000000000000000000000005425a1ca8b650ccfe0620fd10fe6e3dc46f0211d
Arg [2] : 000000000000000000000000d75c77816c83537a6bb97819398fc2694e2e1478
Arg [3] : 000000000000000000000000315fb673a6fa8720cf0341795faad602061d1267
Arg [4] : 000000000000000000000000a98e0024db4a1720a301f464c4dabf685e34d078


Swarm Source

bzzr://4323d9b9c7dbfbae8c1c79260dbe7e723a4c4f6ac76370ae01a35d30e8c343ba

Block Transaction Difficulty Gas Used Reward
View All Blocks Produced

Block Uncle Number Difficulty Gas Used Reward
View All Uncles
Loading...
Loading
Loading...
Loading

Validator Index Block Amount
View All Withdrawals

Transaction Hash Block Value Eth2 PubKey Valid
View All Deposits
Loading...
Loading
[ Download: CSV Export  ]

A contract address hosts a smart contract, which is a set of code stored on the blockchain that runs when predetermined conditions are met. Learn more about addresses in our Knowledge Base.