账户
0x55...3de4
0x55...3de4

0x55...3de4

$500
此合同的源代码已经过验证!
合同元数据
编译器
0.4.25-nightly.2018.6.3+commit.ef8fb63b
语言
Solidity
合同源代码
文件 1 的 1:ReferContract.sol
pragma solidity ^0.4.18;

contract Ownable {
    address public owner;
    address public newOwner;
    
    event OwnershipTransferred(address indexed previousOwner, address indexed newOwner);
  
    constructor() public {
        owner = msg.sender;
    }
    
    modifier onlyOwner() {
        require(msg.sender == owner);
        _;
    }
    
    function transferOwnership(address _newOwner) public onlyOwner {
        newOwner = _newOwner;
    }
    
    function acceptOwnership() public {
        require(msg.sender == newOwner);
        emit OwnershipTransferred(owner, newOwner);
        owner = newOwner;
        newOwner = address(0);
    }
}







contract ReferContractInterface {
    function decrement(address _who) public;
    function mint(address _to, uint _value) public;
    function getBalance(address _who) public view returns(uint);
}

contract ReferConstants {
    uint public constant FIRST_USER_CUT = 40;
    uint public constant SECOND_USER_CUT = 25;
    uint public constant THIRD_USER_CUT = 15;
    uint public constant FOURTH_USER_CUT = 10;
    uint public constant OWNER_CUT = 10;
    event Bought(address user, address directParent, address indirectParent, uint money, uint tokens, uint level);
    event LevelUpdated(address user, uint money, uint level);
    
    using SafeMath for uint;
}

contract ReferContract is ReferConstants, Ownable {
    ReferContractInterface referContractInterface;
    uint public baseRate;
    
    mapping (address => uint) public etherBalance;
    mapping (address => address) public userReferrer;
    mapping (address => uint8) public userLevel;
    mapping (address => uint) public tokensBought;
    
    constructor(address _tokenAddress) public {
        referContractInterface = ReferContractInterface(_tokenAddress);
        baseRate = 3000000000000000;
        // to be consistent with game
        userReferrer[owner] = owner;
        userLevel[owner] = 4;
    }
    
     // Update only if contract is not getting traction or got more
     // traction that initially thought.
     // increase the price if there is huge traffic to compensate more people
     // decrease the price if there is less traffic to attract more users.
    function updateRate(uint _newRate) onlyOwner public {
        require(baseRate != 0);
        // rate shouldn't be less than half or more than twice.
        require(_newRate.mul(2) > baseRate && baseRate.mul(2) > _newRate);
        baseRate = _newRate;
    }
    
    function getRate(uint level) public view returns (uint) {
        if (level == 4) {
            return baseRate.mul(6);
        } else if (level == 3) {
            return baseRate.mul(5);
        } else if (level == 2) {
            return baseRate.mul(3);
        } else if (level == 1) {
            return baseRate.mul(2);
        } else {
            return baseRate.mul(6);
        } 
    }
    
    function fundAccount(address ref, uint eth, uint level) internal {
        if (ref != address(0x0) && userLevel[ref] >= level) {
            etherBalance[ref] += eth;
        } else {
            etherBalance[owner] += eth;
        }
    }
    
    function distributeMoney(address ref, address parent1, uint money) internal {
        // since we are calculating percentage which will be 
        // (money * x)/100
        money = money.div(100);
        
        fundAccount(ref, money.mul(FIRST_USER_CUT), 1);
        fundAccount(parent1, money.mul(SECOND_USER_CUT), 2);
        fundAccount(userReferrer[parent1], money.mul(THIRD_USER_CUT), 3);
        fundAccount(userReferrer[userReferrer[parent1]], money.mul(FOURTH_USER_CUT), 4);
        fundAccount(owner, money.mul(OWNER_CUT), 0);
    }
    
    function buyReferTokens(address ref, uint8 level) payable public {
        require(level > 0 && level < 5);
        
        if (userLevel[msg.sender] == 0) { // new user
            userLevel[msg.sender] = level;
            if (getTokenBalance(ref) < 1) {  // The referee doesn't have a token 
                ref = owner; // change referee
            }
            userReferrer[msg.sender] = ref; // permanently set owner as the referrer
            referContractInterface.decrement(userReferrer[msg.sender]);
        } else { // old user
            require(userLevel[msg.sender] == level);
            if (getTokenBalance(userReferrer[msg.sender]) < 1) { // The referee doesn't have a token
                ref = owner; // only change the parent but don't change gradparents
            } else {
                ref = userReferrer[msg.sender];
            }
            referContractInterface.decrement(ref);
        }
        
        uint tokens = msg.value.div(getRate(level));
        require(tokens >= 5);
        referContractInterface.mint(msg.sender, tokens);
        distributeMoney(ref, userReferrer[userReferrer[msg.sender]] , msg.value);
        tokensBought[msg.sender] += tokens;
        emit Bought(msg.sender, ref, userReferrer[userReferrer[msg.sender]], msg.value, tokens, level);
    }
    
    function upgradeLevel(uint8 level) payable public {
        require(level <= 4);
        require(userLevel[msg.sender] != 0 && userLevel[msg.sender] < level);
        uint rateDiff = getRate(level).sub(getRate(userLevel[msg.sender]));
        uint toBePaid = rateDiff.mul(tokensBought[msg.sender]);
        require(msg.value >= toBePaid);
        userLevel[msg.sender] = level;
        distributeMoney(userReferrer[msg.sender], userReferrer[userReferrer[msg.sender]] , msg.value);
        emit LevelUpdated(msg.sender, msg.value, level);
    }
    
    function getAmountToUpdate(uint8 level) view public returns (uint) {
        uint rate = getRate(level).mul(tokensBought[msg.sender]);
        uint ratePaid = getRate(userLevel[msg.sender]).mul(tokensBought[msg.sender]);
        return rate.sub(ratePaid);
    }
    
    function withdraw() public {
        uint amount = etherBalance[msg.sender];
        etherBalance[msg.sender] = 0;
        msg.sender.transfer(amount);
    }
    
    function getTokenBalance(address _who) public view returns(uint) {
        return referContractInterface.getBalance(_who);
    }
}

