ETH Price: $2,416.21 (-2.59%)
Gas: 4.41 Gwei

Transaction Decoder

Block:
8993452 at Nov-24-2019 04:30:30 PM +UTC
Transaction Fee:
0.003151962 ETH $7.62
Gas Used:
175,109 Gas / 18 Gwei

Emitted Events:

120 0xf26a23019b4699068bb54457f32dafcf22a9d371.0xddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef( 0xddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef, 0x00000000000000000000000030a7503bcb7a3048f759636c25ac372ce498b7b0, 0x00000000000000000000000083e8729a6ca9517a2b5b535246c426df003b54d1, 0x000000000000000000000000000000000000000000000000000000000010e371 )
121 BuyNFT._resetPrice( _game=0xf26a23019b4699068bb54457f32dafcf22a9d371, _tokenId=1106801 )

Account State Difference:

  Address   Before After State Difference Code
(DwarfPool)
498.491675253788927975 Eth498.494827215788927975 Eth0.003151962
0x30a7503B...cE498B7B0 0 Eth0.02 Eth0.02
0x4b30Ac1D...0441fe40a
0x83E8729a...f003b54D1
0.1289285965 Eth
Nonce: 72
0.1057766345 Eth
Nonce: 73
0.023151962
0xf26A2301...F22A9D371

Execution Trace

