/** * Source Code first verified at https://etherscan.io on Thursday, March 21, 2019 (UTC) */ pragma solidity ^0.4.24; /* * gibmireinbier - Full Stack Blockchain Developer * 0xA4a799086aE18D7db6C4b57f496B081b44888888 * [email protected] */ /* CHANGELOGS: . Round 0: 10% bonus for old invester (with limit based on total dividends income in version 1) -- REMOVED by Seizo . Round 0: start price 0.0014 ether, Min. duration 3 days, 30% to Pot, 70% hold for token selling -- REMOVED by Seizo . Round 0: premine function, claim free tokens based on F2M v1 Dividends -- REMOVED by Seizo . BEFORE_SLEEP_DURAION = 30 * ONE_DAY ( Last round must be greater than 28) BUGS FIXED: . SwapToken function : update credit after tokens selling . Referral by token reinvest . Tokenholders tracking on etherscan (emit transfer in mint-, burn-token functions) */ contract F2m{ using SafeMath for *; modifier onlyTokenHolders() { require(balances[msg.sender] > 0, "not own any token"); _; } modifier onlyAdmin(){ require(msg.sender == devTeam, "admin required"); _; } modifier withdrawRight(){ require((msg.sender == address(bankContract)), "Bank Only"); _; } modifier swapNotActived() { require(swapActived == false, "swap actived, stop minting new tokens"); _; } modifier buyable() { require(buyActived == true, "token sale not ready"); _; } // modifier premineable() { // require(buyActived == false && investedAmount == 0, "token sale already"); // _; // } /*============================== = EVENTS = ==============================*/ // ERC20 event Transfer(address indexed from, address indexed to, uint tokens); event Approval(address indexed tokenOwner, address indexed spender, uint tokens); /*===================================== = ERC20 = =====================================*/ uint256 public totalSupply; string public name; string public symbol; uint32 public decimals; uint256 public unitRate; // Balances for each account mapping(address => uint256) balances; // Owner of account approves the transfer of an amount to another account mapping(address => mapping (address => uint256)) allowed; /*================================ = DATASETS = ================================*/ CitizenInterface public citizenContract; LotteryInterface public lotteryContract; BankInterface public bankContract; NewTokenInterface public newTokenContract; WhitelistInterface public whitelistContract; uint256 constant public ONE_HOUR= 3600; uint256 constant public ONE_DAY = 24 * ONE_HOUR; // seconds // uint256 constant public FIRST_POT_MAXIMUM = 200 ether; // uint256 constant public ROUND0_MIN_DURATION = 3 * ONE_DAY; // minimum uint256 constant public BEFORE_SLEEP_DURAION = 30 * ONE_DAY; uint256 public HARD_TOTAL_SUPPLY = 8000000; uint256 public refPercent = 15; uint256 public divPercent = 10; uint256 public fundPercent = 2; // uint256 public potPercent = 30; // set to 0 in func disableRound0() //Start Price uint256 public startPrice = 0.0014 ether; //Most Tolerable Break-Even Period (MTBEP) uint256 constant public BEP = 30; // amount of shares for each address (scaled number) mapping(address => int256) public credit; mapping(address => uint256) public withdrawnAmount; mapping(address => uint256) public fromSellingAmount; mapping(address => uint256) public lastActiveDay; mapping(address => int256) public todayCredit; mapping(address => uint256) public pInvestedSum; uint256 public investedAmount; uint256 public totalBuyVolume; uint256 public totalSellVolume; uint256 public totalDividends; mapping(uint256 => uint256) public totalDividendsByRound; //Profit Per Share uint256 public pps = 0; //log by round mapping(uint256 => uint256) rPps; mapping(address => mapping (uint256 => int256)) rCredit; // uint256 public deployedTime; uint256 public deployedDay; // on/off auto buy Token bool public autoBuy = false; bool public round0 = false; //raise for first round //pps added in day mapping(uint256 => uint256) public ppsInDay; //Avarage pps in a day mapping(uint256 => uint256) public divInDay; mapping(uint256 => uint256) public totalBuyVolumeInDay; mapping(uint256 => uint256) public totalSellVolumeInDay; address public devTeam; //Smart contract address uint256 public swapTime; bool public swapActived = false; bool public buyActived = false; /*======================================= = PUBLIC FUNCTIONS = =======================================*/ constructor (address _devTeam) public { symbol = "F2M2"; name = "Fomo2Moon2"; decimals = 10; unitRate = 10**uint256(decimals); HARD_TOTAL_SUPPLY = HARD_TOTAL_SUPPLY * unitRate; DevTeamInterface(_devTeam).setF2mAddress(address(this)); devTeam = _devTeam; // manuell airdrops to old investers uint256 _amount = 500000 * unitRate; totalSupply += _amount; balances[devTeam] = _amount; emit Transfer(0x0, devTeam, _amount); deployedDay = getToday(); } // function premine() // public // premineable() // { // address _sender = msg.sender; // require(balances[_sender] == 0, "already claimed"); // uint256 _amount = whitelistContract.getPremintAmount(_sender); // totalSupply += _amount; // balances[_sender] = _amount; // emit Transfer(0x0, _sender, _amount); // } // _contract = [f2mAddress, bankAddress, citizenAddress, lotteryAddress, rewardAddress, whitelistAddress]; function joinNetwork(address[6] _contract) public { require(address(citizenContract) == 0x0, "already setup"); bankContract = BankInterface(_contract[1]); citizenContract = CitizenInterface(_contract[2]); lotteryContract = LotteryInterface(_contract[3]); whitelistContract = WhitelistInterface(_contract[5]); } function() public payable { // Thanks for Donation } // one time called, manuell called in case not reached 360ETH for totalPot /* function disableRound0() public onlyAdmin() { require(buyActived && block.timestamp > ROUND0_MIN_DURATION.add(deployedTime), "too early to disable Round0"); firstRoundPrepare(); } */ function activeBuy() public onlyAdmin() { require(buyActived == false, "already actived"); buyActived = true; deployedDay = getToday(); } // Dividends from all sources (DApps, Donate ...) function pushDividends() public payable { // shared to fund and dividends only uint256 ethAmount = msg.value; uint256 dividends = ethAmount * divPercent / (divPercent + fundPercent); uint256 fund = ethAmount.sub(dividends); uint256 _buyPrice = getBuyPrice(); // distributeTax(msg.sender, fund, dividends, 0, 0); distributeTax(msg.sender, fund, dividends, 0); if (autoBuy) devTeamAutoBuy(0, _buyPrice); } function addFund(uint256 _fund) private { credit[devTeam] = credit[devTeam].sub(int256(_fund)); } function addDividends(uint256 _dividends) private { if (_dividends == 0) return; totalDividends += _dividends; uint256 today = getToday(); divInDay[today] = _dividends.add(divInDay[today]); if (totalSupply == 0) { addFund(_dividends); } else { // increased profit with each token // gib mir n bier addFund(_dividends % totalSupply); uint256 deltaShare = _dividends / totalSupply; pps = pps.add(deltaShare); // logs uint256 curRoundId = getCurRoundId(); rPps[curRoundId] += deltaShare; totalDividendsByRound[curRoundId] += _dividends; ppsInDay[today] = deltaShare + ppsInDay[today]; } } function addToRef(address _sender, uint256 _toRef) private { if (_toRef == 0) return; citizenContract.pushRefIncome.value(_toRef)(_sender); } /* function addToPot(uint256 _toPot) private { if (_toPot == 0) return; lotteryContract.pushToPot.value(_toPot)(); uint256 _totalPot = lotteryContract.getTotalPot(); // auto disable Round0 if reached 360ETH for first round if (_totalPot >= FIRST_POT_MAXIMUM) { firstRoundPrepare(); } } */ /* function firstRoundPrepare() private { round0 = false; potPercent = 0; refPercent = 15; divPercent = 10; fundPercent = 2; startPrice = 0.002; } */ function distributeTax( address _sender, uint256 _fund, uint256 _dividends, uint256 _toRef) // uint256 _toPot) private { addFund(_fund); addDividends(_dividends); addToRef(_sender, _toRef); //addToPot(_toPot); } function updateCredit(address _owner, uint256 _currentEthAmount, uint256 _rDividends, uint256 _todayDividends) private { // basicly to keep ethBalance not changed, after token balances changed (minted or burned) // ethBalance = pps * tokens -credit uint256 curRoundId = getCurRoundId(); credit[_owner] = int256(pps.mul(balances[_owner])).sub(int256(_currentEthAmount)); // logs rCredit[_owner][curRoundId] = int256(rPps[curRoundId] * balances[_owner]) - int256(_rDividends); todayCredit[_owner] = int256(ppsInDay[getToday()] * balances[_owner]) - int256(_todayDividends); } function mintToken(address _buyer, uint256 _taxedAmount, uint256 _buyPrice) private swapNotActived() buyable() returns(uint256) { uint256 revTokens = ethToToken(_taxedAmount, _buyPrice); investedAmount = investedAmount.add(_taxedAmount); // lottery ticket buy could be blocked without this // the 1% from ticket buy will increases tokenSellPrice when totalSupply capped if (revTokens + totalSupply > HARD_TOTAL_SUPPLY) revTokens = HARD_TOTAL_SUPPLY.sub(totalSupply); balances[_buyer] = balances[_buyer].add(revTokens); totalSupply = totalSupply.add(revTokens); emit Transfer(0x0, _buyer, revTokens); return revTokens; } function burnToken(address _seller, uint256 _tokenAmount) private returns (uint256) { require(balances[_seller] >= _tokenAmount, "not enough to burn"); uint256 revEthAmount = tokenToEth(_tokenAmount); investedAmount = investedAmount.sub(revEthAmount); balances[_seller] = balances[_seller].sub(_tokenAmount); totalSupply = totalSupply.sub(_tokenAmount); emit Transfer(_seller, 0x0, _tokenAmount); return revEthAmount; } function devTeamAutoBuy(uint256 _reserved, uint256 _buyPrice) private { uint256 _refClaim = citizenContract.devTeamReinvest(); credit[devTeam] -= int256(_refClaim); uint256 _ethAmount = ethBalance(devTeam); if ((_ethAmount + _reserved) / _buyPrice + totalSupply > HARD_TOTAL_SUPPLY) return; uint256 _rDividends = getRDividends(devTeam); uint256 _todayDividends = getTodayDividendsByAddress(devTeam); mintToken(devTeam, _ethAmount, _buyPrice); updateCredit(devTeam, 0, _rDividends, _todayDividends); } function buy() public payable { address _buyer = msg.sender; buyFor(_buyer); } /* function checkLimit(address _buyer) private view { require(!round0 || !whitelistContract.isLimited(_buyer, pInvestedSum[_buyer]), "Limited"); } */ function buyFor(address _buyer) public payable { //ADD Round0 WHITE LIST // tax = fund + dividends + toRef + toPot; updateLastActive(_buyer); uint256 _buyPrice = getBuyPrice(); uint256 ethAmount = msg.value; pInvestedSum[_buyer] += ethAmount; // checkLimit(_buyer); uint256 onePercent = ethAmount / 100; uint256 fund = onePercent.mul(fundPercent); uint256 dividends = onePercent.mul(divPercent); uint256 toRef = onePercent.mul(refPercent); // uint256 toPot = onePercent.mul(potPercent); // uint256 tax = fund + dividends + toRef + toPot; uint256 tax = fund + dividends + toRef; uint256 taxedAmount = ethAmount.sub(tax); totalBuyVolume = totalBuyVolume + ethAmount; totalBuyVolumeInDay[getToday()] += ethAmount; // distributeTax(_buyer, fund, dividends, toRef, toPot); distributeTax(_buyer, fund, dividends, toRef); if (autoBuy) devTeamAutoBuy(taxedAmount, _buyPrice); uint256 curEthBalance = ethBalance(_buyer); uint256 _rDividends = getRDividends(_buyer); uint256 _todayDividends = getTodayDividendsByAddress(_buyer); mintToken(_buyer, taxedAmount, _buyPrice); updateCredit(_buyer, curEthBalance, _rDividends, _todayDividends); } function sell(uint256 _tokenAmount) public onlyTokenHolders() { // tax = fund only updateLastActive(msg.sender); address seller = msg.sender; uint256 curEthBalance = ethBalance(seller); uint256 _rDividends = getRDividends(seller); uint256 _todayDividends = getTodayDividendsByAddress(seller); uint256 ethAmount = burnToken(seller, _tokenAmount); uint256 fund = ethAmount.mul(fundPercent) / 100; uint256 taxedAmount = ethAmount.sub(fund); totalSellVolume = totalSellVolume + ethAmount; totalSellVolumeInDay[getToday()] += ethAmount; curEthBalance = curEthBalance.add(taxedAmount); fromSellingAmount[seller] += taxedAmount; updateCredit(seller, curEthBalance, _rDividends, _todayDividends); // distributeTax(msg.sender, fund, 0, 0, 0); distributeTax(msg.sender, fund, 0, 0); } function devTeamWithdraw() public returns(uint256) { address sender = msg.sender; require(sender == devTeam, "dev. Team only"); uint256 amount = ethBalance(sender); if (amount == 0) return 0; credit[sender] += int256(amount); withdrawnAmount[sender] = amount.add(withdrawnAmount[sender]); devTeam.transfer(amount); return amount; } function withdrawFor(address sender) public withdrawRight() returns(uint256) { uint256 amount = ethBalance(sender); if (amount == 0) return 0; credit[sender] = credit[sender].add(int256(amount)); withdrawnAmount[sender] = amount.add(withdrawnAmount[sender]); bankContract.pushToBank.value(amount)(sender); return amount; } function updateAllowed(address _from, address _to, uint256 _tokenAmount) private { require(balances[_from] >= _tokenAmount, "not enough to transfer"); if (_from != msg.sender) allowed[_from][_to] = allowed[_from][_to].sub(_tokenAmount); } function transferFrom(address _from, address _to, uint256 _tokenAmount) public returns(bool) { updateAllowed(_from, _to, _tokenAmount); updateLastActive(_from); updateLastActive(_to); uint256 curEthBalance_from = ethBalance(_from); uint256 _rDividends_from = getRDividends(_from); uint256 _todayDividends_from = getTodayDividendsByAddress(_from); uint256 curEthBalance_to = ethBalance(_to); uint256 _rDividends_to = getRDividends(_to); uint256 _todayDividends_to = getTodayDividendsByAddress(_to); uint256 taxedTokenAmount = _tokenAmount; balances[_from] -= taxedTokenAmount; balances[_to] += taxedTokenAmount; updateCredit(_from, curEthBalance_from, _rDividends_from, _todayDividends_from); updateCredit(_to, curEthBalance_to, _rDividends_to, _todayDividends_to); // fire event emit Transfer(_from, _to, taxedTokenAmount); return true; } function transfer(address _to, uint256 _tokenAmount) public returns (bool) { transferFrom(msg.sender, _to, _tokenAmount); return true; } function approve(address spender, uint tokens) public returns (bool success) { allowed[msg.sender][spender] = tokens; emit Approval(msg.sender, spender, tokens); return true; } function updateLastActive(address _sender) private { if (lastActiveDay[_sender] != getToday()) { lastActiveDay[_sender] = getToday(); todayCredit[_sender] = 0; } } /*---------- ADMINISTRATOR ONLY FUNCTIONS ----------*/ function setAutoBuy() public onlyAdmin() { autoBuy = !autoBuy; } /*---------- HELPERS AND CALCULATORS ----------*/ function totalEthBalance() public view returns(uint256) { return address(this).balance; } function ethBalance(address _address) public view returns(uint256) { return (uint256) ((int256)(pps.mul(balances[_address])).sub(credit[_address])); } function getTotalDividendsByAddress(address _invester) public view returns(uint256) { return (ethBalance(_invester)) + (withdrawnAmount[_invester]) - (fromSellingAmount[_invester]); } function getTodayDividendsByAddress(address _invester) public view returns(uint256) { int256 _todayCredit = (getToday() == lastActiveDay[_invester]) ? todayCredit[_invester] : 0; return (uint256) ((int256)(ppsInDay[getToday()] * balances[_invester]) - _todayCredit); } /*========================================== = public FUNCTIONS = ==========================================*/ /** * Return the sell price of 1 individual token. */ function getSellPrice() public view returns(uint256) { if (totalSupply == 0) { return 0; } else { return investedAmount / totalSupply; } } function getSellPriceAfterTax() public view returns(uint256) { uint256 _sellPrice = getSellPrice(); uint256 taxPercent = fundPercent; return _sellPrice * (100 - taxPercent) / 100; } /** * Return the buy price of 1 individual token. * Start Price + (7-day Average Dividend Payout) x BEP x HARD_TOTAL_SUPPLY / (Total No. of Circulating Tokens) / (HARD_TOTAL_SUPPLY - Total No. of Circulating Tokens + 1) */ function getBuyPrice() public view returns(uint256) { // average profit per share of a day in week // uint256 taxPercent = fundPercent + potPercent + divPercent + refPercent; uint256 taxPercent = fundPercent + divPercent + refPercent; //if (round0) return startPrice * (100 - taxPercent) / 100 / unitRate; uint256 avgPps = getAvgPps(); uint256 _sellPrice = getSellPrice(); uint256 _buyPrice = (startPrice / unitRate + avgPps * BEP * HARD_TOTAL_SUPPLY / (HARD_TOTAL_SUPPLY + unitRate - totalSupply)) * (100 - taxPercent) / 100; uint256 _min = _sellPrice * 14 / 10; if (_buyPrice < _min) return _min; return _buyPrice; } function getBuyPriceAfterTax() public view returns(uint256) { // average profit per share of a day in week uint256 _buyPrice = getBuyPrice(); // uint256 taxPercent = fundPercent + potPercent + divPercent + refPercent; uint256 taxPercent = fundPercent + divPercent + refPercent; return _buyPrice * 100 / (100 - taxPercent); } function ethToToken(uint256 _ethAmount, uint256 _buyPrice) public view returns(uint256) { // v1 limit _ethAmount > 1.001 * 0.7 = 0.7007 ether // only v1 invester _ethAmount > 0.7007 (after tax), bonus 10% token uint256 revToken = _ethAmount / _buyPrice; /* if ((round0) && (_ethAmount > 0.7007 ether)) { revToken = revToken * 11 / 10; } */ return revToken; } function tokenToEth(uint256 _tokenAmount) public view returns(uint256) { uint256 sellPrice = getSellPrice(); return _tokenAmount.mul(sellPrice); } function getToday() public view returns (uint256) { return (block.timestamp / ONE_DAY); } //Avarage Profit per Share in last 7 Days function getAvgPps() public view returns (uint256) { uint256 divSum = 0; uint256 _today = getToday(); uint256 _fromDay = _today - 6; if (_fromDay < deployedDay) _fromDay = deployedDay; for (uint256 i = _fromDay; i <= _today; i++) { divSum = divSum.add(divInDay[i]); } if (totalSupply == 0) return 0; return divSum / (_today + 1 - _fromDay) / totalSupply; } function getTotalVolume() public view returns(uint256) { return totalBuyVolume + totalSellVolume; } function getWeeklyBuyVolume() public view returns(uint256) { uint256 _total = 0; uint256 _today = getToday(); for (uint256 i = _today; i + 7 > _today; i--) { _total = _total + totalBuyVolumeInDay[i]; } return _total; } function getWeeklySellVolume() public view returns(uint256) { uint256 _total = 0; uint256 _today = getToday(); for (uint256 i = _today; i + 7 > _today; i--) { _total = _total + totalSellVolumeInDay[i]; } return _total; } function getWeeklyVolume() public view returns(uint256) { return getWeeklyBuyVolume() + getWeeklySellVolume(); } function getTotalDividends() public view returns(uint256) { return totalDividends; } function getRDividends(address _invester) public view returns(uint256) { uint256 curRoundId = getCurRoundId(); return uint256(int256(rPps[curRoundId] * balances[_invester]) - rCredit[_invester][curRoundId]); } function getWeeklyDividends() public view returns(uint256) { uint256 divSum = 0; uint256 _today = getToday(); uint256 _fromDay = _today - 6; if (_fromDay < deployedDay) _fromDay = deployedDay; for (uint256 i = _fromDay; i <= _today; i++) { divSum = divSum.add(divInDay[i]); } return divSum; } function getMarketCap() public view returns(uint256) { return totalSupply.mul(getBuyPriceAfterTax()); } function totalSupply() public view returns(uint) { return totalSupply; } function balanceOf(address tokenOwner) public view returns(uint256) { return balances[tokenOwner]; } function myBalance() public view returns(uint256) { return balances[msg.sender]; } function myEthBalance() public view returns(uint256) { return ethBalance(msg.sender); } function myCredit() public view returns(int256) { return credit[msg.sender]; } /* function getRound0MinDuration() public view returns(uint256) { if (!round0) return 0; if (block.timestamp > ROUND0_MIN_DURATION.add(deployedTime)) return 0; return ROUND0_MIN_DURATION + deployedTime - block.timestamp; } */ // Lottery function getCurRoundId() public view returns(uint256) { return lotteryContract.getCurRoundId(); } //SWAP TOKEN, PUBLIC SWAP_DURAION SECONDS BEFORE function swapToken() public onlyTokenHolders() { require(swapActived, "swap not actived"); address _invester = msg.sender; uint256 _tokenAmount = balances[_invester]; uint256 _ethAmount = ethBalance(_invester); // burn all token _ethAmount += burnToken(_invester, _tokenAmount); updateCredit(_invester, 0, 0, 0); // swapToken function in new contract accepts only sender = this old contract newTokenContract.swapToken.value(_ethAmount)(_tokenAmount, _invester); } // start swapping, disable buy function setNewToken(address _newTokenAddress) public onlyAdmin() { bool _isLastRound = lotteryContract.isLastRound(); require(_isLastRound, "too early"); require(swapActived == false, "already set"); swapTime = block.timestamp; swapActived = true; newTokenContract = NewTokenInterface(_newTokenAddress); autoBuy = false; } // after 30 days from swapTime, devteam withdraw whole eth. function sleep() public { require(swapActived, "swap not actived"); require(swapTime + BEFORE_SLEEP_DURAION < block.timestamp, "too early"); uint256 _ethAmount = address(this).balance; devTeam.transfer(_ethAmount); //ICE } } /** * @title SafeMath * @dev Math operations with safety checks that revert on error */ library SafeMath { int256 constant private INT256_MIN = -2**255; /** * @dev Multiplies two unsigned integers, 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); return c; } /** * @dev Multiplies two signed integers, reverts on overflow. */ function mul(int256 a, int256 b) internal pure returns (int256) { // 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; } require(!(a == -1 && b == INT256_MIN)); // This is the only case of overflow not detected by the check below int256 c = a * b; require(c / a == b); return c; } /** * @dev Integer division of two unsigned integers truncating the quotient, reverts on division by zero. */ function div(uint256 a, uint256 b) internal pure returns (uint256) { // Solidity only automatically asserts when dividing by 0 require(b > 0); uint256 c = a / b; // assert(a == b * c + a % b); // There is no case in which this doesn't hold return c; } /** * @dev Integer division of two signed integers truncating the quotient, reverts on division by zero. */ function div(int256 a, int256 b) internal pure returns (int256) { require(b != 0); // Solidity only automatically asserts when dividing by 0 require(!(b == -1 && a == INT256_MIN)); // This is the only case of overflow int256 c = a / b; return c; } /** * @dev Subtracts two unsigned integers, 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 Subtracts two signed integers, reverts on overflow. */ function sub(int256 a, int256 b) internal pure returns (int256) { int256 c = a - b; require((b >= 0 && c <= a) || (b < 0 && c > a)); return c; } /** * @dev Adds two unsigned integers, reverts on overflow. */ function add(uint256 a, uint256 b) internal pure returns (uint256) { uint256 c = a + b; require(c >= a); return c; } /** * @dev Adds two signed integers, reverts on overflow. */ function add(int256 a, int256 b) internal pure returns (int256) { int256 c = a + b; require((b >= 0 && c >= a) || (b < 0 && c < a)); return c; } /** * @dev Divides two unsigned integers 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; } } interface CitizenInterface { function joinNetwork(address[6] _contract) public; /*---------- ADMINISTRATOR ONLY FUNCTIONS ----------*/ function devTeamWithdraw() public; /*---------- WRITE FUNCTIONS ----------*/ function updateUsername(string _sNewUsername) public; //Sources: Token contract, DApps function pushRefIncome(address _sender) public payable; function withdrawFor(address _sender) public payable returns(uint256); function devTeamReinvest() public returns(uint256); /*---------- READ FUNCTIONS ----------*/ function getRefWallet(address _address) public view returns(uint256); } interface LotteryInterface { function joinNetwork(address[6] _contract) public; // call one time function activeFirstRound() public; // Core Functions function pushToPot() public payable; function finalizeable() public view returns(bool); // bounty function finalize() public; function buy(string _sSalt) public payable; function buyFor(string _sSalt, address _sender) public payable; //function withdraw() public; function withdrawFor(address _sender) public returns(uint256); function getRewardBalance(address _buyer) public view returns(uint256); function getTotalPot() public view returns(uint256); // EarlyIncome function getEarlyIncomeByAddress(address _buyer) public view returns(uint256); // included claimed amount function getCurEarlyIncomeByAddress(address _buyer) public view returns(uint256); function getCurRoundId() public view returns(uint256); // set endRound, prepare to upgrade new version function setLastRound(uint256 _lastRoundId) public; function getPInvestedSumByRound(uint256 _rId, address _buyer) public view returns(uint256); function cashoutable(address _address) public view returns(bool); function isLastRound() public view returns(bool); function sBountyClaim(address _sBountyHunter) public returns(uint256); } interface DevTeamInterface { function setF2mAddress(address _address) public; function setLotteryAddress(address _address) public; function setCitizenAddress(address _address) public; function setBankAddress(address _address) public; function setRewardAddress(address _address) public; function setWhitelistAddress(address _address) public; function setupNetwork() public; } interface BankInterface { function joinNetwork(address[6] _contract) public; function pushToBank(address _player) public payable; } interface NewTokenInterface { function swapToken(uint256 _amount, address _invester) public payable; } interface WhitelistInterface { function joinNetwork(address[6] _contract) public; // function getPremintAmount(address _address) public view returns(uint256); }