文件 1 的 1:DogCore.sol
pragma solidity ^0.4.18;
contract Ownable {
address public owner;
function Ownable() public {
owner = msg.sender;
}
modifier onlyOwner() {
require(msg.sender == owner);
_;
}
function transferOwnership(address newOwner) public onlyOwner {
if (newOwner != address(0)) {
owner = newOwner;
}
}
}
contract ERC721 {
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;
event Transfer(address from, address to, uint256 tokenId);
event Approval(address owner, address approved, uint256 tokenId);
function supportsInterface(bytes4 _interfaceID) external view returns (bool);
}
contract GeneScienceInterface {
function isGeneScience() public pure returns (bool);
function mixGenes(uint256 genes1, uint256 genes2, uint256 targetBlock) public returns (uint256);
}
contract VariationInterface {
function isVariation() public pure returns(bool);
function createVariation(uint256 _gene, uint256 _totalSupply) public returns (uint8);
function registerVariation(uint256 _dogId, address _owner) public;
}
contract LotteryInterface {
function isLottery() public pure returns (bool);
function checkLottery(uint256 genes) public pure returns (uint8 lotclass);
function registerLottery(uint256 _dogId) public payable returns (uint8);
function getCLottery()
public
view
returns (
uint8[7] luckyGenes1,
uint256 totalAmount1,
uint256 openBlock1,
bool isReward1,
uint256 term1,
uint8 currentGenes1,
uint256 tSupply,
uint256 sPoolAmount1,
uint256[] reward1
);
}
contract DogAccessControl {
event ContractUpgrade(address newContract);
address public ceoAddress;
address public cfoAddress;
address public cooAddress;
bool public paused = false;
modifier onlyCEO() {
require(msg.sender == ceoAddress);
_;
}
modifier onlyCFO() {
require(msg.sender == cfoAddress);
_;
}
modifier onlyCOO() {
require(msg.sender == cooAddress);
_;
}
modifier onlyCLevel() {
require(msg.sender == cooAddress || msg.sender == ceoAddress || msg.sender == cfoAddress);
_;
}
function setCEO(address _newCEO) external onlyCEO {
require(_newCEO != address(0));
ceoAddress = _newCEO;
}
function setCFO(address _newCFO) external onlyCEO {
require(_newCFO != address(0));
cfoAddress = _newCFO;
}
function setCOO(address _newCOO) external onlyCEO {
require(_newCOO != address(0));
cooAddress = _newCOO;
}
modifier whenNotPaused() {
require(!paused);
_;
}
modifier whenPaused {
require(paused);
_;
}
function pause() external onlyCLevel whenNotPaused {
paused = true;
}
function unpause() public onlyCEO whenPaused {
paused = false;
}
}
contract DogBase is DogAccessControl {
event Birth(address owner, uint256 dogId, uint256 matronId, uint256 sireId, uint256 genes, uint16 generation, uint8 variation, uint256 gen0, uint256 birthTime, uint256 income, uint16 cooldownIndex);
event Transfer(address from, address to, uint256 tokenId);
struct Dog {
uint256 genes;
uint256 birthTime;
uint64 cooldownEndBlock;
uint32 matronId;
uint32 sireId;
uint32 siringWithId;
uint16 cooldownIndex;
uint16 generation;
uint8 variation;
uint256 gen0;
}
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(24 hours),
uint32(2 days),
uint32(3 days),
uint32(5 days)
];
uint256 public secondsPerBlock = 15;
Dog[] dogs;
mapping (uint256 => address) dogIndexToOwner;
mapping (address => uint256) ownershipTokenCount;
mapping (uint256 => address) public dogIndexToApproved;
mapping (uint256 => address) public sireAllowedToAddress;
SaleClockAuction public saleAuction;
SiringClockAuction public siringAuction;
VariationInterface public variation;
LotteryInterface public lottery;
uint256 public autoBirthFee = 7500 szabo;
uint256 public gen0Profit = 500 szabo;
uint256 public creationProfit = 1000 szabo;
mapping (address => uint256) public profit;
function _sendMoney(address _to, uint256 _money) internal {
spendMoney += _money;
require(address(this).balance >= spendMoney);
profit[_to] += _money;
}
function sendMoney(address _to, uint256 _money) external {
require(msg.sender == address(lottery) || msg.sender == address(variation));
_sendMoney(_to, _money);
}
event Withdraw(address _owner, uint256 _value);
function withdraw() public {
uint256 value = profit[msg.sender];
require(value > 0);
msg.sender.transfer(value);
spendMoney -= value;
delete profit[msg.sender];
Withdraw(msg.sender, value);
}
uint256 public spendMoney;
function setGen0Profit(uint256 _value) public onlyCEO {
uint256 ration = _value * 100 / autoBirthFee;
require(ration > 0);
require(_value <= 100);
gen0Profit = _value;
}
function setCreationProfit(uint256 _value) public onlyCEO {
uint256 ration = _value * 100 / autoBirthFee;
require(ration > 0);
require(_value <= 100);
creationProfit = _value;
}
function _transfer(address _from, address _to, uint256 _tokenId) internal {
ownershipTokenCount[_to]++;
dogIndexToOwner[_tokenId] = _to;
if (_from != address(0)) {
ownershipTokenCount[_from]--;
delete sireAllowedToAddress[_tokenId];
delete dogIndexToApproved[_tokenId];
}
Transfer(_from, _to, _tokenId);
}
function _createDog(
uint256 _matronId,
uint256 _sireId,
uint256 _generation,
uint256 _genes,
address _owner,
uint8 _variation,
uint256 _gen0,
bool _isGen0Siring
)
internal
returns (uint)
{
require(_matronId == uint256(uint32(_matronId)));
require(_sireId == uint256(uint32(_sireId)));
require(_generation == uint256(uint16(_generation)));
uint16 cooldownIndex = uint16(_generation / 2);
if (cooldownIndex > 13) {
cooldownIndex = 13;
}
Dog memory _dog = Dog({
genes: _genes,
birthTime: block.number,
cooldownEndBlock: 0,
matronId: uint32(_matronId),
sireId: uint32(_sireId),
siringWithId: 0,
cooldownIndex: cooldownIndex,
generation: uint16(_generation),
variation : uint8(_variation),
gen0 : _gen0
});
uint256 newDogId = dogs.push(_dog) - 1;
require(newDogId < 23887872);
Birth(
_owner,
newDogId,
uint256(_dog.matronId),
uint256(_dog.sireId),
_dog.genes,
uint16(_generation),
_variation,
_gen0,
block.number,
_isGen0Siring ? 0 : gen0Profit,
cooldownIndex
);
_transfer(0, _owner, newDogId);
return newDogId;
}
function setSecondsPerBlock(uint256 secs) external onlyCLevel {
require(secs < cooldowns[0]);
secondsPerBlock = secs;
}
}
contract DogOwnership is DogBase, ERC721 {
string public constant name = "HelloDog";
string public constant symbol = "HD";
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)"));
function supportsInterface(bytes4 _interfaceID) external view returns (bool)
{
return ((_interfaceID == InterfaceSignature_ERC165) || (_interfaceID == InterfaceSignature_ERC721));
}
function _owns(address _claimant, uint256 _tokenId) internal view returns (bool) {
return dogIndexToOwner[_tokenId] == _claimant;
}
function _approvedFor(address _claimant, uint256 _tokenId) internal view returns (bool) {
return dogIndexToApproved[_tokenId] == _claimant;
}
function _approve(uint256 _tokenId, address _approved) internal {
dogIndexToApproved[_tokenId] = _approved;
}
function balanceOf(address _owner) public view returns (uint256 count) {
return ownershipTokenCount[_owner];
}
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);
}
function approve(
address _to,
uint256 _tokenId
)
external
whenNotPaused
{
require(_owns(msg.sender, _tokenId));
_approve(_tokenId, _to);
Approval(msg.sender, _to, _tokenId);
}
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);
}
function totalSupply() public view returns (uint) {
return dogs.length - 1;
}
function ownerOf(uint256 _tokenId)
external
view
returns (address owner)
{
owner = dogIndexToOwner[_tokenId];
require(owner != address(0));
}
}
contract DogBreeding is DogOwnership {
event Pregnant(address owner, uint256 matronId, uint256 sireId, uint256 matronCooldownEndBlock, uint256 sireCooldownEndBlock, uint256 matronCooldownIndex, uint256 sireCooldownIndex);
uint256 public pregnantDogs;
GeneScienceInterface public geneScience;
function setGeneScienceAddress(address _address) external onlyCEO {
GeneScienceInterface candidateContract = GeneScienceInterface(_address);
require(candidateContract.isGeneScience());
geneScience = candidateContract;
}
function _isReadyToBreed(Dog _dog) internal view returns (bool) {
return (_dog.siringWithId == 0) && (_dog.cooldownEndBlock <= uint64(block.number));
}
function _isSiringPermitted(uint256 _sireId, uint256 _matronId) internal view returns (bool) {
address matronOwner = dogIndexToOwner[_matronId];
address sireOwner = dogIndexToOwner[_sireId];
return (matronOwner == sireOwner || sireAllowedToAddress[_sireId] == matronOwner);
}
function _triggerCooldown(Dog storage _dog) internal {
_dog.cooldownEndBlock = uint64((cooldowns[_dog.cooldownIndex]/secondsPerBlock) + block.number);
if (_dog.cooldownIndex < 13) {
_dog.cooldownIndex += 1;
}
}
function approveSiring(address _addr, uint256 _sireId)
external
whenNotPaused
{
require(_owns(msg.sender, _sireId));
sireAllowedToAddress[_sireId] = _addr;
}
function setAutoBirthFee(uint256 val) external onlyCEO {
require(val > 0);
autoBirthFee = val;
}
function _isReadyToGiveBirth(Dog _matron) private view returns (bool) {
return (_matron.siringWithId != 0) && (_matron.cooldownEndBlock <= uint64(block.number));
}
function isReadyToBreed(uint256 _dogId)
public
view
returns (bool)
{
require(_dogId > 1);
Dog storage dog = dogs[_dogId];
return _isReadyToBreed(dog);
}
function isPregnant(uint256 _dogId)
public
view
returns (bool)
{
return dogs[_dogId].siringWithId != 0;
}
function _isValidMatingPair(
Dog storage _matron,
uint256 _matronId,
Dog storage _sire,
uint256 _sireId
)
private
view
returns(bool)
{
if (_matronId == _sireId) {
return false;
}
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;
}
if (_sire.matronId == _matron.matronId || _sire.matronId == _matron.sireId) {
return false;
}
if (_sire.sireId == _matron.matronId || _sire.sireId == _matron.sireId) {
return false;
}
return true;
}
function _canBreedWithViaAuction(uint256 _matronId, uint256 _sireId)
internal
view
returns (bool)
{
Dog storage matron = dogs[_matronId];
Dog storage sire = dogs[_sireId];
return _isValidMatingPair(matron, _matronId, sire, _sireId);
}
function getOwner(uint256 _tokenId) public view returns(address){
address owner = dogIndexToOwner[_tokenId];
if(owner == address(saleAuction)){
return saleAuction.getSeller(_tokenId);
} else if (owner == address(siringAuction)){
return siringAuction.getSeller(_tokenId);
} else if (owner == address(this)){
return address(0);
}
return owner;
}
function _breedWith(uint256 _matronId, uint256 _sireId) internal {
require(_matronId > 1);
require(_sireId > 1);
Dog storage sire = dogs[_sireId];
Dog storage matron = dogs[_matronId];
require(sire.variation == 0);
require(matron.variation == 0);
if (matron.generation > 0) {
var(,,openBlock,,,,,,) = lottery.getCLottery();
if (matron.birthTime < openBlock) {
require(lottery.checkLottery(matron.genes) == 100);
}
}
matron.siringWithId = uint32(_sireId);
_triggerCooldown(sire);
_triggerCooldown(matron);
delete sireAllowedToAddress[_matronId];
delete sireAllowedToAddress[_sireId];
pregnantDogs++;
cfoAddress.transfer(autoBirthFee);
address owner = getOwner(0);
if(owner != address(0)){
_sendMoney(owner, creationProfit);
}
owner = getOwner(1);
if(owner != address(0)){
_sendMoney(owner, creationProfit);
}
if (matron.generation > 0) {
owner = getOwner(matron.gen0);
if(owner != address(0)){
_sendMoney(owner, gen0Profit);
}
}
Pregnant(dogIndexToOwner[_matronId], _matronId, _sireId, matron.cooldownEndBlock, sire.cooldownEndBlock, matron.cooldownIndex, sire.cooldownIndex);
}
function breedWithAuto(uint256 _matronId, uint256 _sireId)
external
payable
whenNotPaused
{
uint256 totalFee = autoBirthFee + creationProfit + creationProfit;
Dog storage matron = dogs[_matronId];
if (matron.generation > 0) {
totalFee += gen0Profit;
}
require(msg.value >= totalFee);
require(_owns(msg.sender, _matronId));
require(_isSiringPermitted(_sireId, _matronId));
require(_isReadyToBreed(matron));
Dog storage sire = dogs[_sireId];
require(_isReadyToBreed(sire));
require(_isValidMatingPair(matron, _matronId, sire, _sireId));
_breedWith(_matronId, _sireId);
uint256 breedExcess = msg.value - totalFee;
if (breedExcess > 0) {
msg.sender.transfer(breedExcess);
}
}
bool public giveBirthByUser = false;
function setGiveBirthType(bool _value) public onlyCEO {
giveBirthByUser = _value;
}
function giveBirth(uint256 _matronId, uint256 genes)
external
whenNotPaused
returns(uint256)
{
Dog storage matron = dogs[_matronId];
require(matron.birthTime != 0);
require(_isReadyToGiveBirth(matron));
uint256 sireId = matron.siringWithId;
Dog storage sire = dogs[sireId];
uint16 parentGen = matron.generation;
if (sire.generation > matron.generation) {
parentGen = sire.generation;
}
uint256 gen0 = matron.generation == 0 ? _matronId : matron.gen0;
uint256 childGenes = genes;
if(giveBirthByUser){
require(address(geneScience) != address(0));
childGenes = geneScience.mixGenes(matron.genes, sire.genes, matron.cooldownEndBlock - 1);
} else {
require(msg.sender == ceoAddress || msg.sender == cooAddress || msg.sender == cfoAddress);
}
address owner = dogIndexToOwner[_matronId];
uint8 _variation = variation.createVariation(childGenes, dogs.length);
bool isGen0Siring = matron.generation == 0;
uint256 kittenId = _createDog(_matronId, matron.siringWithId, parentGen + 1, childGenes, owner, _variation, gen0, isGen0Siring);
delete matron.siringWithId;
pregnantDogs--;
if(_variation != 0){
variation.registerVariation(kittenId, owner);
_transfer(owner, address(variation), kittenId);
}
return kittenId;
}
}
contract ClockAuctionBase {
struct Auction {
address seller;
uint128 startingPrice;
uint128 endingPrice;
uint64 duration;
uint64 startedAt;
}
ERC721 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);
function _owns(address _claimant, uint256 _tokenId) internal view returns (bool) {
return (nonFungibleContract.ownerOf(_tokenId) == _claimant);
}
function _escrow(address _owner, uint256 _tokenId) internal {
nonFungibleContract.transferFrom(_owner, this, _tokenId);
}
function _transfer(address _receiver, uint256 _tokenId) internal {
nonFungibleContract.transfer(_receiver, _tokenId);
}
function _addAuction(uint256 _tokenId, Auction _auction) internal {
require(_auction.duration >= 1 minutes);
tokenIdToAuction[_tokenId] = _auction;
AuctionCreated(
uint256(_tokenId),
uint256(_auction.startingPrice),
uint256(_auction.endingPrice),
uint256(_auction.duration)
);
}
function _cancelAuction(uint256 _tokenId, address _seller) internal {
_removeAuction(_tokenId);
_transfer(_seller, _tokenId);
AuctionCancelled(_tokenId);
}
function _bid(uint256 _tokenId, uint256 _bidAmount, address _to)
internal
returns (uint256)
{
Auction storage auction = tokenIdToAuction[_tokenId];
require(_isOnAuction(auction));
uint256 price = _currentPrice(auction);
uint256 auctioneerCut = computeCut(price);
uint256 fee = 0;
if (_tokenId == 0 || _tokenId == 1) {
fee = price / 5;
}
require((_bidAmount + auctioneerCut + fee) >= price);
address seller = auction.seller;
_removeAuction(_tokenId);
if (price > 0) {
uint256 sellerProceeds = price - auctioneerCut - fee;
seller.transfer(sellerProceeds);
}
AuctionSuccessful(_tokenId, price, _to);
return price;
}
function _removeAuction(uint256 _tokenId) internal {
delete tokenIdToAuction[_tokenId];
}
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
);
}
function _computeCurrentPrice(
uint256 _startingPrice,
uint256 _endingPrice,
uint256 _duration,
uint256 _secondsPassed
)
internal
pure
returns (uint256)
{
if (_secondsPassed >= _duration) {
return _endingPrice;
} else {
int256 totalPriceChange = int256(_endingPrice) - int256(_startingPrice);
int256 currentPriceChange = totalPriceChange * int256(_secondsPassed) / int256(_duration);
int256 currentPrice = int256(_startingPrice) + currentPriceChange;
return uint256(currentPrice);
}
}
function computeCut(uint256 _price) public view returns (uint256) {
return _price * ownerCut / 10000;
}
}
contract Pausable is Ownable {
event Pause();
event Unpause();
bool public paused = false;
modifier whenNotPaused() {
require(!paused);
_;
}
modifier whenPaused {
require(paused);
_;
}
function pause() public onlyOwner whenNotPaused returns (bool) {
paused = true;
Pause();
return true;
}
function unpause() public onlyOwner whenPaused returns (bool) {
paused = false;
Unpause();
return true;
}
}
contract ClockAuction is Pausable, ClockAuctionBase {
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)"));
function ClockAuction(address _nftAddress, uint256 _cut) public {
require(_cut <= 10000);
ownerCut = _cut;
ERC721 candidateContract = ERC721(_nftAddress);
require(candidateContract.supportsInterface(InterfaceSignature_ERC721));
nonFungibleContract = candidateContract;
}
function withdrawBalance() external {
address nftAddress = address(nonFungibleContract);
require(
msg.sender == owner ||
msg.sender == nftAddress
);
nftAddress.transfer(address(this).balance);
}
function cancelAuction(uint256 _tokenId)
external
{
require(_tokenId > 1);
Auction storage auction = tokenIdToAuction[_tokenId];
require(_isOnAuction(auction));
address seller = auction.seller;
require(msg.sender == seller);
_cancelAuction(_tokenId, seller);
}
function cancelAuctionWhenPaused(uint256 _tokenId)
whenPaused
onlyOwner
external
{
Auction storage auction = tokenIdToAuction[_tokenId];
require(_isOnAuction(auction));
_cancelAuction(_tokenId, auction.seller);
}
function getAuction(uint256 _tokenId)
external
view
returns
(
address seller,
uint256 startingPrice,
uint256 endingPrice,
uint256 duration,
uint256 startedAt
) {
Auction storage auction = tokenIdToAuction[_tokenId];
require(_isOnAuction(auction));
return (
auction.seller,
auction.startingPrice,
auction.endingPrice,
auction.duration,
auction.startedAt
);
}
function getSeller(uint256 _tokenId) external view returns(address){
Auction storage auction = tokenIdToAuction[_tokenId];
if(_isOnAuction(auction)){
return auction.seller;
} else {
return nonFungibleContract.ownerOf(_tokenId);
}
}
function getCurrentPrice(uint256 _tokenId)
external
view
returns (uint256)
{
Auction storage auction = tokenIdToAuction[_tokenId];
require(_isOnAuction(auction));
return _currentPrice(auction);
}
}
contract SiringClockAuction is ClockAuction {
bool public isSiringClockAuction = true;
function SiringClockAuction(address _nftAddr, uint256 _cut) public ClockAuction(_nftAddr, _cut) {}
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);
}
function bid(uint256 _tokenId, address _to)
external
payable
{
require(msg.sender == address(nonFungibleContract));
address seller = tokenIdToAuction[_tokenId].seller;
_bid(_tokenId, msg.value, _to);
_transfer(seller, _tokenId);
}
}
contract SaleClockAuction is ClockAuction {
bool public isSaleClockAuction = true;
uint256 public gen0SaleCount;
uint256[5] public lastGen0SalePrices;
function SaleClockAuction(address _nftAddr, uint256 _cut) public ClockAuction(_nftAddr, _cut) {}
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);
}
function bid(uint256 _tokenId, address _to)
external
payable
{
require(msg.sender == address(nonFungibleContract));
address seller = tokenIdToAuction[_tokenId].seller;
require(seller != _to);
uint256 price = _bid(_tokenId, msg.value, _to);
_transfer(_to, _tokenId);
if (seller == address(nonFungibleContract)) {
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;
}
}
contract DogAuction is DogBreeding {
uint256 public constant GEN0_AUCTION_DURATION = 1 days;
function setSaleAuctionAddress(address _address) external onlyCEO {
SaleClockAuction candidateContract = SaleClockAuction(_address);
require(candidateContract.isSaleClockAuction());
saleAuction = candidateContract;
}
function setSiringAuctionAddress(address _address) external onlyCEO {
SiringClockAuction candidateContract = SiringClockAuction(_address);
require(candidateContract.isSiringClockAuction());
siringAuction = candidateContract;
}
function createSaleAuction(
uint256 _dogId,
uint256 _startingPrice,
uint256 _endingPrice,
uint256 _duration
)
external
whenNotPaused
{
require(_owns(msg.sender, _dogId) || _approvedFor(msg.sender, _dogId));
require(!isPregnant(_dogId));
_approve(_dogId, saleAuction);
saleAuction.createAuction(
_dogId,
_startingPrice,
_endingPrice,
_duration,
dogIndexToOwner[_dogId]
);
}
function createSiringAuction(
uint256 _dogId,
uint256 _startingPrice,
uint256 _endingPrice,
uint256 _duration
)
external
whenNotPaused
{
Dog storage dog = dogs[_dogId];
require(dog.variation == 0);
require(_owns(msg.sender, _dogId));
require(isReadyToBreed(_dogId));
_approve(_dogId, siringAuction);
siringAuction.createAuction(
_dogId,
_startingPrice,
_endingPrice,
_duration,
msg.sender
);
}
function bidOnSiringAuction(
uint256 _sireId,
uint256 _matronId
)
external
payable
whenNotPaused
{
require(_owns(msg.sender, _matronId));
require(isReadyToBreed(_matronId));
require(_canBreedWithViaAuction(_matronId, _sireId));
uint256 currentPrice = siringAuction.getCurrentPrice(_sireId);
uint256 totalFee = currentPrice + autoBirthFee + creationProfit + creationProfit;
Dog storage matron = dogs[_matronId];
if (matron.generation > 0) {
totalFee += gen0Profit;
}
require(msg.value >= totalFee);
uint256 auctioneerCut = saleAuction.computeCut(currentPrice);
siringAuction.bid.value(currentPrice - auctioneerCut)(_sireId, msg.sender);
_breedWith(uint32(_matronId), uint32(_sireId));
uint256 bidExcess = msg.value - totalFee;
if (bidExcess > 0) {
msg.sender.transfer(bidExcess);
}
}
function bidOnSaleAuction(
uint256 _dogId
)
external
payable
whenNotPaused
{
Dog storage dog = dogs[_dogId];
if (dog.generation > 0) {
var(,,openBlock,,,,,,) = lottery.getCLottery();
if (dog.birthTime < openBlock) {
require(lottery.checkLottery(dog.genes) == 100);
}
}
uint256 currentPrice = saleAuction.getCurrentPrice(_dogId);
require(msg.value >= currentPrice);
bool isCreationKitty = _dogId == 0 || _dogId == 1;
uint256 fee = 0;
if (isCreationKitty) {
fee = uint256(currentPrice / 5);
}
uint256 auctioneerCut = saleAuction.computeCut(currentPrice);
saleAuction.bid.value(currentPrice - (auctioneerCut + fee))(_dogId, msg.sender);
if (isCreationKitty) {
cfoAddress.transfer(fee);
uint256 nextPrice = uint256(uint128(2 * currentPrice));
if (nextPrice < currentPrice) {
nextPrice = currentPrice;
}
_approve(_dogId, saleAuction);
saleAuction.createAuction(
_dogId,
nextPrice,
nextPrice,
GEN0_AUCTION_DURATION,
msg.sender);
}
uint256 bidExcess = msg.value - currentPrice;
if (bidExcess > 0) {
msg.sender.transfer(bidExcess);
}
}
}
contract DogMinting is DogAuction {
uint256 public constant GEN0_CREATION_LIMIT = 40000;
uint256 public constant GEN0_STARTING_PRICE = 200 finney;
uint256 public gen0CreatedCount;
function createGen0Dog(uint256 _genes) external onlyCLevel returns(uint256) {
require(gen0CreatedCount < GEN0_CREATION_LIMIT);
uint256 dogId = _createDog(0, 0, 0, _genes, address(this), 0, 0, false);
_approve(dogId, msg.sender);
gen0CreatedCount++;
return dogId;
}
function computeNextGen0Price() public view returns (uint256) {
uint256 avePrice = saleAuction.averageGen0SalePrice();
require(avePrice == uint256(uint128(avePrice)));
uint256 nextPrice = avePrice + (avePrice / 2);
if (nextPrice < GEN0_STARTING_PRICE) {
nextPrice = GEN0_STARTING_PRICE;
}
return nextPrice;
}
}
contract DogCore is DogMinting {
address public newContractAddress;
function DogCore() public {
paused = true;
ceoAddress = msg.sender;
cooAddress = msg.sender;
_createDog(0, 0, 0, uint256(0), address(this), 0, 0, false);
_approve(0, cooAddress);
_createDog(0, 0, 0, uint256(0), address(this), 0, 0, false);
_approve(1, cooAddress);
}
function setNewAddress(address _v2Address) external onlyCEO whenPaused {
newContractAddress = _v2Address;
ContractUpgrade(_v2Address);
}
function() external payable {
require(
msg.sender == address(saleAuction) ||
msg.sender == address(siringAuction) ||
msg.sender == ceoAddress
);
}
function getDog(uint256 _id)
external
view
returns (
uint256 cooldownIndex,
uint256 nextActionAt,
uint256 siringWithId,
uint256 birthTime,
uint256 matronId,
uint256 sireId,
uint256 generation,
uint256 genes,
uint8 variation,
uint256 gen0
) {
Dog storage dog = dogs[_id];
cooldownIndex = uint256(dog.cooldownIndex);
nextActionAt = uint256(dog.cooldownEndBlock);
siringWithId = uint256(dog.siringWithId);
birthTime = uint256(dog.birthTime);
matronId = uint256(dog.matronId);
sireId = uint256(dog.sireId);
generation = uint256(dog.generation);
genes = uint256(dog.genes);
variation = uint8(dog.variation);
gen0 = uint256(dog.gen0);
}
function unpause() public onlyCEO whenPaused {
require(saleAuction != address(0));
require(siringAuction != address(0));
require(lottery != address(0));
require(variation != address(0));
require(newContractAddress == address(0));
super.unpause();
}
function setLotteryAddress(address _address) external onlyCEO {
require(address(lottery) == address(0));
LotteryInterface candidateContract = LotteryInterface(_address);
require(candidateContract.isLottery());
lottery = candidateContract;
}
function setVariationAddress(address _address) external onlyCEO {
require(address(variation) == address(0));
VariationInterface candidateContract = VariationInterface(_address);
require(candidateContract.isVariation());
variation = candidateContract;
}
function registerLottery(uint256 _dogId) external returns (uint8) {
require(_owns(msg.sender, _dogId));
require(lottery.registerLottery(_dogId) == 0);
_transfer(msg.sender, address(lottery), _dogId);
}
function getAvailableBlance() external view returns(uint256){
return address(this).balance - spendMoney;
}
}