ETH Price: $2,239.27 (-1.25%)

Transaction Decoder

Block:
6406265 at Sep-27-2018 01:24:19 AM +UTC
Transaction Fee:
0.001277294 ETH $2.86
Gas Used:
67,226 Gas / 19 Gwei

Emitted Events:

37 TripleROI.Withdraw( investor=[Sender] 0x6c9b509113d491e9ecb1319f351df80695543d09, amount=44000000000000 )
38 TripleROI.Invest( investor=[Sender] 0x6c9b509113d491e9ecb1319f351df80695543d09, amount=30000000000000000 )

Account State Difference:

  Address   Before After State Difference Code
(DwarfPool)
676.749624272510028797 Eth676.750901566510028797 Eth0.001277294
0x305fCb82...5b76E603b 2.76999401 Eth2.77149401 Eth0.0015
0x6c9b5091...695543D09
0.043993499148174539 Eth
Nonce: 81
0.012760205148174539 Eth
Nonce: 82
0.031233294
0x6FCfddA0...d75086F6B 50.488054000000000074 Eth50.516510000000000074 Eth0.028456

Execution Trace

ETH 0.03 TripleROI.buy( _referredBy=0x41FE3738B503cBaFD01C1Fd8DD66b7fE6Ec11b01 )
  • ETH 0.000044 0x6c9b509113d491e9ecb1319f351df80695543d09.CALL( )
  • ETH 0.0015 0x305fcb82036deaa7fea967d45dfd7755b76e603b.CALL( )
    pragma solidity ^0.4.25;
    
    /**
    Triple ROI: https://12hourtrains.github.io/
    
    Earn 4% per 3 hours, triple your ROI every 3 hours you HODL!
    
    3 hours: 4%
    6 hours: 12%
    9 hours: 36%
    12 hours: 108%
    ...etc...
    
    */
    contract TripleROI {
    
        using SafeMath for uint256;
    
        mapping(address => uint256) investments;
        mapping(address => uint256) joined;
        mapping(address => uint256) referrer;
    
        uint256 public step = 1000;
        uint256 public minimum = 10 finney;
        uint256 public maximum = 5 ether;
        uint256 public stakingRequirement = 0.3 ether;
        address public ownerWallet;
        address public owner;
        bool public gameStarted;
    
        event Invest(address investor, uint256 amount);
        event Withdraw(address investor, uint256 amount);
        event Bounty(address hunter, uint256 amount);
        event OwnershipTransferred(address indexed previousOwner, address indexed newOwner);
    
        /**
         * @dev Сonstructor Sets the original roles of the contract
         */
    
        constructor() public {
            owner = msg.sender;
            ownerWallet = msg.sender;
        }
    
        /**
         * @dev Modifiers
         */
    
        modifier onlyOwner() {
            require(msg.sender == owner);
            _;
        }
    
        function startGame() public onlyOwner {
            gameStarted = true;
        }
    
        /**
         * @dev Allows current owner to transfer control of the contract to a newOwner.
         * @param newOwner The address to transfer ownership to.
         * @param newOwnerWallet The address to transfer ownership to.
         */
        function transferOwnership(address newOwner, address newOwnerWallet) public onlyOwner {
            require(newOwner != address(0));
            emit OwnershipTransferred(owner, newOwner);
            owner = newOwner;
            ownerWallet = newOwnerWallet;
        }
    
        /**
         * @dev Investments
         */
        function () public payable {
            buy(0x0);
        }
    
        function buy(address _referredBy) public payable {
            require(msg.value >= minimum);
            require(msg.value <= maximum);
            require(gameStarted);
    
            address _customerAddress = msg.sender;
    
            if(
               // is this a referred purchase?
               _referredBy != 0x0000000000000000000000000000000000000000 &&
    
               // no cheating!
               _referredBy != _customerAddress &&
    
               // does the referrer have at least X whole tokens?
               // i.e is the referrer a godly chad masternode
               investments[_referredBy] >= stakingRequirement
           ){
               // wealth redistribution
               referrer[_referredBy] = referrer[_referredBy].add(msg.value.mul(5).div(100));
           }
    
           if (investments[msg.sender] > 0){
               withdraw();
           }
           
           investments[msg.sender] = investments[msg.sender].add(msg.value);
           joined[msg.sender] = block.timestamp;
           ownerWallet.transfer(msg.value.mul(5).div(100));
           emit Invest(msg.sender, msg.value);
        }
    
        /**
        * @dev Evaluate current balance
        * @param _address Address of investor
        */
        function getBalance(address _address) view public returns (uint256) {
            uint256 minutesCount = now.sub(joined[_address]).div(1 minutes);
            
            // update roi multiplier
            // 4% flat during first 3 hours
            // 12% flat during 6 hours
            // 36% flat during 9 hours
            // 108% flat after 12 hours
            uint256 userROIMultiplier = 3**(minutesCount / 180);
            
            uint256 percent;
            uint256 balance;
            
            for(uint i=1; i<userROIMultiplier; i=i*3){
                // add each percent -
                // 4% flat during first 3 hours
                // 12% flat during 6 hours
                // 36% flat during 9 hours
                // 108% flat after 12 hours
                // etc - add all these up
                percent = investments[_address].mul(step).div(1000) * i;
                balance += percent.mul(60).div(1500);
            }
            
            // Finally, add the balance for the current multiplier
            percent = investments[_address].mul(step).div(1000) * userROIMultiplier;
            balance += percent.mul(minutesCount % 60).div(1500);
    
            return balance;
        }
    
        /**
        * @dev Withdraw dividends from contract
        */
        function withdraw() public returns (bool){
            require(joined[msg.sender] > 0);
            
            uint256 balance = getBalance(msg.sender);
            
            // Reset ROI mulitplier of user
            joined[msg.sender] = block.timestamp;
            
            if (address(this).balance > balance){
                if (balance > 0){
                    msg.sender.transfer(balance);
                    emit Withdraw(msg.sender, balance);
                }
                return true;
            } else {
                if (balance > 0) {
                    msg.sender.transfer(address(this).balance);
                    emit Withdraw(msg.sender, balance);
                }
                return true;
            }
        }
    
        /**
        * @dev Bounty reward
        */
        function bounty() public {
            uint256 refBalance = checkReferral(msg.sender);
            if(refBalance >= minimum) {
                 if (address(this).balance > refBalance) {
                    referrer[msg.sender] = 0;
                    msg.sender.transfer(refBalance);
                    emit Bounty(msg.sender, refBalance);
                 }
            }
        }
    
        /**
        * @dev Gets balance of the sender address.
        * @return An uint256 representing the amount owned by the msg.sender.
        */
        function checkBalance() public view returns (uint256) {
            return getBalance(msg.sender);
        }
    
    
        /**
        * @dev Gets investments of the specified address.
        * @param _investor The address to query the the balance of.
        * @return An uint256 representing the amount owned by the passed address.
        */
        function checkInvestments(address _investor) public view returns (uint256) {
            return investments[_investor];
        }
    
        /**
        * @dev Gets referrer balance of the specified address.
        * @param _hunter The address of the referrer
        * @return An uint256 representing the referral earnings.
        */
        function checkReferral(address _hunter) public view returns (uint256) {
            return referrer[_hunter];
        }
    }
    
    /**
     * @title SafeMath
     * @dev Math operations with safety checks that throw on error
     */
    library SafeMath {
        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) {
            // 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 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;
        }
    }