Contract Source Code:
File 1 of 1 : _8thereum
pragma solidity ^0.4.24;
contract _8thereum {
/*=================================
= MODIFIERS =
=================================*/
// only people with tokens
modifier onlyTokenHolders()
{
require(myTokens() > 0);
_;
}
// only people with profits
modifier onlyDividendPositive()
{
require(myDividends(true) > 0);
_;
}
// only owner
modifier onlyOwner()
{
require (address(msg.sender) == owner);
_;
}
// only non-whales
modifier onlyNonOwner()
{
require (address(msg.sender) != owner);
_;
}
modifier onlyFoundersIfNotPublic()
{
if(!openToThePublic)
{
require (founders[address(msg.sender)] == true);
}
_;
}
modifier onlyApprovedContracts()
{
if(!gameList[msg.sender])
{
require (msg.sender == tx.origin);
}
_;
}
/*==============================
= EVENTS =
==============================*/
event onTokenPurchase(
address indexed customerAddress,
uint256 incomingEthereum,
uint256 tokensMinted,
address indexed referredBy
);
event onTokenSell(
address indexed customerAddress,
uint256 tokensBurned,
uint256 ethereumEarned
);
event onReinvestment(
address indexed customerAddress,
uint256 ethereumReinvested,
uint256 tokensMinted
);
event onWithdraw(
address indexed customerAddress,
uint256 ethereumWithdrawn
);
event lotteryPayout(
address customerAddress,
uint256 lotterySupply
);
event whaleDump(
uint256 amount
);
// ERC20
event Transfer(
address indexed from,
address indexed to,
uint256 tokens
);
/*=====================================
= CONFIGURABLES =
=====================================*/
string public name = "8thereum";
string public symbol = "BIT";
bool public openToThePublic = false;
address public owner;
uint8 constant public decimals = 18;
uint8 constant internal dividendFee = 15;
uint256 constant internal tokenPrice = 500000000000000;//0.0005 ether
uint256 constant internal magnitude = 2**64;
uint256 constant public referralLinkRequirement = 5e18;// 5 token minimum for referral link
/*================================
= DATASETS =
================================*/
mapping(address => bool) internal gameList;
mapping(address => uint256) internal publicTokenLedger;
mapping(address => uint256) public whaleLedger;
mapping(address => uint256) public gameLedger;
mapping(address => uint256) internal referralBalances;
mapping(address => int256) internal payoutsTo_;
mapping(address => mapping(address => uint256)) public gamePlayers;
mapping(address => bool) internal founders;
address[] lotteryPlayers;
uint256 internal lotterySupply = 0;
uint256 internal tokenSupply = 0;
uint256 internal gameSuppply = 0;
uint256 internal profitPerShare_;
/*=======================================
= PUBLIC FUNCTIONS =
=======================================*/
/*
* -- APPLICATION ENTRY POINTS --
*/
constructor()
public
{
// no admin, but the owner of the contract is the address used for whale
owner = address(msg.sender);
// add founders here... Founders don't get any special priveledges except being first in line at launch day
founders[owner] = true; //owner's address
founders[0x7e474fe5Cfb720804860215f407111183cbc2f85] = true; //KENNY
founders[0x5138240E96360ad64010C27eB0c685A8b2eDE4F2] = true; //crypt0b!t
founders[0xAA7A7C2DECB180f68F11E975e6D92B5Dc06083A6] = true; //NumberOfThings
founders[0x6DC622a04Fd13B6a1C3C5B229CA642b8e50e1e74] = true; //supermanlxvi
founders[0x41a21b264F9ebF6cF571D4543a5b3AB1c6bEd98C] = true; //Ravi
}
/**
* Converts all incoming ethereum to tokens for the caller, and passes down the referral address
*/
function buy(address referredyBy)
onlyFoundersIfNotPublic()
public
payable
returns(uint256)
{
require (msg.sender == tx.origin);
excludeWhale(referredyBy);
}
/**
* Fallback function to handle ethereum that was send straight to the contract
*/
function()
onlyFoundersIfNotPublic()
payable
public
{
require (msg.sender == tx.origin);
excludeWhale(0x0);
}
/**
* Converts all of caller's dividends to tokens.
*/
function reinvest()
onlyDividendPositive()
onlyNonOwner()
public
{
require (msg.sender == tx.origin);
// fetch dividends
uint256 dividends = myDividends(false); // retrieve ref. bonus later in the code
// pay out the dividends virtually
address customerAddress = msg.sender;
payoutsTo_[customerAddress] += int256(SafeMath.mul(dividends, magnitude));
// retrieve ref. bonus
dividends += referralBalances[customerAddress];
referralBalances[customerAddress] = 0;
// dispatch a buy order with the virtualized "withdrawn dividends"
uint256 _tokens = purchaseTokens(dividends, 0x0);
// fire event for logging
emit onReinvestment(customerAddress, dividends, _tokens);
}
/**
* Alias of sell() and withdraw().
*/
function exit()
onlyNonOwner()
onlyTokenHolders()
public
{
require (msg.sender == tx.origin);
// get token count for caller & sell them all
address customerAddress = address(msg.sender);
uint256 _tokens = publicTokenLedger[customerAddress];
if(_tokens > 0)
{
sell(_tokens);
}
withdraw();
}
/**
* Withdraws all of the callers earnings.
*/
function withdraw()
onlyNonOwner()
onlyDividendPositive()
public
{
require (msg.sender == tx.origin);
// setup data
address customerAddress = msg.sender;
uint256 dividends = myDividends(false); // get ref. bonus later in the code
// update dividend tracker
payoutsTo_[customerAddress] += int256(SafeMath.mul(dividends, magnitude));
// add ref. bonus
dividends += referralBalances[customerAddress];
referralBalances[customerAddress] = 0;
customerAddress.transfer(dividends);
// fire event for logging
emit onWithdraw(customerAddress, dividends);
}
/**
* Liquifies tokens to ethereum.
*/
function sell(uint256 _amountOfTokens)
onlyNonOwner()
onlyTokenHolders()
public
{
require (msg.sender == tx.origin);
require((_amountOfTokens <= publicTokenLedger[msg.sender]) && (_amountOfTokens > 0));
uint256 _tokens = _amountOfTokens;
uint256 ethereum = tokensToEthereum_(_tokens);
uint256 dividends = (ethereum * dividendFee) / 100;
uint256 taxedEthereum = SafeMath.sub(ethereum, dividends);
//Take some divs for the lottery and whale
uint256 lotteryAndWhaleFee = dividends / 3;
dividends -= lotteryAndWhaleFee;
//figure out the lotteryFee
uint256 lotteryFee = lotteryAndWhaleFee / 2;
//add tokens to the whale
uint256 whaleFee = lotteryAndWhaleFee - lotteryFee;
whaleLedger[owner] += whaleFee;
//add tokens to the lotterySupply
lotterySupply += ethereumToTokens_(lotteryFee);
// burn the sold tokens
tokenSupply -= _tokens;
publicTokenLedger[msg.sender] -= _tokens;
// update dividends tracker
int256 _updatedPayouts = (int256) (profitPerShare_ * _tokens + (taxedEthereum * magnitude));
payoutsTo_[msg.sender] -= _updatedPayouts;
// dividing by zero is a bad idea
if (tokenSupply > 0)
{
// update the amount of dividends per token
profitPerShare_ = SafeMath.add(profitPerShare_, (dividends * magnitude) / tokenSupply);
}
// fire event for logging
emit onTokenSell(msg.sender, _tokens, taxedEthereum);
}
/**
* Transfer tokens from the caller to a new holder.
*/
function transfer(address _toAddress, uint256 _amountOfTokens)
onlyNonOwner()
onlyTokenHolders()
onlyApprovedContracts()
public
returns(bool)
{
assert(_toAddress != owner);
// setup
if(gameList[msg.sender] == true) //If game is transferring tokens
{
require((_amountOfTokens <= gameLedger[msg.sender]) && (_amountOfTokens > 0 ));
// exchange tokens
gameLedger[msg.sender] -= _amountOfTokens;
gameSuppply -= _amountOfTokens;
publicTokenLedger[_toAddress] += _amountOfTokens;
// update dividend trackers
payoutsTo_[_toAddress] += int256(profitPerShare_ * _amountOfTokens);
}
else if (gameList[_toAddress] == true) //If customer transferring tokens to game
{
// make sure we have the requested tokens
//each game should only cost one token to play
require((_amountOfTokens <= publicTokenLedger[msg.sender]) && (_amountOfTokens > 0 && (_amountOfTokens == 1e18)));
// exchange tokens
publicTokenLedger[msg.sender] -= _amountOfTokens;
gameLedger[_toAddress] += _amountOfTokens;
gameSuppply += _amountOfTokens;
gamePlayers[_toAddress][msg.sender] += _amountOfTokens;
// update dividend trackers
payoutsTo_[msg.sender] -= int256(profitPerShare_ * _amountOfTokens);
}
else{
// make sure we have the requested tokens
require((_amountOfTokens <= publicTokenLedger[msg.sender]) && (_amountOfTokens > 0 ));
// exchange tokens
publicTokenLedger[msg.sender] -= _amountOfTokens;
publicTokenLedger[_toAddress] += _amountOfTokens;
// update dividend trackers
payoutsTo_[msg.sender] -= int256(profitPerShare_ * _amountOfTokens);
payoutsTo_[_toAddress] += int256(profitPerShare_ * _amountOfTokens);
}
// fire event for logging
emit Transfer(msg.sender, _toAddress, _amountOfTokens);
// ERC20
return true;
}
/*---------- OWNER ONLY FUNCTIONS ----------*/
/**
* future games can be added so they can't earn divs on their token balances
*/
function setGames(address newGameAddress)
onlyOwner()
public
{
gameList[newGameAddress] = true;
}
/**
* Want to prevent snipers from buying prior to launch
*/
function goPublic()
onlyOwner()
public
returns(bool)
{
openToThePublic = true;
return openToThePublic;
}
/*---------- HELPERS AND CALCULATORS ----------*/
/**
* Method to view the current Ethereum stored in the contract
*/
function totalEthereumBalance()
public
view
returns(uint)
{
return address(this).balance;
}
/**
* Retrieve the total token supply.
*/
function totalSupply()
public
view
returns(uint256)
{
return (tokenSupply + lotterySupply + gameSuppply); //adds the tokens from ambassadors to the supply (but not to the dividends calculation which is based on the supply)
}
/**
* Retrieve the tokens owned by the caller.
*/
function myTokens()
public
view
returns(uint256)
{
return balanceOf(msg.sender);
}
/**
* Retrieve the dividends owned by the caller.
* If `_includeReferralBonus` is to to 1/true, the referral bonus will be included in the calculations.
* The reason for this, is that in the frontend, we will want to get the total divs (global + ref)
* But in the internal calculations, we want them separate.
*/
function myDividends(bool _includeReferralBonus)
public
view
returns(uint256)
{
return _includeReferralBonus ? dividendsOf(msg.sender) + referralBalances[msg.sender] : dividendsOf(msg.sender) ;
}
/**
* Retrieve the token balance of any single address.
*/
function balanceOf(address customerAddress)
view
public
returns(uint256)
{
uint256 balance;
if (customerAddress == owner)
{
// to show div balance of owner
balance = whaleLedger[customerAddress];
}
else if(gameList[customerAddress] == true)
{
// games can still see their token balance
balance = gameLedger[customerAddress];
}
else
{
// to see token balance for anyone else
balance = publicTokenLedger[customerAddress];
}
return balance;
}
/**
* Retrieve the dividend balance of any single address.
*/
function dividendsOf(address customerAddress)
view
public
returns(uint256)
{
return (uint256) ((int256)(profitPerShare_ * publicTokenLedger[customerAddress]) - payoutsTo_[customerAddress]) / magnitude;
}
/**
* Return the buy and sell price of 1 individual token.
*/
function buyAndSellPrice()
public
pure
returns(uint256)
{
uint256 ethereum = tokenPrice;
uint256 dividends = SafeMath.div(SafeMath.mul(ethereum, dividendFee ), 100);
uint256 taxedEthereum = SafeMath.sub(ethereum, dividends);
return taxedEthereum;
}
/**
* Function for the frontend to dynamically retrieve the price of buy orders.
*/
function calculateTokensReceived(uint256 ethereumToSpend)
public
pure
returns(uint256)
{
require(ethereumToSpend >= tokenPrice);
uint256 dividends = SafeMath.div(SafeMath.mul(ethereumToSpend, dividendFee ), 100);
uint256 taxedEthereum = SafeMath.sub(ethereumToSpend, dividends);
uint256 amountOfTokens = ethereumToTokens_(taxedEthereum);
return amountOfTokens;
}
/**
* Function for the frontend to dynamically retrieve the price of sell orders.
*/
function calculateEthereumReceived(uint256 tokensToSell)
public
view
returns(uint256)
{
require(tokensToSell <= tokenSupply);
uint256 ethereum = tokensToEthereum_(tokensToSell);
uint256 dividends = SafeMath.div(SafeMath.mul(ethereum, dividendFee ), 100);
uint256 taxedEthereum = SafeMath.sub(ethereum, dividends);
return taxedEthereum;
}
/*==========================================
= INTERNAL FUNCTIONS =
==========================================*/
function excludeWhale(address referredyBy)
onlyNonOwner()
internal
returns(uint256)
{
require (msg.sender == tx.origin);
uint256 tokenAmount;
tokenAmount = purchaseTokens(msg.value, referredyBy); //redirects to purchaseTokens so same functionality
if(gameList[msg.sender] == true)
{
tokenSupply = SafeMath.sub(tokenSupply, tokenAmount); // takes out game's tokens from the tokenSupply (important for redistribution)
publicTokenLedger[msg.sender] = SafeMath.sub(publicTokenLedger[msg.sender], tokenAmount); // takes out game's tokens from its ledger so it is "officially" holding 0 tokens. (=> doesn't receive dividends anymore)
gameLedger[msg.sender] += tokenAmount; //it gets a special ledger so it can't sell its tokens
gameSuppply += tokenAmount; // we need this for a correct totalSupply() number later
}
return tokenAmount;
}
function purchaseTokens(uint256 incomingEthereum, address referredyBy)
internal
returns(uint256)
{
require (msg.sender == tx.origin);
// data setup
uint256 undividedDivs = SafeMath.div(SafeMath.mul(incomingEthereum, dividendFee ), 100);
//divide the divs
uint256 lotteryAndWhaleFee = undividedDivs / 3;
uint256 referralBonus = lotteryAndWhaleFee;
uint256 dividends = SafeMath.sub(undividedDivs, (referralBonus + lotteryAndWhaleFee));
uint256 taxedEthereum = incomingEthereum - undividedDivs;
uint256 amountOfTokens = ethereumToTokens_(taxedEthereum);
uint256 whaleFee = lotteryAndWhaleFee / 2;
//add divs to whale
whaleLedger[owner] += whaleFee;
//add tokens to the lotterySupply
lotterySupply += ethereumToTokens_(lotteryAndWhaleFee - whaleFee);
//add entry to lottery
lotteryPlayers.push(msg.sender);
uint256 fee = dividends * magnitude;
require(amountOfTokens > 0 && (amountOfTokens + tokenSupply) > tokenSupply);
// is the user referred by a masternode?
if(
// is this a referred purchase?
referredyBy != 0x0000000000000000000000000000000000000000 &&
// no cheating!
referredyBy != msg.sender &&
//can't use games for referralBonus
gameList[referredyBy] == false &&
// does the referrer have at least 5 tokens?
publicTokenLedger[referredyBy] >= referralLinkRequirement
)
{
// wealth redistribution
referralBalances[referredyBy] += referralBonus;
} else
{
// no ref purchase
// add the referral bonus back
dividends += referralBonus;
fee = dividends * magnitude;
}
uint256 payoutDividends = isWhalePaying();
// we can't give people infinite ethereum
if(tokenSupply > 0)
{
// add tokens to the pool
tokenSupply += amountOfTokens;
// take the amount of dividends gained through this transaction, and allocates them evenly to each shareholder
profitPerShare_ += ((payoutDividends + dividends) * magnitude / (tokenSupply));
// calculate the amount of tokens the customer receives over his purchase
fee -= fee-(amountOfTokens * (dividends * magnitude / (tokenSupply)));
} else
{
// add tokens to the pool
tokenSupply = amountOfTokens;
//if there are zero tokens prior to this buy, and the whale is triggered, send dividends back to whale
if(whaleLedger[owner] == 0)
{
whaleLedger[owner] = payoutDividends;
}
}
// update circulating supply & the ledger address for the customer
publicTokenLedger[msg.sender] += amountOfTokens;
// Tells the contract that the buyer doesn't deserve dividends for the tokens before they owned them;
// BUT, you still get the whale's divs from your purchase.... so, you still get SOMETHING.
int256 _updatedPayouts = int256((profitPerShare_ * amountOfTokens) - fee);
payoutsTo_[msg.sender] += _updatedPayouts;
// fire event for logging
emit onTokenPurchase(msg.sender, incomingEthereum, amountOfTokens, referredyBy);
return amountOfTokens;
}
/**
* Calculate token sell value.
* It's a simple algorithm. Hopefully, you don't need a whitepaper with it in scientific notation.
*/
function isWhalePaying()
private
returns(uint256)
{
uint256 payoutDividends = 0;
// this is where we check for lottery winner
if(whaleLedger[owner] >= 1 ether)
{
if(lotteryPlayers.length > 0)
{
uint256 winner = uint256(blockhash(block.number-1))%lotteryPlayers.length;
publicTokenLedger[lotteryPlayers[winner]] += lotterySupply;
emit lotteryPayout(lotteryPlayers[winner], lotterySupply);
tokenSupply += lotterySupply;
lotterySupply = 0;
delete lotteryPlayers;
}
//whale pays out everyone its divs
payoutDividends = whaleLedger[owner];
whaleLedger[owner] = 0;
emit whaleDump(payoutDividends);
}
return payoutDividends;
}
/**
* Calculate Token price based on an amount of incoming ethereum
*It's a simple algorithm. Hopefully, you don't need a whitepaper with it in scientific notation.
*/
function ethereumToTokens_(uint256 ethereum)
internal
pure
returns(uint256)
{
uint256 tokensReceived = ((ethereum / tokenPrice) * 1e18);
return tokensReceived;
}
/**
* Calculate token sell value.
* It's a simple algorithm. Hopefully, you don't need a whitepaper with it in scientific notation.
*/
function tokensToEthereum_(uint256 coin)
internal
pure
returns(uint256)
{
uint256 ethReceived = tokenPrice * (SafeMath.div(coin, 1e18));
return ethReceived;
}
}
/**
* @title SafeMath
* @dev Math operations with safety checks that throw on error
*/
library SafeMath {
/**
* @dev Multiplies two numbers, throws on overflow.
*/
function mul(uint256 a, uint256 b) internal pure returns (uint256) {
if (a == 0) {
return 0;
}
uint256 c = a * b;
assert(c / a == b);
return c;
}
/**
* @dev Integer division of two numbers, truncating the quotient.
*/
function div(uint256 a, uint256 b) internal pure returns (uint256) {
// assert(b > 0); // Solidity automatically throws 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 Substracts two numbers, throws on overflow (i.e. if subtrahend is greater than minuend).
*/
function sub(uint256 a, uint256 b) internal pure returns (uint256) {
assert(b <= a);
return a - b;
}
/**
* @dev Adds two numbers, throws on overflow.
*/
function add(uint256 a, uint256 b) internal pure returns (uint256) {
uint256 c = a + b;
assert(c >= a);
return c;
}
}