ETH 0.02 BuyNFT.buy( _game=0xf26A23019b4699068bb54457f32dAFCF22A9D371, tokenId=1106801 )
  • CryptoDerby: Horse.081812fc( )
  • CryptoDerby: Horse.23b872dd( )
  • ETH 0.02 0x30a7503bcb7a3048f759636c25ac372ce498b7b0.CALL( )
    pragma solidity 0.5.11;
    pragma experimental ABIEncoderV2;
    library SafeMath {
    
        /**
        * @dev Multiplies two numbers, reverts on overflow.
        */
        function mul(uint256 a, uint256 b) internal pure returns (uint256) {
            // Gas optimization: this is cheaper than requiring 'a' not being zero, but the
            // benefit is lost if 'b' is also tested.
            // See: https://github.com/OpenZeppelin/openzeppelin-solidity/pull/522
            if (a == 0) {
                return 0;
            }
    
            uint256 c = a * b;
            require(c / a == b);
    
            return c;
        }
    
        /**
        * @dev Integer division of two numbers truncating the quotient, reverts on division by zero.
        */
        function div(uint256 a, uint256 b) internal pure returns (uint256) {
            require(b > 0); // Solidity only automatically asserts 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;
        }
    
        /**
        * @dev Subtracts two numbers, reverts on overflow (i.e. if subtrahend is greater than minuend).
        */
        function sub(uint256 a, uint256 b) internal pure returns (uint256) {
            require(b <= a);
            uint256 c = a - b;
    
            return c;
        }
    
        /**
        * @dev Adds two numbers, reverts on overflow.
        */
        function add(uint256 a, uint256 b) internal pure returns (uint256) {
            uint256 c = a + b;
            require(c >= a);
    
            return c;
        }
    
        /**
        * @dev Divides two numbers and returns the remainder (unsigned integer modulo),
        * reverts when dividing by zero.
        */
        function mod(uint256 a, uint256 b) internal pure returns (uint256) {
            require(b != 0);
            return a % b;
        }
    }
    /**
     * @title Ownable
     * @dev The Ownable contract has an owner address, and provides basic authorization control
     * functions, this simplifies the implementation of "user permissions".
     */
    contract Ownable {
        address public owner;
    
    
        event OwnershipTransferred(address indexed previousOwner, address indexed newOwner);
    
    
        /**
         * @dev The Ownable constructor sets the original `owner` of the contract to the sender
         * account.
         */
        constructor() public {
            owner = msg.sender;
        }
    
        /**
         * @dev Throws if called by any account other than the owner.
         */
        modifier onlyOwner() {
            require(msg.sender == owner);
            _;
        }
    
        /**
         * @dev Allows the current owner to transfer control of the contract to a newOwner.
         * @param newOwner The address to transfer ownership to.
         */
        function transferOwnership(address newOwner) public onlyOwner {
            require(newOwner != address(0));
            emit OwnershipTransferred(owner, newOwner);
            owner = newOwner;
        }
    
    }
    
    contract IERC721 {
        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 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 transfer(address to, uint256 tokenId) public;
    
        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 memory data) public;
    }
    /**
     * @title ERC20Basic
     * @dev Simpler version of ERC20 interface
     * @dev see https://github.com/ereum/EIPs/issues/179
     */
    contract ERC20BasicInterface {
        function totalSupply() public view returns (uint256);
    
        function balanceOf(address who) public view returns (uint256);
    
        function transfer(address to, uint256 value) public returns (bool);
    
        function transferFrom(address from, address to, uint256 value) public returns (bool);
    
        event Transfer(address indexed from, address indexed to, uint256 value);
    
        uint8 public decimals;
    }
    
    contract BuyNFT is Ownable {
    
        using SafeMath for uint256;
        address public ceoAddress = address(0xFce92D4163AA532AA096DE8a3C4fEf9f875Bc55F);
        ERC20BasicInterface public hbwalletToken = ERC20BasicInterface(0xEc7ba74789694d0d03D458965370Dc7cF2FE75Ba);
        // ERC20BasicInterface public hbwalletToken = ERC20BasicInterface(0x91013928b1C4dbd0D5cB21BA5b052BfD840A7a7F);
        uint256 public Percen = 1000;
        uint256 public hightLightFee = 27 finney;
        struct Price {
            address payable tokenOwner;
            uint256 Price;
            uint256 fee;
            uint isHightlight;
        }
        struct Game {
            mapping(uint256 => Price) tokenPrice;
            uint[] tokenIdSale;
            uint256 Fee;
            uint256 PercenDiscountOnHBWallet;
            uint256 limitHBWALLETForDiscount;
            uint256 limitFee;
        }
    
        mapping(address => Game) public Games;
        address[] public arrGames;
        constructor() public {
            arrGames = [
            0x06012c8cf97BEaD5deAe237070F9587f8E7A266d,
            0x1276dce965ADA590E42d62B3953dDc1DDCeB0392,
            0xE60D2325f996e197EEdDed8964227a0c6CA82D0f,
            0xECd6b4A2f82b0c9FB283A4a8a1ef5ADf555f794b,
            0xf26A23019b4699068bb54457f32dAFCF22A9D371,
            0x8c9b261Faef3b3C2e64ab5E58e04615F8c788099,
            0x6EbeAf8e8E946F0716E6533A6f2cefc83f60e8Ab,
            0x5D00d312e171Be5342067c09BaE883f9Bcb2003B,
            0xBfdE6246Df72d3ca86419628CaC46a9d2B60393C,
            0x543EcFB0d28fA40D639494957e7cBA52460F490E,
            0xF5b0A3eFB8e8E4c201e2A935F110eAaF3FFEcb8d,
            0xbc5370374FE08d699cf7fcd2e625A93BF393cCC4,
            0x31AF195dB332bc9203d758C74dF5A5C5e597cDb7,
            0x1a94fce7ef36Bc90959E206bA569a12AFBC91ca1,
            0x30a2fA3c93Fb9F93D1EFeFfd350c6A6BB62ba000,
            0x69A1d45318dE72d6Add20D4952398901E0E4a8e5,
            0x4F41d10F7E67fD16bDe916b4A6DC3Dd101C57394
            ];
            for(uint i = 0; i< arrGames.length; i++) {
                Games[arrGames[i]].Fee = 50;
                Games[arrGames[i]].PercenDiscountOnHBWallet = 25;
                Games[arrGames[i]].limitHBWALLETForDiscount = 200;
                Games[arrGames[i]].limitFee = 1 finney;
            }
    
            // Games[address(0xac9D8D6dB95828259069226456DDe98d8E296c5f)].Fee = 50;
            // Games[address(0xac9D8D6dB95828259069226456DDe98d8E296c5f)].PercenDiscountOnHBWallet = 25;
            // Games[address(0xac9D8D6dB95828259069226456DDe98d8E296c5f)].limitHBWALLETForDiscount = 200;
            // Games[address(0xac9D8D6dB95828259069226456DDe98d8E296c5f)].limitFee = 1 finney;
            // arrGames.push(address(0xac9D8D6dB95828259069226456DDe98d8E296c5f));
        }
    
        function getTokenPrice(address _game, uint256 _tokenId) public
        returns (address _tokenOwner, uint256 _Price, uint256 _fee, uint _isHightlight) {
            IERC721 erc721Address = IERC721(_game);
            if(erc721Address.ownerOf(_tokenId) != Games[_game].tokenPrice[_tokenId].tokenOwner
            && erc721Address.ownerOf(_tokenId) != address(this)) resetPrice(_game, _tokenId);
            return (Games[_game].tokenPrice[_tokenId].tokenOwner,
            Games[_game].tokenPrice[_tokenId].Price,
            Games[_game].tokenPrice[_tokenId].fee,
            Games[_game].tokenPrice[_tokenId].isHightlight);
        }
        function getArrGames() public view returns(address[] memory){
            return arrGames;
        }
        /**
         * @dev Throws if called by any account other than the ceo address.
         */
        modifier onlyCeoAddress() {
            require(msg.sender == ceoAddress);
            _;
        }
        modifier isOwnerOf(address _game, uint256 _tokenId) {
            IERC721 erc721Address = IERC721(_game);
            require(erc721Address.ownerOf(_tokenId) == msg.sender);
            _;
        }
        event _setPrice(address _game, uint256 _tokenId, uint256 _Price, uint _isHightLight, uint8 _type);
        event _resetPrice(address _game, uint256 _tokenId);
        function ownerOf(address _game, uint256 _tokenId) public view returns (address){
            IERC721 erc721Address = IERC721(_game);
            return erc721Address.ownerOf(_tokenId);
        }
    
        function balanceOf() public view returns (uint256){
            return address(this).balance;
        }
    
        function getApproved(address _game, uint256 _tokenId) public view returns (address){
            IERC721 erc721Address = IERC721(_game);
            return erc721Address.getApproved(_tokenId);
        }
    
        function setPrice(address _game, uint256 _tokenId, uint256 _price, uint256 _fee, uint _isHightLight) internal {
            Games[_game].tokenPrice[_tokenId] = Price(msg.sender, _price, _fee, _isHightLight);
            Games[_game].tokenIdSale.push(_tokenId);
            bool flag = false;
            for(uint i = 0; i< arrGames.length; i++) {
                if(arrGames[i] == _game) flag = true;
            }
            if(!flag) arrGames.push(_game);
        }
    
        function calFee(address _game, uint256 _price) public view returns (uint256){
            uint256 senderHBBalance = hbwalletToken.balanceOf(msg.sender);
            uint256 fee =_price.mul(Games[_game].Fee).div(Percen);
            if(senderHBBalance >= Games[_game].limitHBWALLETForDiscount) fee = _price.mul(Games[_game].PercenDiscountOnHBWallet).div(Percen);
            return fee;
        }
        function calFeeHightLight(address _game, uint256 _tokenId, uint _isHightLight) public view returns (uint256){
            uint256 _hightLightFee = 0;
            if (_isHightLight == 1 && (Games[_game].tokenPrice[_tokenId].Price == 0 || Games[_game].tokenPrice[_tokenId].isHightlight != 1)) {
                _hightLightFee = hightLightFee;
            }
            return _hightLightFee;
        }
        function calPrice(address _game, uint256 _tokenId, uint256 _Price, uint _isHightLight) public view
        returns(uint256 _Need) {
            uint256 fee;
            uint256 _hightLightFee = calFeeHightLight(_game, _tokenId, _isHightLight);
            uint256 Need;
            uint256 totalFee;
            if (Games[_game].tokenPrice[_tokenId].Price < _Price) {
                fee = calFee(_game, _Price.sub(Games[_game].tokenPrice[_tokenId].Price));
                totalFee = calFee(_game, _Price);
                if(Games[_game].tokenPrice[_tokenId].Price == 0 && fee < Games[_game].limitFee) {
                    Need = Games[_game].limitFee.add(_hightLightFee);
                } else if(Games[_game].tokenPrice[_tokenId].Price > 0 && totalFee < Games[_game].limitFee) {
                    Need = _hightLightFee;
                } else {
                    if(totalFee.add(_hightLightFee) < Games[_game].tokenPrice[_tokenId].fee) Need = 0;
                    else Need = totalFee.add(_hightLightFee).sub(Games[_game].tokenPrice[_tokenId].fee);
                }
    
            } else {
                Need = _hightLightFee;
            }
            return Need;
        }
        function setPriceFee(address _game, uint256 _tokenId, uint256 _Price, uint _isHightLight) public payable isOwnerOf(_game, _tokenId) {
            require(Games[_game].tokenPrice[_tokenId].Price != _Price);
            uint256 Need = calPrice(_game, _tokenId, _Price, _isHightLight);
    
            require(msg.value >= Need);
            uint256 _hightLightFee = calFeeHightLight(_game, _tokenId, _isHightLight);
            uint256 fee;
            if (Games[_game].tokenPrice[_tokenId].Price < _Price) {
                fee = calFee(_game, _Price.sub(Games[_game].tokenPrice[_tokenId].Price));
                uint256 totalFee = calFee(_game, _Price);
    
                if(Games[_game].tokenPrice[_tokenId].Price == 0 && fee < Games[_game].limitFee) {
    
                    fee = Games[_game].limitFee;
                } else if(Games[_game].tokenPrice[_tokenId].Price > 0 && totalFee < Games[_game].limitFee) {
    
                    fee = 0;
                } else {
                    if(totalFee.add(_hightLightFee) < Games[_game].tokenPrice[_tokenId].fee) fee = 0;
                    else fee = totalFee.sub(Games[_game].tokenPrice[_tokenId].fee);
                }
                fee = fee.add(Games[_game].tokenPrice[_tokenId].fee);
            } else {
    
                fee = Games[_game].tokenPrice[_tokenId].fee;
            }
    
            setPrice(_game, _tokenId, _Price, fee, _isHightLight);
            emit _setPrice(_game, _tokenId, _Price, _isHightLight, 1);
        }
    
        function removePrice(address _game, uint256 _tokenId) public isOwnerOf(_game, _tokenId){
            msg.sender.transfer(Games[_game].tokenPrice[_tokenId].fee);
            if(Games[_game].tokenPrice[_tokenId].tokenOwner == address(this)) {
                IERC721 erc721Address = IERC721(_game);
                erc721Address.transfer(Games[_game].tokenPrice[_tokenId].tokenOwner, _tokenId);
            }
            resetPrice(_game, _tokenId);
        }
    
        function setLimitFee(address _game, uint256 _Fee, uint256 _limitFee, uint256 _hightLightFee,
            uint256 _PercenDiscountOnHBWallet, uint256  _limitHBWALLETForDiscount) public onlyOwner {
            require(_Fee >= 0 && _limitFee >= 0 && _hightLightFee >= 0);
            Games[_game].Fee = _Fee;
            Games[_game].limitFee = _limitFee;
            Games[_game].PercenDiscountOnHBWallet = _PercenDiscountOnHBWallet;
            Games[_game].limitHBWALLETForDiscount = _limitHBWALLETForDiscount;
            hightLightFee = _hightLightFee;
        }
        function setLimitFeeAll(address[] memory _game, uint256[] memory _Fee, uint256[] memory _limitFee, uint256 _hightLightFee,
            uint256[] memory _PercenDiscountOnHBWallet, uint256[]  memory _limitHBWALLETForDiscount) public onlyOwner {
            require(_game.length == _Fee.length);
            for(uint i = 0; i < _game.length; i++){
                require(_Fee[i] >= 0 && _limitFee[i] >= 0);
                Games[_game[i]].Fee = _Fee[i];
                Games[_game[i]].limitFee = _limitFee[i];
                Games[_game[i]].PercenDiscountOnHBWallet = _PercenDiscountOnHBWallet[i];
                Games[_game[i]].limitHBWALLETForDiscount = _limitHBWALLETForDiscount[i];
            }
    
            hightLightFee = _hightLightFee;
        }
        function _withdraw(uint256 amount) internal {
            require(address(this).balance >= amount);
            if(amount > 0) {
                msg.sender.transfer(amount);
            }
        }
        function withdraw(uint256 amount) public onlyCeoAddress {
            _withdraw(amount);
        }
        function cancelBussinessByGameId(address _game, uint256 _tokenId) private {
            IERC721 erc721Address = IERC721(_game);
            if (Games[_game].tokenPrice[_tokenId].tokenOwner == erc721Address.ownerOf(_tokenId)
            || Games[_game].tokenPrice[_tokenId].tokenOwner == address(this)) {
    
                uint256 amount = Games[_game].tokenPrice[_tokenId].fee;
                if(Games[_game].tokenPrice[_tokenId].isHightlight == 1) amount = amount.add(hightLightFee);
                if( amount > 0 && address(this).balance >= amount) {
                    Games[_game].tokenPrice[_tokenId].tokenOwner.transfer(amount);
                }
                if(Games[_game].tokenPrice[_tokenId].tokenOwner == address(this)) erc721Address.transfer(Games[_game].tokenPrice[_tokenId].tokenOwner, _tokenId);
                resetPrice(_game, _tokenId);
            }
        }
    
        function cancelBussinessByGame(address _game) private {
            uint256[] memory _arrTokenId = Games[_game].tokenIdSale;
            for (uint i = 0; i < _arrTokenId.length; i++) {
                cancelBussinessByGameId(_game, _arrTokenId[i]);
            }
    
        }
        function cancelBussiness() public onlyCeoAddress {
            for(uint j = 0; j< arrGames.length; j++) {
                address _game = arrGames[j];
                cancelBussinessByGame(_game);
            }
            _withdraw(address(this).balance);
        }
    
        function revenue() public view returns (uint256){
            uint256 fee;
            for(uint j = 0; j< arrGames.length; j++) {
                address _game = arrGames[j];
                IERC721 erc721Address = IERC721(arrGames[j]);
                for (uint i = 0; i < Games[_game].tokenIdSale.length; i++) {
                    uint256 _tokenId = Games[_game].tokenIdSale[i];
                    if (Games[_game].tokenPrice[_tokenId].tokenOwner == erc721Address.ownerOf(_tokenId)) {
    
                        fee = fee.add(Games[_game].tokenPrice[_tokenId].fee);
                        if(Games[_game].tokenPrice[_tokenId].isHightlight == 1) fee = fee.add(hightLightFee);
                    }
                }
            }
    
            uint256 amount = address(this).balance.sub(fee);
            return amount;
        }
    
        function changeCeo(address _address) public onlyCeoAddress {
            require(_address != address(0));
            ceoAddress = _address;
    
        }
    
        function buy(address _game, uint256 tokenId) public payable {
            IERC721 erc721Address = IERC721(_game);
            require(erc721Address.getApproved(tokenId) == address(this));
            require(Games[_game].tokenPrice[tokenId].Price > 0 && Games[_game].tokenPrice[tokenId].Price == msg.value);
            erc721Address.transferFrom(Games[_game].tokenPrice[tokenId].tokenOwner, msg.sender, tokenId);
            Games[_game].tokenPrice[tokenId].tokenOwner.transfer(msg.value);
            resetPrice(_game, tokenId);
        }
    
        function buyWithoutCheckApproved(address _game, uint256 tokenId) public payable {
            IERC721 erc721Address = IERC721(_game);
            require(Games[_game].tokenPrice[tokenId].Price > 0 && Games[_game].tokenPrice[tokenId].Price == msg.value);
            erc721Address.transferFrom(Games[_game].tokenPrice[tokenId].tokenOwner, msg.sender, tokenId);
            Games[_game].tokenPrice[tokenId].tokenOwner.transfer(msg.value);
            resetPrice(_game, tokenId);
        }
    
        function buyFromSmartcontractViaTransfer(address _game, uint256 _tokenId) public payable {
            IERC721 erc721Address = IERC721(_game);
            require(Games[_game].tokenPrice[_tokenId].Price == msg.value);
            require(erc721Address.ownerOf(_tokenId) == address(this));
            erc721Address.transfer(msg.sender, _tokenId);
            Games[_game].tokenPrice[_tokenId].tokenOwner.transfer(msg.value);
            resetPrice(_game, _tokenId);
        }
        // Move the last element to the deleted spot.
        // Delete the last element, then correct the length.
        function _burnArrayTokenIdSale(address _game, uint256 index)  internal {
            if (index >= Games[_game].tokenIdSale.length) return;
    
            for (uint i = index; i<Games[_game].tokenIdSale.length-1; i++){
                Games[_game].tokenIdSale[i] = Games[_game].tokenIdSale[i+1];
            }
            delete Games[_game].tokenIdSale[Games[_game].tokenIdSale.length-1];
            Games[_game].tokenIdSale.length--;
        }
    
        function resetPrice(address _game, uint256 _tokenId) private {
            Games[_game].tokenPrice[_tokenId] = Price(address(0), 0, 0, 0);
            for (uint8 i = 0; i < Games[_game].tokenIdSale.length; i++) {
                if (Games[_game].tokenIdSale[i] == _tokenId) {
                    _burnArrayTokenIdSale(_game, i);
                }
            }
            emit _resetPrice(_game, _tokenId);
        }
    }