ETH Price: $1,995.39 (+0.25%)

Transaction Decoder

Block:
9007792 at Nov-27-2019 03:49:15 AM +UTC
Transaction Fee:
0.000104946 ETH $0.21
Gas Used:
52,473 Gas / 2 Gwei

Account State Difference:

  Address   Before After State Difference Code
0x38Fc01C6...012124E0A
0.251879866015358756 Eth
Nonce: 17
0.251774920015358756 Eth
Nonce: 18
0.000104946
(Spark Pool)
49.860891142246550752 Eth49.860996088246550752 Eth0.000104946

Execution Trace

League.CALL( )
  • ETH 0.003 0x38fc01c6059b08b5119d62c9182b674012124e0a.CALL( )
    {"AdminBase.sol":{"content":"pragma solidity ^0.5.0;\n\ncontract AdminBase {\n  address public owner;\n  mapping (address =\u003e bool) admins;\n\n  /**\n   * @dev Initializes the contract setting the deployer as the initial owner.\n   */\n  constructor () public {\n    owner = msg.sender;\n    admins[msg.sender] = true;\n  }\n\n  /**\n   * @dev Throws if called by any account other than the owner.\n   */\n  modifier onlyowner() {\n    require(isowner(), \"AdminBase: caller is not the owner\");\n    _;\n  }\n\n  modifier onlyAdmin() {\n    require(admins[msg.sender], \"AdminBase: caller is not the Admin\");\n    _;\n  }\n\n  function addAdmin(address account) public onlyowner {\n    admins[account] = true;\n  }\n\n  function removeAdmin(address account) public onlyowner {\n    admins[account] = false;\n  }\n\n  /**\n   * @dev Returns true if the caller is the current owner.\n   */\n  function isowner() public view returns (bool) {\n    return msg.sender == owner;\n  }\n\n  function isAdmin() public view returns (bool) {\n    return admins[msg.sender];\n  }\n\n  /**\n   * @dev Transfers ownership of the contract to a new account (`newOwner`).\n   * Can only be called by the current owner.\n   */\n  function transferowner(address newowner)\n  public onlyowner {\n    owner = newowner;\n  }\n}"},"League.sol":{"content":"pragma solidity ^0.5.0;\n\nimport \"./SafeMath.sol\";\nimport \"./LeagueBase.sol\";\nimport \"./AdminBase.sol\";\n\ncontract League is LeagueBase,AdminBase {\n    using SafeMath for uint;\n    uint public _dailyInvest = 0;\n    uint public _staticPool = 0;\n    uint public _outInvest = 0;\n    uint public _safePool = 0;\n    uint public _gloryPool = 0;\n    mapping(address =\u003e Player) allPlayers;\n    address[] public allAddress = new address[](0);\n    uint[] public lockedRound = new uint[](0);\n    address[] dailyPlayers = new address[](0);\n    uint _rand = 88;\n    uint _startTime = 0;\n    bool _actived = true;\n\n    function () external payable {\n        if(msg.value \u003e 0){\n            invest(address(0));\n        }else{\n            withdraw();\n        }\n    }\n\n    function invest(address payable parentAddr) public payable isHuman() {\n        require(msg.value \u003e= 0.5 ether, \"Parameter Error\");\n        require(isStart(), \"Game Start Limit\");\n        require(_actived, \"Game Active Limit\");\n        bool isFirst = false;\n        if(allPlayers[msg.sender].index == 0){\n            isFirst = true;\n            if(msg.sender == parentAddr) parentAddr = address(0);\n            Player memory parent = allPlayers[parentAddr];\n            if(parent.index == 0) {\n                parentAddr = address(0);\n            }\n            allPlayers[msg.sender] = Player({\n                self : msg.sender,\n                parent : parentAddr,\n                bonus: 0,\n                totalBonus : 0,\n                invest : msg.value,\n                sons : 0,\n                round: lockedRound.length,\n                index: allAddress.length\n            });\n            allAddress.push(msg.sender);\n        }else{\n            Player storage user = allPlayers[msg.sender];\n            uint totalBonus = 0;\n            uint bonus = 0;\n            bool outFlag;\n            (totalBonus, bonus, outFlag) = calcBonus(user.self);\n            require(outFlag, \"Out Only\");\n            user.bonus = bonus;\n            user.totalBonus = 0;\n            user.invest = msg.value;\n            user.round = lockedRound.length;\n        }\n        _dailyInvest = _dailyInvest.add(msg.value);\n        _safePool = _safePool.add(msg.value.div(20));\n        _gloryPool = _gloryPool.add(msg.value.mul(3).div(25));\n        _staticPool = _staticPool.add(msg.value.mul(11).div(20));\n        dailyPlayers.push(msg.sender);\n        Player memory self = allPlayers[msg.sender];\n        Player memory parent = allPlayers[self.parent];\n        uint parentVal = msg.value.div(10);\n        if(isFirst == true) {\n            investBonus(parent.self, parentVal, true, 1);\n        } else {\n            investBonus(parent.self, parentVal, true, 0);\n        }\n        Player memory grand = allPlayers[parent.parent];\n        if(grand.sons \u003e= 2){\n            uint grandVal = msg.value.div(20);\n            investBonus(grand.self, grandVal, true, 0);\n        }\n        emit logUserInvest(msg.sender, parentAddr, isFirst, msg.value, now);\n    }\n\n    function calcBonus(address target) public view returns(uint, uint, bool) {\n        Player memory player = allPlayers[target];\n        if(player.invest == 0) {\n            return (player.totalBonus, player.bonus, true);\n        }\n        uint lockedBonus = calcLocked(target);\n        uint totalBonus = player.totalBonus.add(lockedBonus);\n        bool outFlag = false;\n        uint less = 0;\n        uint maxIncome = 0;\n        if(player.invest \u003c 11 ether){\n            maxIncome = player.invest.mul(3).div(2);\n        }else if(player.invest \u003e= 11 ether \u0026\u0026 player.invest \u003c 21 ether){\n            maxIncome = player.invest.mul(9).div(5);\n        }else if(player.invest \u003e= 21 ether){\n            maxIncome = player.invest.mul(2);\n        }\n        if (totalBonus \u003e= maxIncome) {\n            less = totalBonus.sub(maxIncome);\n            outFlag = true;\n        }\n        totalBonus = totalBonus.sub(less);\n        uint bonus = player.bonus.add(lockedBonus).sub(less);\n        return (totalBonus, bonus, outFlag);\n    }\n\n    function calcLocked(address target) public view returns(uint) {\n        Player memory self = allPlayers[target];\n        uint randTotal = 0;\n        for(uint i = self.round; i\u003clockedRound.length; i++){\n            randTotal = randTotal.add(lockedRound[i]);\n        }\n        uint lockedBonus = self.invest.mul(randTotal).div(1000);\n        return lockedBonus;\n    }\n\n    function saveRound() internal {\n        uint releaseLocked = _safePool.sub(_outInvest).div(5);\n        uint x = _staticPool.div(releaseLocked);\n        uint rand = 0;\n        if(x\u003c20) {\n            rand = 3;\n            if(_staticPool \u003c releaseLocked.mul(rand).div(10)) rand = 0;\n        } else if (x\u003e=20 \u0026\u0026 x\u003c30) rand = 5;\n        else if (x\u003e=30 \u0026\u0026 x\u003c40)  rand = 10;\n        else if (x\u003e=40) rand = 20;\n        _staticPool = _staticPool.sub(releaseLocked.mul(rand).div(10));\n        lockedRound.push(rand);\n        emit logRandom(rand, now);\n    }\n\n\n    function sendGloryAward(address[] memory plays, uint[] memory selfAmount, uint totalAmount)\n    public onlyAdmin() {\n        _gloryPool = _gloryPool.sub(totalAmount);\n        for(uint i = 0; i \u003c plays.length; i++){\n            investBonus(plays[i], selfAmount[i], false, 0);\n            emit logGlory(plays[i], selfAmount[i], now);\n        }\n    }\n\n    function lottery() internal {\n        uint luckNum = dailyPlayers.length;\n        if (luckNum \u003e= 30) {\n            luckNum = 30;\n        }\n        address[] memory luckyDogs = new address[](luckNum);\n        uint[] memory luckyAmounts = new uint[](luckNum);\n        if (luckNum \u003c= 30) {\n            for(uint i = 0; i\u003cluckNum; i++) {\n                luckyDogs[i] = dailyPlayers[i];\n            }\n        } else {\n            for(uint i = 0; i\u003cluckNum; i++){\n                uint random = getRandom(dailyPlayers.length);\n                luckyDogs[i] = dailyPlayers[random];\n                delete dailyPlayers[random];\n            }\n        }\n        uint totalRandom = 0;\n        for(uint i = 0; i\u003cluckNum; i++){\n            luckyAmounts[i] = getRandom(50).add(1);\n            totalRandom = totalRandom.add(luckyAmounts[i]);\n        }\n        uint lotteryAmount = 0;\n        uint luckyPool = _dailyInvest.mul(3).div(100);\n        for(uint i = 0; i\u003cluckNum; i++){\n            lotteryAmount = luckyAmounts[i].mul(luckyPool).div(totalRandom);\n            investBonus(luckyDogs[i], lotteryAmount, false ,0);\n            emit logLucky(luckyDogs[i], lotteryAmount, now, 1);\n        }\n    }\n\n    function leagueGame() public onlyAdmin() {\n        saveRound();\n        msg.sender.transfer(_dailyInvest.div(10));\n        lottery();\n        _dailyInvest = 0;\n        delete dailyPlayers;\n    }\n\n    function withdraw() public isHuman() {\n        require(isStart(), \"Game Start Limit\");\n        Player storage user = allPlayers[msg.sender];\n        uint totalBonus = 0;\n        uint withdrawBonus = 0;\n        bool outFlag;\n        (totalBonus, withdrawBonus, outFlag) = calcBonus(user.self);\n        if(outFlag) {\n            _outInvest = _outInvest.add(user.invest);\n            user.totalBonus = 0;\n            user.invest = 0;\n        }else {\n            user.totalBonus = totalBonus;\n        }\n        require(withdrawBonus\u003e0, \"Above 0 Limit\");\n        user.round = lockedRound.length;\n        user.bonus = 0;\n        msg.sender.transfer(withdrawBonus);\n        emit logWithDraw(msg.sender, withdrawBonus, now);\n    }\n\n    function investBonus(address targetAddr, uint bonus, bool totalFlag, uint addson)\n    internal {\n        if(targetAddr == address(0) || allPlayers[targetAddr].invest == 0 || bonus == 0) return;\n        Player storage target = allPlayers[targetAddr];\n        target.bonus = target.bonus.add(bonus);\n        if(addson != 0) target.sons = target.sons+1;\n        if(totalFlag) target.totalBonus = target.totalBonus.add(bonus);\n    }\n\n    function getRandom(uint max)\n    internal returns(uint) {\n        _rand++;\n        uint rand = _rand**2;\n        uint random = uint(keccak256(abi.encodePacked(block.difficulty, now, msg.sender, rand)));\n        return random % max;\n    }\n\n    function start(uint time) external onlyAdmin() {\n        require(time \u003e now, \"Invalid Time\");\n        _startTime = time;\n    }\n\n    function setActive(bool flag) public onlyAdmin() {\n        _actived = flag;\n    }\n\n    function startArgs(uint staticPool, uint safePool, uint outInvest, uint dailyInvest, uint[] memory locks) public onlyAdmin() {\n        _staticPool = staticPool;\n        _safePool = safePool;\n        _outInvest = outInvest;\n        _dailyInvest = dailyInvest;\n        for(uint i = 0; i\u003clocks.length; i++) {\n            lockedRound.push(locks[i]);\n        }\n    }\n\n    function startGame(\n        address[] memory plays, address[] memory parents,\n        uint[] memory bonus, uint[] memory totalBonus,\n        uint[] memory totalInvests, uint[] memory sons, uint[] memory round)\n    public onlyAdmin() {\n        for(uint i = 0; i\u003cplays.length; i++) {\n            Player storage user = allPlayers[plays[i]];\n            user.self = plays[i];\n            user.parent = parents[i];\n            user.bonus = bonus[i];\n            user.totalBonus = totalBonus[i];\n            user.invest = totalInvests[i];\n            user.sons = sons[i];\n            user.round = round[i];\n            user.index = allAddress.length;\n            allAddress.push(plays[i]);\n        }\n    }\n\n    function isStart() public view returns(bool) {\n        return _startTime != 0 \u0026\u0026 now \u003e _startTime;\n    }\n\n    function userInfo(address payable target)\n    public view returns (address, address, address, uint, uint, uint, uint, uint){\n        Player memory self = allPlayers[target];\n        Player memory parent = allPlayers[self.parent];\n        Player memory grand = allPlayers[parent.parent];\n        Player memory great = allPlayers[grand.parent];\n        return (parent.self, grand.self, great.self,\n        self.bonus, self.totalBonus, self.invest, self.sons, self.round);\n    }\n\n    modifier isHuman() {\n        require(tx.origin == msg.sender, \"Human Only\");\n        _;\n    }\n\n}"},"LeagueBase.sol":{"content":"pragma solidity ^0.5.0;\n\ncontract LeagueBase {\n    struct Player {\n        address self;\n        address parent;\n        uint bonus;\n        uint totalBonus;\n        uint invest;\n        uint sons;\n        uint round;\n        uint index;\n    }\n\n    event logRandom(uint random, uint timestamp);\n\n    event logLucky(address indexed target, uint money, uint timestamp, uint types);\n\n    event logUserInvest(address indexed playerAddress, address indexed parentAddress, bool firstFlag, uint money, uint timestamp);\n\n    event logWithDraw(address indexed playerAddress, uint money, uint timestamp);\n\n    event logGlory(address indexed playerAddress, uint money, uint timestamp);\n\n    event logFomo(address indexed target, uint money);\n}"},"SafeMath.sol":{"content":"pragma solidity ^0.5.0;\n\n/**\n * @dev Wrappers over Solidity\u0027s arithmetic operations with added overflow\n * checks.\n *\n * Arithmetic operations in Solidity wrap on overflow. This can easily result\n * in bugs, because programmers usually assume that an overflow raises an\n * error, which is the standard behavior in high level programming languages.\n * `SafeMath` restores this intuition by reverting the transaction when an\n * operation overflows.\n *\n * Using this library instead of the unchecked operations eliminates an entire\n * class of bugs, so it\u0027s recommended to use it always.\n */\nlibrary SafeMath {\n    /**\n     * @dev Returns the addition of two unsigned integers, reverting on\n     * overflow.\n     *\n     * Counterpart to Solidity\u0027s `+` operator.\n     *\n     * Requirements:\n     * - Addition cannot overflow.\n     */\n    function add(uint256 a, uint256 b) internal pure returns (uint256) {\n        uint256 c = a + b;\n        require(c \u003e= a, \"SafeMath: addition overflow\");\n\n        return c;\n    }\n\n    /**\n     * @dev Returns the subtraction of two unsigned integers, reverting on\n     * overflow (when the result is negative).\n     *\n     * Counterpart to Solidity\u0027s `-` operator.\n     *\n     * Requirements:\n     * - Subtraction cannot overflow.\n     */\n    function sub(uint256 a, uint256 b) internal pure returns (uint256) {\n        require(b \u003c= a, \"SafeMath: subtraction overflow\");\n        uint256 c = a - b;\n\n        return c;\n    }\n\n    /**\n     * @dev Returns the multiplication of two unsigned integers, reverting on\n     * overflow.\n     *\n     * Counterpart to Solidity\u0027s `*` operator.\n     *\n     * Requirements:\n     * - Multiplication cannot overflow.\n     */\n    function mul(uint256 a, uint256 b) internal pure returns (uint256) {\n        // Gas optimization: this is cheaper than requiring \u0027a\u0027 not being zero, but the\n        // benefit is lost if \u0027b\u0027 is also tested.\n        // See: https://github.com/OpenZeppelin/openzeppelin-contracts/pull/522\n        if (a == 0) {\n            return 0;\n        }\n\n        uint256 c = a * b;\n        require(c / a == b, \"SafeMath: multiplication overflow\");\n\n        return c;\n    }\n\n    /**\n     * @dev Returns the integer division of two unsigned integers. Reverts on\n     * division by zero. The result is rounded towards zero.\n     *\n     * Counterpart to Solidity\u0027s `/` operator. Note: this function uses a\n     * `revert` opcode (which leaves remaining gas untouched) while Solidity\n     * uses an invalid opcode to revert (consuming all remaining gas).\n     *\n     * Requirements:\n     * - The divisor cannot be zero.\n     */\n    function div(uint256 a, uint256 b) internal pure returns (uint256) {\n        // Solidity only automatically asserts when dividing by 0\n        require(b \u003e 0, \"SafeMath: division by zero\");\n        uint256 c = a / b;\n        // assert(a == b * c + a % b); // There is no case in which this doesn\u0027t hold\n\n        return c;\n    }\n}"}}