ETH Price: $2,926.01 (-1.92%)

Transaction Decoder

Block:
11156537 at Oct-30-2020 06:31:11 AM +UTC
Transaction Fee:
0.019960952 ETH $58.41
Gas Used:
453,658 Gas / 44 Gwei

Emitted Events:

51 0x37236cd05b34cc79d3715af2383e96dd7443dcf1.0x8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b925( 0x8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b925, 0x00000000000000000000000003981a2dc3f5e17b5e98174b6bf6623cf9652788, 0x00000000000000000000000001aac5236ad205ebbe4f6819bc64ef5bef40b71c, 000000000000000000000000000000000000000000000000000000003b9aca00 )
52 0x37236cd05b34cc79d3715af2383e96dd7443dcf1.0xddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef( 0xddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef, 0x00000000000000000000000003981a2dc3f5e17b5e98174b6bf6623cf9652788, 0x0000000000000000000000000000000000000000000000000000000000000000, 000000000000000000000000000000000000000000000000000000000000012c )
53 AxieCore.Transfer( _from=0x0000000000000000000000000000000000000000, _to=[Sender] 0x03981a2dc3f5e17b5e98174b6bf6623cf9652788, _tokenId=171174 )
54 AxieCore.AxieSpawned( _axieId=171174, _owner=[Sender] 0x03981a2dc3f5e17b5e98174b6bf6623cf9652788, _genes=0 )

Account State Difference:

  Address   Before After State Difference Code
