Transaction Hash:
Block:
7089500 at Jan-18-2019 10:34:55 PM +UTC
Transaction Fee:
0.000233376 ETH
$0.43
Gas Used:
155,584 Gas / 1.5 Gwei
Emitted Events:
37 |
EggStorage.Approval( _owner=0x5302D0b614947EC0b2c3607C838ceb0262027560, _approved=0x00000000...000000000, _tokenId=2979 )
|
38 |
EggStorage.Transfer( _from=0x5302D0b614947EC0b2c3607C838ceb0262027560, _to=[Sender] 0xfefbdc19a0d855a8b9bbf79144bc32cc7eeda019, _tokenId=2979 )
|
39 |
Gold.Transfer( from=[Sender] 0xfefbdc19a0d855a8b9bbf79144bc32cc7eeda019, to=0x5302D0b614947EC0b2c3607C838ceb0262027560, value=2000000000000000000000 )
|
40 |
Events.EggBought( buyer=[Sender] 0xfefbdc19a0d855a8b9bbf79144bc32cc7eeda019, seller=0x5302D0b614947EC0b2c3607C838ceb0262027560, id=2979, price=2000000000000000000000 )
|
Account State Difference:
Address | Before | After | State Difference | ||
---|---|---|---|---|---|
0x150b0b96...683bF9739 | |||||
0x52bc44d5...b7d7bE3b5
Miner
| (Nanopool) | 9,132.042696680414932204 Eth | 9,132.042930056414932204 Eth | 0.000233376 | |
0xbBA8FBaa...BAA74172A | (Dragonereum: Egg Marketplace) | ||||
0xfCAd2859...8f9009F7b | |||||
0xFEfBdC19...c7EedA019 |
2.163702180680419964 Eth
Nonce: 3675
|
2.163468804680419964 Eth
Nonce: 3676
| 0.000233376 |
Execution Trace
MainMarket.buyEgg( _id=2979, _expectedPrice=2000000000000000000000, _isGold=True )
MarketplaceController.buyEgg( _sender=0xFEfBdC19a0d855a8b9bBf79144BC32Cc7EedA019, _value=0, _id=2979, _expectedPrice=2000000000000000000000, _isGold=True ) => ( seller=0x5302D0b614947EC0b2c3607C838ceb0262027560, price=2000000000000000000000, success=True )
-
EggMarketplace.sellerOf( _id=2979 ) => ( 0x5302D0b614947EC0b2c3607C838ceb0262027560 )
-
EggStorage.isApprovedOrOwner( _spender=0x6D81d1fda601Df52f83188DCe617b65AC9b3C5BE, _tokenId=2979 ) => ( True )
-
EggStorage.ownerOf( _tokenId=2979 ) => ( 0x5302D0b614947EC0b2c3607C838ceb0262027560 )
-
Gold.balanceOf( owner=0xFEfBdC19a0d855a8b9bBf79144BC32Cc7EedA019 ) => ( 2100000000000000000000 )
-
EggMarketplace.buyToken( _tokenId=2979, _value=2100000000000000000000, _expectedPrice=2000000000000000000000, _expectedIsGold=True ) => ( price=2000000000000000000000 )
-
EggStorage.transferFrom( _from=0x5302D0b614947EC0b2c3607C838ceb0262027560, _to=0xFEfBdC19a0d855a8b9bBf79144BC32Cc7EedA019, _tokenId=2979 )
-
Gold.remoteTransfer( _to=0x5302D0b614947EC0b2c3607C838ceb0262027560, _value=2000000000000000000000 )
-
-
0x5302d0b614947ec0b2c3607c838ceb0262027560.CALL( )
-
Events.emitEggBought( _buyer=0xFEfBdC19a0d855a8b9bBf79144BC32Cc7EedA019, _seller=0x5302D0b614947EC0b2c3607C838ceb0262027560, _id=2979, _price=2000000000000000000000 )
buyEgg[MainMarket (ln:229)]
buyEgg[MainMarket (ln:238)]
_transferEth[MainMarket (ln:246)]
transfer[MainMarket (ln:221)]
transfer[MainMarket (ln:223)]
sub[MainMarket (ln:223)]
emitEggBought[MainMarket (ln:247)]
transfer[MainMarket (ln:249)]
emitEggRemovedFromSale[MainMarket (ln:250)]
File 1 of 6: MainMarket
File 2 of 6: EggStorage
File 3 of 6: Gold
File 4 of 6: Events
File 5 of 6: MarketplaceController
File 6 of 6: EggMarketplace
pragma solidity 0.4.25; library SafeMath256 { function mul(uint256 a, uint256 b) internal pure returns (uint256) { if (a == 0) { return 0; } uint256 c = a * b; assert(c / a == b); return c; } function div(uint256 a, uint256 b) internal pure returns (uint256) { return a / b; } function sub(uint256 a, uint256 b) internal pure returns (uint256) { assert(b <= a); return a - b; } function add(uint256 a, uint256 b) internal pure returns (uint256) { uint256 c = a + b; assert(c >= a); return c; } function pow(uint256 a, uint256 b) internal pure returns (uint256) { if (a == 0) return 0; if (b == 0) return 1; uint256 c = a ** b; assert(c / (a ** (b - 1)) == a); return c; } } contract Ownable { address public owner; event OwnershipTransferred(address indexed previousOwner, address indexed newOwner); function _validateAddress(address _addr) internal pure { require(_addr != address(0), "invalid address"); } constructor() public { owner = msg.sender; } modifier onlyOwner() { require(msg.sender == owner, "not a contract owner"); _; } function transferOwnership(address newOwner) public onlyOwner { _validateAddress(newOwner); emit OwnershipTransferred(owner, newOwner); owner = newOwner; } } contract Pausable is Ownable { event Pause(); event Unpause(); bool public paused = false; modifier whenNotPaused() { require(!paused, "contract is paused"); _; } modifier whenPaused() { require(paused, "contract is not paused"); _; } function pause() public onlyOwner whenNotPaused { paused = true; emit Pause(); } function unpause() public onlyOwner whenPaused { paused = false; emit Unpause(); } } contract Controllable is Ownable { mapping(address => bool) controllers; modifier onlyController { require(_isController(msg.sender), "no controller rights"); _; } function _isController(address _controller) internal view returns (bool) { return controllers[_controller]; } function _setControllers(address[] _controllers) internal { for (uint256 i = 0; i < _controllers.length; i++) { _validateAddress(_controllers[i]); controllers[_controllers[i]] = true; } } } contract Upgradable is Controllable { address[] internalDependencies; address[] externalDependencies; function getInternalDependencies() public view returns(address[]) { return internalDependencies; } function getExternalDependencies() public view returns(address[]) { return externalDependencies; } function setInternalDependencies(address[] _newDependencies) public onlyOwner { for (uint256 i = 0; i < _newDependencies.length; i++) { _validateAddress(_newDependencies[i]); } internalDependencies = _newDependencies; } function setExternalDependencies(address[] _newDependencies) public onlyOwner { externalDependencies = _newDependencies; _setControllers(_newDependencies); } } contract HumanOriented { modifier onlyHuman() { require(msg.sender == tx.origin, "not a human"); _; } } contract Events { function emitEggCreated(address, uint256) external; function emitDragonOnSale(address, uint256) external; function emitDragonRemovedFromSale(address, uint256) external; function emitDragonRemovedFromBreeding(address, uint256) external; function emitDragonOnBreeding(address, uint256) external; function emitDragonBought(address, address, uint256, uint256) external; function emitDragonBreedingBought(address, address, uint256, uint256) external; function emitDistributionUpdated(uint256, uint256, uint256) external; function emitEggOnSale(address, uint256) external; function emitEggRemovedFromSale(address, uint256) external; function emitEggBought(address, address, uint256, uint256) external; function emitGoldSellOrderCreated(address, uint256, uint256) external; function emitGoldSellOrderCancelled(address) external; function emitGoldSold(address, address, uint256, uint256) external; function emitGoldBuyOrderCreated(address, uint256, uint256) external; function emitGoldBuyOrderCancelled(address) external; function emitGoldBought(address, address, uint256, uint256) external; function emitSkillOnSale(address, uint256) external; function emitSkillRemovedFromSale(address, uint256) external; function emitSkillBought(address, address, uint256, uint256, uint256) external; } contract MarketplaceController { function buyEgg(address, uint256, uint256, uint256, bool) external returns (address, uint256, bool); function sellEgg(address, uint256, uint256, uint256, uint16, bool) external; function removeEggFromSale(address, uint256) external; function buyDragon(address, uint256, uint256, uint256, bool) external returns (address, uint256, bool); function sellDragon(address, uint256, uint256, uint256, uint16, bool) external; function removeDragonFromSale(address, uint256) external; function buyBreeding(address, uint256, uint256, uint256, uint256, bool) external returns (uint256, address, uint256, bool); function sellBreeding(address, uint256, uint256, uint256, uint16, bool) external; function removeBreedingFromSale(address, uint256) external; function buySkill(address, uint256, uint256, uint256, uint32) external returns (address, uint256, bool); function sellSkill(address, uint256, uint256) external; function removeSkillFromSale(address, uint256) external; } contract GoldMarketplace { function createSellOrder(address, uint256, uint256) external; function cancelSellOrder(address) external; function fillSellOrder(address, uint256, address, uint256, uint256) external returns (uint256); function createBuyOrder(address, uint256, uint256, uint256) external; function cancelBuyOrder(address) external; function fillBuyOrder(address, address, uint256, uint256) external returns (uint256); } //////////////CONTRACT////////////// contract MainMarket is Pausable, Upgradable, HumanOriented { using SafeMath256 for uint256; MarketplaceController public marketplaceController; GoldMarketplace goldMarketplace; Events events; // MARKETPLACE function _transferEth( address _from, address _to, uint256 _available, uint256 _required_, bool _isGold ) internal { uint256 _required = _required_; if (_isGold) { _required = 0; } _to.transfer(_required); if (_available > _required) { _from.transfer(_available.sub(_required)); } } // EGG function buyEgg( uint256 _id, uint256 _expectedPrice, bool _isGold ) external onlyHuman whenNotPaused payable { ( address _seller, uint256 _price, bool _success ) = marketplaceController.buyEgg( msg.sender, msg.value, _id, _expectedPrice, _isGold ); if (_success) { _transferEth(msg.sender, _seller, msg.value, _price, _isGold); events.emitEggBought(msg.sender, _seller, _id, _price); } else { msg.sender.transfer(msg.value); events.emitEggRemovedFromSale(_seller, _id); } } function sellEgg( uint256 _id, uint256 _maxPrice, uint256 _minPrice, uint16 _period, bool _isGold ) external onlyHuman whenNotPaused { marketplaceController.sellEgg(msg.sender, _id, _maxPrice, _minPrice, _period, _isGold); events.emitEggOnSale(msg.sender, _id); } function removeEggFromSale(uint256 _id) external onlyHuman whenNotPaused { marketplaceController.removeEggFromSale(msg.sender, _id); events.emitEggRemovedFromSale(msg.sender, _id); } // DRAGON function buyDragon( uint256 _id, uint256 _expectedPrice, bool _isGold ) external onlyHuman whenNotPaused payable { ( address _seller, uint256 _price, bool _success ) = marketplaceController.buyDragon( msg.sender, msg.value, _id, _expectedPrice, _isGold ); if (_success) { _transferEth(msg.sender, _seller, msg.value, _price, _isGold); events.emitDragonBought(msg.sender, _seller, _id, _price); } else { msg.sender.transfer(msg.value); events.emitDragonRemovedFromSale(_seller, _id); } } function sellDragon( uint256 _id, uint256 _maxPrice, uint256 _minPrice, uint16 _period, bool _isGold ) external onlyHuman whenNotPaused { marketplaceController.sellDragon(msg.sender, _id, _maxPrice, _minPrice, _period, _isGold); events.emitDragonOnSale(msg.sender, _id); } function removeDragonFromSale(uint256 _id) external onlyHuman whenNotPaused { marketplaceController.removeDragonFromSale(msg.sender, _id); events.emitDragonRemovedFromSale(msg.sender, _id); } // BREEDING function buyBreeding( uint256 _momId, uint256 _dadId, uint256 _expectedPrice, bool _isGold ) external onlyHuman whenNotPaused payable { ( uint256 _eggId, address _seller, uint256 _price, bool _success ) = marketplaceController.buyBreeding( msg.sender, msg.value, _momId, _dadId, _expectedPrice, _isGold ); if (_success) { events.emitEggCreated(msg.sender, _eggId); _transferEth(msg.sender, _seller, msg.value, _price, _isGold); events.emitDragonBreedingBought(msg.sender, _seller, _dadId, _price); } else { msg.sender.transfer(msg.value); events.emitDragonRemovedFromBreeding(_seller, _dadId); } } function sellBreeding( uint256 _id, uint256 _maxPrice, uint256 _minPrice, uint16 _period, bool _isGold ) external onlyHuman whenNotPaused { marketplaceController.sellBreeding(msg.sender, _id, _maxPrice, _minPrice, _period, _isGold); events.emitDragonOnBreeding(msg.sender, _id); } function removeBreedingFromSale(uint256 _id) external onlyHuman whenNotPaused { marketplaceController.removeBreedingFromSale(msg.sender, _id); events.emitDragonRemovedFromBreeding(msg.sender, _id); } // GOLD // SELL function fillGoldSellOrder( address _seller, uint256 _price, uint256 _amount ) external onlyHuman whenNotPaused payable { address(goldMarketplace).transfer(msg.value); uint256 _priceForOne = goldMarketplace.fillSellOrder(msg.sender, msg.value, _seller, _price, _amount); events.emitGoldSold(msg.sender, _seller, _amount, _priceForOne); } function createGoldSellOrder( uint256 _price, uint256 _amount ) external onlyHuman whenNotPaused { goldMarketplace.createSellOrder(msg.sender, _price, _amount); events.emitGoldSellOrderCreated(msg.sender, _price, _amount); } function cancelGoldSellOrder() external onlyHuman whenNotPaused { goldMarketplace.cancelSellOrder(msg.sender); events.emitGoldSellOrderCancelled(msg.sender); } // BUY function fillGoldBuyOrder( address _buyer, uint256 _price, uint256 _amount ) external onlyHuman whenNotPaused { uint256 _priceForOne = goldMarketplace.fillBuyOrder(msg.sender, _buyer, _price, _amount); events.emitGoldBought(msg.sender, _buyer, _amount, _priceForOne); } function createGoldBuyOrder( uint256 _price, uint256 _amount ) external onlyHuman whenNotPaused payable { address(goldMarketplace).transfer(msg.value); goldMarketplace.createBuyOrder(msg.sender, msg.value, _price, _amount); events.emitGoldBuyOrderCreated(msg.sender, _price, _amount); } function cancelGoldBuyOrder() external onlyHuman whenNotPaused { goldMarketplace.cancelBuyOrder(msg.sender); events.emitGoldBuyOrderCancelled(msg.sender); } // SKILL function buySkill( uint256 _id, uint256 _target, uint256 _expectedPrice, uint32 _expectedEffect ) external onlyHuman whenNotPaused { ( address _seller, uint256 _price, bool _success ) = marketplaceController.buySkill( msg.sender, _id, _target, _expectedPrice, _expectedEffect ); if (_success) { events.emitSkillBought(msg.sender, _seller, _id, _target, _price); } else { events.emitSkillRemovedFromSale(_seller, _id); } } function sellSkill( uint256 _id, uint256 _price ) external onlyHuman whenNotPaused { marketplaceController.sellSkill(msg.sender, _id, _price); events.emitSkillOnSale(msg.sender, _id); } function removeSkillFromSale(uint256 _id) external onlyHuman whenNotPaused { marketplaceController.removeSkillFromSale(msg.sender, _id); events.emitSkillRemovedFromSale(msg.sender, _id); } // UPDATE CONTRACT function setInternalDependencies(address[] _newDependencies) public onlyOwner { super.setInternalDependencies(_newDependencies); marketplaceController = MarketplaceController(_newDependencies[0]); goldMarketplace = GoldMarketplace(_newDependencies[1]); events = Events(_newDependencies[2]); } }
File 2 of 6: EggStorage
pragma solidity 0.4.25; library SafeMath256 { function mul(uint256 a, uint256 b) internal pure returns (uint256) { if (a == 0) { return 0; } uint256 c = a * b; assert(c / a == b); return c; } function div(uint256 a, uint256 b) internal pure returns (uint256) { return a / b; } function sub(uint256 a, uint256 b) internal pure returns (uint256) { assert(b <= a); return a - b; } function add(uint256 a, uint256 b) internal pure returns (uint256) { uint256 c = a + b; assert(c >= a); return c; } function pow(uint256 a, uint256 b) internal pure returns (uint256) { if (a == 0) return 0; if (b == 0) return 1; uint256 c = a ** b; assert(c / (a ** (b - 1)) == a); return c; } } contract Ownable { address public owner; event OwnershipTransferred(address indexed previousOwner, address indexed newOwner); function _validateAddress(address _addr) internal pure { require(_addr != address(0), "invalid address"); } constructor() public { owner = msg.sender; } modifier onlyOwner() { require(msg.sender == owner, "not a contract owner"); _; } function transferOwnership(address newOwner) public onlyOwner { _validateAddress(newOwner); emit OwnershipTransferred(owner, newOwner); owner = newOwner; } } contract Controllable is Ownable { mapping(address => bool) controllers; modifier onlyController { require(_isController(msg.sender), "no controller rights"); _; } function _isController(address _controller) internal view returns (bool) { return controllers[_controller]; } function _setControllers(address[] _controllers) internal { for (uint256 i = 0; i < _controllers.length; i++) { _validateAddress(_controllers[i]); controllers[_controllers[i]] = true; } } } contract Upgradable is Controllable { address[] internalDependencies; address[] externalDependencies; function getInternalDependencies() public view returns(address[]) { return internalDependencies; } function getExternalDependencies() public view returns(address[]) { return externalDependencies; } function setInternalDependencies(address[] _newDependencies) public onlyOwner { for (uint256 i = 0; i < _newDependencies.length; i++) { _validateAddress(_newDependencies[i]); } internalDependencies = _newDependencies; } function setExternalDependencies(address[] _newDependencies) public onlyOwner { externalDependencies = _newDependencies; _setControllers(_newDependencies); } } contract ERC721Basic { event Transfer(address indexed _from, address indexed _to, uint256 indexed _tokenId); event Approval(address indexed _owner, address indexed _approved, uint256 indexed _tokenId); event ApprovalForAll(address indexed _owner, address indexed _operator, bool _approved); function balanceOf(address _owner) public view returns (uint256 _balance); function ownerOf(uint256 _tokenId) public view returns (address _owner); function exists(uint256 _tokenId) public view returns (bool _exists); function approve(address _to, uint256 _tokenId) public; function getApproved(uint256 _tokenId) public view returns (address _operator); function setApprovalForAll(address _operator, bool _approved) public; function isApprovedForAll(address _owner, address _operator) public view returns (bool); function transferFrom(address _from, address _to, uint256 _tokenId) public; function safeTransferFrom(address _from, address _to, uint256 _tokenId) public; function safeTransferFrom(address _from, address _to, uint256 _tokenId, bytes _data) public; function supportsInterface(bytes4 _interfaceID) external pure returns (bool); } contract ERC721Enumerable is ERC721Basic { function totalSupply() public view returns (uint256); function tokenOfOwnerByIndex(address _owner, uint256 _index) public view returns (uint256 _tokenId); function tokenByIndex(uint256 _index) public view returns (uint256); } contract ERC721Metadata is ERC721Basic { function name() public view returns (string _name); function symbol() public view returns (string _symbol); function tokenURI(uint256 _tokenId) public view returns (string); } contract ERC721 is ERC721Basic, ERC721Enumerable, ERC721Metadata {} contract ERC721Receiver { function onERC721Received( address _operator, address _from, uint256 _tokenId, bytes _data ) public returns(bytes4); } contract ERC721BasicToken is ERC721Basic, Upgradable { using SafeMath256 for uint256; // Equals to `bytes4(keccak256("onERC721Received(address,address,uint256,bytes)"))` // which can be also obtained as `IERC721Receiver(0).onERC721Received.selector` bytes4 private constant _ERC721_RECEIVED = 0x150b7a02; // Mapping from token ID to owner mapping (uint256 => address) internal tokenOwner; // Mapping from token ID to approved address mapping (uint256 => address) internal tokenApprovals; // Mapping from owner to number of owned token mapping (address => uint256) internal ownedTokensCount; // Mapping from owner to operator approvals mapping (address => mapping (address => bool)) internal operatorApprovals; function _checkRights(bool _has) internal pure { require(_has, "no rights to manage"); } function _validateAddress(address _addr) internal pure { require(_addr != address(0), "invalid address"); } function _checkOwner(uint256 _tokenId, address _owner) internal view { require(ownerOf(_tokenId) == _owner, "not an owner"); } function _checkThatUserHasTokens(bool _has) internal pure { require(_has, "user has no tokens"); } function balanceOf(address _owner) public view returns (uint256) { _validateAddress(_owner); return ownedTokensCount[_owner]; } function ownerOf(uint256 _tokenId) public view returns (address) { address owner = tokenOwner[_tokenId]; _validateAddress(owner); return owner; } function exists(uint256 _tokenId) public view returns (bool) { address owner = tokenOwner[_tokenId]; return owner != address(0); } function _approve(address _from, address _to, uint256 _tokenId) internal { address owner = ownerOf(_tokenId); require(_to != owner, "can't be approved to owner"); _checkRights(_from == owner || isApprovedForAll(owner, _from)); if (getApproved(_tokenId) != address(0) || _to != address(0)) { tokenApprovals[_tokenId] = _to; emit Approval(owner, _to, _tokenId); } } function approve(address _to, uint256 _tokenId) public { _approve(msg.sender, _to, _tokenId); } function remoteApprove(address _to, uint256 _tokenId) external onlyController { _approve(tx.origin, _to, _tokenId); } function getApproved(uint256 _tokenId) public view returns (address) { require(exists(_tokenId), "token doesn't exist"); return tokenApprovals[_tokenId]; } function setApprovalForAll(address _to, bool _approved) public { require(_to != msg.sender, "wrong sender"); operatorApprovals[msg.sender][_to] = _approved; emit ApprovalForAll(msg.sender, _to, _approved); } function isApprovedForAll(address _owner, address _operator) public view returns (bool) { return operatorApprovals[_owner][_operator]; } function transferFrom(address _from, address _to, uint256 _tokenId) public { _checkRights(isApprovedOrOwner(msg.sender, _tokenId)); _validateAddress(_from); _validateAddress(_to); clearApproval(_from, _tokenId); removeTokenFrom(_from, _tokenId); addTokenTo(_to, _tokenId); emit Transfer(_from, _to, _tokenId); } function safeTransferFrom( address _from, address _to, uint256 _tokenId ) public { safeTransferFrom(_from, _to, _tokenId, ""); } function safeTransferFrom( address _from, address _to, uint256 _tokenId, bytes _data ) public { transferFrom(_from, _to, _tokenId); require(checkAndCallSafeTransfer(_from, _to, _tokenId, _data), "can't make safe transfer"); } function isApprovedOrOwner(address _spender, uint256 _tokenId) public view returns (bool) { address owner = ownerOf(_tokenId); return _spender == owner || getApproved(_tokenId) == _spender || isApprovedForAll(owner, _spender); } function _mint(address _to, uint256 _tokenId) internal { _validateAddress(_to); addTokenTo(_to, _tokenId); emit Transfer(address(0), _to, _tokenId); } function _burn(address _owner, uint256 _tokenId) internal { clearApproval(_owner, _tokenId); removeTokenFrom(_owner, _tokenId); emit Transfer(_owner, address(0), _tokenId); } function clearApproval(address _owner, uint256 _tokenId) internal { _checkOwner(_tokenId, _owner); if (tokenApprovals[_tokenId] != address(0)) { tokenApprovals[_tokenId] = address(0); emit Approval(_owner, address(0), _tokenId); } } function addTokenTo(address _to, uint256 _tokenId) internal { require(tokenOwner[_tokenId] == address(0), "token already has an owner"); tokenOwner[_tokenId] = _to; ownedTokensCount[_to] = ownedTokensCount[_to].add(1); } function removeTokenFrom(address _from, uint256 _tokenId) internal { _checkOwner(_tokenId, _from); _checkThatUserHasTokens(ownedTokensCount[_from] > 0); ownedTokensCount[_from] = ownedTokensCount[_from].sub(1); tokenOwner[_tokenId] = address(0); } function _isContract(address addr) internal view returns (bool) { uint256 size; assembly { size := extcodesize(addr) } return size > 0; } function checkAndCallSafeTransfer( address _from, address _to, uint256 _tokenId, bytes _data ) internal returns (bool) { if (!_isContract(_to)) { return true; } bytes4 retval = ERC721Receiver(_to).onERC721Received(msg.sender, _from, _tokenId, _data); return (retval == _ERC721_RECEIVED); } } contract ERC721Token is ERC721, ERC721BasicToken { bytes4 internal constant INTERFACE_SIGNATURE_ERC165 = 0x01ffc9a7; bytes4 internal constant INTERFACE_SIGNATURE_ERC721 = 0x80ac58cd; bytes4 internal constant INTERFACE_SIGNATURE_ERC721TokenReceiver = 0xf0b9e5ba; bytes4 internal constant INTERFACE_SIGNATURE_ERC721Metadata = 0x5b5e139f; bytes4 internal constant INTERFACE_SIGNATURE_ERC721Enumerable = 0x780e9d63; string internal name_; string internal symbol_; // Mapping from owner to list of owned token IDs mapping (address => uint256[]) internal ownedTokens; // Mapping from token ID to index of the owner tokens list mapping(uint256 => uint256) internal ownedTokensIndex; // Array with all token ids, used for enumeration uint256[] internal allTokens; // Mapping from token id to position in the allTokens array mapping(uint256 => uint256) internal allTokensIndex; // Optional mapping for token URIs mapping(uint256 => string) internal tokenURIs; // The contract owner can change the base URL, in case it becomes necessary. It is needed for Metadata. string public url; constructor(string _name, string _symbol) public { name_ = _name; symbol_ = _symbol; } function name() public view returns (string) { return name_; } function symbol() public view returns (string) { return symbol_; } function _validateIndex(bool _isValid) internal pure { require(_isValid, "wrong index"); } function tokenOfOwnerByIndex(address _owner, uint256 _index) public view returns (uint256) { _validateIndex(_index < balanceOf(_owner)); return ownedTokens[_owner][_index]; } function tokensOfOwner(address _owner) external view returns (uint256[]) { return ownedTokens[_owner]; } function getAllTokens() external view returns (uint256[]) { return allTokens; } function totalSupply() public view returns (uint256) { return allTokens.length; } function tokenByIndex(uint256 _index) public view returns (uint256) { _validateIndex(_index < totalSupply()); return allTokens[_index]; } function addTokenTo(address _to, uint256 _tokenId) internal { super.addTokenTo(_to, _tokenId); uint256 length = ownedTokens[_to].length; ownedTokens[_to].push(_tokenId); ownedTokensIndex[_tokenId] = length; } function removeTokenFrom(address _from, uint256 _tokenId) internal { _checkThatUserHasTokens(ownedTokens[_from].length > 0); super.removeTokenFrom(_from, _tokenId); uint256 tokenIndex = ownedTokensIndex[_tokenId]; uint256 lastTokenIndex = ownedTokens[_from].length.sub(1); uint256 lastToken = ownedTokens[_from][lastTokenIndex]; ownedTokens[_from][tokenIndex] = lastToken; ownedTokens[_from][lastTokenIndex] = 0; ownedTokens[_from].length--; ownedTokensIndex[_tokenId] = 0; ownedTokensIndex[lastToken] = tokenIndex; } function _mint(address _to, uint256 _tokenId) internal { super._mint(_to, _tokenId); allTokensIndex[_tokenId] = allTokens.length; allTokens.push(_tokenId); } function _burn(address _owner, uint256 _tokenId) internal { require(allTokens.length > 0, "no tokens"); super._burn(_owner, _tokenId); uint256 tokenIndex = allTokensIndex[_tokenId]; uint256 lastTokenIndex = allTokens.length.sub(1); uint256 lastToken = allTokens[lastTokenIndex]; allTokens[tokenIndex] = lastToken; allTokens[lastTokenIndex] = 0; allTokens.length--; allTokensIndex[_tokenId] = 0; allTokensIndex[lastToken] = tokenIndex; } function supportsInterface(bytes4 _interfaceID) external pure returns (bool) { return ( _interfaceID == INTERFACE_SIGNATURE_ERC165 || _interfaceID == INTERFACE_SIGNATURE_ERC721 || _interfaceID == INTERFACE_SIGNATURE_ERC721TokenReceiver || _interfaceID == INTERFACE_SIGNATURE_ERC721Metadata || _interfaceID == INTERFACE_SIGNATURE_ERC721Enumerable ); } function tokenURI(uint256 _tokenId) public view returns (string) { require(exists(_tokenId), "token doesn't exist"); return string(abi.encodePacked(url, _uint2str(_tokenId))); } function setUrl(string _url) external onlyOwner { url = _url; } function _uint2str(uint _i) internal pure returns (string){ if (i == 0) return "0"; uint i = _i; uint j = _i; uint length; while (j != 0){ length++; j /= 10; } bytes memory bstr = new bytes(length); uint k = length - 1; while (i != 0){ bstr[k--] = byte(48 + i % 10); i /= 10; } return string(bstr); } } contract EggStorage is ERC721Token { struct Egg { uint256[2] parents; uint8 dragonType; // used for genesis only } Egg[] eggs; constructor(string _name, string _symbol) public ERC721Token(_name, _symbol) { eggs.length = 1; // to avoid some issues with 0 } function push(address _sender, uint256[2] _parents, uint8 _dragonType) public onlyController returns (uint256 id) { Egg memory _egg = Egg(_parents, _dragonType); id = eggs.push(_egg).sub(1); _mint(_sender, id); } function get(uint256 _id) external view returns (uint256[2], uint8) { return (eggs[_id].parents, eggs[_id].dragonType); } function remove(address _owner, uint256 _id) external onlyController { delete eggs[_id]; _burn(_owner, _id); } }
File 3 of 6: Gold
pragma solidity 0.4.25; library SafeMath256 { function mul(uint256 a, uint256 b) internal pure returns (uint256) { if (a == 0) { return 0; } uint256 c = a * b; assert(c / a == b); return c; } function div(uint256 a, uint256 b) internal pure returns (uint256) { return a / b; } function sub(uint256 a, uint256 b) internal pure returns (uint256) { assert(b <= a); return a - b; } function add(uint256 a, uint256 b) internal pure returns (uint256) { uint256 c = a + b; assert(c >= a); return c; } function pow(uint256 a, uint256 b) internal pure returns (uint256) { if (a == 0) return 0; if (b == 0) return 1; uint256 c = a ** b; assert(c / (a ** (b - 1)) == a); return c; } } contract Ownable { address public owner; event OwnershipTransferred(address indexed previousOwner, address indexed newOwner); function _validateAddress(address _addr) internal pure { require(_addr != address(0), "invalid address"); } constructor() public { owner = msg.sender; } modifier onlyOwner() { require(msg.sender == owner, "not a contract owner"); _; } function transferOwnership(address newOwner) public onlyOwner { _validateAddress(newOwner); emit OwnershipTransferred(owner, newOwner); owner = newOwner; } } contract Controllable is Ownable { mapping(address => bool) controllers; modifier onlyController { require(_isController(msg.sender), "no controller rights"); _; } function _isController(address _controller) internal view returns (bool) { return controllers[_controller]; } function _setControllers(address[] _controllers) internal { for (uint256 i = 0; i < _controllers.length; i++) { _validateAddress(_controllers[i]); controllers[_controllers[i]] = true; } } } contract Upgradable is Controllable { address[] internalDependencies; address[] externalDependencies; function getInternalDependencies() public view returns(address[]) { return internalDependencies; } function getExternalDependencies() public view returns(address[]) { return externalDependencies; } function setInternalDependencies(address[] _newDependencies) public onlyOwner { for (uint256 i = 0; i < _newDependencies.length; i++) { _validateAddress(_newDependencies[i]); } internalDependencies = _newDependencies; } function setExternalDependencies(address[] _newDependencies) public onlyOwner { externalDependencies = _newDependencies; _setControllers(_newDependencies); } } interface IERC20 { function totalSupply() external view returns (uint256); function balanceOf(address who) external view returns (uint256); function allowance(address owner, address spender) external view returns (uint256); function transfer(address to, uint256 value) external returns (bool); function approve(address spender, uint256 value) external returns (bool); function transferFrom(address from, address to, uint256 value) external returns (bool); event Transfer( address indexed from, address indexed to, uint256 value ); event Approval( address indexed owner, address indexed spender, uint256 value ); } contract ERC20 is IERC20 { using SafeMath256 for uint256; mapping (address => uint256) _balances; mapping (address => mapping (address => uint256)) _allowed; uint256 _totalSupply; string public name; string public symbol; uint8 public decimals; function totalSupply() public view returns (uint256) { return _totalSupply; } function balanceOf(address owner) public view returns (uint256) { return _balances[owner]; } function allowance( address owner, address spender ) public view returns (uint256) { return _allowed[owner][spender]; } function transfer(address to, uint256 value) public returns (bool) { _transfer(msg.sender, to, value); return true; } function _validateAddress(address _addr) internal pure { require(_addr != address(0), "invalid address"); } function approve(address spender, uint256 value) public returns (bool) { _validateAddress(spender); _allowed[msg.sender][spender] = value; emit Approval(msg.sender, spender, value); return true; } function transferFrom( address from, address to, uint256 value ) public returns (bool) { require(value <= _allowed[from][msg.sender], "not enough allowed tokens"); _allowed[from][msg.sender] = _allowed[from][msg.sender].sub(value); _transfer(from, to, value); return true; } function increaseAllowance( address spender, uint256 addedValue ) public returns (bool) { _validateAddress(spender); _allowed[msg.sender][spender] = _allowed[msg.sender][spender].add(addedValue); emit Approval(msg.sender, spender, _allowed[msg.sender][spender]); return true; } function decreaseAllowance( address spender, uint256 subtractedValue ) public returns (bool) { _validateAddress(spender); _allowed[msg.sender][spender] = _allowed[msg.sender][spender].sub(subtractedValue); emit Approval(msg.sender, spender, _allowed[msg.sender][spender]); return true; } function _transfer(address from, address to, uint256 value) internal { require(value <= _balances[from], "not enough tokens"); _validateAddress(to); _balances[from] = _balances[from].sub(value); _balances[to] = _balances[to].add(value); emit Transfer(from, to, value); } function _mint(address account, uint256 value) internal { _validateAddress(account); _totalSupply = _totalSupply.add(value); _balances[account] = _balances[account].add(value); emit Transfer(address(0), account, value); } function _burn(address account, uint256 value) internal { _validateAddress(account); require(value <= _balances[account], "not enough tokens to burn"); _totalSupply = _totalSupply.sub(value); _balances[account] = _balances[account].sub(value); emit Transfer(account, address(0), value); } function _burnFrom(address account, uint256 value) internal { require(value <= _allowed[account][msg.sender], "not enough allowed tokens to burn"); _allowed[account][msg.sender] = _allowed[account][msg.sender].sub(value); _burn(account, value); } } contract Gold is ERC20, Upgradable { address[5] founders = [ 0x23b3763f31F4da6B42F47927BCF66A221E8705Cd, 0x5CFF40372b96e133967d980F72812653163121fa, 0xE246C5Aa2D57878DA70779A75B12dCDFFd77aDBA, 0x950eEAf8ddbA1409dbD25aD16d50A867EEA75c3E, 0x87252E8F04F6c6bC4d2c690893addb7108aa8a5f ]; address foundation = 0x5Ff8957EF7e964E8072815211c9Fc3E7F820F1D4; address NonsenseGames = 0x10208FB4Ef202BdC49803995b0A8CA185383bba4; string constant WP_IPFS_HASH = "QmfR75tK12q2LpkU5dzYqykUUpYswSiewpCbDuwYhRb6M5"; constructor(address treasury) public { name = "Dragonereum Gold"; symbol = "GOLD"; decimals = 18; uint256 _foundersGold = 6000000 * 10**18; // 10% uint256 _foundationGold = 6000000 * 10**18; // 10% uint256 _NonsenseGamesGold = 3000000 * 10**18; // 5% uint256 _gameAccountGold = 45000000 * 10**18; // 75% uint256 _founderStake = _foundersGold.div(founders.length); for (uint256 i = 0; i < founders.length; i++) { _mint(founders[i], _founderStake); } _mint(foundation, _foundationGold); _mint(NonsenseGames, _NonsenseGamesGold); _mint(treasury, _gameAccountGold); require(_totalSupply == 60000000 * 10**18, "wrong total supply"); } function remoteTransfer(address _to, uint256 _value) external onlyController { _transfer(tx.origin, _to, _value); } function burn(uint256 _value) external onlyController { _burn(msg.sender, _value); } }
File 4 of 6: Events
pragma solidity 0.4.25; contract Ownable { address public owner; event OwnershipTransferred(address indexed previousOwner, address indexed newOwner); function _validateAddress(address _addr) internal pure { require(_addr != address(0), "invalid address"); } constructor() public { owner = msg.sender; } modifier onlyOwner() { require(msg.sender == owner, "not a contract owner"); _; } function transferOwnership(address newOwner) public onlyOwner { _validateAddress(newOwner); emit OwnershipTransferred(owner, newOwner); owner = newOwner; } } contract Controllable is Ownable { mapping(address => bool) controllers; modifier onlyController { require(_isController(msg.sender), "no controller rights"); _; } function _isController(address _controller) internal view returns (bool) { return controllers[_controller]; } function _setControllers(address[] _controllers) internal { for (uint256 i = 0; i < _controllers.length; i++) { _validateAddress(_controllers[i]); controllers[_controllers[i]] = true; } } } contract Upgradable is Controllable { address[] internalDependencies; address[] externalDependencies; function getInternalDependencies() public view returns(address[]) { return internalDependencies; } function getExternalDependencies() public view returns(address[]) { return externalDependencies; } function setInternalDependencies(address[] _newDependencies) public onlyOwner { for (uint256 i = 0; i < _newDependencies.length; i++) { _validateAddress(_newDependencies[i]); } internalDependencies = _newDependencies; } function setExternalDependencies(address[] _newDependencies) public onlyOwner { externalDependencies = _newDependencies; _setControllers(_newDependencies); } } //////////////CONTRACT////////////// contract Events is Upgradable { event EggClaimed(address indexed user, uint256 indexed id); event EggSentToNest(address indexed user, uint256 indexed id); event EggHatched(address indexed user, uint256 indexed dragonId, uint256 indexed eggId); event DragonUpgraded(uint256 indexed id); event EggCreated(address indexed user, uint256 indexed id); event DragonOnSale(address indexed seller, uint256 indexed id); event DragonRemovedFromSale(address indexed seller, uint256 indexed id); event DragonRemovedFromBreeding(address indexed seller, uint256 indexed id); event DragonOnBreeding(address indexed seller, uint256 indexed id); event DragonBought(address indexed buyer, address indexed seller, uint256 indexed id, uint256 price); event DragonBreedingBought(address indexed buyer, address indexed seller, uint256 indexed id, uint256 price); event DistributionUpdated(uint256 restAmount, uint256 lastBlock, uint256 interval); event EggOnSale(address indexed seller, uint256 indexed id); event EggRemovedFromSale(address indexed seller, uint256 indexed id); event EggBought(address indexed buyer, address indexed seller, uint256 indexed id, uint256 price); event GoldSellOrderCreated(address indexed seller, uint256 price, uint256 amount); event GoldSellOrderCancelled(address indexed seller); event GoldSold(address indexed buyer, address indexed seller, uint256 amount, uint256 price); event GoldBuyOrderCreated(address indexed buyer, uint256 price, uint256 amount); event GoldBuyOrderCancelled(address indexed buyer); event GoldBought(address indexed seller, address indexed buyer, uint256 amount, uint256 price); event SkillOnSale(address indexed seller, uint256 indexed id); event SkillRemovedFromSale(address indexed seller, uint256 indexed id); event SkillBought(address indexed buyer, address indexed seller, uint256 id, uint256 indexed target, uint256 price); event SkillSet(uint256 indexed id); event SkillUsed(uint256 indexed id, uint256 indexed target); event DragonNameSet(uint256 indexed id, bytes32 name); event DragonTacticsSet(uint256 indexed id, uint8 melee, uint8 attack); event UserNameSet(address indexed user, bytes32 name); event BattleEnded( uint256 indexed battleId, uint256 date, uint256 seed, uint256 attackerId, uint256 indexed winnerId, uint256 indexed looserId, bool isGladiator, uint256 gladiatorBattleId ); event BattleDragonsDetails( uint256 indexed battleId, uint8 winnerLevel, uint32 winnerCoolness, uint8 looserLevel, uint32 looserCoolness ); event BattleHealthAndMana( uint256 indexed battleId, uint32 attackerMaxHealth, uint32 attackerMaxMana, uint32 attackerInitHealth, uint32 attackerInitMana, uint32 opponentMaxHealth, uint32 opponentMaxMana, uint32 opponentInitHealth, uint32 opponentInitMana ); event BattleSkills( uint256 indexed battleId, uint32 attackerAttack, uint32 attackerDefense, uint32 attackerStamina, uint32 attackerSpeed, uint32 attackerIntelligence, uint32 opponentAttack, uint32 opponentDefense, uint32 opponentStamina, uint32 opponentSpeed, uint32 opponentIntelligence ); event BattleTacticsAndBuffs( uint256 indexed battleId, uint8 attackerMeleeChance, uint8 attackerAttackChance, uint8 opponentMeleeChance, uint8 opponentAttackChance, uint32[5] attackerBuffs, uint32[5] opponentBuffs ); event GladiatorBattleEnded( uint256 indexed id, uint256 battleId, address indexed winner, address indexed looser, uint256 reward, bool isGold ); event GladiatorBattleCreated( uint256 indexed id, address indexed user, uint256 indexed dragonId, uint256 bet, bool isGold ); event GladiatorBattleApplicantAdded( uint256 indexed id, address indexed user, uint256 indexed dragonId ); event GladiatorBattleOpponentSelected( uint256 indexed id, uint256 indexed dragonId ); event GladiatorBattleCancelled(uint256 indexed id); event GladiatorBattleBetReturned(uint256 indexed id, address indexed user); event GladiatorBattleOpponentSelectTimeUpdated(uint256 indexed id, uint256 blockNumber); event GladiatorBattleBlockNumberUpdated(uint256 indexed id, uint256 blockNumber); event GladiatorBattleSpectatorBetPlaced( uint256 indexed id, address indexed user, bool indexed willCreatorWin, uint256 bet, bool isGold ); event GladiatorBattleSpectatorBetRemoved(uint256 indexed id, address indexed user); event GladiatorBattleSpectatorRewardPaidOut( uint256 indexed id, address indexed user, uint256 reward, bool isGold ); event LeaderboardRewardsDistributed(uint256[10] dragons, address[10] users); function emitEggClaimed( address _user, uint256 _id ) external onlyController { emit EggClaimed(_user, _id); } function emitEggSentToNest( address _user, uint256 _id ) external onlyController { emit EggSentToNest(_user, _id); } function emitDragonUpgraded( uint256 _id ) external onlyController { emit DragonUpgraded(_id); } function emitEggHatched( address _user, uint256 _dragonId, uint256 _eggId ) external onlyController { emit EggHatched(_user, _dragonId, _eggId); } function emitEggCreated( address _user, uint256 _id ) external onlyController { emit EggCreated(_user, _id); } function emitDragonOnSale( address _user, uint256 _id ) external onlyController { emit DragonOnSale(_user, _id); } function emitDragonRemovedFromSale( address _user, uint256 _id ) external onlyController { emit DragonRemovedFromSale(_user, _id); } function emitDragonRemovedFromBreeding( address _user, uint256 _id ) external onlyController { emit DragonRemovedFromBreeding(_user, _id); } function emitDragonOnBreeding( address _user, uint256 _id ) external onlyController { emit DragonOnBreeding(_user, _id); } function emitDragonBought( address _buyer, address _seller, uint256 _id, uint256 _price ) external onlyController { emit DragonBought(_buyer, _seller, _id, _price); } function emitDragonBreedingBought( address _buyer, address _seller, uint256 _id, uint256 _price ) external onlyController { emit DragonBreedingBought(_buyer, _seller, _id, _price); } function emitDistributionUpdated( uint256 _restAmount, uint256 _lastBlock, uint256 _interval ) external onlyController { emit DistributionUpdated(_restAmount, _lastBlock, _interval); } function emitEggOnSale( address _user, uint256 _id ) external onlyController { emit EggOnSale(_user, _id); } function emitEggRemovedFromSale( address _user, uint256 _id ) external onlyController { emit EggRemovedFromSale(_user, _id); } function emitEggBought( address _buyer, address _seller, uint256 _id, uint256 _price ) external onlyController { emit EggBought(_buyer, _seller, _id, _price); } function emitGoldSellOrderCreated( address _user, uint256 _price, uint256 _amount ) external onlyController { emit GoldSellOrderCreated(_user, _price, _amount); } function emitGoldSellOrderCancelled( address _user ) external onlyController { emit GoldSellOrderCancelled(_user); } function emitGoldSold( address _buyer, address _seller, uint256 _amount, uint256 _price ) external onlyController { emit GoldSold(_buyer, _seller, _amount, _price); } function emitGoldBuyOrderCreated( address _user, uint256 _price, uint256 _amount ) external onlyController { emit GoldBuyOrderCreated(_user, _price, _amount); } function emitGoldBuyOrderCancelled( address _user ) external onlyController { emit GoldBuyOrderCancelled(_user); } function emitGoldBought( address _buyer, address _seller, uint256 _amount, uint256 _price ) external onlyController { emit GoldBought(_buyer, _seller, _amount, _price); } function emitSkillOnSale( address _user, uint256 _id ) external onlyController { emit SkillOnSale(_user, _id); } function emitSkillRemovedFromSale( address _user, uint256 _id ) external onlyController { emit SkillRemovedFromSale(_user, _id); } function emitSkillBought( address _buyer, address _seller, uint256 _id, uint256 _target, uint256 _price ) external onlyController { emit SkillBought(_buyer, _seller, _id, _target, _price); } function emitSkillSet( uint256 _id ) external onlyController { emit SkillSet(_id); } function emitSkillUsed( uint256 _id, uint256 _target ) external onlyController { emit SkillUsed(_id, _target); } function emitDragonNameSet( uint256 _id, bytes32 _name ) external onlyController { emit DragonNameSet(_id, _name); } function emitDragonTacticsSet( uint256 _id, uint8 _melee, uint8 _attack ) external onlyController { emit DragonTacticsSet(_id, _melee, _attack); } function emitUserNameSet( address _user, bytes32 _name ) external onlyController { emit UserNameSet(_user, _name); } function emitBattleEnded( uint256 _battleId, uint256 _date, uint256 _seed, uint256 _attackerId, uint256 _winnerId, uint256 _looserId, bool _isGladiator, uint256 _gladiatorBattleId ) external onlyController { emit BattleEnded( _battleId, _date, _seed, _attackerId, _winnerId, _looserId, _isGladiator, _gladiatorBattleId ); } function emitBattleDragonsDetails( uint256 _battleId, uint8 _winnerLevel, uint32 _winnerCoolness, uint8 _looserLevel, uint32 _looserCoolness ) external onlyController { emit BattleDragonsDetails( _battleId, _winnerLevel, _winnerCoolness, _looserLevel, _looserCoolness ); } function emitBattleHealthAndMana( uint256 _battleId, uint32 _attackerMaxHealth, uint32 _attackerMaxMana, uint32 _attackerInitHealth, uint32 _attackerInitMana, uint32 _opponentMaxHealth, uint32 _opponentMaxMana, uint32 _opponentInitHealth, uint32 _opponentInitMana ) external onlyController { emit BattleHealthAndMana( _battleId, _attackerMaxHealth, _attackerMaxMana, _attackerInitHealth, _attackerInitMana, _opponentMaxHealth, _opponentMaxMana, _opponentInitHealth, _opponentInitMana ); } function emitBattleSkills( uint256 _battleId, uint32 _attackerAttack, uint32 _attackerDefense, uint32 _attackerStamina, uint32 _attackerSpeed, uint32 _attackerIntelligence, uint32 _opponentAttack, uint32 _opponentDefense, uint32 _opponentStamina, uint32 _opponentSpeed, uint32 _opponentIntelligence ) external onlyController { emit BattleSkills( _battleId, _attackerAttack, _attackerDefense, _attackerStamina, _attackerSpeed, _attackerIntelligence, _opponentAttack, _opponentDefense, _opponentStamina, _opponentSpeed, _opponentIntelligence ); } function emitBattleTacticsAndBuffs( uint256 _battleId, uint8 _attackerMeleeChance, uint8 _attackerAttackChance, uint8 _opponentMeleeChance, uint8 _opponentAttackChance, uint32[5] _attackerBuffs, uint32[5] _opponentBuffs ) external onlyController { emit BattleTacticsAndBuffs( _battleId, _attackerMeleeChance, _attackerAttackChance, _opponentMeleeChance, _opponentAttackChance, _attackerBuffs, _opponentBuffs ); } function emitGladiatorBattleEnded( uint256 _id, uint256 _battleId, address _winner, address _looser, uint256 _reward, bool _isGold ) external onlyController { emit GladiatorBattleEnded( _id, _battleId, _winner, _looser, _reward, _isGold ); } function emitGladiatorBattleCreated( uint256 _id, address _user, uint256 _dragonId, uint256 _bet, bool _isGold ) external onlyController { emit GladiatorBattleCreated( _id, _user, _dragonId, _bet, _isGold ); } function emitGladiatorBattleApplicantAdded( uint256 _id, address _user, uint256 _dragonId ) external onlyController { emit GladiatorBattleApplicantAdded( _id, _user, _dragonId ); } function emitGladiatorBattleOpponentSelected( uint256 _id, uint256 _dragonId ) external onlyController { emit GladiatorBattleOpponentSelected( _id, _dragonId ); } function emitGladiatorBattleCancelled( uint256 _id ) external onlyController { emit GladiatorBattleCancelled( _id ); } function emitGladiatorBattleBetReturned( uint256 _id, address _user ) external onlyController { emit GladiatorBattleBetReturned( _id, _user ); } function emitGladiatorBattleOpponentSelectTimeUpdated( uint256 _id, uint256 _blockNumber ) external onlyController { emit GladiatorBattleOpponentSelectTimeUpdated( _id, _blockNumber ); } function emitGladiatorBattleBlockNumberUpdated( uint256 _id, uint256 _blockNumber ) external onlyController { emit GladiatorBattleBlockNumberUpdated( _id, _blockNumber ); } function emitGladiatorBattleSpectatorBetPlaced( uint256 _id, address _user, bool _willCreatorWin, uint256 _value, bool _isGold ) external onlyController { emit GladiatorBattleSpectatorBetPlaced( _id, _user, _willCreatorWin, _value, _isGold ); } function emitGladiatorBattleSpectatorBetRemoved( uint256 _id, address _user ) external onlyController { emit GladiatorBattleSpectatorBetRemoved( _id, _user ); } function emitGladiatorBattleSpectatorRewardPaidOut( uint256 _id, address _user, uint256 _value, bool _isGold ) external onlyController { emit GladiatorBattleSpectatorRewardPaidOut( _id, _user, _value, _isGold ); } function emitLeaderboardRewardsDistributed( uint256[10] _dragons, address[10] _users ) external onlyController { emit LeaderboardRewardsDistributed( _dragons, _users ); } }
File 5 of 6: MarketplaceController
pragma solidity 0.4.25; library SafeMath256 { function mul(uint256 a, uint256 b) internal pure returns (uint256) { if (a == 0) { return 0; } uint256 c = a * b; assert(c / a == b); return c; } function div(uint256 a, uint256 b) internal pure returns (uint256) { return a / b; } function sub(uint256 a, uint256 b) internal pure returns (uint256) { assert(b <= a); return a - b; } function add(uint256 a, uint256 b) internal pure returns (uint256) { uint256 c = a + b; assert(c >= a); return c; } function pow(uint256 a, uint256 b) internal pure returns (uint256) { if (a == 0) return 0; if (b == 0) return 1; uint256 c = a ** b; assert(c / (a ** (b - 1)) == a); return c; } } contract Ownable { address public owner; event OwnershipTransferred(address indexed previousOwner, address indexed newOwner); function _validateAddress(address _addr) internal pure { require(_addr != address(0), "invalid address"); } constructor() public { owner = msg.sender; } modifier onlyOwner() { require(msg.sender == owner, "not a contract owner"); _; } function transferOwnership(address newOwner) public onlyOwner { _validateAddress(newOwner); emit OwnershipTransferred(owner, newOwner); owner = newOwner; } } contract Controllable is Ownable { mapping(address => bool) controllers; modifier onlyController { require(_isController(msg.sender), "no controller rights"); _; } function _isController(address _controller) internal view returns (bool) { return controllers[_controller]; } function _setControllers(address[] _controllers) internal { for (uint256 i = 0; i < _controllers.length; i++) { _validateAddress(_controllers[i]); controllers[_controllers[i]] = true; } } } contract Upgradable is Controllable { address[] internalDependencies; address[] externalDependencies; function getInternalDependencies() public view returns(address[]) { return internalDependencies; } function getExternalDependencies() public view returns(address[]) { return externalDependencies; } function setInternalDependencies(address[] _newDependencies) public onlyOwner { for (uint256 i = 0; i < _newDependencies.length; i++) { _validateAddress(_newDependencies[i]); } internalDependencies = _newDependencies; } function setExternalDependencies(address[] _newDependencies) public onlyOwner { externalDependencies = _newDependencies; _setControllers(_newDependencies); } } contract Core { function breed(address, uint256, uint256) external returns (uint256); function isEggInNest(uint256) external view returns (bool); function useDragonSpecialPeacefulSkill(address, uint256, uint256) external; } contract Marketplace { function sellToken(uint256, address, uint256, uint256, uint16, bool) external; function removeFromAuction(uint256) external; function buyToken(uint256, uint256, uint256, bool) external returns (uint256); function sellerOf(uint256) external view returns (address); } contract EggMarketplace is Marketplace {} contract DragonMarketplace is Marketplace {} contract BreedingMarketplace is Marketplace {} contract GoldMarketplace {} contract SkillMarketplace is Upgradable { function sellToken(uint256, uint256) external; function removeFromAuction(uint256) external; function getAuction(uint256) external view returns (uint256); } contract ERC721Token { function ownerOf(uint256) public view returns (address); function exists(uint256) public view returns (bool); function remoteApprove(address, uint256) external; function isApprovedOrOwner(address, uint256) public view returns (bool); function transferFrom(address, address, uint256) public; } contract DragonStorage is ERC721Token {} contract EggStorage is ERC721Token {} contract ERC20 { function balanceOf(address) public view returns (uint256); } contract Gold is ERC20 { function remoteTransfer(address, uint256) external; } contract Getter { function isDragonBreedingAllowed(uint256) external view returns (bool); function getDragonSpecialPeacefulSkill(uint256) external view returns (uint8, uint32, uint32); function isDragonInGladiatorBattle(uint256) public view returns (bool); } //////////////CONTRACT////////////// contract MarketplaceController is Upgradable { using SafeMath256 for uint256; Core core; BreedingMarketplace breedingMarketplace; EggMarketplace eggMarketplace; DragonMarketplace dragonMarketplace; GoldMarketplace goldMarketplace; SkillMarketplace skillMarketplace; DragonStorage dragonStorage; EggStorage eggStorage; Gold goldTokens; Getter getter; // ACTIONS WITH OWN TOKEN function _isEggOwner(address _user, uint256 _tokenId) internal view returns (bool) { return _user == eggStorage.ownerOf(_tokenId); } function _isDragonOwner(address _user, uint256 _tokenId) internal view returns (bool) { return _user == dragonStorage.ownerOf(_tokenId); } function _checkOwner(bool _isOwner) internal pure { require(_isOwner, "not an owner"); } function _checkEggOwner(uint256 _tokenId, address _user) internal view { _checkOwner(_isEggOwner(_user, _tokenId)); } function _checkDragonOwner(uint256 _tokenId, address _user) internal view { _checkOwner(_isDragonOwner(_user, _tokenId)); } function _compareBuyerAndSeller(address _buyer, address _seller) internal pure { require(_buyer != _seller, "seller can't be buyer"); } function _checkTheDragonIsNotInGladiatorBattle(uint256 _id) internal view { require(!getter.isDragonInGladiatorBattle(_id), "dragon participates in gladiator battle"); } function _checkIfBreedingIsAllowed(uint256 _id) internal view { require(getter.isDragonBreedingAllowed(_id), "dragon has no enough DNA points for breeding"); } function _checkEnoughGold(uint256 _required, uint256 _available) internal pure { require(_required <= _available, "not enough gold"); } function _safeSub(uint256 a, uint256 b) internal pure returns (uint256) { return b > a ? 0 : a.sub(b); } // MARKETPLACE function _transferGold(address _to, uint256 _value) internal { goldTokens.remoteTransfer(_to, _value); } // EGG function buyEgg( address _sender, uint256 _value, uint256 _id, uint256 _expectedPrice, bool _isGold ) external onlyController returns (address seller, uint256 price, bool success) { seller = eggMarketplace.sellerOf(_id); _compareBuyerAndSeller(_sender, seller); if (eggStorage.isApprovedOrOwner(this, _id) && _isEggOwner(seller, _id)) { uint256 _balance = goldTokens.balanceOf(_sender); price = eggMarketplace.buyToken(_id, _isGold ? _balance : _value, _expectedPrice, _isGold); eggStorage.transferFrom(seller, _sender, _id); if (_isGold) { _transferGold(seller, price); } success = true; } else { eggMarketplace.removeFromAuction(_id); success = false; } } function sellEgg( address _sender, uint256 _id, uint256 _maxPrice, uint256 _minPrice, uint16 _period, bool _isGold ) external onlyController { _checkEggOwner(_id, _sender); require(!core.isEggInNest(_id), "egg is in nest"); eggStorage.remoteApprove(this, _id); eggMarketplace.sellToken(_id, _sender, _maxPrice, _minPrice, _period, _isGold); } function removeEggFromSale( address _sender, uint256 _id ) external onlyController { _checkEggOwner(_id, _sender); eggMarketplace.removeFromAuction(_id); } // DRAGON function buyDragon( address _sender, uint256 _value, uint256 _id, uint256 _expectedPrice, bool _isGold ) external onlyController returns (address seller, uint256 price, bool success) { seller = dragonMarketplace.sellerOf(_id); _compareBuyerAndSeller(_sender, seller); if (dragonStorage.isApprovedOrOwner(this, _id) && _isDragonOwner(seller, _id)) { uint256 _balance = goldTokens.balanceOf(_sender); price = dragonMarketplace.buyToken(_id, _isGold ? _balance : _value, _expectedPrice, _isGold); dragonStorage.transferFrom(seller, _sender, _id); if (_isGold) { _transferGold(seller, price); } success = true; } else { dragonMarketplace.removeFromAuction(_id); success = false; } } function sellDragon( address _sender, uint256 _id, uint256 _maxPrice, uint256 _minPrice, uint16 _period, bool _isGold ) external onlyController { _checkDragonOwner(_id, _sender); _checkTheDragonIsNotInGladiatorBattle(_id); require(breedingMarketplace.sellerOf(_id) == address(0), "dragon is on breeding sale"); dragonStorage.remoteApprove(this, _id); dragonMarketplace.sellToken(_id, _sender, _maxPrice, _minPrice, _period, _isGold); } function removeDragonFromSale( address _sender, uint256 _id ) external onlyController { _checkDragonOwner(_id, _sender); dragonMarketplace.removeFromAuction(_id); } // BREEDING function buyBreeding( address _sender, uint256 _value, uint256 _momId, uint256 _dadId, uint256 _expectedPrice, bool _isGold ) external onlyController returns (uint256 eggId, address seller, uint256 price, bool success) { _checkIfBreedingIsAllowed(_momId); require(_momId != _dadId, "the same dragon"); _checkDragonOwner(_momId, _sender); seller = breedingMarketplace.sellerOf(_dadId); _compareBuyerAndSeller(_sender, seller); if (getter.isDragonBreedingAllowed(_dadId) && _isDragonOwner(seller, _dadId)) { uint256 _balance = goldTokens.balanceOf(_sender); price = breedingMarketplace.buyToken(_dadId, _isGold ? _balance : _value, _expectedPrice, _isGold); eggId = core.breed(_sender, _momId, _dadId); if (_isGold) { _transferGold(seller, price); } success = true; } else { breedingMarketplace.removeFromAuction(_dadId); success = false; } } function sellBreeding( address _sender, uint256 _id, uint256 _maxPrice, uint256 _minPrice, uint16 _period, bool _isGold ) external onlyController { _checkIfBreedingIsAllowed(_id); _checkDragonOwner(_id, _sender); _checkTheDragonIsNotInGladiatorBattle(_id); require(dragonMarketplace.sellerOf(_id) == address(0), "dragon is on sale"); breedingMarketplace.sellToken(_id, _sender, _maxPrice, _minPrice, _period, _isGold); } function removeBreedingFromSale( address _sender, uint256 _id ) external onlyController { _checkDragonOwner(_id, _sender); breedingMarketplace.removeFromAuction(_id); } // SKILL function buySkill( address _sender, uint256 _id, uint256 _target, uint256 _expectedPrice, uint32 _expectedEffect ) external onlyController returns (address seller, uint256 price, bool success) { if (dragonStorage.exists(_id)) { price = skillMarketplace.getAuction(_id); seller = dragonStorage.ownerOf(_id); _compareBuyerAndSeller(_sender, seller); _checkTheDragonIsNotInGladiatorBattle(_id); _checkTheDragonIsNotInGladiatorBattle(_target); require(price <= _expectedPrice, "wrong price"); uint256 _balance = goldTokens.balanceOf(_sender); _checkEnoughGold(price, _balance); ( , , uint32 _effect) = getter.getDragonSpecialPeacefulSkill(_id); require(_effect >= _expectedEffect, "effect decreased"); core.useDragonSpecialPeacefulSkill(seller, _id, _target); _transferGold(seller, price); success = true; } else { skillMarketplace.removeFromAuction(_id); success = false; } } function sellSkill( address _sender, uint256 _id, uint256 _price ) external onlyController { _checkDragonOwner(_id, _sender); _checkTheDragonIsNotInGladiatorBattle(_id); (uint8 _skillClass, , ) = getter.getDragonSpecialPeacefulSkill(_id); require(_skillClass > 0, "special peaceful skill is not yet set"); skillMarketplace.sellToken(_id, _price); } function removeSkillFromSale( address _sender, uint256 _id ) external onlyController { _checkDragonOwner(_id, _sender); skillMarketplace.removeFromAuction(_id); } // UPDATE CONTRACT function setInternalDependencies(address[] _newDependencies) public onlyOwner { super.setInternalDependencies(_newDependencies); core = Core(_newDependencies[0]); dragonStorage = DragonStorage(_newDependencies[1]); eggStorage = EggStorage(_newDependencies[2]); dragonMarketplace = DragonMarketplace(_newDependencies[3]); breedingMarketplace = BreedingMarketplace(_newDependencies[4]); eggMarketplace = EggMarketplace(_newDependencies[5]); goldMarketplace = GoldMarketplace(_newDependencies[6]); skillMarketplace = SkillMarketplace(_newDependencies[7]); goldTokens = Gold(_newDependencies[8]); getter = Getter(_newDependencies[9]); } }
File 6 of 6: EggMarketplace
pragma solidity 0.4.25; library SafeMath256 { function mul(uint256 a, uint256 b) internal pure returns (uint256) { if (a == 0) { return 0; } uint256 c = a * b; assert(c / a == b); return c; } function div(uint256 a, uint256 b) internal pure returns (uint256) { return a / b; } function sub(uint256 a, uint256 b) internal pure returns (uint256) { assert(b <= a); return a - b; } function add(uint256 a, uint256 b) internal pure returns (uint256) { uint256 c = a + b; assert(c >= a); return c; } function pow(uint256 a, uint256 b) internal pure returns (uint256) { if (a == 0) return 0; if (b == 0) return 1; uint256 c = a ** b; assert(c / (a ** (b - 1)) == a); return c; } } contract Ownable { address public owner; event OwnershipTransferred(address indexed previousOwner, address indexed newOwner); function _validateAddress(address _addr) internal pure { require(_addr != address(0), "invalid address"); } constructor() public { owner = msg.sender; } modifier onlyOwner() { require(msg.sender == owner, "not a contract owner"); _; } function transferOwnership(address newOwner) public onlyOwner { _validateAddress(newOwner); emit OwnershipTransferred(owner, newOwner); owner = newOwner; } } contract Controllable is Ownable { mapping(address => bool) controllers; modifier onlyController { require(_isController(msg.sender), "no controller rights"); _; } function _isController(address _controller) internal view returns (bool) { return controllers[_controller]; } function _setControllers(address[] _controllers) internal { for (uint256 i = 0; i < _controllers.length; i++) { _validateAddress(_controllers[i]); controllers[_controllers[i]] = true; } } } contract Upgradable is Controllable { address[] internalDependencies; address[] externalDependencies; function getInternalDependencies() public view returns(address[]) { return internalDependencies; } function getExternalDependencies() public view returns(address[]) { return externalDependencies; } function setInternalDependencies(address[] _newDependencies) public onlyOwner { for (uint256 i = 0; i < _newDependencies.length; i++) { _validateAddress(_newDependencies[i]); } internalDependencies = _newDependencies; } function setExternalDependencies(address[] _newDependencies) public onlyOwner { externalDependencies = _newDependencies; _setControllers(_newDependencies); } } //////////////CONTRACT////////////// contract Marketplace is Upgradable { using SafeMath256 for uint256; struct Auction { address seller; uint256 startPrice; uint256 endPrice; uint16 period; // in hours uint256 created; bool isGold; // gold or ether } uint256 constant MULTIPLIER = 1000000; // for more accurate calculations uint16 constant MAX_PERIOD = 8760; // 8760 hours = 1 year uint8 constant FLAT_TYPE = 0; uint8 constant INCREASING_TYPE = 1; uint8 constant DUTCH_TYPE = 2; mapping (address => uint256[]) internal ownedTokens; mapping (uint256 => uint256) internal ownedTokensIndex; mapping (uint256 => uint256) allTokensIndex; mapping (uint256 => Auction) tokenToAuction; uint256[] allTokens; constructor() public {} function sellToken( uint256 _tokenId, address _seller, uint256 _startPrice, uint256 _endPrice, uint16 _period, bool _isGold ) external onlyController { Auction memory _auction; require(_startPrice > 0 && _endPrice > 0, "price must be more than 0"); if (_startPrice != _endPrice) { require(_period > 0 && _period <= MAX_PERIOD, "wrong period value"); } _auction = Auction(_seller, _startPrice, _endPrice, _period, now, _isGold); // if auction doesn't exist if (tokenToAuction[_tokenId].seller == address(0)) { uint256 length = ownedTokens[_seller].length; ownedTokens[_seller].push(_tokenId); ownedTokensIndex[_tokenId] = length; allTokensIndex[_tokenId] = allTokens.length; allTokens.push(_tokenId); } tokenToAuction[_tokenId] = _auction; } function removeFromAuction(uint256 _tokenId) external onlyController { address _seller = tokenToAuction[_tokenId].seller; require(_seller != address(0), "token is not on sale"); _remove(_seller, _tokenId); } function buyToken( uint256 _tokenId, uint256 _value, uint256 _expectedPrice, bool _expectedIsGold ) external onlyController returns (uint256 price) { Auction memory _auction = tokenToAuction[_tokenId]; require(_auction.seller != address(0), "invalid address"); require(_auction.isGold == _expectedIsGold, "wrong currency"); price = _getCurrentPrice(_tokenId); require(price <= _expectedPrice, "wrong price"); require(price <= _value, "not enough ether/gold"); _remove(_auction.seller, _tokenId); } function _remove(address _from, uint256 _tokenId) internal { require(allTokens.length > 0, "no auctions"); delete tokenToAuction[_tokenId]; _removeFrom(_from, _tokenId); uint256 tokenIndex = allTokensIndex[_tokenId]; uint256 lastTokenIndex = allTokens.length.sub(1); uint256 lastToken = allTokens[lastTokenIndex]; allTokens[tokenIndex] = lastToken; allTokens[lastTokenIndex] = 0; allTokens.length--; allTokensIndex[_tokenId] = 0; allTokensIndex[lastToken] = tokenIndex; } function _removeFrom(address _from, uint256 _tokenId) internal { require(ownedTokens[_from].length > 0, "no seller auctions"); uint256 tokenIndex = ownedTokensIndex[_tokenId]; uint256 lastTokenIndex = ownedTokens[_from].length.sub(1); uint256 lastToken = ownedTokens[_from][lastTokenIndex]; ownedTokens[_from][tokenIndex] = lastToken; ownedTokens[_from][lastTokenIndex] = 0; ownedTokens[_from].length--; ownedTokensIndex[_tokenId] = 0; ownedTokensIndex[lastToken] = tokenIndex; } function _getCurrentPrice(uint256 _id) internal view returns (uint256) { Auction memory _auction = tokenToAuction[_id]; if (_auction.startPrice == _auction.endPrice) { return _auction.startPrice; } return _calculateCurrentPrice( _auction.startPrice, _auction.endPrice, _auction.period, _auction.created ); } function _calculateCurrentPrice( uint256 _startPrice, uint256 _endPrice, uint16 _period, uint256 _created ) internal view returns (uint256) { bool isIncreasingType = _startPrice < _endPrice; uint256 _fullPeriod = uint256(1 hours).mul(_period); // price changing period uint256 _interval = isIncreasingType ? _endPrice.sub(_startPrice) : _startPrice.sub(_endPrice); uint256 _pastTime = now.sub(_created); if (_pastTime >= _fullPeriod) return _endPrice; // how much is _pastTime in percents to period uint256 _percent = MULTIPLIER.sub(_fullPeriod.sub(_pastTime).mul(MULTIPLIER).div(_fullPeriod)); uint256 _diff = _interval.mul(_percent).div(MULTIPLIER); return isIncreasingType ? _startPrice.add(_diff) : _startPrice.sub(_diff); } // GETTERS function sellerOf(uint256 _id) external view returns (address) { return tokenToAuction[_id].seller; } function getAuction(uint256 _id) external view returns ( address, uint256, uint256, uint256, uint16, uint256, bool ) { Auction memory _auction = tokenToAuction[_id]; return ( _auction.seller, _getCurrentPrice(_id), _auction.startPrice, _auction.endPrice, _auction.period, _auction.created, _auction.isGold ); } function tokensOfOwner(address _owner) external view returns (uint256[]) { return ownedTokens[_owner]; } function getAllTokens() external view returns (uint256[]) { return allTokens; } function totalSupply() public view returns (uint256) { return allTokens.length; } } contract EggMarketplace is Marketplace {}