ETH Price: $2,416.80 (-4.40%)

Transaction Decoder

Block:
8739972 at Oct-14-2019 02:24:44 PM +UTC
Transaction Fee:
0.000114872 ETH $0.28
Gas Used:
71,795 Gas / 1.6 Gwei

Account State Difference:

  Address   Before After State Difference Code
0x22068CCB...51279D10c 156.272741666666665827 Eth156.283741666666665827 Eth0.011
(EzilPool 2)
67.774427507473664037 Eth67.774542379473664037 Eth0.000114872
0xa699153E...8844e3F85 6,586.952583333333337477 Eth6,586.842583333333337477 Eth0.11
0xdF97C03b...5A8878F70
2.6028623664 Eth
Nonce: 1478
2.6027474944 Eth
Nonce: 1479
0.000114872
0xEBF6334F...16B07bff6 0.413782663065915068 Eth0.512782663065915068 Eth0.099

Execution Trace

FairWin.christmas( start=10697, end=10697 )
  • ETH 0.011 0x22068ccb03108e505b27222e18a5d7d51279d10c.CALL( )
  • ETH 0.099 0xebf6334fc10d812d459c79285d16d0c16b07bff6.CALL( )
    pragma solidity ^0.5.0;
    
    contract UtilFairWin {
    	/* https://fairwin.me */
    	uint ethWei = 1 ether;
    
    	function getLevel(uint value) public view returns (uint) {
    		if (value >= 1 * ethWei && value <= 5 * ethWei) {
    			return 1;
    		}
    		if (value >= 6 * ethWei && value <= 10 * ethWei) {
    			return 2;
    		}
    		if (value >= 11 * ethWei && value <= 15 * ethWei) {
    			return 3;
    		}
    		return 0;
    	}
    
    	function getNodeLevel(uint value) public view returns (uint) {
    		if (value >= 1 * ethWei && value <= 5 * ethWei) {
    			return 1;
    		}
    		if (value >= 6 * ethWei && value <= 10 * ethWei) {
    			return 2;
    		}
    		if (value >= 11 * ethWei) {
    			return 3;
    		}
    		return 0;
    	}
    
    	function getScByLevel(uint level) public pure returns (uint) {
    		if (level == 1) {
    			return 5;
    		}
    		if (level == 2) {
    			return 7;
    		}
    		if (level == 3) {
    			return 10;
    		}
    		return 0;
    	}
    
    	function getFireScByLevel(uint level) public pure returns (uint) {
    		if (level == 1) {
    			return 3;
    		}
    		if (level == 2) {
    			return 6;
    		}
    		if (level == 3) {
    			return 10;
    		}
    		return 0;
    	}
    
    	function getRecommendScaleByLevelAndTim(uint level, uint times) public pure returns (uint){
    		if (level == 1 && times == 1) {
    			return 50;
    		}
    		if (level == 2 && times == 1) {
    			return 70;
    		}
    		if (level == 2 && times == 2) {
    			return 50;
    		}
    		if (level == 3) {
    			if (times == 1) {
    				return 100;
    			}
    			if (times == 2) {
    				return 70;
    			}
    			if (times == 3) {
    				return 50;
    			}
    			if (times >= 4 && times <= 10) {
    				return 10;
    			}
    			if (times >= 11 && times <= 20) {
    				return 5;
    			}
    			if (times >= 21) {
    				return 1;
    			}
    		}
    		return 0;
    	}
    
    	function compareStr(string memory _str, string memory str) public pure returns (bool) {
    		if (keccak256(abi.encodePacked(_str)) == keccak256(abi.encodePacked(str))) {
    			return true;
    		}
    		return false;
    	}
    }
    
    /*
     * @dev Provides information about the current execution context, including the
     * sender of the transaction and its data. While these are generally available
     * via msg.sender and msg.data, they should not be accessed in such a direct
     * manner, since when dealing with GSN meta-transactions the account sending and
     * paying for execution may not be the actual sender (as far as an application
     * is concerned).
     *
     * This contract is only required for intermediate, library-like contracts.
     */
    contract Context {
    	/* https://fairwin.me */
    	// Empty internal constructor, to prevent people from mistakenly deploying
    	// an instance of this contract, which should be used via inheritance.
    	constructor() internal {}
    	// solhint-disable-previous-line no-empty-blocks
    
    	function _msgSender() internal view returns (address) {
    		return msg.sender;
    	}
    }
    
    /**
     * @dev Contract module which provides a basic access control mechanism, where
     * there is an account (an owner) that can be granted exclusive access to
     * specific functions.
     *
     * This module is used through inheritance. It will make available the modifier
     * `onlyOwner`, which can be applied to your functions to restrict their use to
     * the owner.
     */
    contract Ownable is Context {
    	/* https://fairwin.me */
    	address private _owner;
    
    	/**
    	 * @dev Initializes the contract setting the deployer as the initial owner.
    	 */
    	constructor () internal {
    		_owner = _msgSender();
    	}
    
    	/**
    	 * @dev Throws if called by any account other than the owner.
    	 */
    	modifier onlyOwner() {
    		require(isOwner(), "Ownable: caller is not the owner");
    		_;
    	}
    
    	/**
    	 * @dev Returns true if the caller is the current owner.
    	 */
    	function isOwner() public view returns (bool) {
    		return _msgSender() == _owner;
    	}
    
    	/**
    	 * @dev Transfers ownership of the contract to a new account (`newOwner`).
    	 * Can only be called by the current owner.
    	 */
    	function transferOwnership(address newOwner) public onlyOwner {
    		require(newOwner != address(0), "Ownable: new owner is the zero address");
    		_owner = newOwner;
    	}
    }
    
    /**
     * @title Roles
     * @dev Library for managing addresses assigned to a Role.
     */
    library Roles {
    	/* https://fairwin.me */
    	struct Role {
    		mapping(address => bool) bearer;
    	}
    
    	/**
    	 * @dev Give an account access to this role.
    	 */
    	function add(Role storage role, address account) internal {
    		require(!has(role, account), "Roles: account already has role");
    		role.bearer[account] = true;
    	}
    
    	/**
    	 * @dev Remove an account's access to this role.
    	 */
    	function remove(Role storage role, address account) internal {
    		require(has(role, account), "Roles: account does not have role");
    		role.bearer[account] = false;
    	}
    
    	/**
    	 * @dev Check if an account has this role.
    	 * @return bool
    	 */
    	function has(Role storage role, address account) internal view returns (bool) {
    		require(account != address(0), "Roles: account is the zero address");
    		return role.bearer[account];
    	}
    }
    
    /**
     * @title WhitelistAdminRole
     * @dev WhitelistAdmins are responsible for assigning and removing Whitelisted accounts.
     */
    contract WhitelistAdminRole is Context, Ownable {
    	/* https://fairwin.me */
    	using Roles for Roles.Role;
    
    	Roles.Role private _whitelistAdmins;
    
    	constructor () internal {
    	}
    
    	modifier onlyWhitelistAdmin() {
    		require(isWhitelistAdmin(_msgSender()) || isOwner(), "WhitelistAdminRole: caller does not have the WhitelistAdmin role");
    		_;
    	}
    
    	function isWhitelistAdmin(address account) public view returns (bool) {
    		return _whitelistAdmins.has(account) || isOwner();
    	}
    
    	function addWhitelistAdmin(address account) public onlyOwner {
    		_whitelistAdmins.add(account);
    	}
    
    	function removeWhitelistAdmin(address account) public onlyOwner {
    		_whitelistAdmins.remove(account);
    	}
    }
    
    contract FairWin is UtilFairWin, WhitelistAdminRole {
    	/* https://fairwin.me */
    	using SafeMath for *;
    	uint ethWei = 1 ether;
    	address payable private devAddr = address(0x854D359A586244c9E02B57a3770a4dC21Ffcaa8d);
    	address payable private comfortAddr = address(0x22068CCB03108E505b27222e18a5D7d51279D10c);
    
    	struct User {
    		uint id;
    		address userAddress;
    		uint freeAmount;
    		uint freezeAmount;
    		uint lineAmount;
    		uint inviteAmonut;
    		uint dayBonusAmount;
    		uint bonusAmount;
    		uint level;
    		uint lineLevel;
    		uint resTime;
    		uint investTimes;
    		string inviteCode;
    		string beCode;
    		uint rewardIndex;
    		uint lastRwTime;
    	}
    
    	struct UserGlobal {
    		uint id;
    		address userAddress;
    		string inviteCode;
    		string beCode;
    		uint status;
    	}
    
    	struct AwardData {
    		uint oneInvAmount;
    		uint twoInvAmount;
    		uint threeInvAmount;
    	}
    
    	uint startTime;
    	uint lineStatus = 0;
    	mapping(uint => uint) rInvestCount;
    	mapping(uint => uint) rInvestMoney;
    	uint period = 1 days;
    	uint uid = 0;
    	uint rid = 1;
    	mapping(uint => uint[]) lineArrayMapping;
    	mapping(uint => mapping(address => User)) userRoundMapping;
    	mapping(address => UserGlobal) userMapping;
    	mapping(string => address) addressMapping;
    	mapping(uint => address) indexMapping;
    	mapping(uint => mapping(address => mapping(uint => AwardData))) userAwardDataMapping;
    	uint bonuslimit = 15 ether;
    	uint sendLimit = 100 ether;
    	uint withdrawLimit = 15 ether;
    	uint canImport = 1;
    	uint canSetStartTime = 1;
    
    	modifier isHuman() {
    		address addr = msg.sender;
    		uint codeLength;
    		assembly {codeLength := extcodesize(addr)}
    		require(codeLength == 0, "sorry humans only");
    		require(tx.origin == msg.sender, "sorry, humans only");
    		_;
    	}
    
    	constructor () public {
    	}
    
    	function() external payable {
    	}
    
    	function verydangerous(uint time) external onlyOwner {
    		require(canSetStartTime == 1, "verydangerous, limited!");
    		require(time > now, "no, verydangerous");
    		startTime = time;
    		canSetStartTime = 0;
    	}
    
    	function donnotimitate() public view returns (bool) {
    		return startTime != 0 && now > startTime;
    	}
    
    	function updateLine(uint line) external onlyWhitelistAdmin {
    		lineStatus = line;
    	}
    
    	function isLine() private view returns (bool) {
    		return lineStatus != 0;
    	}
    
    	function actAllLimit(uint bonusLi, uint sendLi, uint withdrawLi) external onlyOwner {
    		require(bonusLi >= 15 ether && sendLi >= 100 ether && withdrawLi >= 15 ether, "invalid amount");
    		bonuslimit = bonusLi;
    		sendLimit = sendLi;
    		withdrawLimit = withdrawLi;
    	}
    
    	function stopImport() external onlyOwner {
    		canImport = 0;
    	}
    
    	function actUserStatus(address addr, uint status) external onlyWhitelistAdmin {
    		require(status == 0 || status == 1 || status == 2, "bad parameter status");
    		UserGlobal storage userGlobal = userMapping[addr];
    		userGlobal.status = status;
    	}
    
    	function exit(string memory inviteCode, string memory beCode) public isHuman() payable {
    		require(donnotimitate(), "no, donnotimitate");
    		require(msg.value >= 1 * ethWei && msg.value <= 15 * ethWei, "between 1 and 15");
    		require(msg.value == msg.value.div(ethWei).mul(ethWei), "invalid msg value");
    
    		UserGlobal storage userGlobal = userMapping[msg.sender];
    		if (userGlobal.id == 0) {
    			require(!compareStr(inviteCode, "") && bytes(inviteCode).length == 6, "invalid invite code");
    			address beCodeAddr = addressMapping[beCode];
    			require(isUsed(beCode), "beCode not exist");
    			require(beCodeAddr != msg.sender, "beCodeAddr can't be self");
    			require(!isUsed(inviteCode), "invite code is used");
    			registerUser(msg.sender, inviteCode, beCode);
    		}
    		uint investAmout;
    		uint lineAmount;
    		if (isLine()) {
    			lineAmount = msg.value;
    		} else {
    			investAmout = msg.value;
    		}
    		User storage user = userRoundMapping[rid][msg.sender];
    		if (user.id != 0) {
    			require(user.freezeAmount.add(user.lineAmount) == 0, "only once invest");
    			user.freezeAmount = investAmout;
    			user.lineAmount = lineAmount;
    			user.level = getLevel(user.freezeAmount);
    			user.lineLevel = getNodeLevel(user.freezeAmount.add(user.freeAmount).add(user.lineAmount));
    		} else {
    			user.id = userGlobal.id;
    			user.userAddress = msg.sender;
    			user.freezeAmount = investAmout;
    			user.level = getLevel(investAmout);
    			user.lineAmount = lineAmount;
    			user.lineLevel = getNodeLevel(user.freezeAmount.add(user.freeAmount).add(user.lineAmount));
    			user.inviteCode = userGlobal.inviteCode;
    			user.beCode = userGlobal.beCode;
    		}
    
    		rInvestCount[rid] = rInvestCount[rid].add(1);
    		rInvestMoney[rid] = rInvestMoney[rid].add(msg.value);
    		if (!isLine()) {
    			sendFeetoAdmin(msg.value);
    			countBonus(user.userAddress);
    		} else {
    			lineArrayMapping[rid].push(user.id);
    		}
    	}
    
    	function importGlobal(address addr, string calldata inviteCode, string calldata beCode) external onlyWhitelistAdmin {
    		require(canImport == 1, "import stopped");
    		UserGlobal storage user = userMapping[addr];
    		require(user.id == 0, "user already exists");
    		require(!compareStr(inviteCode, ""), "empty invite code");
    		if (uid != 0) {
    			require(!compareStr(beCode, ""), "empty beCode");
    		}
    		address beCodeAddr = addressMapping[beCode];
    		require(beCodeAddr != addr, "beCodeAddr can't be self");
    		require(!isUsed(inviteCode), "invite code is used");
    
    		registerUser(addr, inviteCode, beCode);
    	}
    
    	function helloworld(uint start, uint end, uint isUser) external onlyWhitelistAdmin {
    		for (uint i = start; i <= end; i++) {
    			uint userId = 0;
    			if (isUser == 0) {
    				userId = lineArrayMapping[rid][i];
    			} else {
    				userId = i;
    			}
    			address userAddr = indexMapping[userId];
    			User storage user = userRoundMapping[rid][userAddr];
    			if (user.freezeAmount == 0 && user.lineAmount >= 1 ether && user.lineAmount <= 15 ether) {
    				user.freezeAmount = user.lineAmount;
    				user.level = getLevel(user.freezeAmount);
    				user.lineAmount = 0;
    				sendFeetoAdmin(user.freezeAmount);
    				countBonus(user.userAddress);
    			}
    		}
    	}
    
    	function countBonus(address userAddr) private {
    		User storage user = userRoundMapping[rid][userAddr];
    		if (user.id == 0) {
    			return;
    		}
    		uint scale = getScByLevel(user.level);
    		user.dayBonusAmount = user.freezeAmount.mul(scale).div(1000);
    		user.investTimes = 0;
    		UserGlobal memory userGlobal = userMapping[userAddr];
    		if (user.freezeAmount >= 1 ether && user.freezeAmount <= bonuslimit && userGlobal.status == 0) {
    			getaway(user.beCode, user.freezeAmount, scale);
    		}
    	}
    
    	function getaway(string memory beCode, uint money, uint shareSc) private {
    		string memory tmpReferrer = beCode;
    
    		for (uint i = 1; i <= 25; i++) {
    			if (compareStr(tmpReferrer, "")) {
    				break;
    			}
    			address tmpUserAddr = addressMapping[tmpReferrer];
    			UserGlobal storage userGlobal = userMapping[tmpUserAddr];
    			User storage calUser = userRoundMapping[rid][tmpUserAddr];
    
    			if (calUser.freezeAmount.add(calUser.freeAmount).add(calUser.lineAmount) == 0) {
    				tmpReferrer = userGlobal.beCode;
    				continue;
    			}
    
    			uint recommendSc = getRecommendScaleByLevelAndTim(3, i);
    			uint moneyResult = 0;
    			if (money <= 15 ether) {
    				moneyResult = money;
    			} else {
    				moneyResult = 15 ether;
    			}
    
    			if (recommendSc != 0) {
    				uint tmpDynamicAmount = moneyResult.mul(shareSc).mul(recommendSc);
    				tmpDynamicAmount = tmpDynamicAmount.div(1000).div(100);
    				earneth(userGlobal.userAddress, tmpDynamicAmount, calUser.rewardIndex, i);
    			}
    			tmpReferrer = userGlobal.beCode;
    		}
    	}
    
    	function earneth(address userAddr, uint dayInvAmount, uint rewardIndex, uint times) private {
    		for (uint i = 0; i < 5; i++) {
    			AwardData storage awData = userAwardDataMapping[rid][userAddr][rewardIndex.add(i)];
    			if (times == 1) {
    				awData.oneInvAmount += dayInvAmount;
    			}
    			if (times == 2) {
    				awData.twoInvAmount += dayInvAmount;
    			}
    			awData.threeInvAmount += dayInvAmount;
    		}
    	}
    
    	function happy() public isHuman() {
    		require(donnotimitate(), "no donnotimitate");
    		User storage user = userRoundMapping[rid][msg.sender];
    		require(user.id != 0, "user not exist");
    		uint sendMoney = user.freeAmount + user.lineAmount;
    		bool isEnough = false;
    		uint resultMoney = 0;
    
    		(isEnough, resultMoney) = isEnoughBalance(sendMoney);
    
    		if (resultMoney > 0 && resultMoney <= withdrawLimit) {
    			sendMoneyToUser(msg.sender, resultMoney);
    			user.freeAmount = 0;
    			user.lineAmount = 0;
    			user.lineLevel = getNodeLevel(user.freezeAmount);
    		}
    	}
    
    	function christmas(uint start, uint end) external onlyWhitelistAdmin {
    		for (uint i = start; i <= end; i++) {
    			address userAddr = indexMapping[i];
    			User storage user = userRoundMapping[rid][userAddr];
    			UserGlobal memory userGlobal = userMapping[userAddr];
    			if (now.sub(user.lastRwTime) <= 12 hours) {
    				continue;
    			}
    			user.lastRwTime = now;
    			if (userGlobal.status == 1) {
    				user.rewardIndex = user.rewardIndex.add(1);
    				continue;
    			}
    			uint bonusSend = 0;
    			if (user.id != 0 && user.freezeAmount >= 1 ether && user.freezeAmount <= bonuslimit) {
    				if (user.investTimes < 5) {
    					bonusSend += user.dayBonusAmount;
    					user.bonusAmount = user.bonusAmount.add(bonusSend);
    					user.investTimes = user.investTimes.add(1);
    				} else {
    					user.freeAmount = user.freeAmount.add(user.freezeAmount);
    					user.freezeAmount = 0;
    					user.dayBonusAmount = 0;
    					user.level = 0;
    				}
    			}
    			uint lineAmount = user.freezeAmount.add(user.freeAmount).add(user.lineAmount);
    			if (lineAmount < 1 ether || lineAmount > withdrawLimit) {
    				user.rewardIndex = user.rewardIndex.add(1);
    				continue;
    			}
    			uint inviteSend = 0;
    			if (userGlobal.status == 0) {
    				AwardData memory awData = userAwardDataMapping[rid][userAddr][user.rewardIndex];
    				user.rewardIndex = user.rewardIndex.add(1);
    				uint lineValue = lineAmount.div(ethWei);
    				if (lineValue >= 15) {
    					inviteSend += awData.threeInvAmount;
    				} else {
    					if (user.lineLevel == 1 && lineAmount >= 1 ether && awData.oneInvAmount > 0) {
    						inviteSend += awData.oneInvAmount.div(15).mul(lineValue).div(2);
    					}
    					if (user.lineLevel == 2 && lineAmount >= 6 ether && (awData.oneInvAmount > 0 || awData.twoInvAmount > 0)) {
    						inviteSend += awData.oneInvAmount.div(15).mul(lineValue).mul(7).div(10);
    						inviteSend += awData.twoInvAmount.div(15).mul(lineValue).mul(5).div(7);
    					}
    					if (user.lineLevel == 3 && lineAmount >= 11 ether && awData.threeInvAmount > 0) {
    						inviteSend += awData.threeInvAmount.div(15).mul(lineValue);
    					}
    					if (user.lineLevel < 3) {
    						uint fireSc = getFireScByLevel(user.lineLevel);
    						inviteSend = inviteSend.mul(fireSc).div(10);
    					}
    				}
    			} else if (userGlobal.status == 2) {
    				user.rewardIndex = user.rewardIndex.add(1);
    			}
    
    			if (bonusSend.add(inviteSend) <= sendLimit) {
    				user.inviteAmonut = user.inviteAmonut.add(inviteSend);
    				bool isEnough = false;
    				uint resultMoney = 0;
    				(isEnough, resultMoney) = isEnoughBalance(bonusSend.add(inviteSend));
    				if (resultMoney > 0) {
    					uint confortMoney = resultMoney.div(10);
    					sendMoneyToUser(comfortAddr, confortMoney);
    					resultMoney = resultMoney.sub(confortMoney);
    					address payable sendAddr = address(uint160(userAddr));
    					sendMoneyToUser(sendAddr, resultMoney);
    				}
    			}
    		}
    	}
    
    	function isEnoughBalance(uint sendMoney) private view returns (bool, uint){
    		if (sendMoney >= address(this).balance) {
    			return (false, address(this).balance);
    		} else {
    			return (true, sendMoney);
    		}
    	}
    
    	function sendFeetoAdmin(uint amount) private {
    		devAddr.transfer(amount.div(25));
    	}
    
    	function sendMoneyToUser(address payable userAddress, uint money) private {
    		if (money > 0) {
    			userAddress.transfer(money);
    		}
    	}
    
    	function isUsed(string memory code) public view returns (bool) {
    		address addr = addressMapping[code];
    		return uint(addr) != 0;
    	}
    
    	function getUserAddressByCode(string memory code) public view returns (address) {
    		require(isWhitelistAdmin(msg.sender), "Permission denied");
    		return addressMapping[code];
    	}
    
    	function registerUser(address addr, string memory inviteCode, string memory beCode) private {
    		UserGlobal storage userGlobal = userMapping[addr];
    		uid++;
    		userGlobal.id = uid;
    		userGlobal.userAddress = addr;
    		userGlobal.inviteCode = inviteCode;
    		userGlobal.beCode = beCode;
    
    		addressMapping[inviteCode] = addr;
    		indexMapping[uid] = addr;
    	}
    
    	function endRound() external onlyOwner {
    		require(address(this).balance < 1 ether, "contract balance must be lower than 1 ether");
    		rid++;
    		startTime = now.add(period).div(1 days).mul(1 days);
    		canSetStartTime = 1;
    	}
    
    	function donnottouch() public view returns (uint, uint, uint, uint, uint, uint, uint, uint, uint, uint, uint, uint) {
    		return (
    		rid,
    		uid,
    		startTime,
    		rInvestCount[rid],
    		rInvestMoney[rid],
    		bonuslimit,
    		sendLimit,
    		withdrawLimit,
    		canImport,
    		lineStatus,
    		lineArrayMapping[rid].length,
    		canSetStartTime
    		);
    	}
    
    	function getUserByAddress(address addr, uint roundId) public view returns (uint[14] memory info, string memory inviteCode, string memory beCode) {
    		require(isWhitelistAdmin(msg.sender) || msg.sender == addr, "Permission denied for view user's privacy");
    
    		if (roundId == 0) {
    			roundId = rid;
    		}
    
    		UserGlobal memory userGlobal = userMapping[addr];
    		User memory user = userRoundMapping[roundId][addr];
    		info[0] = userGlobal.id;
    		info[1] = user.lineAmount;
    		info[2] = user.freeAmount;
    		info[3] = user.freezeAmount;
    		info[4] = user.inviteAmonut;
    		info[5] = user.bonusAmount;
    		info[6] = user.lineLevel;
    		info[7] = user.dayBonusAmount;
    		info[8] = user.rewardIndex;
    		info[9] = user.investTimes;
    		info[10] = user.level;
    		uint grantAmount = 0;
    		if (user.id > 0 && user.freezeAmount >= 1 ether && user.freezeAmount <= bonuslimit && user.investTimes < 5 && userGlobal.status != 1) {
    			grantAmount += user.dayBonusAmount;
    		}
    		if (userGlobal.status == 0) {
    			uint inviteSend = 0;
    			AwardData memory awData = userAwardDataMapping[rid][user.userAddress][user.rewardIndex];
    			uint lineAmount = user.freezeAmount.add(user.freeAmount).add(user.lineAmount);
    			if (lineAmount >= 1 ether) {
    				uint lineValue = lineAmount.div(ethWei);
    				if (lineValue >= 15) {
    					inviteSend += awData.threeInvAmount;
    				} else {
    					if (user.lineLevel == 1 && lineAmount >= 1 ether && awData.oneInvAmount > 0) {
    						inviteSend += awData.oneInvAmount.div(15).mul(lineValue).div(2);
    					}
    					if (user.lineLevel == 2 && lineAmount >= 1 ether && (awData.oneInvAmount > 0 || awData.twoInvAmount > 0)) {
    						inviteSend += awData.oneInvAmount.div(15).mul(lineValue).mul(7).div(10);
    						inviteSend += awData.twoInvAmount.div(15).mul(lineValue).mul(5).div(7);
    					}
    					if (user.lineLevel == 3 && lineAmount >= 1 ether && awData.threeInvAmount > 0) {
    						inviteSend += awData.threeInvAmount.div(15).mul(lineValue);
    					}
    					if (user.lineLevel < 3) {
    						uint fireSc = getFireScByLevel(user.lineLevel);
    						inviteSend = inviteSend.mul(fireSc).div(10);
    					}
    				}
    				grantAmount += inviteSend;
    			}
    		}
    		info[11] = grantAmount;
    		info[12] = user.lastRwTime;
    		info[13] = userGlobal.status;
    
    		return (info, userGlobal.inviteCode, userGlobal.beCode);
    	}
    
    	function getUserAddressById(uint id) public view returns (address) {
    		require(isWhitelistAdmin(msg.sender), "Permission denied");
    		return indexMapping[id];
    	}
    
    	function getLineUserId(uint index, uint rouId) public view returns (uint) {
    		require(isWhitelistAdmin(msg.sender), "Permission denied");
    		if (rouId == 0) {
    			rouId = rid;
    		}
    		return lineArrayMapping[rid][index];
    	}
    }
    
    /**
    * @title SafeMath
    * @dev Math operations with safety checks that revert on error
    */
    library SafeMath {
    	/* https://fairwin.me */
    	/**
    	* @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, "mul overflow");
    
    		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, "div zero");
    		// 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, "lower sub bigger");
    		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, "overflow");
    
    		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, "mod zero");
    		return a % b;
    	}
    
    	/**
    	* @dev compare two numbers and returns the smaller one.
    	*/
    	function min(uint256 a, uint256 b) internal pure returns (uint256) {
    		return a > b ? b : a;
    	}
    }