Transaction Hash:
Block:
7231396 at Feb-17-2019 09:46:14 AM +UTC
Transaction Fee:
0.00057034251269632 ETH
$1.03
Gas Used:
49,595 Gas / 11.500000256 Gwei
Emitted Events:
27 |
HumanBox.LogPayDividends( addr=[Sender] 0x9d7289584908b444569e5c2856aacaa8f9ae9f2d, when=1550396774, dividends=1048611111111111 )
|
28 |
HumanBox.LogBalanceChanged( when=1550396774, balance=58951388888888889 )
|
Account State Difference:
Address | Before | After | State Difference | ||
---|---|---|---|---|---|
0x1ECf1599...1dd7e6220 | 0.06 Eth | 0.058951388888888889 Eth | 0.001048611111111111 | ||
0x9d728958...8f9AE9F2d |
0.212924145139647317 Eth
Nonce: 50
|
0.213402413738062108 Eth
Nonce: 51
| 0.000478268598414791 | ||
0xa177cB8C...d4C743eA3 | |||||
0xEA674fdD...16B898ec8
Miner
| (Ethermine) | 789.157845964086607478 Eth | 789.158416306599303798 Eth | 0.00057034251269632 |
Execution Trace
HumanBox.CALL( )

-
0xa177cb8c2b0157297333bc179f87871d4c743ea3.dbcbaca4( )
-
0xa177cb8c2b0157297333bc179f87871d4c743ea3.dbcbaca4( )
-
0xa177cb8c2b0157297333bc179f87871d4c743ea3.44013585( )
- ETH 0.001048611111111111
0x9d7289584908b444569e5c2856aacaa8f9ae9f2d.CALL( )
[HumanBox (ln:435)]
isZero[HumanBox (ln:437)]
getMyDividends[HumanBox (ln:438)]
sub[HumanBox (ln:534)]
getMemInvestor[HumanBox (ln:534)]
investorInfo[HumanBox (ln:627)]
Investor[HumanBox (ln:628)]
calcDividends[HumanBox (ln:536)]
getMemInvestor[HumanBox (ln:632)]
investorInfo[HumanBox (ln:627)]
Investor[HumanBox (ln:628)]
isZero[HumanBox (ln:635)]
sub[HumanBox (ln:635)]
dailyPercent[HumanBox (ln:640)]
toMemory[HumanBox (ln:648)]
toMemory[HumanBox (ln:650)]
toMemory[HumanBox (ln:652)]
toMemory[HumanBox (ln:654)]
toMemory[HumanBox (ln:656)]
toMemory[HumanBox (ln:658)]
toMemory[HumanBox (ln:660)]
toMemory[HumanBox (ln:662)]
sub[HumanBox (ln:641)]
mmul[HumanBox (ln:641)]
notZero[HumanBox (ln:537)]
setPaymentTime[HumanBox (ln:540)]
nextWave[HumanBox (ln:544)]
startAt[HumanBox (ln:670)]
LogRGPInit[HumanBox (ln:671)]
LogNextWave[HumanBox (ln:672)]
transfer[HumanBox (ln:549)]
LogPayDividends[HumanBox (ln:550)]
doInvest[HumanBox (ln:443)]
isActive[HumanBox (ln:559)]
maxInvestmentAtNow[HumanBox (ln:561)]
requireNotZero[HumanBox (ln:562)]
min[HumanBox (ln:563)]
saveInvestment[HumanBox (ln:564)]
LogRGPInvestment[HumanBox (ln:565)]
currDay[HumanBox (ln:565)]
isActive[HumanBox (ln:567)]
maxInvestmentFor[HumanBox (ln:569)]
requireNotZero[HumanBox (ln:570)]
min[HumanBox (ln:571)]
transfer[HumanBox (ln:577)]
LogSendExcessOfEther[HumanBox (ln:579)]
send[HumanBox (ln:583)]
mul[HumanBox (ln:583)]
send[HumanBox (ln:584)]
mul[HumanBox (ln:584)]
isInvestor[HumanBox (ln:586)]
notZero[HumanBox (ln:589)]
isInvestor[HumanBox (ln:590)]
mmul[HumanBox (ln:594)]
mmul[HumanBox (ln:596)]
mmul[HumanBox (ln:599)]
addInvestment[HumanBox (ln:600)]
LogNewReferral[HumanBox (ln:602)]
calcDividends[HumanBox (ln:606)]
getMemInvestor[HumanBox (ln:632)]
investorInfo[HumanBox (ln:627)]
Investor[HumanBox (ln:628)]
isZero[HumanBox (ln:635)]
sub[HumanBox (ln:635)]
dailyPercent[HumanBox (ln:640)]
toMemory[HumanBox (ln:648)]
toMemory[HumanBox (ln:650)]
toMemory[HumanBox (ln:652)]
toMemory[HumanBox (ln:654)]
toMemory[HumanBox (ln:656)]
toMemory[HumanBox (ln:658)]
toMemory[HumanBox (ln:660)]
toMemory[HumanBox (ln:662)]
sub[HumanBox (ln:641)]
mmul[HumanBox (ln:641)]
notZero[HumanBox (ln:607)]
LogAutomaticReinvest[HumanBox (ln:609)]
addInvestment[HumanBox (ln:614)]
setPaymentTime[HumanBox (ln:615)]
newInvestor[HumanBox (ln:618)]
LogNewInvestor[HumanBox (ln:619)]
LogNewInvesment[HumanBox (ln:623)]
toAddress[HumanBox (ln:443)]
pragma solidity 0.4.25; /** * HumanBox - InvestBox * Category - Finance * Web - https://hmx.global * GitHub - https://github.com/HumanXGroup * Twitter - https://twitter.com/hmx_global * Telegram_channel - https://t.me/hmxglobal_chat * Email: mailto:contact(at sign)hmx.global */ library Math { function min(uint a, uint b) internal pure returns(uint) { if (a > b) { return b; } return a; } } library Zero { function requireNotZero(address addr) internal pure { require(addr != address(0), "require not zero address"); } function requireNotZero(uint val) internal pure { require(val != 0, "require not zero value"); } function notZero(address addr) internal pure returns(bool) { return !(addr == address(0)); } function isZero(address addr) internal pure returns(bool) { return addr == address(0); } function isZero(uint a) internal pure returns(bool) { return a == 0; } function notZero(uint a) internal pure returns(bool) { return a != 0; } } library Percent { struct percent { uint num; uint den; } function mul(percent storage p, uint a) internal view returns (uint) { if (a == 0) { return 0; } return a*p.num/p.den; } function div(percent storage p, uint a) internal view returns (uint) { return a/p.num*p.den; } function sub(percent storage p, uint a) internal view returns (uint) { uint b = mul(p, a); if (b >= a) { return 0; } return a - b; } function add(percent storage p, uint a) internal view returns (uint) { return a + mul(p, a); } function toMemory(percent storage p) internal view returns (Percent.percent memory) { return Percent.percent(p.num, p.den); } function mmul(percent memory p, uint a) internal pure returns (uint) { if (a == 0) { return 0; } return a*p.num/p.den; } function mdiv(percent memory p, uint a) internal pure returns (uint) { return a/p.num*p.den; } function msub(percent memory p, uint a) internal pure returns (uint) { uint b = mmul(p, a); if (b >= a) { return 0; } return a - b; } function madd(percent memory p, uint a) internal pure returns (uint) { return a + mmul(p, a); } } library Address { function toAddress(bytes source) internal pure returns(address addr) { assembly { addr := mload(add(source,0x14)) } return addr; } function isNotContract(address addr) internal view returns(bool) { uint length; assembly { length := extcodesize(addr) } return length == 0; } } /** * @title SafeMath * @dev Math operations with safety checks that revert on error */ library SafeMath { /** * @dev Multiplies two numbers, reverts on overflow. */ function mul(uint256 _a, uint256 _b) internal pure returns (uint256) { if (_a == 0) { return 0; } uint256 c = _a * _b; require(c / _a == _b); 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); // 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); 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); 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); return a % b; } } contract Accessibility { address private owner; modifier onlyOwner() { require(msg.sender == owner, "access denied"); _; } constructor() public { owner = msg.sender; } function disown() internal { delete owner; } } contract Rev1Storage { function investorShortInfo(address addr) public view returns(uint value, uint refBonus); } contract Rev2Storage { function investorInfo(address addr) public view returns(uint investment, uint paymentTime); } library PrivateEntrance { using PrivateEntrance for privateEntrance; using Math for uint; struct privateEntrance { Rev1Storage rev1Storage; Rev2Storage rev2Storage; uint investorMaxInvestment; uint endTimestamp; mapping(address=>bool) hasAccess; } function isActive(privateEntrance storage pe) internal view returns(bool) { return pe.endTimestamp > now; } function maxInvestmentFor(privateEntrance storage pe, address investorAddr) internal view returns(uint) { if (!pe.hasAccess[investorAddr]) { return 0; } (uint maxInvestment, ) = pe.rev1Storage.investorShortInfo(investorAddr); if (maxInvestment == 0) { return 0; } maxInvestment = Math.min(maxInvestment, pe.investorMaxInvestment); (uint currInvestment, ) = pe.rev2Storage.investorInfo(investorAddr); if (currInvestment >= maxInvestment) { return 0; } return maxInvestment-currInvestment; } function provideAccessFor(privateEntrance storage pe, address[] addrs) internal { for (uint16 i; i < addrs.length; i++) { pe.hasAccess[addrs[i]] = true; } } } contract InvestorsStorage is Accessibility { struct Investor { uint investment; uint paymentTime; } uint public size; mapping (address => Investor) private investors; function isInvestor(address addr) public view returns (bool) { return investors[addr].investment > 0; } function investorInfo(address addr) public view returns(uint investment, uint paymentTime) { investment = investors[addr].investment; paymentTime = investors[addr].paymentTime; } function newInvestor(address addr, uint investment, uint paymentTime) public onlyOwner returns (bool) { Investor storage inv = investors[addr]; if (inv.investment != 0 || investment == 0) { return false; } inv.investment = investment; inv.paymentTime = paymentTime; size++; return true; } function addInvestment(address addr, uint investment) public onlyOwner returns (bool) { if (investors[addr].investment == 0) { return false; } investors[addr].investment += investment; return true; } function setPaymentTime(address addr, uint paymentTime) public onlyOwner returns (bool) { if (investors[addr].investment == 0) { return false; } investors[addr].paymentTime = paymentTime; return true; } function disqalify(address addr) public onlyOwner returns (bool) { if (isInvestor(addr)) { investors[addr].investment = 0; } } } library RapidGrowthProtection { using RapidGrowthProtection for rapidGrowthProtection; struct rapidGrowthProtection { uint startTimestamp; uint maxDailyTotalInvestment; uint8 activityDays; mapping(uint8 => uint) dailyTotalInvestment; } function maxInvestmentAtNow(rapidGrowthProtection storage rgp) internal view returns(uint) { uint day = rgp.currDay(); if (day == 0 || day > rgp.activityDays) { return 0; } if (rgp.dailyTotalInvestment[uint8(day)] >= rgp.maxDailyTotalInvestment) { return 0; } return rgp.maxDailyTotalInvestment - rgp.dailyTotalInvestment[uint8(day)]; } function isActive(rapidGrowthProtection storage rgp) internal view returns(bool) { uint day = rgp.currDay(); return day != 0 && day <= rgp.activityDays; } function saveInvestment(rapidGrowthProtection storage rgp, uint investment) internal returns(bool) { uint day = rgp.currDay(); if (day == 0 || day > rgp.activityDays) { return false; } if (rgp.dailyTotalInvestment[uint8(day)] + investment > rgp.maxDailyTotalInvestment) { return false; } rgp.dailyTotalInvestment[uint8(day)] += investment; return true; } function startAt(rapidGrowthProtection storage rgp, uint timestamp) internal { rgp.startTimestamp = timestamp; // restart for (uint8 i = 1; i <= rgp.activityDays; i++) { if (rgp.dailyTotalInvestment[i] != 0) { delete rgp.dailyTotalInvestment[i]; } } } function currDay(rapidGrowthProtection storage rgp) internal view returns(uint day) { if (rgp.startTimestamp > now) { return 0; } day = (now - rgp.startTimestamp) / 24 hours + 1; } } contract HumanBox is Accessibility { using RapidGrowthProtection for RapidGrowthProtection.rapidGrowthProtection; using PrivateEntrance for PrivateEntrance.privateEntrance; using Percent for Percent.percent; using SafeMath for uint; using Math for uint; // easy read for investors using Address for *; using Zero for *; RapidGrowthProtection.rapidGrowthProtection private m_rgp; PrivateEntrance.privateEntrance private m_privEnter; mapping(address => bool) private m_referrals; InvestorsStorage private m_investors; // automatically generates getters uint public constant minInvesment = 10 finney; uint public constant maxBalance = 500e5 ether; address public advertisingAddress; address public adminsAddress; uint public investmentsNumber; uint public waveStartup; // percents Percent.percent private m_5_percent = Percent.percent(1,100); Percent.percent private m_6_percent = Percent.percent(12,1000); Percent.percent private m_7_percent = Percent.percent(13,1000); Percent.percent private m_8_percent = Percent.percent(15,1000); Percent.percent private m_9_percent = Percent.percent(2,100); Percent.percent private m_10_percent = Percent.percent(23,1000); Percent.percent private m_11_percent = Percent.percent(25,1000); Percent.percent private m_12_percent = Percent.percent(3,100); Percent.percent private m_referal_percent = Percent.percent(2,100); Percent.percent private m_referrer_percent = Percent.percent(3,100); Percent.percent private m_referrer_percentMax = Percent.percent(6,100); Percent.percent private m_adminsPercent = Percent.percent(15,100); Percent.percent private m_advertisingPercent = Percent.percent(35,100); // more events for easy read from blockchain event LogPEInit(uint when, address rev1Storage, address rev2Storage, uint investorMaxInvestment, uint endTimestamp); event LogSendExcessOfEther(address indexed addr, uint when, uint value, uint investment, uint excess); event LogNewReferral(address indexed addr, address indexed referrerAddr, uint when, uint refBonus); event LogRGPInit(uint when, uint startTimestamp, uint maxDailyTotalInvestment, uint activityDays); event LogRGPInvestment(address indexed addr, uint when, uint investment, uint indexed day); event LogNewInvesment(address indexed addr, uint when, uint investment, uint value); event LogAutomaticReinvest(address indexed addr, uint when, uint investment); event LogPayDividends(address indexed addr, uint when, uint dividends); event LogNewInvestor(address indexed addr, uint when); event LogBalanceChanged(uint when, uint balance); event LogNextWave(uint when); event LogDisown(uint when); modifier balanceChanged { _; emit LogBalanceChanged(now, address(this).balance); } modifier notFromContract() { require(msg.sender.isNotContract(), "only externally accounts"); _; } constructor() public { adminsAddress = msg.sender; advertisingAddress = msg.sender; nextWave(); } function() public payable { // investor get him dividends if (msg.value.isZero()) { getMyDividends(); return; } // sender do invest doInvest(msg.data.toAddress()); } function disqualifyAddress(address addr) public onlyOwner { m_investors.disqalify(addr); } function doDisown() public onlyOwner { disown(); emit LogDisown(now); } function init(address rev1StorageAddr, uint timestamp) public onlyOwner { // init Rapid Growth Protection m_rgp.startTimestamp = timestamp + 1; m_rgp.maxDailyTotalInvestment = 500 ether; m_rgp.activityDays = 21; emit LogRGPInit( now, m_rgp.startTimestamp, m_rgp.maxDailyTotalInvestment, m_rgp.activityDays ); // init Private Entrance m_privEnter.rev1Storage = Rev1Storage(rev1StorageAddr); m_privEnter.rev2Storage = Rev2Storage(address(m_investors)); m_privEnter.investorMaxInvestment = 50 ether; m_privEnter.endTimestamp = timestamp; emit LogPEInit( now, address(m_privEnter.rev1Storage), address(m_privEnter.rev2Storage), m_privEnter.investorMaxInvestment, m_privEnter.endTimestamp ); } function setAdvertisingAddress(address addr) public onlyOwner { addr.requireNotZero(); advertisingAddress = addr; } function setAdminsAddress(address addr) public onlyOwner { addr.requireNotZero(); adminsAddress = addr; } function privateEntranceProvideAccessFor(address[] addrs) public onlyOwner { m_privEnter.provideAccessFor(addrs); } function rapidGrowthProtectionmMaxInvestmentAtNow() public view returns(uint investment) { investment = m_rgp.maxInvestmentAtNow(); } function investorsNumber() public view returns(uint) { return m_investors.size(); } function balanceETH() public view returns(uint) { return address(this).balance; } function advertisingPercent() public view returns(uint numerator, uint denominator) { (numerator, denominator) = (m_advertisingPercent.num, m_advertisingPercent.den); } function adminsPercent() public view returns(uint numerator, uint denominator) { (numerator, denominator) = (m_adminsPercent.num, m_adminsPercent.den); } function investorInfo(address investorAddr) public view returns(uint investment, uint paymentTime, bool isReferral) { (investment, paymentTime) = m_investors.investorInfo(investorAddr); isReferral = m_referrals[investorAddr]; } function investorDividendsAtNow(address investorAddr) public view returns(uint dividends) { dividends = calcDividends(investorAddr); } function dailyPercentAtNow() public view returns(uint numerator, uint denominator) { Percent.percent memory p = dailyPercent(); (numerator, denominator) = (p.num, p.den); } function getMyDividends() public notFromContract balanceChanged { // calculate dividends //check if 1 day passed after last payment require(now.sub(getMemInvestor(msg.sender).paymentTime) > 24 hours); uint dividends = calcDividends(msg.sender); require (dividends.notZero(), "cannot to pay zero dividends"); // update investor payment timestamp assert(m_investors.setPaymentTime(msg.sender, now)); // check enough eth - goto next wave if needed if (address(this).balance <= dividends) { nextWave(); dividends = address(this).balance; } // transfer dividends to investor msg.sender.transfer(dividends); emit LogPayDividends(msg.sender, now, dividends); } function doInvest(address referrerAddr) public payable notFromContract balanceChanged { uint investment = msg.value; uint receivedEther = msg.value; require(investment >= minInvesment, "investment must be >= minInvesment"); require(address(this).balance <= maxBalance, "the contract eth balance limit"); if (m_rgp.isActive()) { // use Rapid Growth Protection if needed uint rpgMaxInvest = m_rgp.maxInvestmentAtNow(); rpgMaxInvest.requireNotZero(); investment = Math.min(investment, rpgMaxInvest); assert(m_rgp.saveInvestment(investment)); emit LogRGPInvestment(msg.sender, now, investment, m_rgp.currDay()); } else if (m_privEnter.isActive()) { // use Private Entrance if needed uint peMaxInvest = m_privEnter.maxInvestmentFor(msg.sender); peMaxInvest.requireNotZero(); investment = Math.min(investment, peMaxInvest); } // send excess of ether if needed if (receivedEther > investment) { uint excess = receivedEther - investment; msg.sender.transfer(excess); receivedEther = investment; emit LogSendExcessOfEther(msg.sender, now, msg.value, investment, excess); } // commission advertisingAddress.send(m_advertisingPercent.mul(receivedEther)); adminsAddress.send(m_adminsPercent.mul(receivedEther)); bool senderIsInvestor = m_investors.isInvestor(msg.sender); // ref system works only once and only on first invest if (referrerAddr.notZero() && !senderIsInvestor && !m_referrals[msg.sender] && referrerAddr != msg.sender && m_investors.isInvestor(referrerAddr)) { m_referrals[msg.sender] = true; // add referral bonus to investor`s and referral`s investments uint referrerBonus = m_referrer_percent.mmul(investment); if (investment > 10 ether) { referrerBonus = m_referrer_percentMax.mmul(investment); } uint referalBonus = m_referal_percent.mmul(investment); assert(m_investors.addInvestment(referrerAddr, referrerBonus)); // add referrer bonus investment += referalBonus; // add referral bonus emit LogNewReferral(msg.sender, referrerAddr, now, referalBonus); } // automatic reinvest - prevent burning dividends uint dividends = calcDividends(msg.sender); if (senderIsInvestor && dividends.notZero()) { investment += dividends; emit LogAutomaticReinvest(msg.sender, now, dividends); } if (senderIsInvestor) { // update existing investor assert(m_investors.addInvestment(msg.sender, investment)); assert(m_investors.setPaymentTime(msg.sender, now)); } else { // create new investor assert(m_investors.newInvestor(msg.sender, investment, now)); emit LogNewInvestor(msg.sender, now); } investmentsNumber++; emit LogNewInvesment(msg.sender, now, investment, receivedEther); } function getMemInvestor(address investorAddr) internal view returns(InvestorsStorage.Investor memory) { (uint investment, uint paymentTime) = m_investors.investorInfo(investorAddr); return InvestorsStorage.Investor(investment, paymentTime); } function calcDividends(address investorAddr) internal view returns(uint dividends) { InvestorsStorage.Investor memory investor = getMemInvestor(investorAddr); // safe gas if dividends will be 0 if (investor.investment.isZero() || now.sub(investor.paymentTime) < 10 minutes) { return 0; } // for prevent burning daily dividends if 24h did not pass - calculate it per 10 min interval Percent.percent memory p = dailyPercent(); dividends = (now.sub(investor.paymentTime) / 10 minutes) * p.mmul(investor.investment) / 144; } function dailyPercent() internal view returns(Percent.percent memory p) { uint balance = address(this).balance; if (balance < 5 ether) { p = m_5_percent.toMemory(); } else if ( 5 ether <= balance && balance <= 10 ether) { p = m_6_percent.toMemory(); } else if ( 10 ether <= balance && balance <= 30 ether) { p = m_7_percent.toMemory(); } else if ( 30 ether <= balance && balance <= 50 ether) { p = m_8_percent.toMemory(); } else if ( 50 ether <= balance && balance <= 100 ether) { p = m_9_percent.toMemory(); } else if ( 100 ether <= balance && balance <= 300 ether) { p = m_10_percent.toMemory(); } else if ( 300 ether <= balance && balance <= 500 ether) { p = m_11_percent.toMemory(); } else { p = m_12_percent.toMemory(); } } function nextWave() private { m_investors = new InvestorsStorage(); investmentsNumber = 0; waveStartup = now; m_rgp.startAt(now); emit LogRGPInit(now , m_rgp.startTimestamp, m_rgp.maxDailyTotalInvestment, m_rgp.activityDays); emit LogNextWave(now); } }