0x01AAc523...BeF40b71c
(Axie Infinity: Breeding Contract #1)
31.28 Eth31.285 Eth0.005
0x03981A2D...cf9652788
1.16697463309719326 Eth
Nonce: 410
1.14201368109719326 Eth
Nonce: 411
0.024960952
0x10e304a5...65eBDFE34
0x37236CD0...d7443dCF1
(BeePool)
297.287942184998235897 Eth297.307903136998235897 Eth0.019960952
0xF5b0A3eF...F3FFEcb8d

Execution Trace

ETH 0.005 Small Love Potion: Old SLP Token.f5e54063( )
  • ETH 0.005 Axie Infinity: Breeding Contract #1.8f4ffcb1( )
    • 0xa4787fdb16efd4d0f9967001c207f7a6e281b686.6ae17ab7( )
      • AxieCore.getAxie( _axieId=141029 ) => ( 71917742929919486277931196853041324359794463473604994715301149089407416080518, 1580490283 )
      • AxieCore.getAxie( _axieId=139013 ) => ( 26234145218367611277388423096296903098203495979240598206643892883169789284484, 1579013016 )
      • AxieCore.ownerOf( _tokenId=141029 ) => ( 0x03981A2Dc3F5e17B5e98174b6bf6623cf9652788 )
      • AxieCore.ownerOf( _tokenId=139013 ) => ( 0x03981A2Dc3F5e17B5e98174b6bf6623cf9652788 )
      • AxieCore.getAxie( _axieId=141029 ) => ( 71917742929919486277931196853041324359794463473604994715301149089407416080518, 1580490283 )
      • AxieCore.getAxie( _axieId=139013 ) => ( 26234145218367611277388423096296903098203495979240598206643892883169789284484, 1579013016 )
      • 0x10e304a53351b272dc415ad049ad06565ebdfe34.7d831dd4( )
      • 0x10e304a53351b272dc415ad049ad06565ebdfe34.893bb0bf( )
      • 0x10e304a53351b272dc415ad049ad06565ebdfe34.cace40be( )
        • 0x26c89cf33b8473ea8e0513e17bd674d8fd0bc2cd.771c0ad9( )
          • 0x10e304a53351b272dc415ad049ad06565ebdfe34.CALL( )
          • 0x10e304a53351b272dc415ad049ad06565ebdfe34.893bb0bf( )
          • 0x10e304a53351b272dc415ad049ad06565ebdfe34.cace40be( )
            • 0x26c89cf33b8473ea8e0513e17bd674d8fd0bc2cd.771c0ad9( )
              • 0x10e304a53351b272dc415ad049ad06565ebdfe34.CALL( )
              • Small Love Potion: Old SLP Token.79cc6790( )
              • AxieCore.ownerOf( _tokenId=139013 ) => ( 0x03981A2Dc3F5e17B5e98174b6bf6623cf9652788 )
              • 0x10e304a53351b272dc415ad049ad06565ebdfe34.88de9aab( )
                • 0x26c89cf33b8473ea8e0513e17bd674d8fd0bc2cd.cbe44458( )
                  • 0x10e304a53351b272dc415ad049ad06565ebdfe34.CALL( )
                  • AxieCore.spawnAxie( _genes=0, _owner=0x03981A2Dc3F5e17B5e98174b6bf6623cf9652788 ) => ( 171174 )
                    • 0xe8bd438d0383cf4d19641eaa4793eddc6cebeaf1.0e972421( )
                      • AxieCore.CALL( )
                        pragma solidity ^0.4.19;
                        
                        // File: contracts/erc/erc165/IERC165.sol
                        
                        /// @title ERC-165 Standard Interface Detection
                        /// @dev See https://github.com/ethereum/EIPs/blob/master/EIPS/eip-165.md
                        interface IERC165 {
                          /// @notice Query if a contract implements an interface
                          /// @param interfaceID The interface identifier, as specified in ERC-165
                          /// @dev Interface identification is specified in ERC-165. This function
                          ///  uses less than 30,000 gas.
                          /// @return `true` if the contract implements `interfaceID` and
                          ///  `interfaceID` is not 0xffffffff, `false` otherwise
                          function supportsInterface(bytes4 interfaceID) external view returns (bool);
                        }
                        
                        // File: contracts/erc/erc165/ERC165.sol
                        
                        contract ERC165 is IERC165 {
                          /// @dev You must not set element 0xffffffff to true
                          mapping (bytes4 => bool) internal supportedInterfaces;
                        
                          function ERC165() internal {
                            supportedInterfaces[0x01ffc9a7] = true; // ERC-165
                          }
                        
                          function supportsInterface(bytes4 interfaceID) external view returns (bool) {
                            return supportedInterfaces[interfaceID];
                          }
                        }
                        
                        // File: contracts/erc/erc721/IERC721Base.sol
                        
                        /// @title ERC-721 Non-Fungible Token Standard
                        /// @dev See https://github.com/ethereum/EIPs/blob/master/EIPS/eip-721.md
                        ///  Note: the ERC-165 identifier for this interface is 0x6466353c
                        interface IERC721Base /* is IERC165  */ {
                          /// @dev This emits when ownership of any NFT changes by any mechanism.
                          ///  This event emits when NFTs are created (`from` == 0) and destroyed
                          ///  (`to` == 0). Exception: during contract creation, any number of NFTs
                          ///  may be created and assigned without emitting Transfer. At the time of
                          ///  any transfer, the approved address for that NFT (if any) is reset to none.
                          event Transfer(address indexed _from, address indexed _to, uint256 _tokenId);
                        
                          /// @dev This emits when the approved address for an NFT is changed or
                          ///  reaffirmed. The zero address indicates there is no approved address.
                          ///  When a Transfer event emits, this also indicates that the approved
                          ///  address for that NFT (if any) is reset to none.
                          event Approval(address indexed _owner, address indexed _approved, uint256 _tokenId);
                        
                          /// @dev This emits when an operator is enabled or disabled for an owner.
                          ///  The operator can manage all NFTs of the owner.
                          event ApprovalForAll(address indexed _owner, address indexed _operator, bool _approved);
                        
                          /// @notice Count all NFTs assigned to an owner
                          /// @dev NFTs assigned to the zero address are considered invalid, and this
                          ///  function throws for queries about the zero address.
                          /// @param _owner An address for whom to query the balance
                          /// @return The number of NFTs owned by `_owner`, possibly zero
                          function balanceOf(address _owner) external view returns (uint256);
                        
                          /// @notice Find the owner of an NFT
                          /// @param _tokenId The identifier for an NFT
                          /// @dev NFTs assigned to zero address are considered invalid, and queries
                          ///  about them do throw.
                          /// @return The address of the owner of the NFT
                          function ownerOf(uint256 _tokenId) external view returns (address);
                        
                          /// @notice Transfers the ownership of an NFT from one address to another address
                          /// @dev Throws unless `msg.sender` is the current owner, an authorized
                          ///  operator, or the approved address for this NFT. Throws if `_from` is
                          ///  not the current owner. Throws if `_to` is the zero address. Throws if
                          ///  `_tokenId` is not a valid NFT. When transfer is complete, this function
                          ///  checks if `_to` is a smart contract (code size > 0). If so, it calls
                          ///  `onERC721Received` on `_to` and throws if the return value is not
                          ///  `bytes4(keccak256("onERC721Received(address,uint256,bytes)"))`.
                          /// @param _from The current owner of the NFT
                          /// @param _to The new owner
                          /// @param _tokenId The NFT to transfer
                          /// @param _data Additional data with no specified format, sent in call to `_to`
                          // solium-disable-next-line arg-overflow
                          function safeTransferFrom(address _from, address _to, uint256 _tokenId, bytes _data) external payable;
                        
                          /// @notice Transfers the ownership of an NFT from one address to another address
                          /// @dev This works identically to the other function with an extra data parameter,
                          ///  except this function just sets data to []
                          /// @param _from The current owner of the NFT
                          /// @param _to The new owner
                          /// @param _tokenId The NFT to transfer
                          function safeTransferFrom(address _from, address _to, uint256 _tokenId) external payable;
                        
                          /// @notice Transfer ownership of an NFT -- THE CALLER IS RESPONSIBLE
                          ///  TO CONFIRM THAT `_to` IS CAPABLE OF RECEIVING NFTS OR ELSE
                          ///  THEY MAY BE PERMANENTLY LOST
                          /// @dev Throws unless `msg.sender` is the current owner, an authorized
                          ///  operator, or the approved address for this NFT. Throws if `_from` is
                          ///  not the current owner. Throws if `_to` is the zero address. Throws if
                          ///  `_tokenId` is not a valid NFT.
                          /// @param _from The current owner of the NFT
                          /// @param _to The new owner
                          /// @param _tokenId The NFT to transfer
                          function transferFrom(address _from, address _to, uint256 _tokenId) external payable;
                        
                          /// @notice Set or reaffirm the approved address for an NFT
                          /// @dev The zero address indicates there is no approved address.
                          /// @dev Throws unless `msg.sender` is the current NFT owner, or an authorized
                          ///  operator of the current owner.
                          /// @param _approved The new approved NFT controller
                          /// @param _tokenId The NFT to approve
                          function approve(address _approved, uint256 _tokenId) external payable;
                        
                          /// @notice Enable or disable approval for a third party ("operator") to manage
                          ///  all your asset.
                          /// @dev Emits the ApprovalForAll event
                          /// @param _operator Address to add to the set of authorized operators.
                          /// @param _approved True if the operators is approved, false to revoke approval
                          function setApprovalForAll(address _operator, bool _approved) external;
                        
                          /// @notice Get the approved address for a single NFT
                          /// @dev Throws if `_tokenId` is not a valid NFT
                          /// @param _tokenId The NFT to find the approved address for
                          /// @return The approved address for this NFT, or the zero address if there is none
                          function getApproved(uint256 _tokenId) external view returns (address);
                        
                          /// @notice Query if an address is an authorized operator for another address
                          /// @param _owner The address that owns the NFTs
                          /// @param _operator The address that acts on behalf of the owner
                          /// @return True if `_operator` is an approved operator for `_owner`, false otherwise
                          function isApprovedForAll(address _owner, address _operator) external view returns (bool);
                        }
                        
                        // File: contracts/erc/erc721/IERC721Enumerable.sol
                        
                        /// @title ERC-721 Non-Fungible Token Standard, optional enumeration extension
                        /// @dev See https://github.com/ethereum/EIPs/blob/master/EIPS/eip-721.md
                        ///  Note: the ERC-165 identifier for this interface is 0x780e9d63
                        interface IERC721Enumerable /* is IERC721Base */ {
                          /// @notice Count NFTs tracked by this contract
                          /// @return A count of valid NFTs tracked by this contract, where each one of
                          ///  them has an assigned and queryable owner not equal to the zero address
                          function totalSupply() external view returns (uint256);
                        
                          /// @notice Enumerate valid NFTs
                          /// @dev Throws if `_index` >= `totalSupply()`.
                          /// @param _index A counter less than `totalSupply()`
                          /// @return The token identifier for the `_index`th NFT,
                          ///  (sort order not specified)
                          function tokenByIndex(uint256 _index) external view returns (uint256);
                        
                          /// @notice Enumerate NFTs assigned to an owner
                          /// @dev Throws if `_index` >= `balanceOf(_owner)` or if
                          ///  `_owner` is the zero address, representing invalid NFTs.
                          /// @param _owner An address where we are interested in NFTs owned by them
                          /// @param _index A counter less than `balanceOf(_owner)`
                          /// @return The token identifier for the `_index`th NFT assigned to `_owner`,
                          ///   (sort order not specified)
                          function tokenOfOwnerByIndex(address _owner, uint256 _index) external view returns (uint256 _tokenId);
                        }
                        
                        // File: contracts/erc/erc721/IERC721TokenReceiver.sol
                        
                        /// @dev Note: the ERC-165 identifier for this interface is 0xf0b9e5ba
                        interface IERC721TokenReceiver {
                          /// @notice Handle the receipt of an NFT
                          /// @dev The ERC721 smart contract calls this function on the recipient
                          ///  after a `transfer`. This function MAY throw to revert and reject the
                          ///  transfer. This function MUST use 50,000 gas or less. Return of other
                          ///  than the magic value MUST result in the transaction being reverted.
                          ///  Note: the contract address is always the message sender.
                          /// @param _from The sending address
                          /// @param _tokenId The NFT identifier which is being transfered
                          /// @param _data Additional data with no specified format
                          /// @return `bytes4(keccak256("onERC721Received(address,uint256,bytes)"))`
                          ///  unless throwing
                        	function onERC721Received(address _from, uint256 _tokenId, bytes _data) external returns (bytes4);
                        }
                        
                        // File: contracts/core/dependency/AxieManager.sol
                        
                        interface AxieSpawningManager {
                        	function isSpawningAllowed(uint256 _genes, address _owner) external returns (bool);
                          function isRebirthAllowed(uint256 _axieId, uint256 _genes) external returns (bool);
                        }
                        
                        interface AxieRetirementManager {
                          function isRetirementAllowed(uint256 _axieId, bool _rip) external returns (bool);
                        }
                        
                        interface AxieMarketplaceManager {
                          function isTransferAllowed(address _from, address _to, uint256 _axieId) external returns (bool);
                        }
                        
                        interface AxieGeneManager {
                          function isEvolvementAllowed(uint256 _axieId, uint256 _newGenes) external returns (bool);
                        }
                        
                        // File: contracts/core/dependency/AxieDependency.sol
                        
                        contract AxieDependency {
                        
                          address public whitelistSetterAddress;
                        
                          AxieSpawningManager public spawningManager;
                          AxieRetirementManager public retirementManager;
                          AxieMarketplaceManager public marketplaceManager;
                          AxieGeneManager public geneManager;
                        
                          mapping (address => bool) public whitelistedSpawner;
                          mapping (address => bool) public whitelistedByeSayer;
                          mapping (address => bool) public whitelistedMarketplace;
                          mapping (address => bool) public whitelistedGeneScientist;
                        
                          function AxieDependency() internal {
                            whitelistSetterAddress = msg.sender;
                          }
                        
                          modifier onlyWhitelistSetter() {
                            require(msg.sender == whitelistSetterAddress);
                            _;
                          }
                        
                          modifier whenSpawningAllowed(uint256 _genes, address _owner) {
                            require(
                              spawningManager == address(0) ||
                                spawningManager.isSpawningAllowed(_genes, _owner)
                            );
                            _;
                          }
                        
                          modifier whenRebirthAllowed(uint256 _axieId, uint256 _genes) {
                            require(
                              spawningManager == address(0) ||
                                spawningManager.isRebirthAllowed(_axieId, _genes)
                            );
                            _;
                          }
                        
                          modifier whenRetirementAllowed(uint256 _axieId, bool _rip) {
                            require(
                              retirementManager == address(0) ||
                                retirementManager.isRetirementAllowed(_axieId, _rip)
                            );
                            _;
                          }
                        
                          modifier whenTransferAllowed(address _from, address _to, uint256 _axieId) {
                            require(
                              marketplaceManager == address(0) ||
                                marketplaceManager.isTransferAllowed(_from, _to, _axieId)
                            );
                            _;
                          }
                        
                          modifier whenEvolvementAllowed(uint256 _axieId, uint256 _newGenes) {
                            require(
                              geneManager == address(0) ||
                                geneManager.isEvolvementAllowed(_axieId, _newGenes)
                            );
                            _;
                          }
                        
                          modifier onlySpawner() {
                            require(whitelistedSpawner[msg.sender]);
                            _;
                          }
                        
                          modifier onlyByeSayer() {
                            require(whitelistedByeSayer[msg.sender]);
                            _;
                          }
                        
                          modifier onlyMarketplace() {
                            require(whitelistedMarketplace[msg.sender]);
                            _;
                          }
                        
                          modifier onlyGeneScientist() {
                            require(whitelistedGeneScientist[msg.sender]);
                            _;
                          }
                        
                          /*
                           * @dev Setting the whitelist setter address to `address(0)` would be a irreversible process.
                           *  This is to lock changes to Axie's contracts after their development is done.
                           */
                          function setWhitelistSetter(address _newSetter) external onlyWhitelistSetter {
                            whitelistSetterAddress = _newSetter;
                          }
                        
                          function setSpawningManager(address _manager) external onlyWhitelistSetter {
                            spawningManager = AxieSpawningManager(_manager);
                          }
                        
                          function setRetirementManager(address _manager) external onlyWhitelistSetter {
                            retirementManager = AxieRetirementManager(_manager);
                          }
                        
                          function setMarketplaceManager(address _manager) external onlyWhitelistSetter {
                            marketplaceManager = AxieMarketplaceManager(_manager);
                          }
                        
                          function setGeneManager(address _manager) external onlyWhitelistSetter {
                            geneManager = AxieGeneManager(_manager);
                          }
                        
                          function setSpawner(address _spawner, bool _whitelisted) external onlyWhitelistSetter {
                            require(whitelistedSpawner[_spawner] != _whitelisted);
                            whitelistedSpawner[_spawner] = _whitelisted;
                          }
                        
                          function setByeSayer(address _byeSayer, bool _whitelisted) external onlyWhitelistSetter {
                            require(whitelistedByeSayer[_byeSayer] != _whitelisted);
                            whitelistedByeSayer[_byeSayer] = _whitelisted;
                          }
                        
                          function setMarketplace(address _marketplace, bool _whitelisted) external onlyWhitelistSetter {
                            require(whitelistedMarketplace[_marketplace] != _whitelisted);
                            whitelistedMarketplace[_marketplace] = _whitelisted;
                          }
                        
                          function setGeneScientist(address _geneScientist, bool _whitelisted) external onlyWhitelistSetter {
                            require(whitelistedGeneScientist[_geneScientist] != _whitelisted);
                            whitelistedGeneScientist[_geneScientist] = _whitelisted;
                          }
                        }
                        
                        // File: contracts/core/AxieAccessControl.sol
                        
                        contract AxieAccessControl {
                        
                          address public ceoAddress;
                          address public cfoAddress;
                          address public cooAddress;
                        
                          function AxieAccessControl() internal {
                            ceoAddress = msg.sender;
                          }
                        
                          modifier onlyCEO() {
                            require(msg.sender == ceoAddress);
                            _;
                          }
                        
                          modifier onlyCFO() {
                            require(msg.sender == cfoAddress);
                            _;
                          }
                        
                          modifier onlyCOO() {
                            require(msg.sender == cooAddress);
                            _;
                          }
                        
                          modifier onlyCLevel() {
                            require(
                              // solium-disable operator-whitespace
                              msg.sender == ceoAddress ||
                                msg.sender == cfoAddress ||
                                msg.sender == cooAddress
                              // solium-enable operator-whitespace
                            );
                            _;
                          }
                        
                          function setCEO(address _newCEO) external onlyCEO {
                            require(_newCEO != address(0));
                            ceoAddress = _newCEO;
                          }
                        
                          function setCFO(address _newCFO) external onlyCEO {
                            cfoAddress = _newCFO;
                          }
                        
                          function setCOO(address _newCOO) external onlyCEO {
                            cooAddress = _newCOO;
                          }
                        
                          function withdrawBalance() external onlyCFO {
                            cfoAddress.transfer(this.balance);
                          }
                        }
                        
                        // File: contracts/core/lifecycle/AxiePausable.sol
                        
                        contract AxiePausable is AxieAccessControl {
                        
                          bool public paused = false;
                        
                          modifier whenNotPaused() {
                            require(!paused);
                            _;
                          }
                        
                          modifier whenPaused {
                            require(paused);
                            _;
                          }
                        
                          function pause() external onlyCLevel whenNotPaused {
                            paused = true;
                          }
                        
                          function unpause() public onlyCEO whenPaused {
                            paused = false;
                          }
                        }
                        
                        // File: zeppelin/contracts/math/SafeMath.sol
                        
                        /**
                         * @title SafeMath
                         * @dev Math operations with safety checks that throw on error
                         */
                        library SafeMath {
                          function mul(uint256 a, uint256 b) internal constant returns (uint256) {
                            uint256 c = a * b;
                            assert(a == 0 || c / a == b);
                            return c;
                          }
                        
                          function div(uint256 a, uint256 b) internal constant returns (uint256) {
                            // assert(b > 0); // Solidity automatically throws when dividing by 0
                            uint256 c = a / b;
                            // assert(a == b * c + a % b); // There is no case in which this doesn't hold
                            return c;
                          }
                        
                          function sub(uint256 a, uint256 b) internal constant returns (uint256) {
                            assert(b <= a);
                            return a - b;
                          }
                        
                          function add(uint256 a, uint256 b) internal constant returns (uint256) {
                            uint256 c = a + b;
                            assert(c >= a);
                            return c;
                          }
                        }
                        
                        // File: contracts/core/erc721/AxieERC721BaseEnumerable.sol
                        
                        contract AxieERC721BaseEnumerable is ERC165, IERC721Base, IERC721Enumerable, AxieDependency, AxiePausable {
                          using SafeMath for uint256;
                        
                          // @dev Total amount of tokens.
                          uint256 private _totalTokens;
                        
                          // @dev Mapping from token index to ID.
                          mapping (uint256 => uint256) private _overallTokenId;
                        
                          // @dev Mapping from token ID to index.
                          mapping (uint256 => uint256) private _overallTokenIndex;
                        
                          // @dev Mapping from token ID to owner.
                          mapping (uint256 => address) private _tokenOwner;
                        
                          // @dev For a given owner and a given operator, store whether
                          //  the operator is allowed to manage tokens on behalf of the owner.
                          mapping (address => mapping (address => bool)) private _tokenOperator;
                        
                          // @dev Mapping from token ID to approved address.
                          mapping (uint256 => address) private _tokenApproval;
                        
                          // @dev Mapping from owner to list of owned token IDs.
                          mapping (address => uint256[]) private _ownedTokens;
                        
                          // @dev Mapping from token ID to index in the owned token list.
                          mapping (uint256 => uint256) private _ownedTokenIndex;
                        
                          function AxieERC721BaseEnumerable() internal {
                            supportedInterfaces[0x6466353c] = true; // ERC-721 Base
                            supportedInterfaces[0x780e9d63] = true; // ERC-721 Enumerable
                          }
                        
                          // solium-disable function-order
                        
                          modifier mustBeValidToken(uint256 _tokenId) {
                            require(_tokenOwner[_tokenId] != address(0));
                            _;
                          }
                        
                          function _isTokenOwner(address _ownerToCheck, uint256 _tokenId) private view returns (bool) {
                            return _tokenOwner[_tokenId] == _ownerToCheck;
                          }
                        
                          function _isTokenOperator(address _operatorToCheck, uint256 _tokenId) private view returns (bool) {
                            return whitelistedMarketplace[_operatorToCheck] ||
                              _tokenOperator[_tokenOwner[_tokenId]][_operatorToCheck];
                          }
                        
                          function _isApproved(address _approvedToCheck, uint256 _tokenId) private view returns (bool) {
                            return _tokenApproval[_tokenId] == _approvedToCheck;
                          }
                        
                          modifier onlyTokenOwner(uint256 _tokenId) {
                            require(_isTokenOwner(msg.sender, _tokenId));
                            _;
                          }
                        
                          modifier onlyTokenOwnerOrOperator(uint256 _tokenId) {
                            require(_isTokenOwner(msg.sender, _tokenId) || _isTokenOperator(msg.sender, _tokenId));
                            _;
                          }
                        
                          modifier onlyTokenAuthorized(uint256 _tokenId) {
                            require(
                              // solium-disable operator-whitespace
                              _isTokenOwner(msg.sender, _tokenId) ||
                                _isTokenOperator(msg.sender, _tokenId) ||
                                _isApproved(msg.sender, _tokenId)
                              // solium-enable operator-whitespace
                            );
                            _;
                          }
                        
                          // ERC-721 Base
                        
                          function balanceOf(address _owner) external view returns (uint256) {
                            require(_owner != address(0));
                            return _ownedTokens[_owner].length;
                          }
                        
                          function ownerOf(uint256 _tokenId) external view mustBeValidToken(_tokenId) returns (address) {
                            return _tokenOwner[_tokenId];
                          }
                        
                          function _addTokenTo(address _to, uint256 _tokenId) private {
                            require(_to != address(0));
                        
                            _tokenOwner[_tokenId] = _to;
                        
                            uint256 length = _ownedTokens[_to].length;
                            _ownedTokens[_to].push(_tokenId);
                            _ownedTokenIndex[_tokenId] = length;
                          }
                        
                          function _mint(address _to, uint256 _tokenId) internal {
                            require(_tokenOwner[_tokenId] == address(0));
                        
                            _addTokenTo(_to, _tokenId);
                        
                            _overallTokenId[_totalTokens] = _tokenId;
                            _overallTokenIndex[_tokenId] = _totalTokens;
                            _totalTokens = _totalTokens.add(1);
                        
                            Transfer(address(0), _to, _tokenId);
                          }
                        
                          function _removeTokenFrom(address _from, uint256 _tokenId) private {
                            require(_from != address(0));
                        
                            uint256 _tokenIndex = _ownedTokenIndex[_tokenId];
                            uint256 _lastTokenIndex = _ownedTokens[_from].length.sub(1);
                            uint256 _lastTokenId = _ownedTokens[_from][_lastTokenIndex];
                        
                            _tokenOwner[_tokenId] = address(0);
                        
                            // Insert the last token into the position previously occupied by the removed token.
                            _ownedTokens[_from][_tokenIndex] = _lastTokenId;
                            _ownedTokenIndex[_lastTokenId] = _tokenIndex;
                        
                            // Resize the array.
                            delete _ownedTokens[_from][_lastTokenIndex];
                            _ownedTokens[_from].length--;
                        
                            // Remove the array if no more tokens are owned to prevent pollution.
                            if (_ownedTokens[_from].length == 0) {
                              delete _ownedTokens[_from];
                            }
                        
                            // Update the index of the removed token.
                            delete _ownedTokenIndex[_tokenId];
                          }
                        
                          function _burn(uint256 _tokenId) internal {
                            address _from = _tokenOwner[_tokenId];
                        
                            require(_from != address(0));
                        
                            _removeTokenFrom(_from, _tokenId);
                            _totalTokens = _totalTokens.sub(1);
                        
                            uint256 _tokenIndex = _overallTokenIndex[_tokenId];
                            uint256 _lastTokenId = _overallTokenId[_totalTokens];
                        
                            delete _overallTokenIndex[_tokenId];
                            delete _overallTokenId[_totalTokens];
                            _overallTokenId[_tokenIndex] = _lastTokenId;
                            _overallTokenIndex[_lastTokenId] = _tokenIndex;
                        
                            Transfer(_from, address(0), _tokenId);
                          }
                        
                          function _isContract(address _address) private view returns (bool) {
                            uint _size;
                            // solium-disable-next-line security/no-inline-assembly
                            assembly { _size := extcodesize(_address) }
                            return _size > 0;
                          }
                        
                          function _transferFrom(
                            address _from,
                            address _to,
                            uint256 _tokenId,
                            bytes _data,
                            bool _check
                          )
                            internal
                            mustBeValidToken(_tokenId)
                            onlyTokenAuthorized(_tokenId)
                            whenTransferAllowed(_from, _to, _tokenId)
                          {
                            require(_isTokenOwner(_from, _tokenId));
                            require(_to != address(0));
                            require(_to != _from);
                        
                            _removeTokenFrom(_from, _tokenId);
                        
                            delete _tokenApproval[_tokenId];
                            Approval(_from, address(0), _tokenId);
                        
                            _addTokenTo(_to, _tokenId);
                        
                            if (_check && _isContract(_to)) {
                              IERC721TokenReceiver(_to).onERC721Received.gas(50000)(_from, _tokenId, _data);
                            }
                        
                            Transfer(_from, _to, _tokenId);
                          }
                        
                          // solium-disable arg-overflow
                        
                          function safeTransferFrom(address _from, address _to, uint256 _tokenId, bytes _data) external payable {
                            _transferFrom(_from, _to, _tokenId, _data, true);
                          }
                        
                          function safeTransferFrom(address _from, address _to, uint256 _tokenId) external payable {
                            _transferFrom(_from, _to, _tokenId, "", true);
                          }
                        
                          function transferFrom(address _from, address _to, uint256 _tokenId) external payable {
                            _transferFrom(_from, _to, _tokenId, "", false);
                          }
                        
                          // solium-enable arg-overflow
                        
                          function approve(
                            address _approved,
                            uint256 _tokenId
                          )
                            external
                            payable
                            mustBeValidToken(_tokenId)
                            onlyTokenOwnerOrOperator(_tokenId)
                            whenNotPaused
                          {
                            address _owner = _tokenOwner[_tokenId];
                        
                            require(_owner != _approved);
                            require(_tokenApproval[_tokenId] != _approved);
                        
                            _tokenApproval[_tokenId] = _approved;
                        
                            Approval(_owner, _approved, _tokenId);
                          }
                        
                          function setApprovalForAll(address _operator, bool _approved) external whenNotPaused {
                            require(_tokenOperator[msg.sender][_operator] != _approved);
                            _tokenOperator[msg.sender][_operator] = _approved;
                            ApprovalForAll(msg.sender, _operator, _approved);
                          }
                        
                          function getApproved(uint256 _tokenId) external view mustBeValidToken(_tokenId) returns (address) {
                            return _tokenApproval[_tokenId];
                          }
                        
                          function isApprovedForAll(address _owner, address _operator) external view returns (bool) {
                            return _tokenOperator[_owner][_operator];
                          }
                        
                          // ERC-721 Enumerable
                        
                          function totalSupply() external view returns (uint256) {
                            return _totalTokens;
                          }
                        
                          function tokenByIndex(uint256 _index) external view returns (uint256) {
                            require(_index < _totalTokens);
                            return _overallTokenId[_index];
                          }
                        
                          function tokenOfOwnerByIndex(address _owner, uint256 _index) external view returns (uint256 _tokenId) {
                            require(_owner != address(0));
                            require(_index < _ownedTokens[_owner].length);
                            return _ownedTokens[_owner][_index];
                          }
                        }
                        
                        // File: contracts/erc/erc721/IERC721Metadata.sol
                        
                        /// @title ERC-721 Non-Fungible Token Standard, optional metadata extension
                        /// @dev See https://github.com/ethereum/EIPs/blob/master/EIPS/eip-721.md
                        ///  Note: the ERC-165 identifier for this interface is 0x5b5e139f
                        interface IERC721Metadata /* is IERC721Base */ {
                          /// @notice A descriptive name for a collection of NFTs in this contract
                          function name() external pure returns (string _name);
                        
                          /// @notice An abbreviated name for NFTs in this contract
                          function symbol() external pure returns (string _symbol);
                        
                          /// @notice A distinct Uniform Resource Identifier (URI) for a given asset.
                          /// @dev Throws if `_tokenId` is not a valid NFT. URIs are defined in RFC
                          ///  3986. The URI may point to a JSON file that conforms to the "ERC721
                          ///  Metadata JSON Schema".
                          function tokenURI(uint256 _tokenId) external view returns (string);
                        }
                        
                        // File: contracts/core/erc721/AxieERC721Metadata.sol
                        
                        contract AxieERC721Metadata is AxieERC721BaseEnumerable, IERC721Metadata {
                          string public tokenURIPrefix = "https://axieinfinity.com/erc/721/axies/";
                          string public tokenURISuffix = ".json";
                        
                          function AxieERC721Metadata() internal {
                            supportedInterfaces[0x5b5e139f] = true; // ERC-721 Metadata
                          }
                        
                          function name() external pure returns (string) {
                            return "Axie";
                          }
                        
                          function symbol() external pure returns (string) {
                            return "AXIE";
                          }
                        
                          function setTokenURIAffixes(string _prefix, string _suffix) external onlyCEO {
                            tokenURIPrefix = _prefix;
                            tokenURISuffix = _suffix;
                          }
                        
                          function tokenURI(
                            uint256 _tokenId
                          )
                            external
                            view
                            mustBeValidToken(_tokenId)
                            returns (string)
                          {
                            bytes memory _tokenURIPrefixBytes = bytes(tokenURIPrefix);
                            bytes memory _tokenURISuffixBytes = bytes(tokenURISuffix);
                            uint256 _tmpTokenId = _tokenId;
                            uint256 _length;
                        
                            do {
                              _length++;
                              _tmpTokenId /= 10;
                            } while (_tmpTokenId > 0);
                        
                            bytes memory _tokenURIBytes = new bytes(_tokenURIPrefixBytes.length + _length + 5);
                            uint256 _i = _tokenURIBytes.length - 6;
                        
                            _tmpTokenId = _tokenId;
                        
                            do {
                              _tokenURIBytes[_i--] = byte(48 + _tmpTokenId % 10);
                              _tmpTokenId /= 10;
                            } while (_tmpTokenId > 0);
                        
                            for (_i = 0; _i < _tokenURIPrefixBytes.length; _i++) {
                              _tokenURIBytes[_i] = _tokenURIPrefixBytes[_i];
                            }
                        
                            for (_i = 0; _i < _tokenURISuffixBytes.length; _i++) {
                              _tokenURIBytes[_tokenURIBytes.length + _i - 5] = _tokenURISuffixBytes[_i];
                            }
                        
                            return string(_tokenURIBytes);
                          }
                        }
                        
                        // File: contracts/core/erc721/AxieERC721.sol
                        
                        // solium-disable-next-line no-empty-blocks
                        contract AxieERC721 is AxieERC721BaseEnumerable, AxieERC721Metadata {
                        }
                        
                        // File: contracts/core/AxieCore.sol
                        
                        // solium-disable-next-line no-empty-blocks
                        contract AxieCore is AxieERC721 {
                          struct Axie {
                            uint256 genes;
                            uint256 bornAt;
                          }
                        
                          Axie[] axies;
                        
                          event AxieSpawned(uint256 indexed _axieId, address indexed _owner, uint256 _genes);
                          event AxieRebirthed(uint256 indexed _axieId, uint256 _genes);
                          event AxieRetired(uint256 indexed _axieId);
                          event AxieEvolved(uint256 indexed _axieId, uint256 _oldGenes, uint256 _newGenes);
                        
                          function AxieCore() public {
                            axies.push(Axie(0, now)); // The void Axie
                            _spawnAxie(0, msg.sender); // Will be Puff
                            _spawnAxie(0, msg.sender); // Will be Kotaro
                            _spawnAxie(0, msg.sender); // Will be Ginger
                            _spawnAxie(0, msg.sender); // Will be Stella
                          }
                        
                          function getAxie(
                            uint256 _axieId
                          )
                            external
                            view
                            mustBeValidToken(_axieId)
                            returns (uint256 /* _genes */, uint256 /* _bornAt */)
                          {
                            Axie storage _axie = axies[_axieId];
                            return (_axie.genes, _axie.bornAt);
                          }
                        
                          function spawnAxie(
                            uint256 _genes,
                            address _owner
                          )
                            external
                            onlySpawner
                            whenSpawningAllowed(_genes, _owner)
                            returns (uint256)
                          {
                            return _spawnAxie(_genes, _owner);
                          }
                        
                          function rebirthAxie(
                            uint256 _axieId,
                            uint256 _genes
                          )
                            external
                            onlySpawner
                            mustBeValidToken(_axieId)
                            whenRebirthAllowed(_axieId, _genes)
                          {
                            Axie storage _axie = axies[_axieId];
                            _axie.genes = _genes;
                            _axie.bornAt = now;
                            AxieRebirthed(_axieId, _genes);
                          }
                        
                          function retireAxie(
                            uint256 _axieId,
                            bool _rip
                          )
                            external
                            onlyByeSayer
                            whenRetirementAllowed(_axieId, _rip)
                          {
                            _burn(_axieId);
                        
                            if (_rip) {
                              delete axies[_axieId];
                            }
                        
                            AxieRetired(_axieId);
                          }
                        
                          function evolveAxie(
                            uint256 _axieId,
                            uint256 _newGenes
                          )
                            external
                            onlyGeneScientist
                            mustBeValidToken(_axieId)
                            whenEvolvementAllowed(_axieId, _newGenes)
                          {
                            uint256 _oldGenes = axies[_axieId].genes;
                            axies[_axieId].genes = _newGenes;
                            AxieEvolved(_axieId, _oldGenes, _newGenes);
                          }
                        
                          function _spawnAxie(uint256 _genes, address _owner) private returns (uint256 _axieId) {
                            Axie memory _axie = Axie(_genes, now);
                            _axieId = axies.push(_axie) - 1;
                            _mint(_owner, _axieId);
                            AxieSpawned(_axieId, _owner, _genes);
                          }
                        }