Transaction Hash:
Block:
8728618 at Oct-12-2019 07:40:02 PM +UTC
Transaction Fee:
0.000194408 ETH
$0.40
Gas Used:
24,301 Gas / 8 Gwei
Account State Difference:
| Address | Before | After | State Difference | ||
|---|---|---|---|---|---|
| 0xa699153E...8844e3F85 | 7,818.704605333333336535 Eth | 7,807.704605333333336535 Eth | 11 | ||
| 0xD46B44Df...860d8fc08 |
7.269761214109375 Eth
Nonce: 4
|
18.269566806109375 Eth
Nonce: 5
| 10.999805592 | ||
|
0xEA674fdD...16B898ec8
Miner
| (Ethermine) | 762.405615502979659912 Eth | 762.405809910979659912 Eth | 0.000194408 |
Execution Trace
FairWin.CALL( )
- ETH 11
0xd46b44dff3d565605bc927a07f065ef860d8fc08.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;
}
}