Transactions
Token Transfers
Tokens
Internal Transactions
Coin Balance History
Logs
Code
Read Contract
Write Contract
- Contract name:
- PetCore
- Optimization enabled
- true
- Compiler version
- v0.5.17+commit.d19bba13
- Optimization runs
- 200
- EVM Version
- default
- Verified at
- 2022-06-24T07:09:17.706904Z
Contract source code
/** *Submitted for verification at BscScan.com on 2021-04-27 */ pragma solidity ^0.5.0; library SafeMath { function add(uint256 a, uint256 b) internal pure returns (uint256) { uint256 c = a + b; require(c >= a, "SafeMath: addition overflow"); return c; } function sub(uint256 a, uint256 b) internal pure returns (uint256) { require(b <= a, "SafeMath: subtraction overflow"); uint256 c = a - b; return c; } } /** * @title Ownable * @dev The Ownable contract has an owner address, and provides basic authorization control * functions, this simplifies the implementation of "user permissions". */ contract Ownable { address public owner; /** * @dev The Ownable constructor sets the original `owner` of the contract to the sender * account. */ constructor() public { owner = msg.sender; } /** * @dev Throws if called by any account other than the owner. */ modifier onlyOwner() { require(msg.sender == owner, "Ownable: caller is not the owner"); _; } /** * @dev Allows the current owner to transfer control of the contract to a newOwner. * @param newOwner The address to transfer ownership to. */ function transferOwnership(address newOwner) external onlyOwner { if (newOwner != address(0)) { owner = newOwner; } } } contract KRC721 { function totalSupply() public view returns (uint256 total); function balanceOf(address _owner) public view returns (uint256 balance); function ownerOf(uint256 _tokenId) external view returns (address owner); function approve(address _to, uint256 _tokenId) external; function transfer(address _to, uint256 _tokenId) external; function transferFrom(address _from, address _to, uint256 _tokenId) external; // Events event Transfer(address from, address to, uint256 tokenId); event Approval(address owner, address approved, uint256 tokenId); function supportsInterface(bytes4 _interfaceID) external view returns (bool); } interface IGeneScience { /// @dev given genes of pet 1 & 2, return a genetic combination - may have a random factor /// @param genes1 genes of mom /// @param genes2 genes of sire /// @return the genes that are supposed to be passed down the child function mixGenes(uint256 genes1, uint256 genes2, uint256 targetBlock) external view returns (uint256); } interface IKRC20 { function balanceOf(address owner) external view returns (uint); function allowance(address owner, address spender) external view returns (uint); function approve(address spender, uint value) external returns (bool); function transfer(address to, uint value) external returns (bool); function transferFrom(address from, address to, uint value) external returns (bool); } interface IPetCore { function createPet(address _owner) external; } contract PetAccessControl is Ownable { // @dev Keeps track whether the contract is paused. When that is true, most actions are blocked bool public paused = false; modifier whenNotPaused() { require(!paused); _; } modifier whenPaused { require(paused); _; } function pause() external onlyOwner whenNotPaused { paused = true; } function unpause() external onlyOwner whenPaused { // can't unpause if contract was upgraded paused = false; } } contract PetBase is PetAccessControl { /// @dev The Birth event is fired whenever a new pet comes into existence. event Birth(address owner, uint256 PetId, uint256 matronId, uint256 sireId, uint256 genes); /// @dev Transfer event as defined in current draft of KRC721. event Transfer(address from, address to, uint256 tokenId); /*** DATA TYPES ***/ struct Pet { // The Pet's genetic code is packed into these 256-bits uint256 genes; // The timestamp from the block when this pet came into existence. uint64 birthTime; // The minimum timestamp after which this pet can engage in breeding // activities again. uint64 cooldownEndBlock; uint256 matronId; uint256 sireId; // Set to the ID of the sire pet for matrons that are pregnant, // zero otherwise. A non-zero value here is how we know a pet // is pregnant. Used to retrieve the genetic material for the new // pet when the birth transpires. uint256 siringWithId; // Set to the index in the cooldown array that represents // the current cooldown duration for this Pet. This starts at zero // for gen0 pets, and is initialized to floor(generation/2) for others. // Incremented by one for each successful breeding action, regardless // of whether this pet is acting as matron or sire. uint16 cooldownIndex; // The "generation number" of this pet. pets minted by the CP contract // for sale are called "gen0" and have a generation number of 0. The // generation number of all other pets is the larger of the two generation // numbers of their parents, plus one. // (i.e. max(matron.generation, sire.generation) + 1) uint16 generation; // The stages of this pet, starts from the junior stage, when feeding on, the pet grows to adulthood and middle-Age uint16 stages; } /*** CONSTANTS ***/ /// @dev A lookup table indipeting 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 pet /// is bred, encouraging owners not to just keep breeding the same pet over /// and over again. Caps out at one week (a pet can breed an unbounded number /// of times, and the maximum cooldown is always seven days). uint32[14] public cooldowns = [ uint32(1 minutes), uint32(2 minutes), uint32(5 minutes), uint32(10 minutes), uint32(30 minutes), uint32(1 hours), uint32(2 hours), uint32(4 hours), uint32(8 hours), uint32(16 hours), uint32(1 days), uint32(2 days), uint32(4 days), uint32(7 days) ]; // An approximation of currently how many seconds are in between blocks. uint256 public secondsPerBlock = 6; /*** STORAGE ***/ /// @dev An array containing the Pet struct for all pets in existence. The ID /// of each pet is actually an index into this array. Note that ID 0 is a negapet, /// the unPet, the mythical beast that is the parent of all gen0 pets. Pet[] pets; mapping (uint256 => address) public PetIndexToOwner; // Used internally inside balanceOf() to resolve ownership count. mapping (address => uint256) ownershipTokenCount; /// @dev A mapping from PetIDs to an address that has been approved to call /// transferFrom(). mapping (uint256 => address) public PetIndexToApproved; /// @dev A mapping from PetIDs to an address that has been approved to use /// this Pet for siring via breedWith(). mapping (uint256 => address) public sireAllowedToAddress; SaleClockAuction public saleAuction; /// @dev The address of a custom ClockAuction subclassed contract that handles siring /// auctions. Needs to be separate from saleAuction because the actions taken on success /// after a sales and siring auction are quite different. SiringClockAuction public siringAuction; /// @dev Assigns ownership of a specific Pet to an address. function _transfer(address _from, address _to, uint256 _tokenId) internal { ownershipTokenCount[_to]++; PetIndexToOwner[_tokenId] = _to; if (_from != address(0)) { ownershipTokenCount[_from]--; delete sireAllowedToAddress[_tokenId]; delete PetIndexToApproved[_tokenId]; } emit Transfer(_from, _to, _tokenId); } /// @dev An internal method that creates a new Pet and stores it. /// @param _matronId The Pet ID of the matron of this pet (zero for gen0) /// @param _sireId The Pet ID of the sire of this pet (zero for gen0) /// @param _generation The generation number of this pet. /// @param _genes The Pet's genetic code. /// @param _owner The inital owner of this pet, must be non-zero (except for the unPet, ID 0) function _createPet( uint256 _matronId, uint256 _sireId, uint256 _generation, uint256 _genes, address _owner ) internal returns (uint) { // New Pet starts with the same cooldown as parent gen/2 uint16 cooldownIndex = uint16(_generation / 2); if (cooldownIndex > 13) { cooldownIndex = 13; } Pet memory _Pet = Pet({ genes: _genes, birthTime: uint64(now), cooldownEndBlock: 0, matronId: uint32(_matronId), sireId: uint32(_sireId), siringWithId: 0, cooldownIndex: cooldownIndex, generation: uint16(_generation), stages: uint16(1) }); uint256 newpetId = pets.push(_Pet) - 1; emit Birth( _owner, newpetId, uint256(_Pet.matronId), uint256(_Pet.sireId), _Pet.genes ); _transfer(address(0), _owner, newpetId); return newpetId; } function setSecondsPerBlock(uint256 secs) external onlyOwner { require(secs < cooldowns[0]); secondsPerBlock = secs; } } contract PetOwnership is PetBase, KRC721 { string public constant name = "My DeFi Pet"; string public constant symbol = "MDP"; bytes4 constant InterfaceSignature_KRC165 = bytes4(keccak256('supportsInterface(bytes4)')); bytes4 constant InterfaceSignature_KRC721 = 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)')); function supportsInterface(bytes4 _interfaceID) external view returns (bool) { return ((_interfaceID == InterfaceSignature_KRC165) || (_interfaceID == InterfaceSignature_KRC721)); } /// @dev Checks if a given address is the current owner of a particular Pet. /// @param _claimant the address we are validating against. /// @param _tokenId pet id, only valid when > 0 function _owns(address _claimant, uint256 _tokenId) internal view returns (bool) { return PetIndexToOwner[_tokenId] == _claimant; } /// @dev Checks if a given address currently has transferApproval for a particular Pet. /// @param _claimant the address we are confirming pet is approved for. /// @param _tokenId pet id, only valid when > 0 function _approvedFor(address _claimant, uint256 _tokenId) internal view returns (bool) { return PetIndexToApproved[_tokenId] == _claimant; } function _approve(uint256 _tokenId, address _approved) internal { PetIndexToApproved[_tokenId] = _approved; } /// @notice Returns the number of pets owned by a specific address. /// @param _owner The owner address to check. function balanceOf(address _owner) public view returns (uint256 count) { return ownershipTokenCount[_owner]; } /// @notice Transfers a Pet to another address /// @param _to The address of the recipient, can be a user or contract. /// @param _tokenId The ID of the Pet to transfer. function transfer( address _to, uint256 _tokenId ) external whenNotPaused { require(_to != address(0)); require(_to != address(this)); require(_to != address(saleAuction)); require(_to != address(siringAuction)); require(_owns(msg.sender, _tokenId)); _transfer(msg.sender, _to, _tokenId); } /// @param _to The address to be granted transfer approval. Pass address(0) to /// clear all approvals. /// @param _tokenId The ID of the Pet that can be transferred if this call succeeds. function approve( address _to, uint256 _tokenId ) external whenNotPaused { require(_owns(msg.sender, _tokenId)); _approve(_tokenId, _to); emit Approval(msg.sender, _to, _tokenId); } /// @param _from The address that owns the Pet to be transfered. /// @param _to The address that should take ownership of the Pet. Can be any address, /// including the caller. /// @param _tokenId The ID of the Pet to be transferred. function transferFrom( address _from, address _to, uint256 _tokenId ) external whenNotPaused { require(_to != address(0)); require(_to != address(this)); require(_approvedFor(msg.sender, _tokenId)); require(_owns(_from, _tokenId)); _transfer(_from, _to, _tokenId); } /// @notice Returns the total number of pets currently in existence. function totalSupply() public view returns (uint) { return pets.length - 1; } /// @notice Returns the address currently assigned ownership of a given Pet. function ownerOf(uint256 _tokenId) external view returns (address owner) { owner = PetIndexToOwner[_tokenId]; require(owner != address(0)); } /// @notice Returns a list of all Pet IDs assigned to an address. /// @param _owner The owner whose pets we are interested in. function tokensOfOwner(address _owner) external view returns(uint256[] memory ownerTokens) { uint256 tokenCount = balanceOf(_owner); if (tokenCount == 0) { return new uint256[](0); } else { uint256[] memory result = new uint256[](tokenCount); uint256 totalpets = totalSupply(); uint256 resultIndex = 0; uint256 petId; for (petId = 1; petId <= totalpets; petId++) { if (PetIndexToOwner[petId] == _owner) { result[resultIndex] = petId; resultIndex++; } } return result; } } } /// @title A facet of PetCore that manages Pet siring, gestation, and birth. contract PetBreeding is PetOwnership { address public dpetToken = 0xfb62AE373acA027177D1c18Ee0862817f9080d08; /// @dev The Pregnant event is fired when two pets successfully breed and the pregnancy /// timer begins for the matron. event Pregnant(address owner, uint256 matronId, uint256 sireId, uint256 cooldownEndBlock); uint256 public autoBirthFee = 1*10**18; // pet token // Keeps track of number of pregnant pets. uint256 public pregnantpets; address public geneScience; function setGeneScienceAddress(address _address) external onlyOwner { geneScience = _address; } /// @dev Checks that a given pet is able to breed. Requires that the /// current cooldown is finished (for sires) and also checks that there is /// no pending pregnancy. function _isReadyToBreed(Pet memory _pet) internal view returns (bool) { return (_pet.siringWithId == 0) && (_pet.cooldownEndBlock <= uint64(block.number)); } /// @dev Check if a sire has authorized breeding with this matron. True if both sire /// and matron have the same owner, or if the sire has given siring permission to /// the matron's owner (via approveSiring()). function _isSiringPermitted(uint256 _sireId, uint256 _matronId) internal view returns (bool) { address matronOwner = PetIndexToOwner[_matronId]; address sireOwner = PetIndexToOwner[_sireId]; return (matronOwner == sireOwner || sireAllowedToAddress[_sireId] == matronOwner); } /// @dev Set the cooldownEndTime for the given Pet, based on its current cooldownIndex. /// @param _pet A reference to the Pet in storage which needs its timer started. function _triggerCooldown(Pet storage _pet) internal { _pet.cooldownEndBlock = uint64((cooldowns[_pet.cooldownIndex]/secondsPerBlock) + block.number); if (_pet.cooldownIndex < 13) { _pet.cooldownIndex += 1; } } /// @notice Grants approval to another user to sire with one of your pets. /// @param _addr The address that will be able to sire with your Pet. Set to /// address(0) to clear all siring approvals for this Pet. /// @param _sireId A Pet that you own that _addr will now be able to sire with. function approveSiring(address _addr, uint256 _sireId) external whenNotPaused { require(_owns(msg.sender, _sireId)); sireAllowedToAddress[_sireId] = _addr; } function setAutoBirthFee(uint256 val) external onlyOwner { autoBirthFee = val; } function _isReadyToGiveBirth(Pet memory _matron) private view returns (bool) { return (_matron.siringWithId != 0) && (_matron.cooldownEndBlock <= uint64(block.number)); } /// @notice Checks that a given pet is able to breed /// @param _PetId reference the id of the pet function isReadyToBreed(uint256 _PetId) public view returns (bool) { require(_PetId > 0); Pet storage pet = pets[_PetId]; return _isReadyToBreed(pet); } /// @dev Checks whether a Pet is currently pregnant. /// @param _PetId reference the id of the pet function isPregnant(uint256 _PetId) public view returns (bool) { require(_PetId > 0); return pets[_PetId].siringWithId != 0; } /// @param _matron A reference to the Pet struct of the potential matron. /// @param _matronId The matron's ID. /// @param _sire A reference to the Pet struct of the potential sire. /// @param _sireId The sire's ID function _isValidMatingPair( Pet storage _matron, uint256 _matronId, Pet storage _sire, uint256 _sireId ) private view returns(bool) { // A Pet can't breed with itself! if (_matronId == _sireId) { return false; } // pets can't breed with their parents. if (_matron.matronId == _sireId || _matron.sireId == _sireId) { return false; } if (_sire.matronId == _matronId || _sire.sireId == _matronId) { return false; } if (_sire.matronId == 0 || _matron.matronId == 0) { return true; } // pets 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; } return true; } /// @dev Internal check to see if a given sire and matron are a valid mating pair for /// breeding via auction. function _canBreedWithViaAuction(uint256 _matronId, uint256 _sireId) internal view returns (bool) { Pet storage matron = pets[_matronId]; Pet storage sire = pets[_sireId]; return _isValidMatingPair(matron, _matronId, sire, _sireId); } /// @param _matronId The ID of the proposed matron. /// @param _sireId The ID of the proposed sire. function canBreedWith(uint256 _matronId, uint256 _sireId) external view returns(bool) { require(_matronId > 0); require(_sireId > 0); Pet storage matron = pets[_matronId]; Pet storage sire = pets[_sireId]; return _isValidMatingPair(matron, _matronId, sire, _sireId) && _isSiringPermitted(_sireId, _matronId); } function _breedWith(uint256 _matronId, uint256 _sireId) internal { // Grab a reference to the pets from storage. Pet storage sire = pets[_sireId]; Pet storage matron = pets[_matronId]; // Mark the matron as pregnant, keeping track of who the sire is. matron.siringWithId = uint32(_sireId); // Trigger the cooldown for both parents. _triggerCooldown(sire); _triggerCooldown(matron); delete sireAllowedToAddress[_matronId]; delete sireAllowedToAddress[_sireId]; pregnantpets++; emit Pregnant(PetIndexToOwner[_matronId], _matronId, _sireId, matron.cooldownEndBlock); } /// @param _matronId The ID of the Pet acting as matron /// @param _sireId The ID of the Pet acting as sire function breedWithAuto(uint256 _matronId, uint256 _sireId, uint256 _amount) external whenNotPaused { // Checks for . require(_amount >= autoBirthFee, "Must payment"); require(IKRC20(dpetToken).transferFrom(msg.sender, address(this), _amount)); // Caller must own the matron. require(_owns(msg.sender, _matronId)); require(_isSiringPermitted(_sireId, _matronId)); // Grab a reference to the potential matron Pet storage matron = pets[_matronId]; // Make sure matron isn't pregnant, or in the middle of a siring cooldown require(_isReadyToBreed(matron)); // Grab a reference to the potential sire Pet storage sire = pets[_sireId]; // Make sure sire isn't pregnant, or in the middle of a siring cooldown require(_isReadyToBreed(sire)); require(_isValidMatingPair( matron, _matronId, sire, _sireId )); _breedWith(_matronId, _sireId); } /// @notice Have a pregnant Pet give birth! /// @param _matronId A Pet ready to give birth. /// @return The Pet ID of the new pet. function giveBirth(uint256 _matronId) external whenNotPaused returns(uint256) { Pet storage matron = pets[_matronId]; // Check that the matron is a valid pet. require(matron.birthTime != 0, "Invalid pet"); require(_isReadyToGiveBirth(matron), "Not ready birth"); uint256 sireId = matron.siringWithId; Pet storage sire = pets[sireId]; uint16 parentGen = matron.generation; if (sire.generation > matron.generation) { parentGen = sire.generation; } uint256 childGenes = IGeneScience(geneScience).mixGenes(matron.genes, sire.genes, matron.cooldownEndBlock - 1); address owner = PetIndexToOwner[_matronId]; uint256 petId = _createPet(_matronId, matron.siringWithId, parentGen + 1, childGenes, owner); delete matron.siringWithId; pregnantpets--; return petId; } } /// @title Auction Core contract ClockAuctionBase { using SafeMath for uint256; address public dpetToken = 0xfb62AE373acA027177D1c18Ee0862817f9080d08; // Represents an auction on an NFT struct Auction { // Current owner of NFT address seller; // Price at beginning of auction uint128 startingPrice; // Price at end of auction uint128 endingPrice; // Duration (in seconds) of auction uint64 duration; // Time when auction started uint64 startedAt; } // Reference to contract tracking NFT ownership KRC721 public nonFungibleContract; uint256 public ownerCut; mapping (uint256 => Auction) tokenIdToAuction; event AuctionCreated(uint256 tokenId, uint256 startingPrice, uint256 endingPrice, uint256 duration); event AuctionSuccessful(uint256 tokenId, uint256 totalPrice, address winner); event AuctionCancelled(uint256 tokenId); /// @dev Returns true if the claimant owns the token. /// @param _claimant - Address claiming to own the token. /// @param _tokenId - ID of token whose ownership to verify. function _owns(address _claimant, uint256 _tokenId) internal view returns (bool) { return (nonFungibleContract.ownerOf(_tokenId) == _claimant); } /// @dev Escrows the NFT, assigning ownership to this contract. /// @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, address(this), _tokenId); } /// @dev Transfers an NFT owned by this contract to another address. /// @param _receiver - Address to transfer NFT to. /// @param _tokenId - ID of token to transfer. function _transfer(address _receiver, uint256 _tokenId) internal { nonFungibleContract.transfer(_receiver, _tokenId); } /// @dev Adds an auction to the list of open auctions. /// @param _tokenId The ID of the token to be put on auction. /// @param _auction Auction to add. function _addAuction(uint256 _tokenId, Auction memory _auction) internal { require(_auction.duration >= 1 minutes); tokenIdToAuction[_tokenId] = _auction; emit AuctionCreated( uint256(_tokenId), uint256(_auction.startingPrice), uint256(_auction.endingPrice), uint256(_auction.duration) ); } /// @dev Cancels an auction unconditionally. function _cancelAuction(uint256 _tokenId, address _seller) internal { _removeAuction(_tokenId); _transfer(_seller, _tokenId); emit AuctionCancelled(_tokenId); } /// @dev Computes the price and transfers winnings. function _bid(uint256 _tokenId, uint256 _bidAmount) internal returns (uint256) { // Get a reference to the auction struct Auction storage auction = tokenIdToAuction[_tokenId]; require(_isOnAuction(auction)); // Check that the bid is greater than or equal to the current price uint256 price = _currentPrice(auction); require(_bidAmount >= price); 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); if (price > 0) { uint256 auctioneerCut = _computeCut(price); uint256 sellerProceeds = price - auctioneerCut; require(IKRC20(dpetToken).transfer(seller, sellerProceeds)); } uint256 bidExcess = _bidAmount - price; require(IKRC20(dpetToken).transfer(msg.sender, bidExcess)); emit AuctionSuccessful(_tokenId, price, msg.sender); return price; } /// @dev Removes an auction from the list of open auctions. /// @param _tokenId - ID of NFT on auction. function _removeAuction(uint256 _tokenId) internal { delete tokenIdToAuction[_tokenId]; } /// @dev Returns true if the NFT is on auction. /// @param _auction - Auction to check. function _isOnAuction(Auction storage _auction) internal view returns (bool) { return (_auction.startedAt > 0); } function _currentPrice(Auction storage _auction) internal view returns (uint256) { uint256 secondsPassed = 0; if (now > _auction.startedAt) { secondsPassed = now - _auction.startedAt; } return _computeCurrentPrice( _auction.startingPrice, _auction.endingPrice, _auction.duration, secondsPassed ); } /// @dev Computes the current price of an auction. function _computeCurrentPrice( uint256 _startingPrice, uint256 _endingPrice, uint256 _duration, uint256 _secondsPassed ) internal pure returns (uint256) { if (_secondsPassed >= _duration) { return _endingPrice; } else { uint256 totalPriceChange = _endingPrice.sub(_startingPrice); uint256 currentPriceChange = totalPriceChange * _secondsPassed / _duration; uint256 currentPrice = _startingPrice + currentPriceChange; return currentPrice; } } /// @dev Computes owner's cut of a sale. /// @param _price - Sale price of NFT. function _computeCut(uint256 _price) internal view returns (uint256) { return _price * ownerCut / 10000; } } /** * @title Pausable * @dev Base contract which allows children to implement an emergency stop mechanism. */ contract Pausable is Ownable { event Pause(); event Unpause(); bool public paused = false; /** * @dev modifier to allow actions only when the contract IS paused */ modifier whenNotPaused() { require(!paused); _; } /** * @dev modifier to allow actions only when the contract IS NOT paused */ modifier whenPaused { require(paused); _; } /** * @dev called by the owner to pause, triggers stopped state */ function pause() external onlyOwner whenNotPaused returns (bool) { paused = true; emit Pause(); return true; } /** * @dev called by the owner to unpause, returns to normal state */ function unpause() external onlyOwner whenPaused returns (bool) { paused = false; emit Unpause(); return true; } } /// @title Clock auction for non-fungible tokens. contract ClockAuction is Pausable, ClockAuctionBase { bytes4 constant InterfaceSignature_KRC721 = bytes4(0x9a20483d); /// @param _nftAddress - address of a deployed contract implementing /// the Nonfungible Interface. /// @param _cut - percent cut the owner takes on each auction, must be /// between 0-10,000. constructor(address _nftAddress, uint256 _cut) public { require(_cut <= 10000); ownerCut = _cut; KRC721 candidateContract = KRC721(_nftAddress); require(candidateContract.supportsInterface(InterfaceSignature_KRC721)); nonFungibleContract = candidateContract; } function withdrawBalance() external onlyOwner { address(uint160(owner)).transfer(address(this).balance); IKRC20(dpetToken).transfer(owner, getBalance()); } function changeCut(uint256 _cut) external onlyOwner { require(_cut <= 10000); ownerCut = _cut; } function getBalance() view public returns(uint256) { return IKRC20(dpetToken).balanceOf(address(this)); } /// @dev Creates and begins a new auction. /// @param _tokenId - ID of token to auction, sender must be owner. /// @param _startingPrice - Price of item (in wei) at beginning of auction. /// @param _endingPrice - Price of item (in wei) at end of auction. /// @param _duration - Length of time to move between starting /// price and ending price (in seconds). /// @param _seller - Seller, if not the message sender function createAuction( uint256 _tokenId, uint256 _startingPrice, uint256 _endingPrice, uint256 _duration, address _seller ) external whenNotPaused { require(_startingPrice == uint256(uint128(_startingPrice))); require(_endingPrice == uint256(uint128(_endingPrice))); require(_duration == uint256(uint64(_duration))); require(_owns(msg.sender, _tokenId), "Not PetId owner"); _escrow(msg.sender, _tokenId); Auction memory auction = Auction( _seller, uint128(_startingPrice), uint128(_endingPrice), uint64(_duration), uint64(now) ); _addAuction(_tokenId, auction); } /// @dev Bids on an open auction, completing the auction and transferring /// ownership of the NFT if enough KAI is supplied. /// @param _tokenId - ID of token to bid on. function bid(uint256 _tokenId, uint256 _amount) external whenNotPaused { // require(IKRC20(dpetToken).transfer(address(this), _amount)); // _bid will throw if the bid or funds transfer fails _bid(_tokenId, _amount); _transfer(msg.sender, _tokenId); } /// @dev Cancels an auction that hasn't been won yet. /// Returns the NFT to original owner. /// @notice This is a state-modifying function that can /// be called while the contract is paused. /// @param _tokenId - ID of token on auction function cancelAuction(uint256 _tokenId) external { Auction storage auction = tokenIdToAuction[_tokenId]; require(_isOnAuction(auction), "TokenID is a must on auction"); address seller = auction.seller; require(msg.sender == seller); _cancelAuction(_tokenId, seller); } /// @dev Cancels an auction when the contract is paused. /// Only the owner may do this, and NFTs are returned to /// the seller. This should only be used in emergencies. /// @param _tokenId - ID of the NFT on auction to cancel. function cancelAuctionWhenPaused(uint256 _tokenId) whenPaused onlyOwner external { Auction storage auction = tokenIdToAuction[_tokenId]; require(_isOnAuction(auction), "TokenID is a must on auction"); _cancelAuction(_tokenId, auction.seller); } /// @dev Returns auction info for an NFT on auction. /// @param _tokenId - ID of NFT on auction. function getAuction(uint256 _tokenId) external view returns ( address seller, uint256 startingPrice, uint256 endingPrice, uint256 duration, uint256 startedAt ) { Auction storage auction = tokenIdToAuction[_tokenId]; require(_isOnAuction(auction), "TokenID is a must on auction"); return ( auction.seller, auction.startingPrice, auction.endingPrice, auction.duration, auction.startedAt ); } /// @dev Returns the current price of an auction. /// @param _tokenId - ID of the token price we are checking. function getCurrentPrice(uint256 _tokenId) external view returns (uint256) { Auction storage auction = tokenIdToAuction[_tokenId]; require(_isOnAuction(auction), "TokenID is a must on auction"); return _currentPrice(auction); } } /// @title Reverse auction modified for siring /// @notice We omit a fallback function to prevent accidental sends to this contract. contract SiringClockAuction is ClockAuction { bool public isSiringClockAuction = true; constructor(address _nftAddr, uint256 _cut) public ClockAuction(_nftAddr, _cut) {} /// @dev Creates and begins a new auction. /// @param _tokenId - ID of token to auction, sender must be owner. /// @param _startingPrice - Price of item (in wei) at beginning of auction. /// @param _endingPrice - Price of item (in wei) at end of auction. /// @param _duration - Length of auction (in seconds). /// @param _seller - Seller, if not the message sender function createAuction( uint256 _tokenId, uint256 _startingPrice, uint256 _endingPrice, uint256 _duration, address _seller ) external { require(_startingPrice == uint256(uint128(_startingPrice))); require(_endingPrice == uint256(uint128(_endingPrice))); require(_duration == uint256(uint64(_duration))); require(msg.sender == address(nonFungibleContract)); _escrow(_seller, _tokenId); Auction memory auction = Auction( _seller, uint128(_startingPrice), uint128(_endingPrice), uint64(_duration), uint64(now) ); _addAuction(_tokenId, auction); } /// @dev Places a bid for siring. Requires the sender /// is the PetCore contract because all bid methods /// should be wrapped. Also returns the Pet to the /// seller rather than the winner. function bid(uint256 _tokenId, uint256 _amount) external { // require(IKRC20(dpetToken).transferFrom(msg.sender, address(this), _amount)); require(msg.sender == address(nonFungibleContract)); address seller = tokenIdToAuction[_tokenId].seller; // _bid checks that token ID is valid and will throw if bid fails _bid(_tokenId, _amount); // We transfer the Pet back to the seller, the winner will get // the offspring _transfer(seller, _tokenId); } } /// @title Clock auction modified for sale of pets contract SaleClockAuction is ClockAuction { bool public isSaleClockAuction = true; // Tracks last 5 sale price of gen0 Pet sales uint256 public gen0SaleCount; uint256[5] public lastGen0SalePrices; constructor(address _nftAddr, uint256 _cut) public ClockAuction(_nftAddr, _cut) {} /// @dev Creates and begins a new auction. /// @param _tokenId - ID of token to auction, sender must be owner. /// @param _startingPrice - Price of item (in wei) at beginning of auction. /// @param _endingPrice - Price of item (in wei) at end of auction. /// @param _duration - Length of auction (in seconds). /// @param _seller - Seller, if not the message sender function createAuction( uint256 _tokenId, uint256 _startingPrice, uint256 _endingPrice, uint256 _duration, address _seller ) external { require(_startingPrice == uint256(uint128(_startingPrice))); require(_endingPrice == uint256(uint128(_endingPrice))); require(_duration == uint256(uint64(_duration))); require(msg.sender == address(nonFungibleContract)); _escrow(_seller, _tokenId); Auction memory auction = Auction( _seller, uint128(_startingPrice), uint128(_endingPrice), uint64(_duration), uint64(now) ); _addAuction(_tokenId, auction); } /// @dev Updates lastSalePrice if seller is the nft contract /// Otherwise, works the same as default bid method. function bid(uint256 _tokenId, uint256 _amount) external { require(IKRC20(dpetToken).transferFrom(msg.sender, address(this), _amount)); // _bid verifies token ID size address seller = tokenIdToAuction[_tokenId].seller; uint256 price = _bid(_tokenId, _amount); _transfer(msg.sender, _tokenId); // If not a gen0 auction, exit if (seller == address(nonFungibleContract)) { // Track gen0 sale prices lastGen0SalePrices[gen0SaleCount % 5] = price; gen0SaleCount++; } } function averageGen0SalePrice() external view returns (uint256) { uint256 sum = 0; for (uint256 i = 0; i < 5; i++) { sum += lastGen0SalePrices[i]; } return sum / 5; } } /// @title all functions related to creating pets contract PetMinting is PetBreeding, IPetCore { // Counts the number of pets the contract owner has created. uint256 public gen0CreatedCount; uint256 public gen0Price = 1* 10**18; address public stakingContract; uint256 private nonce; /** * @dev Throws if called by any account other than the staking contract. */ modifier onlyStakingContract() { require(msg.sender == stakingContract, "Ownable: caller is not the staking contract"); _; } /// @param _owner the future owner of the created pets. function createPromoPet(address _owner, uint256 _amount) external { require(_amount >= gen0Price, "INVALID AMOUNT"); require(IKRC20(dpetToken).transferFrom(msg.sender, address(this), _amount)); gen0CreatedCount++; uint256 genes = _randomPetGenes(); _createPet(0, 0, 0, genes, _owner); } function createPet(address _owner) external onlyStakingContract { gen0CreatedCount++; uint256 genes = _randomPetGenes(); _createPet(0, 0, 0, genes, _owner); } function createGen0Auction(address _owner, uint256 _genes) external onlyOwner { gen0CreatedCount++; _createPet(0, 0, 0, _genes, _owner); } function updateGen0Price(uint256 _gen0Price) external onlyOwner { gen0Price = _gen0Price; } function setStakingContract(address _stakingContract) external onlyOwner { stakingContract = _stakingContract; } function _randomPetGenes() internal returns (uint256) { uint256 randomN = uint256(blockhash(block.number)); uint256 genes = uint256(keccak256(abi.encodePacked(randomN, block.timestamp, nonce))) % (10 **72) + 1*10**71; nonce++; return genes; } } contract PetCore is PetMinting { uint256 public amountToAdulthood = 10 * 10**18; uint256 public amountToMiddleAge = 15 * 10**18; address public siringAuctionAddr; address public saleAuctionAddr; constructor() public { paused = false; // start with the mythical pet 0 - so we don't have generation-0 parent issues _createPet(0, 0, 0, uint256(-1), address(0)); } /// @dev Reject all KAI from being sent here, unless it's from one of the /// two auction contracts. function() external payable { require( msg.sender == address(saleAuction) || msg.sender == address(siringAuction) ); } /// @dev Sets the reference to the sale auction. /// @param _address - Address of sale contract. function setSaleAuctionAddress(address _address) external onlyOwner { SaleClockAuction candidateContract = SaleClockAuction(_address); require(candidateContract.isSaleClockAuction()); // Set the new contract address saleAuction = candidateContract; saleAuctionAddr = _address; } function setSiringAuctionAddress(address _address) external onlyOwner { SiringClockAuction candidateContract = SiringClockAuction(_address); require(candidateContract.isSiringClockAuction()); // Set the new contract address siringAuction = candidateContract; siringAuctionAddr = _address; } function createSaleAuction( uint256 _PetId, uint256 _startingPrice, uint256 _endingPrice, uint256 _duration ) external whenNotPaused { require(_owns(msg.sender, _PetId), "Not PetId owner"); require(!isPregnant(_PetId), "Pet is pregnant"); _approve(_PetId, address(saleAuction)); saleAuction.createAuction( _PetId, _startingPrice, _endingPrice, _duration, msg.sender ); } function createSiringAuction( uint256 _PetId, uint256 _startingPrice, uint256 _endingPrice, uint256 _duration ) external whenNotPaused { // Auction contract checks input sizes // If Pet is already on any auction, this will throw // because it will be owned by the auction contract. require(_owns(msg.sender, _PetId), "Not PetId owner"); require(isReadyToBreed(_PetId), "Not ready to breed"); _approve(_PetId, address(siringAuction)); // Siring auction throws if inputs are invalid and clears // transfer and sire approval after escrowing the Pet. siringAuction.createAuction( _PetId, _startingPrice, _endingPrice, _duration, msg.sender ); } /// @dev Completes a siring auction by bidding. /// Immediately breeds the winning matron with the sire on auction. /// @param _sireId - ID of the sire on auction. /// @param _matronId - ID of the matron owned by the bidder. function bidOnSiringAuction( uint256 _sireId, uint256 _matronId, uint256 _amount ) external whenNotPaused { require(IKRC20(dpetToken).transferFrom(msg.sender, address(this), _amount)); // Auction contract checks input sizes require(_owns(msg.sender, _matronId), "Not matron owner"); require(isReadyToBreed(_matronId), "Not ready to breed"); require(_canBreedWithViaAuction(_matronId, _sireId), "Can't breed with via auction"); // Define the current price of the auction. uint256 currentPrice = siringAuction.getCurrentPrice(_sireId); require(_amount >= currentPrice + autoBirthFee); // // Siring auction will throw if the bid fails. require(IKRC20(dpetToken).transfer(siringAuctionAddr, _amount)); siringAuction.bid(_sireId, _amount); _breedWith(uint32(_matronId), uint32(_sireId)); } /// @notice Returns all the relevant information about a specific Pet. /// @param _id The ID of the Pet of interest. function getPet(uint256 _id) public view returns ( bool isGestating, bool isReady, uint256 cooldownIndex, uint256 nextActionAt, uint256 siringWithId, uint256 birthTime, uint256 matronId, uint256 sireId, uint256 generation, string memory genes, uint256 stages ) { Pet storage pet = pets[_id]; isGestating = (pet.siringWithId != 0); isReady = (pet.cooldownEndBlock <= block.number); cooldownIndex = uint256(pet.cooldownIndex); nextActionAt = uint256(pet.cooldownEndBlock); siringWithId = uint256(pet.siringWithId); birthTime = uint256(pet.birthTime); matronId = uint256(pet.matronId); sireId = uint256(pet.sireId); generation = uint256(pet.generation); genes = _uintToStr(pet.genes); stages = uint256(pet.stages); } /// @notice feed on a specific Pet. /// @param _petId The ID of the Pet of interest. /// @param _amount. function feedOnPet(uint256 _petId, uint256 _amount) external { require(IKRC20(dpetToken).transferFrom(msg.sender, address(this), _amount)); Pet storage pet = pets[_petId]; if (_amount == amountToAdulthood) { require(pet.stages == 1, "INVALID STAGE 1"); pet.stages += 1; } if (_amount == amountToMiddleAge) { require(pet.stages == 2, "INVALID STAGE 2"); pet.stages += 1; } } function setAmountToAdulthood(uint256 _amountToAdulthood) external onlyOwner { amountToAdulthood = _amountToAdulthood; } function setAmountToMiddleAge(uint256 _amountToMiddleAge) external onlyOwner { amountToMiddleAge = _amountToMiddleAge; } function getBalance() public view returns(uint256) { return IKRC20(dpetToken).balanceOf(address(this)); } function withdrawBalance() external onlyOwner { IKRC20(dpetToken).transfer(owner, getBalance()); } function _uintToStr(uint _i) private pure returns (string memory _uintAsString) { uint number = _i; if (number == 0) { return "0"; } uint j = number; uint len; while (j != 0) { len++; j /= 10; } bytes memory bstr = new bytes(len); uint k = len - 1; while (number != 0) { bstr[k--] = byte(uint8(48 + number % 10)); number /= 10; } return string(bstr); } } contract GeneScience is IGeneScience { uint256 internal constant maskLast8Bits = uint256(0xff); uint256 internal constant maskFirst248Bits = uint256(~0xff); /// @dev given a characteristic and 2 genes (unsorted) - returns > 0 if the genes ascended, that's the value /// @param trait1 any trait of that characteristic /// @param trait2 any trait of that characteristic /// @param rand is expected to be a 3 bits number (0~7) /// @return -1 if didnt match any ascention, OR a number from 0 to 30 for the ascended trait function _ascend(uint8 trait1, uint8 trait2, uint256 rand) internal pure returns(uint8 ascension) { ascension = 0; uint8 smallT = trait1; uint8 bigT = trait2; if (smallT > bigT) { bigT = trait1; smallT = trait2; } if ((bigT - smallT == 1) && smallT % 2 == 0) { // The rand argument is expected to be a random number 0-7. // 1st and 2nd tier: 1/4 chance (rand is 0 or 1) // 3rd and 4th tier: 1/8 chance (rand is 0) // must be at least this much to ascend uint256 maxRand; if (smallT < 23) maxRand = 1; else maxRand = 0; if (rand <= maxRand ) { ascension = (smallT / 2) + 16; } } } /// @dev given a number get a slice of any bits, at certain offset /// @param _n a number to be sliced /// @param _nbits how many bits long is the new number /// @param _offset how many bits to skip function _sliceNumber(uint256 _n, uint256 _nbits, uint256 _offset) private pure returns (uint256) { // mask is made by shifting left an offset number of times uint256 mask = uint256((2**_nbits) - 1) << _offset; // AND n with mask, and trim to max of _nbits bits return uint256((_n & mask) >> _offset); } /// @dev Get a 5 bit slice from an input as a number /// @param _input bits, encoded as uint /// @param _slot from 0 to 50 function _get5Bits(uint256 _input, uint256 _slot) internal pure returns(uint8) { return uint8(_sliceNumber(_input, uint256(5), _slot * 5)); } /// @dev Parse a pet gene and returns all of 12 "trait stack" that makes the characteristics /// @param _genes pet gene /// @return the 48 traits that composes the genetic code, logically divided in stacks of 4, where only the first trait of each stack may express function decode(uint256 _genes) public pure returns(uint8[] memory) { uint8[] memory traits = new uint8[](48); uint256 i; for(i = 0; i < 48; i++) { traits[i] = _get5Bits(_genes, i); } return traits; } /// @dev Given an array of traits return the number that represent genes function encode(uint8[] memory _traits) public pure returns (uint256 _genes) { _genes = 0; for(uint256 i = 0; i < 48; i++) { _genes = _genes << 5; // bitwise OR trait with _genes _genes = _genes | _traits[47 - i]; } return _genes; } /// @dev return the expressing traits /// @param _genes the long number expressing pet genes function expressingTraits(uint256 _genes) public pure returns(uint8[12] memory) { uint8[12] memory express; for(uint256 i = 0; i < 12; i++) { express[i] = _get5Bits(_genes, i * 4); } return express; } /// @dev the function as defined in the breeding contract - as defined in CK bible function mixGenes(uint256 _genes1, uint256 _genes2, uint256 _targetBlock) public view returns (uint256) { // require(block.number > _targetBlock); uint256 randomN = uint256(blockhash(_targetBlock)); uint256 rand; if (randomN == 0) { _targetBlock = (block.number & maskFirst248Bits) + (_targetBlock & maskLast8Bits); // The computation above could result in a block LARGER than the current block, // if so, subtract 256. if (_targetBlock >= block.number) _targetBlock -= 256; randomN = uint256(blockhash(_targetBlock)); } // generate 256 bits of random, using as much entropy as we can from // sources that can't change between calls. randomN = uint256(keccak256(abi.encodePacked(randomN, _genes1, _genes2, _targetBlock))); uint256 randomIndex = 0; uint8[] memory genes1Array = decode(_genes1); uint8[] memory genes2Array = decode(_genes2); // All traits that will belong to baby uint8[] memory babyArray = new uint8[](48); // A pointer to the trait we are dealing with currently uint256 traitPos; // Trait swap value holder uint8 swap; // iterate all 12 characteristics for(uint256 i = 0; i < 12; i++) { // pick 4 traits for characteristic i uint256 j; // store the current random value // uint256 rand; for(j = 3; j >= 1; j--) { traitPos = (i * 4) + j; rand = _sliceNumber(randomN, 2, randomIndex); // 0~3 randomIndex += 2; // 1/4 of a chance of gene swapping forward towards expressing. if (rand == 0) { // do it for parent 1 swap = genes1Array[traitPos]; genes1Array[traitPos] = genes1Array[traitPos - 1]; genes1Array[traitPos - 1] = swap; } rand = _sliceNumber(randomN, 2, randomIndex); // 0~3 randomIndex += 2; if (rand == 0) { // do it for parent 2 swap = genes2Array[traitPos]; genes2Array[traitPos] = genes2Array[traitPos - 1]; genes2Array[traitPos - 1] = swap; } } } // We have 256 - 144 = 112 bits of randomness left at this point. We will use up to // four bits for the first slot of each trait (three for the possible ascension, one // to pick between mom and dad if the ascension fails, for a total of 48 bits. The other // traits use one bit to pick between parents (36 gene pairs, 36 genes), leaving us // well within our entropy budget. // done shuffling parent genes, now let's decide on choosing trait and if ascending. // NOTE: Ascensions ONLY happen in the "top slot" of each characteristic. This saves // gas and also ensures ascensions only happen when they're visible. for(traitPos = 0; traitPos < 48; traitPos++) { // See if this trait pair should ascend uint8 ascendedTrait = 0; // There are two checks here. The first is straightforward, only the trait // in the first slot can ascend. The first slot is zero mod 4. // // The second check is more subtle: Only values that are one apart can ascend, // which is what we check inside the _ascend method. However, this simple mask // and compare is very cheap (9 gas) and will filter out about half of the // non-ascending pairs without a function call. // // The comparison itself just checks that one value is even, and the other // is odd. if ((traitPos % 4 == 0) && (genes1Array[traitPos] & 1) != (genes2Array[traitPos] & 1)) { rand = _sliceNumber(randomN, 3, randomIndex); randomIndex += 3; ascendedTrait = _ascend(genes1Array[traitPos], genes2Array[traitPos], rand); } if (ascendedTrait > 0) { babyArray[traitPos] = uint8(ascendedTrait); } else { // did not ascend, pick one of the parent's traits for the baby // We use the top bit of rand for this (the bottom three bits were used // to check for the ascension itself). rand = _sliceNumber(randomN, 1, randomIndex); randomIndex += 1; if (rand == 0) { babyArray[traitPos] = uint8(genes1Array[traitPos]); } else { babyArray[traitPos] = uint8(genes2Array[traitPos]); } } } return encode(babyArray); } }
Contract ABI
[{"type":"constructor","stateMutability":"nonpayable","payable":false,"inputs":[]},{"type":"event","name":"Approval","inputs":[{"type":"address","name":"owner","internalType":"address","indexed":false},{"type":"address","name":"approved","internalType":"address","indexed":false},{"type":"uint256","name":"tokenId","internalType":"uint256","indexed":false}],"anonymous":false},{"type":"event","name":"Birth","inputs":[{"type":"address","name":"owner","internalType":"address","indexed":false},{"type":"uint256","name":"PetId","internalType":"uint256","indexed":false},{"type":"uint256","name":"matronId","internalType":"uint256","indexed":false},{"type":"uint256","name":"sireId","internalType":"uint256","indexed":false},{"type":"uint256","name":"genes","internalType":"uint256","indexed":false}],"anonymous":false},{"type":"event","name":"Pregnant","inputs":[{"type":"address","name":"owner","internalType":"address","indexed":false},{"type":"uint256","name":"matronId","internalType":"uint256","indexed":false},{"type":"uint256","name":"sireId","internalType":"uint256","indexed":false},{"type":"uint256","name":"cooldownEndBlock","internalType":"uint256","indexed":false}],"anonymous":false},{"type":"event","name":"Transfer","inputs":[{"type":"address","name":"from","internalType":"address","indexed":false},{"type":"address","name":"to","internalType":"address","indexed":false},{"type":"uint256","name":"tokenId","internalType":"uint256","indexed":false}],"anonymous":false},{"type":"fallback","stateMutability":"payable","payable":true},{"type":"function","stateMutability":"view","payable":false,"outputs":[{"type":"address","name":"","internalType":"address"}],"name":"PetIndexToApproved","inputs":[{"type":"uint256","name":"","internalType":"uint256"}],"constant":true},{"type":"function","stateMutability":"view","payable":false,"outputs":[{"type":"address","name":"","internalType":"address"}],"name":"PetIndexToOwner","inputs":[{"type":"uint256","name":"","internalType":"uint256"}],"constant":true},{"type":"function","stateMutability":"view","payable":false,"outputs":[{"type":"uint256","name":"","internalType":"uint256"}],"name":"amountToAdulthood","inputs":[],"constant":true},{"type":"function","stateMutability":"view","payable":false,"outputs":[{"type":"uint256","name":"","internalType":"uint256"}],"name":"amountToMiddleAge","inputs":[],"constant":true},{"type":"function","stateMutability":"nonpayable","payable":false,"outputs":[],"name":"approve","inputs":[{"type":"address","name":"_to","internalType":"address"},{"type":"uint256","name":"_tokenId","internalType":"uint256"}],"constant":false},{"type":"function","stateMutability":"nonpayable","payable":false,"outputs":[],"name":"approveSiring","inputs":[{"type":"address","name":"_addr","internalType":"address"},{"type":"uint256","name":"_sireId","internalType":"uint256"}],"constant":false},{"type":"function","stateMutability":"view","payable":false,"outputs":[{"type":"uint256","name":"","internalType":"uint256"}],"name":"autoBirthFee","inputs":[],"constant":true},{"type":"function","stateMutability":"view","payable":false,"outputs":[{"type":"uint256","name":"count","internalType":"uint256"}],"name":"balanceOf","inputs":[{"type":"address","name":"_owner","internalType":"address"}],"constant":true},{"type":"function","stateMutability":"nonpayable","payable":false,"outputs":[],"name":"bidOnSiringAuction","inputs":[{"type":"uint256","name":"_sireId","internalType":"uint256"},{"type":"uint256","name":"_matronId","internalType":"uint256"},{"type":"uint256","name":"_amount","internalType":"uint256"}],"constant":false},{"type":"function","stateMutability":"nonpayable","payable":false,"outputs":[],"name":"breedWithAuto","inputs":[{"type":"uint256","name":"_matronId","internalType":"uint256"},{"type":"uint256","name":"_sireId","internalType":"uint256"},{"type":"uint256","name":"_amount","internalType":"uint256"}],"constant":false},{"type":"function","stateMutability":"view","payable":false,"outputs":[{"type":"bool","name":"","internalType":"bool"}],"name":"canBreedWith","inputs":[{"type":"uint256","name":"_matronId","internalType":"uint256"},{"type":"uint256","name":"_sireId","internalType":"uint256"}],"constant":true},{"type":"function","stateMutability":"view","payable":false,"outputs":[{"type":"uint32","name":"","internalType":"uint32"}],"name":"cooldowns","inputs":[{"type":"uint256","name":"","internalType":"uint256"}],"constant":true},{"type":"function","stateMutability":"nonpayable","payable":false,"outputs":[],"name":"createGen0Auction","inputs":[{"type":"address","name":"_owner","internalType":"address"},{"type":"uint256","name":"_genes","internalType":"uint256"}],"constant":false},{"type":"function","stateMutability":"nonpayable","payable":false,"outputs":[],"name":"createPet","inputs":[{"type":"address","name":"_owner","internalType":"address"}],"constant":false},{"type":"function","stateMutability":"nonpayable","payable":false,"outputs":[],"name":"createPromoPet","inputs":[{"type":"address","name":"_owner","internalType":"address"},{"type":"uint256","name":"_amount","internalType":"uint256"}],"constant":false},{"type":"function","stateMutability":"nonpayable","payable":false,"outputs":[],"name":"createSaleAuction","inputs":[{"type":"uint256","name":"_PetId","internalType":"uint256"},{"type":"uint256","name":"_startingPrice","internalType":"uint256"},{"type":"uint256","name":"_endingPrice","internalType":"uint256"},{"type":"uint256","name":"_duration","internalType":"uint256"}],"constant":false},{"type":"function","stateMutability":"nonpayable","payable":false,"outputs":[],"name":"createSiringAuction","inputs":[{"type":"uint256","name":"_PetId","internalType":"uint256"},{"type":"uint256","name":"_startingPrice","internalType":"uint256"},{"type":"uint256","name":"_endingPrice","internalType":"uint256"},{"type":"uint256","name":"_duration","internalType":"uint256"}],"constant":false},{"type":"function","stateMutability":"view","payable":false,"outputs":[{"type":"address","name":"","internalType":"address"}],"name":"dpetToken","inputs":[],"constant":true},{"type":"function","stateMutability":"nonpayable","payable":false,"outputs":[],"name":"feedOnPet","inputs":[{"type":"uint256","name":"_petId","internalType":"uint256"},{"type":"uint256","name":"_amount","internalType":"uint256"}],"constant":false},{"type":"function","stateMutability":"view","payable":false,"outputs":[{"type":"uint256","name":"","internalType":"uint256"}],"name":"gen0CreatedCount","inputs":[],"constant":true},{"type":"function","stateMutability":"view","payable":false,"outputs":[{"type":"uint256","name":"","internalType":"uint256"}],"name":"gen0Price","inputs":[],"constant":true},{"type":"function","stateMutability":"view","payable":false,"outputs":[{"type":"address","name":"","internalType":"address"}],"name":"geneScience","inputs":[],"constant":true},{"type":"function","stateMutability":"view","payable":false,"outputs":[{"type":"uint256","name":"","internalType":"uint256"}],"name":"getBalance","inputs":[],"constant":true},{"type":"function","stateMutability":"view","payable":false,"outputs":[{"type":"bool","name":"isGestating","internalType":"bool"},{"type":"bool","name":"isReady","internalType":"bool"},{"type":"uint256","name":"cooldownIndex","internalType":"uint256"},{"type":"uint256","name":"nextActionAt","internalType":"uint256"},{"type":"uint256","name":"siringWithId","internalType":"uint256"},{"type":"uint256","name":"birthTime","internalType":"uint256"},{"type":"uint256","name":"matronId","internalType":"uint256"},{"type":"uint256","name":"sireId","internalType":"uint256"},{"type":"uint256","name":"generation","internalType":"uint256"},{"type":"string","name":"genes","internalType":"string"},{"type":"uint256","name":"stages","internalType":"uint256"}],"name":"getPet","inputs":[{"type":"uint256","name":"_id","internalType":"uint256"}],"constant":true},{"type":"function","stateMutability":"nonpayable","payable":false,"outputs":[{"type":"uint256","name":"","internalType":"uint256"}],"name":"giveBirth","inputs":[{"type":"uint256","name":"_matronId","internalType":"uint256"}],"constant":false},{"type":"function","stateMutability":"view","payable":false,"outputs":[{"type":"bool","name":"","internalType":"bool"}],"name":"isPregnant","inputs":[{"type":"uint256","name":"_PetId","internalType":"uint256"}],"constant":true},{"type":"function","stateMutability":"view","payable":false,"outputs":[{"type":"bool","name":"","internalType":"bool"}],"name":"isReadyToBreed","inputs":[{"type":"uint256","name":"_PetId","internalType":"uint256"}],"constant":true},{"type":"function","stateMutability":"view","payable":false,"outputs":[{"type":"string","name":"","internalType":"string"}],"name":"name","inputs":[],"constant":true},{"type":"function","stateMutability":"view","payable":false,"outputs":[{"type":"address","name":"","internalType":"address"}],"name":"owner","inputs":[],"constant":true},{"type":"function","stateMutability":"view","payable":false,"outputs":[{"type":"address","name":"owner","internalType":"address"}],"name":"ownerOf","inputs":[{"type":"uint256","name":"_tokenId","internalType":"uint256"}],"constant":true},{"type":"function","stateMutability":"nonpayable","payable":false,"outputs":[],"name":"pause","inputs":[],"constant":false},{"type":"function","stateMutability":"view","payable":false,"outputs":[{"type":"bool","name":"","internalType":"bool"}],"name":"paused","inputs":[],"constant":true},{"type":"function","stateMutability":"view","payable":false,"outputs":[{"type":"uint256","name":"","internalType":"uint256"}],"name":"pregnantpets","inputs":[],"constant":true},{"type":"function","stateMutability":"view","payable":false,"outputs":[{"type":"address","name":"","internalType":"contract SaleClockAuction"}],"name":"saleAuction","inputs":[],"constant":true},{"type":"function","stateMutability":"view","payable":false,"outputs":[{"type":"address","name":"","internalType":"address"}],"name":"saleAuctionAddr","inputs":[],"constant":true},{"type":"function","stateMutability":"view","payable":false,"outputs":[{"type":"uint256","name":"","internalType":"uint256"}],"name":"secondsPerBlock","inputs":[],"constant":true},{"type":"function","stateMutability":"nonpayable","payable":false,"outputs":[],"name":"setAmountToAdulthood","inputs":[{"type":"uint256","name":"_amountToAdulthood","internalType":"uint256"}],"constant":false},{"type":"function","stateMutability":"nonpayable","payable":false,"outputs":[],"name":"setAmountToMiddleAge","inputs":[{"type":"uint256","name":"_amountToMiddleAge","internalType":"uint256"}],"constant":false},{"type":"function","stateMutability":"nonpayable","payable":false,"outputs":[],"name":"setAutoBirthFee","inputs":[{"type":"uint256","name":"val","internalType":"uint256"}],"constant":false},{"type":"function","stateMutability":"nonpayable","payable":false,"outputs":[],"name":"setGeneScienceAddress","inputs":[{"type":"address","name":"_address","internalType":"address"}],"constant":false},{"type":"function","stateMutability":"nonpayable","payable":false,"outputs":[],"name":"setSaleAuctionAddress","inputs":[{"type":"address","name":"_address","internalType":"address"}],"constant":false},{"type":"function","stateMutability":"nonpayable","payable":false,"outputs":[],"name":"setSecondsPerBlock","inputs":[{"type":"uint256","name":"secs","internalType":"uint256"}],"constant":false},{"type":"function","stateMutability":"nonpayable","payable":false,"outputs":[],"name":"setSiringAuctionAddress","inputs":[{"type":"address","name":"_address","internalType":"address"}],"constant":false},{"type":"function","stateMutability":"nonpayable","payable":false,"outputs":[],"name":"setStakingContract","inputs":[{"type":"address","name":"_stakingContract","internalType":"address"}],"constant":false},{"type":"function","stateMutability":"view","payable":false,"outputs":[{"type":"address","name":"","internalType":"address"}],"name":"sireAllowedToAddress","inputs":[{"type":"uint256","name":"","internalType":"uint256"}],"constant":true},{"type":"function","stateMutability":"view","payable":false,"outputs":[{"type":"address","name":"","internalType":"contract SiringClockAuction"}],"name":"siringAuction","inputs":[],"constant":true},{"type":"function","stateMutability":"view","payable":false,"outputs":[{"type":"address","name":"","internalType":"address"}],"name":"siringAuctionAddr","inputs":[],"constant":true},{"type":"function","stateMutability":"view","payable":false,"outputs":[{"type":"address","name":"","internalType":"address"}],"name":"stakingContract","inputs":[],"constant":true},{"type":"function","stateMutability":"view","payable":false,"outputs":[{"type":"bool","name":"","internalType":"bool"}],"name":"supportsInterface","inputs":[{"type":"bytes4","name":"_interfaceID","internalType":"bytes4"}],"constant":true},{"type":"function","stateMutability":"view","payable":false,"outputs":[{"type":"string","name":"","internalType":"string"}],"name":"symbol","inputs":[],"constant":true},{"type":"function","stateMutability":"view","payable":false,"outputs":[{"type":"uint256[]","name":"ownerTokens","internalType":"uint256[]"}],"name":"tokensOfOwner","inputs":[{"type":"address","name":"_owner","internalType":"address"}],"constant":true},{"type":"function","stateMutability":"view","payable":false,"outputs":[{"type":"uint256","name":"","internalType":"uint256"}],"name":"totalSupply","inputs":[],"constant":true},{"type":"function","stateMutability":"nonpayable","payable":false,"outputs":[],"name":"transfer","inputs":[{"type":"address","name":"_to","internalType":"address"},{"type":"uint256","name":"_tokenId","internalType":"uint256"}],"constant":false},{"type":"function","stateMutability":"nonpayable","payable":false,"outputs":[],"name":"transferFrom","inputs":[{"type":"address","name":"_from","internalType":"address"},{"type":"address","name":"_to","internalType":"address"},{"type":"uint256","name":"_tokenId","internalType":"uint256"}],"constant":false},{"type":"function","stateMutability":"nonpayable","payable":false,"outputs":[],"name":"transferOwnership","inputs":[{"type":"address","name":"newOwner","internalType":"address"}],"constant":false},{"type":"function","stateMutability":"nonpayable","payable":false,"outputs":[],"name":"unpause","inputs":[],"constant":false},{"type":"function","stateMutability":"nonpayable","payable":false,"outputs":[],"name":"updateGen0Price","inputs":[{"type":"uint256","name":"_gen0Price","internalType":"uint256"}],"constant":false},{"type":"function","stateMutability":"nonpayable","payable":false,"outputs":[],"name":"withdrawBalance","inputs":[],"constant":false}]
Deployed ByteCode
0x6080604052600436106103815760003560e01c80636fbde40d116101d1578063a376af0f11610102578063e6cbe351116100a0578063f2fde38b1161006f578063f2fde38b14610d98578063f35f7a2614610dcb578063fcca3daa14610df5578063fee983d614610e0a57610381565b8063e6cbe35114610d44578063ee99205c14610d59578063f1ca941014610d6e578063f2b47d5214610d8357610381565b8063b4a31a07116100dc578063b4a31a0714610ca8578063be61219114610cbd578063d3e6f49f14610ce7578063d58d0e1b14610d1157610381565b8063a376af0f14610c45578063a9059cbb14610c5a578063b0c35c0514610c9357610381565b806388c2a0bf1161016f57806395d89b411161014957806395d89b4114610b8a57806399d5175e14610b9f5780639d6fac6f14610bcf5780639dd373b914610c1257610381565b806388c2a0bf14610b155780638da5cb5b14610b3f57806392f64cce14610b5457610381565b80637a7d4937116101ab5780637a7d493714610a535780637d9b6a1514610a685780638456cb5914610a7d5780638462151c14610a9257610381565b80636fbde40d146109b457806370a08231146109e7578063795e153514610a1a57610381565b8063388d67be116102b65780634dfff04f116102545780635c975abb116102235780635c975abb1461094b5780635fd8c710146109605780636352211e146109755780636bbb0f0e1461099f57610381565b80634dfff04f146107ce5780635663896e1461080757806359d55194146108315780635c295f5a1461092157610381565b806346116e6f1161029057806346116e6f1461070e57806346d22c70146107385780634ad8c938146107685780634b85fd55146107a457610381565b8063388d67be146106a85780633d7d3f5a146106bd5780633f4ba83a146106f957610381565b806314001f4c116103235780631ee12453116102fd5780631ee12453146105f357806321717ebf1461061d57806323b872dd1461063257806324e7a38a1461067557610381565b806314001f4c1461058157806318160ddd146105b45780631940a936146105c957610381565b8063095ea7b31161035f578063095ea7b3146104ba5780630d39f99e146104f35780630f47ec221461052457806312065fe01461055a57610381565b8063012a4d80146103af57806301ffc9a7146103e857806306fdde0314610430575b6009546001600160a01b03163314806103a45750600a546001600160a01b031633145b6103ad57600080fd5b005b3480156103bb57600080fd5b506103ad600480360360408110156103d257600080fd5b506001600160a01b038135169060200135610e34565b3480156103f457600080fd5b5061041c6004803603602081101561040b57600080fd5b50356001600160e01b031916610e9d565b604080519115158252519081900360200190f35b34801561043c57600080fd5b50610445611078565b6040805160208082528351818301528351919283929083019185019080838360005b8381101561047f578181015183820152602001610467565b50505050905090810190601f1680156104ac5780820380516001836020036101000a031916815260200191505b509250505060405180910390f35b3480156104c657600080fd5b506103ad600480360360408110156104dd57600080fd5b506001600160a01b03813516906020013561109f565b3480156104ff57600080fd5b5061050861111f565b604080516001600160a01b039092168252519081900360200190f35b34801561053057600080fd5b506103ad6004803603606081101561054757600080fd5b508035906020810135906040013561112e565b34801561056657600080fd5b5061056f61146e565b60408051918252519081900360200190f35b34801561058d57600080fd5b506103ad600480360360208110156105a457600080fd5b50356001600160a01b03166114ea565b3480156105c057600080fd5b5061056f6115db565b3480156105d557600080fd5b5061041c600480360360208110156105ec57600080fd5b50356115e5565b3480156105ff57600080fd5b506103ad6004803603602081101561061657600080fd5b503561161d565b34801561062957600080fd5b5061050861166f565b34801561063e57600080fd5b506103ad6004803603606081101561065557600080fd5b506001600160a01b0381358116916020810135909116906040013561167e565b34801561068157600080fd5b506103ad6004803603602081101561069857600080fd5b50356001600160a01b03166116ef565b3480156106b457600080fd5b5061056f61175e565b3480156106c957600080fd5b506103ad600480360360808110156106e057600080fd5b5080359060208101359060408101359060600135611764565b34801561070557600080fd5b506103ad6118b2565b34801561071a57600080fd5b506105086004803603602081101561073157600080fd5b5035611924565b34801561074457600080fd5b5061041c6004803603604081101561075b57600080fd5b508035906020013561193f565b34801561077457600080fd5b506103ad6004803603608081101561078b57600080fd5b50803590602081013590604081013590606001356119be565b3480156107b057600080fd5b506103ad600480360360208110156107c757600080fd5b5035611af0565b3480156107da57600080fd5b506103ad600480360360408110156107f157600080fd5b506001600160a01b038135169060200135611b42565b34801561081357600080fd5b506103ad6004803603602081101561082a57600080fd5b5035611b9a565b34801561083d57600080fd5b5061085b6004803603602081101561085457600080fd5b5035611c00565b604051808c1515151581526020018b1515151581526020018a815260200189815260200188815260200187815260200186815260200185815260200184815260200180602001838152602001828103825284818151815260200191508051906020019080838360005b838110156108dc5781810151838201526020016108c4565b50505050905090810190601f1680156109095780820380516001836020036101000a031916815260200191505b509c5050505050505050505050505060405180910390f35b34801561092d57600080fd5b506105086004803603602081101561094457600080fd5b5035611d26565b34801561095757600080fd5b5061041c611d41565b34801561096c57600080fd5b506103ad611d51565b34801561098157600080fd5b506105086004803603602081101561099857600080fd5b5035611e3c565b3480156109ab57600080fd5b50610508611e5e565b3480156109c057600080fd5b506103ad600480360360208110156109d757600080fd5b50356001600160a01b0316611e6d565b3480156109f357600080fd5b5061056f60048036036020811015610a0a57600080fd5b50356001600160a01b0316611f5e565b348015610a2657600080fd5b506103ad60048036036040811015610a3d57600080fd5b506001600160a01b038135169060200135611f79565b348015610a5f57600080fd5b5061056f612074565b348015610a7457600080fd5b5061056f61207a565b348015610a8957600080fd5b506103ad612080565b348015610a9e57600080fd5b50610ac560048036036020811015610ab557600080fd5b50356001600160a01b03166120f9565b60408051602080825283518183015283519192839290830191858101910280838360005b83811015610b01578181015183820152602001610ae9565b505050509050019250505060405180910390f35b348015610b2157600080fd5b5061056f60048036036020811015610b3857600080fd5b50356121c0565b348015610b4b57600080fd5b50610508612470565b348015610b6057600080fd5b506103ad60048036036060811015610b7757600080fd5b508035906020810135906040013561247f565b348015610b9657600080fd5b50610445612721565b348015610bab57600080fd5b506103ad60048036036040811015610bc257600080fd5b5080359060200135612740565b348015610bdb57600080fd5b50610bf960048036036020811015610bf257600080fd5b5035612904565b6040805163ffffffff9092168252519081900360200190f35b348015610c1e57600080fd5b506103ad60048036036020811015610c3557600080fd5b50356001600160a01b0316612931565b348015610c5157600080fd5b5061056f6129a0565b348015610c6657600080fd5b506103ad60048036036040811015610c7d57600080fd5b506001600160a01b0381351690602001356129a6565b348015610c9f57600080fd5b5061056f612a3a565b348015610cb457600080fd5b5061056f612a40565b348015610cc957600080fd5b506103ad60048036036020811015610ce057600080fd5b5035612a46565b348015610cf357600080fd5b5061041c60048036036020811015610d0a57600080fd5b5035612a98565b348015610d1d57600080fd5b506103ad60048036036020811015610d3457600080fd5b50356001600160a01b0316612b59565b348015610d5057600080fd5b50610508612bc6565b348015610d6557600080fd5b50610508612bd5565b348015610d7a57600080fd5b5061056f612be4565b348015610d8f57600080fd5b50610508612bea565b348015610da457600080fd5b506103ad60048036036020811015610dbb57600080fd5b50356001600160a01b0316612bf9565b348015610dd757600080fd5b5061050860048036036020811015610dee57600080fd5b5035612c74565b348015610e0157600080fd5b50610508612c8f565b348015610e1657600080fd5b506103ad60048036036020811015610e2d57600080fd5b5035612c9e565b6000546001600160a01b03163314610e81576040805162461bcd60e51b815260206004820181905260248201526000805160206135df833981519152604482015290519081900360640190fd5b600f80546001019055610e98600080808486612cf0565b505050565b604080517f737570706f727473496e74657266616365286279746573342900000000000000815290519081900360190190206000906001600160e01b0319838116911614806110705750604080517f746f6b656e4d657461646174612875696e743235362c737472696e67290000008152815190819003601d01812075746f6b656e734f664f776e657228616464726573732960501b82529151908190036016018120908060256135ba8239604080519182900360250182207f7472616e7366657228616464726573732c75696e743235362900000000000000835281519283900360190183207f617070726f766528616464726573732c75696e74323536290000000000000000845282519384900360180184206f6f776e65724f662875696e743235362960801b855283519485900360100185207162616c616e63654f6628616464726573732960701b865284519586900360120186206c746f74616c537570706c79282960981b8752855196879003600d0187206773796d626f6c282960c01b88528651978890036008018820656e616d65282960d01b89529651978890036006019097206001600160e01b03198d81169190971890971818181818189390931893909318919091169190911490505b90505b919050565b6040518060400160405280600b81526020016a135e481119519a4814195d60aa1b81525081565b600054600160a01b900460ff16156110b657600080fd5b6110c03382612f2e565b6110c957600080fd5b6110d38183612f4e565b604080513381526001600160a01b038416602082015280820183905290517f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b9259181900360600190a15050565b600b546001600160a01b031681565b600054600160a01b900460ff161561114557600080fd5b600b54604080516323b872dd60e01b81523360048201523060248201526044810184905290516001600160a01b03909216916323b872dd916064808201926020929091908290030181600087803b15801561119f57600080fd5b505af11580156111b3573d6000803e3d6000fd5b505050506040513d60208110156111c957600080fd5b50516111d457600080fd5b6111de3383612f2e565b611222576040805162461bcd60e51b815260206004820152601060248201526f2737ba1036b0ba3937b71037bbb732b960811b604482015290519081900360640190fd5b61122b82612a98565b611271576040805162461bcd60e51b8152602060048201526012602482015271139bdd081c9958591e481d1bc8189c99595960721b604482015290519081900360640190fd5b61127b8284612f7c565b6112cc576040805162461bcd60e51b815260206004820152601c60248201527f43616e27742062726565642077697468207669612061756374696f6e00000000604482015290519081900360640190fd5b600a54604080516362ae87ab60e11b81526004810186905290516000926001600160a01b03169163c55d0f56916024808301926020929190829003018186803b15801561131857600080fd5b505afa15801561132c573d6000803e3d6000fd5b505050506040513d602081101561134257600080fd5b5051600c54909150810182101561135857600080fd5b600b546015546040805163a9059cbb60e01b81526001600160a01b039283166004820152602481018690529051919092169163a9059cbb9160448083019260209291908290030181600087803b1580156113b157600080fd5b505af11580156113c5573d6000803e3d6000fd5b505050506040513d60208110156113db57600080fd5b50516113e657600080fd5b600a5460408051630b30c8ff60e31b8152600481018790526024810185905290516001600160a01b039092169163598647f89160448082019260009290919082900301818387803b15801561143a57600080fd5b505af115801561144e573d6000803e3d6000fd5b505050506114688363ffffffff168563ffffffff16612fc7565b50505050565b600b54604080516370a0823160e01b815230600482015290516000926001600160a01b0316916370a08231916024808301926020929190829003018186803b1580156114b957600080fd5b505afa1580156114cd573d6000803e3d6000fd5b505050506040513d60208110156114e357600080fd5b5051905090565b6000546001600160a01b03163314611537576040805162461bcd60e51b815260206004820181905260248201526000805160206135df833981519152604482015290519081900360640190fd5b6000819050806001600160a01b03166376190f8f6040518163ffffffff1660e01b815260040160206040518083038186803b15801561157557600080fd5b505afa158015611589573d6000803e3d6000fd5b505050506040513d602081101561159f57600080fd5b50516115aa57600080fd5b600a80546001600160a01b039283166001600160a01b03199182161790915560158054939092169216919091179055565b6004546000190190565b60008082116115f357600080fd5b6004828154811061160057fe5b906000526020600020906006020160040154600014159050919050565b6000546001600160a01b0316331461166a576040805162461bcd60e51b815260206004820181905260248201526000805160206135df833981519152604482015290519081900360640190fd5b601055565b600a546001600160a01b031681565b600054600160a01b900460ff161561169557600080fd5b6001600160a01b0382166116a857600080fd5b6001600160a01b0382163014156116be57600080fd5b6116c833826130d4565b6116d157600080fd5b6116db8382612f2e565b6116e457600080fd5b610e988383836130f4565b6000546001600160a01b0316331461173c576040805162461bcd60e51b815260206004820181905260248201526000805160206135df833981519152604482015290519081900360640190fd5b600e80546001600160a01b0319166001600160a01b0392909216919091179055565b600d5481565b600054600160a01b900460ff161561177b57600080fd5b6117853385612f2e565b6117c8576040805162461bcd60e51b815260206004820152600f60248201526e2737ba102832ba24b21037bbb732b960891b604482015290519081900360640190fd5b6117d1846115e5565b15611815576040805162461bcd60e51b815260206004820152600f60248201526e14195d081a5cc81c1c9959db985b9d608a1b604482015290519081900360640190fd5b60095461182c9085906001600160a01b0316612f4e565b600954604080516313f5f20560e11b81526004810187905260248101869052604481018590526064810184905233608482015290516001600160a01b03909216916327ebe40a9160a48082019260009290919082900301818387803b15801561189457600080fd5b505af11580156118a8573d6000803e3d6000fd5b5050505050505050565b6000546001600160a01b031633146118ff576040805162461bcd60e51b815260206004820181905260248201526000805160206135df833981519152604482015290519081900360640190fd5b600054600160a01b900460ff1661191557600080fd5b6000805460ff60a01b19169055565b6008602052600090815260409020546001600160a01b031681565b600080831161194d57600080fd5b6000821161195a57600080fd5b60006004848154811061196957fe5b9060005260206000209060060201905060006004848154811061198857fe5b906000526020600020906006020190506119a4828683876131d6565b80156119b557506119b584866132ac565b95945050505050565b600054600160a01b900460ff16156119d557600080fd5b6119df3385612f2e565b611a22576040805162461bcd60e51b815260206004820152600f60248201526e2737ba102832ba24b21037bbb732b960891b604482015290519081900360640190fd5b611a2b84612a98565b611a71576040805162461bcd60e51b8152602060048201526012602482015271139bdd081c9958591e481d1bc8189c99595960721b604482015290519081900360640190fd5b600a54611a889085906001600160a01b0316612f4e565b600a54604080516313f5f20560e11b81526004810187905260248101869052604481018590526064810184905233608482015290516001600160a01b03909216916327ebe40a9160a48082019260009290919082900301818387803b15801561189457600080fd5b6000546001600160a01b03163314611b3d576040805162461bcd60e51b815260206004820181905260248201526000805160206135df833981519152604482015290519081900360640190fd5b600c55565b600054600160a01b900460ff1615611b5957600080fd5b611b633382612f2e565b611b6c57600080fd5b600090815260086020526040902080546001600160a01b0319166001600160a01b0392909216919091179055565b6000546001600160a01b03163314611be7576040805162461bcd60e51b815260206004820181905260248201526000805160206135df833981519152604482015290519081900360640190fd5b60015463ffffffff168110611bfb57600080fd5b600355565b6000806000806000806000806000606060008060048d81548110611c2057fe5b906000526020600020906006020190508060040154600014159b50438160010160089054906101000a90046001600160401b03166001600160401b031611159a508060050160009054906101000a900461ffff1661ffff1699508060010160089054906101000a90046001600160401b03166001600160401b03169850806004015497508060010160009054906101000a90046001600160401b03166001600160401b0316965080600201549550806003015494508060050160029054906101000a900461ffff1661ffff169350611cfb8160000154613301565b92508060050160049054906101000a900461ffff1661ffff1691505091939597999b90929496989a50565b6005602052600090815260409020546001600160a01b031681565b600054600160a01b900460ff1681565b6000546001600160a01b03163314611d9e576040805162461bcd60e51b815260206004820181905260248201526000805160206135df833981519152604482015290519081900360640190fd5b600b546000546001600160a01b039182169163a9059cbb9116611dbf61146e565b6040518363ffffffff1660e01b815260040180836001600160a01b03166001600160a01b0316815260200182815260200192505050602060405180830381600087803b158015611e0e57600080fd5b505af1158015611e22573d6000803e3d6000fd5b505050506040513d6020811015611e3857600080fd5b5050565b6000818152600560205260409020546001600160a01b03168061107357600080fd5b6016546001600160a01b031681565b6000546001600160a01b03163314611eba576040805162461bcd60e51b815260206004820181905260248201526000805160206135df833981519152604482015290519081900360640190fd5b6000819050806001600160a01b03166385b861886040518163ffffffff1660e01b815260040160206040518083038186803b158015611ef857600080fd5b505afa158015611f0c573d6000803e3d6000fd5b505050506040513d6020811015611f2257600080fd5b5051611f2d57600080fd5b600980546001600160a01b039283166001600160a01b03199182161790915560168054939092169216919091179055565b6001600160a01b031660009081526006602052604090205490565b601054811015611fc1576040805162461bcd60e51b815260206004820152600e60248201526d1253959053125108105353d5539560921b604482015290519081900360640190fd5b600b54604080516323b872dd60e01b81523360048201523060248201526044810184905290516001600160a01b03909216916323b872dd916064808201926020929091908290030181600087803b15801561201b57600080fd5b505af115801561202f573d6000803e3d6000fd5b505050506040513d602081101561204557600080fd5b505161205057600080fd5b600f8054600101905560006120636133c5565b905061146860008060008487612cf0565b60035481565b60105481565b6000546001600160a01b031633146120cd576040805162461bcd60e51b815260206004820181905260248201526000805160206135df833981519152604482015290519081900360640190fd5b600054600160a01b900460ff16156120e457600080fd5b6000805460ff60a01b1916600160a01b179055565b6060600061210683611f5e565b905080612123575050604080516000815260208101909152611073565b60608160405190808252806020026020018201604052801561214f578160200160208202803883390190505b509050600061215c6115db565b9050600060015b8281116121b3576000818152600560205260409020546001600160a01b03888116911614156121ab578084838151811061219957fe5b60209081029190910101526001909101905b600101612163565b8395505050505050611073565b60008054600160a01b900460ff16156121d857600080fd5b6000600483815481106121e757fe5b6000918252602090912060069091020160018101549091506001600160401b0316612247576040805162461bcd60e51b815260206004820152600b60248201526a125b9d985b1a59081c195d60aa1b604482015290519081900360640190fd5b60408051610120810182528254815260018301546001600160401b038082166020840152600160401b90910416918101919091526002820154606082015260038201546080820152600482015460a0820152600582015461ffff80821660c0840152620100008204811660e0840152600160201b909104166101008201526122ce90613448565b612311576040805162461bcd60e51b815260206004820152600f60248201526e09cdee840e4cac2c8f240c4d2e4e8d608b1b604482015290519081900360640190fd5b60008160040154905060006004828154811061232957fe5b6000918252602090912060058086015460069093029091019081015490925061ffff6201000092839004811692909104168110156123725750600581015462010000900461ffff165b600e5484548354600187015460408051630d9f5aed60e01b8152600481019490945260248401929092526000196001600160401b03600160401b909204821601166044830152516000926001600160a01b031691630d9f5aed916064808301926020929190829003018186803b1580156123eb57600080fd5b505afa1580156123ff573d6000803e3d6000fd5b505050506040513d602081101561241557600080fd5b505160008881526005602052604081205460048801549293506001600160a01b03169161244d908a9061ffff60018801168686612cf0565b60006004909801979097555050600d805460001901905550929350505050919050565b6000546001600160a01b031681565b600054600160a01b900460ff161561249657600080fd5b600c548110156124dc576040805162461bcd60e51b815260206004820152600c60248201526b135d5cdd081c185e5b595b9d60a21b604482015290519081900360640190fd5b600b54604080516323b872dd60e01b81523360048201523060248201526044810184905290516001600160a01b03909216916323b872dd916064808201926020929091908290030181600087803b15801561253657600080fd5b505af115801561254a573d6000803e3d6000fd5b505050506040513d602081101561256057600080fd5b505161256b57600080fd5b6125753384612f2e565b61257e57600080fd5b61258882846132ac565b61259157600080fd5b6000600484815481106125a057fe5b6000918252602091829020604080516101208101825260069093029091018054835260018101546001600160401b0380821695850195909552600160401b9004909316908201526002820154606082015260038201546080820152600482015460a0820152600582015461ffff80821660c0840152620100008204811660e0840152600160201b9091041661010082015290915061263d90613471565b61264657600080fd5b60006004848154811061265557fe5b6000918252602091829020604080516101208101825260069093029091018054835260018101546001600160401b0380821695850195909552600160401b9004909316908201526002820154606082015260038201546080820152600482015460a0820152600582015461ffff80821660c0840152620100008204811660e0840152600160201b909104166101008201529091506126f290613471565b6126fb57600080fd5b612707828683876131d6565b61271057600080fd5b61271a8585612fc7565b5050505050565b6040518060400160405280600381526020016204d44560ec1b81525081565b600b54604080516323b872dd60e01b81523360048201523060248201526044810184905290516001600160a01b03909216916323b872dd916064808201926020929091908290030181600087803b15801561279a57600080fd5b505af11580156127ae573d6000803e3d6000fd5b505050506040513d60208110156127c457600080fd5b50516127cf57600080fd5b6000600483815481106127de57fe5b90600052602060002090600602019050601354821415612877576005810154600160201b900461ffff1660011461284e576040805162461bcd60e51b815260206004820152600f60248201526e494e56414c4944205354414745203160881b604482015290519081900360640190fd5b60058101805461ffff600160201b80830482166001019091160265ffff00000000199091161790555b601454821415610e98576005810154600160201b900461ffff166002146128d7576040805162461bcd60e51b815260206004820152600f60248201526e24a72b20a624a21029aa20a3a2901960891b604482015290519081900360640190fd5b60058101805461ffff600160201b80830482166001019091160265ffff0000000019909116179055505050565b600181600e811061291157fe5b60089182820401919006600402915054906101000a900463ffffffff1681565b6000546001600160a01b0316331461297e576040805162461bcd60e51b815260206004820181905260248201526000805160206135df833981519152604482015290519081900360640190fd5b601180546001600160a01b0319166001600160a01b0392909216919091179055565b60135481565b600054600160a01b900460ff16156129bd57600080fd5b6001600160a01b0382166129d057600080fd5b6001600160a01b0382163014156129e657600080fd5b6009546001600160a01b0383811691161415612a0157600080fd5b600a546001600160a01b0383811691161415612a1c57600080fd5b612a263382612f2e565b612a2f57600080fd5b611e383383836130f4565b600c5481565b60145481565b6000546001600160a01b03163314612a93576040805162461bcd60e51b815260206004820181905260248201526000805160206135df833981519152604482015290519081900360640190fd5b601455565b6000808211612aa657600080fd5b600060048381548110612ab557fe5b6000918252602091829020604080516101208101825260069093029091018054835260018101546001600160401b0380821695850195909552600160401b9004909316908201526002820154606082015260038201546080820152600482015460a0820152600582015461ffff80821660c0840152620100008204811660e0840152600160201b90910416610100820152909150612b5290613471565b9392505050565b6011546001600160a01b03163314612ba25760405162461bcd60e51b815260040180806020018281038252602b81526020018061358f602b913960400191505060405180910390fd5b600f805460010190556000612bb56133c5565b9050610e9860008060008486612cf0565b6009546001600160a01b031681565b6011546001600160a01b031681565b600f5481565b600e546001600160a01b031681565b6000546001600160a01b03163314612c46576040805162461bcd60e51b815260206004820181905260248201526000805160206135df833981519152604482015290519081900360640190fd5b6001600160a01b03811615612c7157600080546001600160a01b0319166001600160a01b0383161790555b50565b6007602052600090815260409020546001600160a01b031681565b6015546001600160a01b031681565b6000546001600160a01b03163314612ceb576040805162461bcd60e51b815260206004820181905260248201526000805160206135df833981519152604482015290519081900360640190fd5b601355565b600060028404600d61ffff82161115612d075750600d5b612d0f613542565b604051806101200160405280868152602001426001600160401b0316815260200160006001600160401b031681526020018963ffffffff1681526020018863ffffffff168152602001600081526020018361ffff1681526020018761ffff168152602001600161ffff16815250905060006001600483908060018154018082558091505090600182039060005260206000209060060201600090919290919091506000820151816000015560208201518160010160006101000a8154816001600160401b0302191690836001600160401b0316021790555060408201518160010160086101000a8154816001600160401b0302191690836001600160401b03160217905550606082015181600201556080820151816003015560a0820151816004015560c08201518160050160006101000a81548161ffff021916908361ffff16021790555060e08201518160050160026101000a81548161ffff021916908361ffff1602179055506101008201518160050160046101000a81548161ffff021916908361ffff16021790555050500390507f0a5311bd2a6608f08a180df2ee7c5946819a649b204b554bb8e39825b2c50ad5858284606001518560800151866000015160405180866001600160a01b03166001600160a01b031681526020018581526020018481526020018381526020018281526020019550505050505060405180910390a1612f22600086836130f4565b98975050505050505050565b6000908152600560205260409020546001600160a01b0391821691161490565b60009182526007602052604090912080546001600160a01b0319166001600160a01b03909216919091179055565b60008060048481548110612f8c57fe5b90600052602060002090600602019050600060048481548110612fab57fe5b906000526020600020906006020190506119b5828683876131d6565b600060048281548110612fd657fe5b90600052602060002090600602019050600060048481548110612ff557fe5b906000526020600020906006020190508263ffffffff16816004018190555061301d82613499565b61302681613499565b600084815260086020908152604080832080546001600160a01b031990811690915586845281842080549091169055600d805460019081019091558784526005835292819020549284015481516001600160a01b039094168452918301879052828101869052600160401b9091046001600160401b03166060830152517f241ea03ca20251805084d27d4440371c34a0b85ff108f6bb5611248f73818b80916080908290030190a150505050565b6000908152600760205260409020546001600160a01b0391821691161490565b6001600160a01b038083166000818152600660209081526040808320805460010190558583526005909152902080546001600160a01b0319169091179055831615613187576001600160a01b038316600090815260066020908152604080832080546000190190558383526008825280832080546001600160a01b03199081169091556007909252909120805490911690555b604080516001600160a01b0380861682528416602082015280820183905290517fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef9181900360600190a1505050565b6000818414156131e8575060006132a4565b81856002015414806131fd5750818560030154145b1561320a575060006132a4565b838360020154148061321f5750838360030154145b1561322c575060006132a4565b6002830154158061323f57506002850154155b1561324c575060016132a4565b846002015483600201541480613269575084600301548360020154145b15613276575060006132a4565b846002015483600301541480613293575084600301548360030154145b156132a0575060006132a4565b5060015b949350505050565b60008181526005602052604080822054848352908220546001600160a01b039182169116808214806119b557506000858152600860205260409020546001600160a01b03908116908316149250505092915050565b606081806133285750506040805180820190915260018152600360fc1b6020820152611073565b8060005b811561334057600101600a8204915061332c565b6060816040519080825280601f01601f19166020018201604052801561336d576020820181803883390190505b50905060001982015b84156133bb57600a850660300160f81b8282806001900393508151811061339957fe5b60200101906001600160f81b031916908160001a905350600a85049450613376565b5095945050505050565b6012805460408051434060208083019190915242828401526060808301859052835180840390910181526080909201909252805191012060019091019091557d90e40fbeea1d3a4abc8955e946fe31cdcf66f634e100000000000000000090067d0e7d34c64a9c85d4460dbbca87196b61618a4bd2168000000000000000000190565b60008160a00151600014158015611070575050604001516001600160401b034381169116111590565b60008160a001516000148015611070575050604001516001600160401b034381169116111590565b600354600582015443919060019061ffff16600e81106134b557fe5b600891828204019190066004029054906101000a900463ffffffff1663ffffffff16816134de57fe5b6001840180546fffffffffffffffff00000000000000001916600160401b93909204939093016001600160401b0316919091021790556005810154600d61ffff9091161015612c7157600501805461ffff8082166001011661ffff19909116179055565b6040805161012081018252600080825260208201819052918101829052606081018290526080810182905260a0810182905260c0810182905260e081018290526101008101919091529056fe4f776e61626c653a2063616c6c6572206973206e6f7420746865207374616b696e6720636f6e74726163747472616e7366657246726f6d28616464726573732c616464726573732c75696e74323536294f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572a265627a7a72315820d9dc322dc23884a0eda3010b0bcad8e2e3f7f61fdd1e593ba6af9cfbfbfe703f64736f6c63430005110032