library SafeMath {
    function mul(uint256 a, uint256 b) internal pure returns (uint256 c) {
        if (a == 0) {
            return 0;
        }
        
        c = a * b;
        assert(c / a == b);
        return c;
    }
    
    function div(uint256 a, uint256 b) internal pure returns (uint256) {
        return a / b;
    }
    
    function sub(uint256 a, uint256 b) internal pure returns (uint256) {
        assert(b <= a);
        return a - b;
    }
    
    function add(uint256 a, uint256 b) internal pure returns (uint256 c) {
        c = a + b;
        assert(c >= a);
        return c;
    }
}
设置
{
  "compilationTarget": {
    "ReferContract.sol": "ReferContract"
  },
  "evmVersion": "byzantium",
  "libraries": {},
  "optimizer": {
    "enabled": true,
    "runs": 200
  },
  "remappings": []
}
ABI
[{"constant":true,"inputs":[],"name":"baseRate","outputs":[{"name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"name":"","type":"address"}],"name":"tokensBought","outputs":[{"name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"name":"","type":"address"}],"name":"userLevel","outputs":[{"name":"","type":"uint8"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"name":"_who","type":"address"}],"name":"getTokenBalance","outputs":[{"name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[],"name":"withdraw","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"name":"ref","type":"address"},{"name":"level","type":"uint8"}],"name":"buyReferTokens","outputs":[],"payable":true,"stateMutability":"payable","type":"function"},{"constant":true,"inputs":[],"name":"SECOND_USER_CUT","outputs":[{"name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"name":"level","type":"uint256"}],"name":"getRate","outputs":[{"name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"name":"_newRate","type":"uint256"}],"name":"updateRate","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[],"name":"acceptOwnership","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[{"name":"","type":"address"}],"name":"userReferrer","outputs":[{"name":"","type":"address"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"owner","outputs":[{"name":"","type":"address"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"name":"level","type":"uint8"}],"name":"upgradeLevel","outputs":[],"payable":true,"stateMutability":"payable","type":"function"},{"constant":true,"inputs":[],"name":"OWNER_CUT","outputs":[{"name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"FOURTH_USER_CUT","outputs":[{"name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"THIRD_USER_CUT","outputs":[{"name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"name":"","type":"address"}],"name":"etherBalance","outputs":[{"name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"newOwner","outputs":[{"name":"","type":"address"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"FIRST_USER_CUT","outputs":[{"name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"name":"level","type":"uint8"}],"name":"getAmountToUpdate","outputs":[{"name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"name":"_newOwner","type":"address"}],"name":"transferOwnership","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"inputs":[{"name":"_tokenAddress","type":"address"}],"payable":false,"stateMutability":"nonpayable","type":"constructor"},{"anonymous":false,"inputs":[{"indexed":true,"name":"previousOwner","type":"address"},{"indexed":true,"name":"newOwner","type":"address"}],"name":"OwnershipTransferred","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"name":"user","type":"address"},{"indexed":false,"name":"directParent","type":"address"},{"indexed":false,"name":"indirectParent","type":"address"},{"indexed":false,"name":"money","type":"uint256"},{"indexed":false,"name":"tokens","type":"uint256"},{"indexed":false,"name":"level","type":"uint256"}],"name":"Bought","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"name":"user","type":"address"},{"indexed":false,"name":"money","type":"uint256"},{"indexed":false,"name":"level","type":"uint256"}],"name":"LevelUpdated","type":"event"}]