/*
SPDX-License-Identifier: MIT
A Bankteller Production
Bankroll Network
Copyright 2020
*/
pragma solidity ^0.4.25;
/**
* @title Ownable
* @dev The Ownable contract has an owner address, and provides basic authorization control
* functions, this simplifies the implementation of "user permissions".
*/
contract Ownable {
address public owner;
event OwnershipTransferred(
address indexed previousOwner,
address indexed newOwner
);
/**
* @dev The Ownable constructor sets the original `owner` of the contract to the sender
* account.
*/
constructor() public {
owner = msg.sender;
}
/**
* @dev Throws if called by any account other than the owner.
*/
modifier onlyOwner() {
require(msg.sender == owner, "Not current owner");
_;
}
/**
* @dev Allows the current owner to transfer control of the contract to a newOwner.
* @param newOwner The address to transfer ownership to.
*/
function transferOwnership(address newOwner) public onlyOwner {
require(newOwner != address(0), "Non-zero address required");
emit OwnershipTransferred(owner, newOwner);
owner = newOwner;
}
}
contract Token {
function approve(address spender, uint256 value) public returns (bool);
function transferFrom(
address from,
address to,
uint256 value
) public returns (bool);
function transfer(address to, uint256 value) public returns (bool);
function balanceOf(address who) public view returns (uint256);
}
contract UniSwapV2LiteRouter {
//function ethToTokenSwapInput(uint256 min_tokens) public payable returns (uint256);
function WETH() external pure returns (address);
function swapExactTokensForTokens(
uint256 amountIn,
uint256 amountOutMin,
address[] path,
address to,
uint256 deadline
) external returns (uint256[] amounts);
function swapExactETHForTokens(
uint256 amountOutMin,
address[] path,
address to,
uint256 deadline
) external payable returns (uint256[] amounts);
function getAmountsOut(uint256 amountIn, address[] path)
external
view
returns (uint256[] amounts);
}
/*
* @dev Moon is a perpetual rewards contract
*/
contract BankrollNetworkMoon is Ownable {
using SafeMath for uint256;
/*=================================
= MODIFIERS =
=================================*/
/// @dev Only people with tokens
modifier onlyBagholders {
require(myTokens() > 0, "Insufficient tokens");
_;
}
/// @dev Only people with profits
modifier onlyStronghands {
require(myDividends() > 0, "Insufficient dividends");
_;
}
/*==============================
= EVENTS =
==============================*/
event onLeaderBoard(
address indexed customerAddress,
uint256 invested,
uint256 tokens,
uint256 soldTokens,
uint256 timestamp
);
event onTokenPurchase(
address indexed customerAddress,
uint256 incomingeth,
uint256 tokensMinted,
uint256 timestamp
);
event onTokenSell(
address indexed customerAddress,
uint256 tokensBurned,
uint256 ethEarned,
uint256 timestamp
);
event onReinvestment(
address indexed customerAddress,
uint256 ethReinvested,
uint256 tokensMinted,
uint256 timestamp
);
event onWithdraw(
address indexed customerAddress,
uint256 ethWithdrawn,
uint256 timestamp
);
event onClaim(
address indexed customerAddress,
uint256 tokens,
uint256 timestamp
);
event onTransfer(
address indexed from,
address indexed to,
uint256 tokens,
uint256 timestamp
);
event onUpdateIntervals(uint256 payout, uint256 fund);
event onCollateraltoReward(
uint256 collateralAmount,
uint256 rewardAmount,
uint256 timestamp
);
event onEthtoCollateral(
uint256 ethAmount,
uint256 tokenAmount,
uint256 timestamp
);
event onRewardtoCollateral(
uint256 ethAmount,
uint256 tokenAmount,
uint256 timestamp
);
event onBalance(uint256 balance, uint256 rewardBalance, uint256 timestamp);
event onDonation(address indexed from, uint256 amount, uint256 timestamp);
event onRouterUpdate(address oldAddress, address newAddress);
event onFlushUpdate(uint256 oldFlushSize, uint256 newFlushSize);
// Onchain Stats!!!
struct Stats {
uint256 invested;
uint256 reinvested;
uint256 withdrawn;
uint256 rewarded;
uint256 contributed;
uint256 transferredTokens;
uint256 receivedTokens;
uint256 xInvested;
uint256 xReinvested;
uint256 xRewarded;
uint256 xContributed;
uint256 xWithdrawn;
uint256 xTransferredTokens;
uint256 xReceivedTokens;
}
/*=====================================
= CONFIGURABLES =
=====================================*/
/// @dev 15% dividends for token purchase
uint8 internal constant entryFee_ = 10;
/// @dev 5% dividends for token selling
uint8 internal constant exitFee_ = 10;
uint8 internal constant instantFee = 20;
uint8 constant payoutRate_ = 2;
uint256 internal constant magnitude = 2**64;
/*=================================
= DATASETS =
================================*/
// amount of shares for each address (scaled number)
mapping(address => uint256) private tokenBalanceLedger_;
mapping(address => int256) private payoutsTo_;
mapping(address => Stats) private stats;
//on chain referral tracking
uint256 private tokenSupply_;
uint256 private profitPerShare_;
uint256 public totalDeposits;
uint256 internal lastBalance_;
uint256 public players;
uint256 public totalTxs;
uint256 public collateralBuffer_;
uint256 public lastPayout;
uint256 public lastFunding;
uint256 public totalClaims;
uint256 public balanceInterval = 6 hours;
uint256 public payoutInterval = 2 seconds;
uint256 public fundingInterval = 2 seconds;
uint256 public flushSize = 0.00000000001 ether;
address public swapAddress;
address public rewardAddress;
address public collateralAddress;
Token private rewardToken;
Token private collateralToken;
UniSwapV2LiteRouter private swap;
/*=======================================
= PUBLIC FUNCTIONS =
=======================================*/
constructor(
address _collateralAddress,
address _rewardAddress,
address _swapAddress
) public Ownable() {
rewardAddress = _rewardAddress;
rewardToken = Token(_rewardAddress);
collateralAddress = _collateralAddress;
collateralToken = Token(_collateralAddress);
swapAddress = _swapAddress;
swap = UniSwapV2LiteRouter(_swapAddress);
lastPayout = now;
lastFunding = now;
}
/// @dev Converts all incoming eth to tokens for the caller, and passes down the referral addy (if any)
function buy() public payable returns (uint256) {
return buyFor(msg.sender);
}
/// @dev Converts all incoming eth to tokens for the caller, and passes down the referral addy (if any)
function buyFor(address _customerAddress) public payable returns (uint256) {
require(msg.value > 0, "Non-zero amount required");
//Convert ETH to collateral
uint256 _buy_amount = ethToCollateral(msg.value);
totalDeposits += _buy_amount;
uint256 amount = purchaseTokens(_customerAddress, _buy_amount);
emit onLeaderBoard(
_customerAddress,
stats[_customerAddress].invested,
tokenBalanceLedger_[_customerAddress],
stats[_customerAddress].withdrawn,
now
);
//distribute
distribute();
return amount;
}
/**
* @dev Fallback function to handle eth that was send straight to the contract
* Unfortunately we cannot use a referral address this way.
*/
function() public payable {
//Just bounce
require(false, "This contract does not except ETH");
}
/// @dev Converts all of caller's dividends to tokens.
function reinvest() public onlyStronghands {
// fetch dividends
uint256 _dividends = myDividends();
// retrieve ref. bonus later in the code
// pay out the dividends virtually
address _customerAddress = msg.sender;
payoutsTo_[_customerAddress] += (int256)(_dividends * magnitude);
// dispatch a buy order with the virtualized "withdrawn dividends"
uint256 _tokens = purchaseTokens(msg.sender, _dividends);
// fire event
emit onReinvestment(_customerAddress, _dividends, _tokens, now);
//Stats
stats[_customerAddress].reinvested = SafeMath.add(
stats[_customerAddress].reinvested,
_dividends
);
stats[_customerAddress].xReinvested += 1;
emit onLeaderBoard(
_customerAddress,
stats[_customerAddress].invested,
tokenBalanceLedger_[_customerAddress],
stats[_customerAddress].withdrawn,
now
);
//distribute
distribute();
}
/// @dev Withdraws all of the callers earnings.
function withdraw() public onlyStronghands {
// setup data
address _customerAddress = msg.sender;
uint256 _dividends = myDividends();
// update dividend tracker
payoutsTo_[_customerAddress] += (int256)(_dividends * magnitude);
// lambo delivery service
collateralToken.transfer(_customerAddress, _dividends);
//stats
stats[_customerAddress].withdrawn = SafeMath.add(
stats[_customerAddress].withdrawn,
_dividends
);
stats[_customerAddress].xWithdrawn += 1;
totalTxs += 1;
// fire event
emit onWithdraw(_customerAddress, _dividends, now);
//distribute
distribute();
}
/// @dev Liquifies STCK to collateral tokens.
function sell(uint256 _amountOfTokens) public onlyBagholders {
// setup data
address _customerAddress = msg.sender;
require(
_amountOfTokens <= tokenBalanceLedger_[_customerAddress],
"Amount of tokens is greater than balance"
);
// data setup
uint256 _undividedDividends = SafeMath.mul(_amountOfTokens, exitFee_) /
100;
uint256 _taxedeth = SafeMath.sub(_amountOfTokens, _undividedDividends);
// burn the sold tokens
tokenSupply_ = SafeMath.sub(tokenSupply_, _amountOfTokens);
tokenBalanceLedger_[_customerAddress] = SafeMath.sub(
tokenBalanceLedger_[_customerAddress],
_amountOfTokens
);
// update dividends tracker
int256 _updatedPayouts = (int256)(
profitPerShare_ * _amountOfTokens + (_taxedeth * magnitude)
);
payoutsTo_[_customerAddress] -= _updatedPayouts;
//drip and buybacks applied after supply is updated
allocateFees(_undividedDividends);
// fire event
emit onTokenSell(_customerAddress, _amountOfTokens, _taxedeth, now);
emit onLeaderBoard(
_customerAddress,
stats[_customerAddress].invested,
tokenBalanceLedger_[_customerAddress],
stats[_customerAddress].withdrawn,
now
);
//distribute
distribute();
}
/**
* @dev Transfer tokens from the caller to a new holder.
* Zero fees
*/
function transfer(address _toAddress, uint256 _amountOfTokens)
external
onlyBagholders
returns (bool)
{
// setup
address _customerAddress = msg.sender;
// make sure we have the requested tokens
require(
_amountOfTokens <= tokenBalanceLedger_[_customerAddress],
"Amount of tokens is greater than balance"
);
// withdraw all outstanding dividends first
if (myDividends() > 0) {
withdraw();
}
// exchange tokens
tokenBalanceLedger_[_customerAddress] = SafeMath.sub(
tokenBalanceLedger_[_customerAddress],
_amountOfTokens
);
tokenBalanceLedger_[_toAddress] = SafeMath.add(
tokenBalanceLedger_[_toAddress],
_amountOfTokens
);
// update dividend trackers
payoutsTo_[_customerAddress] -= (int256)(
profitPerShare_ * _amountOfTokens
);
payoutsTo_[_toAddress] += (int256)(profitPerShare_ * _amountOfTokens);
/* Members
A player can be initialized by buying or receiving and we want to add the user ASAP
*/
if (
stats[_toAddress].invested == 0 &&
stats[_toAddress].receivedTokens == 0
) {
players += 1;
}
//Stats
stats[_customerAddress].xTransferredTokens += 1;
stats[_customerAddress].transferredTokens += _amountOfTokens;
stats[_toAddress].receivedTokens += _amountOfTokens;
stats[_toAddress].xReceivedTokens += 1;
totalTxs += 1;
// fire event
emit onTransfer(_customerAddress, _toAddress, _amountOfTokens, now);
emit onLeaderBoard(
_customerAddress,
stats[_customerAddress].invested,
tokenBalanceLedger_[_customerAddress],
stats[_customerAddress].withdrawn,
now
);
emit onLeaderBoard(
_toAddress,
stats[_toAddress].invested,
tokenBalanceLedger_[_toAddress],
stats[_toAddress].withdrawn,
now
);
// ERC20
return true;
}
/*=====================================
= HELPERS AND CALCULATORS =
=====================================*/
/**
* @dev Method to view the current collateral stored in the contract
*/
function totalTokenBalance() public view returns (uint256) {
return collateralToken.balanceOf(address(this));
}
/**
* @dev Method to view the current collateral stored in the contract
*/
function totalRewardTokenBalance() public view returns (uint256) {
return rewardToken.balanceOf(address(this));
}
/// @dev Retrieve the total token supply.
function totalSupply() public view returns (uint256) {
return tokenSupply_;
}
/// @dev Retrieve the tokens owned by the caller.
function myTokens() public view returns (uint256) {
address _customerAddress = msg.sender;
return balanceOf(_customerAddress);
}
/**
* @dev Retrieve the dividends owned by the caller.
*/
function myDividends() public view returns (uint256) {
address _customerAddress = msg.sender;
return dividendsOf(_customerAddress);
}
/// @dev Retrieve the token balance of any single address.
function balanceOf(address _customerAddress) public view returns (uint256) {
return tokenBalanceLedger_[_customerAddress];
}
/// @dev Retrieve the token balance of any single address.
function tokenBalance(address _customerAddress)
public
view
returns (uint256)
{
return _customerAddress.balance;
}
/// @dev Retrieve the dividend balance of any single address.
function dividendsOf(address _customerAddress)
public
view
returns (uint256)
{
return
(uint256)(
(int256)(
profitPerShare_ * tokenBalanceLedger_[_customerAddress]
) - payoutsTo_[_customerAddress]
) / magnitude;
}
/// @dev Return the sell price of 1 individual token.
function sellPrice() public pure returns (uint256) {
uint256 _eth = 1e18;
uint256 _dividends = SafeMath.div(SafeMath.mul(_eth, exitFee_), 100);
uint256 _taxedeth = SafeMath.sub(_eth, _dividends);
return _taxedeth;
}
/// @dev Return the buy price of 1 individual token.
function buyPrice() public pure returns (uint256) {
uint256 _eth = 1e18;
uint256 _dividends = SafeMath.div(SafeMath.mul(_eth, entryFee_), 100);
uint256 _taxedeth = SafeMath.add(_eth, _dividends);
return _taxedeth;
}
/// @dev Function for the frontend to dynamically retrieve the price scaling of buy orders.
function calculateTokensReceived(uint256 _ethToSpend)
public
view
returns (uint256)
{
//Get the amount of the token in ETH and compare to the swapSize
address[] memory path = new address[](2);
path[0] = swap.WETH();
path[1] = collateralAddress;
uint256[] memory amounts = swap.getAmountsOut(_ethToSpend, path);
uint256 _dividends = SafeMath.div(
SafeMath.mul(amounts[1], entryFee_),
100
);
uint256 _taxedeth = SafeMath.sub(amounts[1], _dividends);
uint256 _amountOfTokens = _taxedeth;
return _amountOfTokens;
}
/// @dev Function for the frontend to dynamically retrieve the price scaling of sell orders.
function calculateethReceived(uint256 _tokensToSell)
public
view
returns (uint256)
{
require(
_tokensToSell <= tokenSupply_,
"Tokens to sell greater than supply"
);
uint256 _eth = _tokensToSell;
uint256 _dividends = SafeMath.div(SafeMath.mul(_eth, exitFee_), 100);
uint256 _taxedeth = SafeMath.sub(_eth, _dividends);
return _taxedeth;
}
/// @dev Stats of any single address
function statsOf(address _customerAddress)
public
view
returns (uint256[14] memory)
{
Stats memory s = stats[_customerAddress];
uint256[14] memory statArray = [
s.invested,
s.withdrawn,
s.rewarded,
s.contributed,
s.transferredTokens,
s.receivedTokens,
s.xInvested,
s.xRewarded,
s.xContributed,
s.xWithdrawn,
s.xTransferredTokens,
s.xReceivedTokens,
s.reinvested,
s.xReinvested
];
return statArray;
}
/// @dev Calculate daily estimate of collateral tokens awarded
function dailyEstimate(address _customerAddress)
public
view
returns (uint256)
{
uint256 share = totalRewardTokenBalance().mul(payoutRate_).div(100);
uint256 amount = (tokenSupply_ > 0)
? share.mul(tokenBalanceLedger_[_customerAddress]).div(
tokenSupply_
)
: 0;
if (amount > 0){
address[] memory path = new address[](3);
path[0] = rewardAddress;
path[1] = swap.WETH();
path[2] = collateralAddress;
uint256[] memory amounts = swap.getAmountsOut(amount, path);
return amounts[2];
}
return 0;
}
/*==========================================
= INTERNAL FUNCTIONS =
==========================================*/
/// @dev Distribute undividend in and out fees across drip pools and instant divs
function allocateFees(uint256 fee) private {
uint256 _share = fee.div(100);
uint256 _instant = _share.mul(instantFee);
uint256 _collateral = fee.safeSub(_instant);
//Apply divs
profitPerShare_ = SafeMath.add(
profitPerShare_,
(_instant * magnitude) / tokenSupply_
);
//Add to dividend drip pools
collateralBuffer_ += _collateral;
}
// @dev Distribute drip pools
function distribute() private {
if (now.safeSub(lastBalance_) > balanceInterval) {
emit onBalance(totalTokenBalance(), totalRewardTokenBalance(), now);
lastBalance_ = now;
}
if (now.safeSub(lastPayout) > payoutInterval && totalRewardTokenBalance() > 0) {
//Don't distribute if we don't have sufficient profit
//A portion of the dividend is paid out according to the rate
uint256 share = totalRewardTokenBalance()
.mul(payoutRate_)
.div(100)
.div(24 hours);
//divide the profit by seconds in the day
uint256 profit = share * now.safeSub(lastPayout);
//Get the amount of the token in ETH and compare to the swapSize
address[] memory path = new address[](2);
path[0] = rewardAddress;
path[1] = swap.WETH();
if (profit > 0){
uint256[] memory amounts = swap.getAmountsOut(profit, path);
if (amounts[1] > flushSize) {
profit = rewardToCollateral(profit);
totalClaims += profit;
//Apply reward bonus as collateral bonus divs
profitPerShare_ = SafeMath.add(
profitPerShare_,
(profit * magnitude) / tokenSupply_
);
lastPayout = now;
} else {
fundRewardPool();
}
} else {
fundRewardPool();
}
} else {
fundRewardPool();
}
}
/// @dev Fund reward pool using the router; initial time and size logic gates and orchestration
function fundRewardPool() private {
//Only buy once
if (SafeMath.safeSub(now, lastFunding) >= fundingInterval) {
//Get the amount of the token in ETH and compare to the swapSize
address[] memory path = new address[](2);
path[0] = collateralAddress;
path[1] = swap.WETH();
if (collateralBuffer_ > 0){
uint256[] memory amounts = swap.getAmountsOut(
collateralBuffer_,
path
);
if (amounts[1] >= flushSize) {
uint256 amount = collateralBuffer_;
//reset Collector
collateralBuffer_ = 0;
//reward token buyback; tokens come to address(this) in the rewardsToken
collateralToReward(amount);
lastFunding = now;
}
}
}
}
//Execute the buyback against the router using WETH as a bridge
function collateralToReward(uint256 amount) private returns (uint256) {
address[] memory path = new address[](3);
path[0] = collateralAddress;
path[1] = swap.WETH();
path[2] = rewardAddress;
//Need to be able to approve the collateral token for transfer
require(
collateralToken.approve(swapAddress, amount),
"Amount approved not available"
);
uint256[] memory amounts = swap.swapExactTokensForTokens(
amount,
1,
path,
address(this),
now + 24 hours
);
//2nd index is token amount
emit onCollateraltoReward(amount, amounts[2], now);
return amounts[2];
}
function rewardToCollateral(uint256 amount) private returns (uint256) {
address[] memory path = new address[](3);
path[0] = rewardAddress;
path[1] = swap.WETH();
path[2] = collateralAddress;
//Need to be able to approve the collateral token for transfer
require(
rewardToken.approve(swapAddress, amount),
"Amount approved not available"
);
uint256[] memory amounts = swap.swapExactTokensForTokens(
amount,
1,
path,
address(this),
now + 24 hours
);
//2nd index is token amount
emit onRewardtoCollateral(amount, amounts[2], now);
return amounts[2];
}
/// @dev ETH to tokens
function ethToCollateral(uint256 amount) private returns (uint256) {
address[] memory path = new address[](2);
path[0] = swap.WETH();
path[1] = collateralAddress;
uint256[] memory amounts = swap.swapExactETHForTokens.value(amount)(
1,
path,
address(this),
now + 24 hours
);
//2nd index is token amount
emit onEthtoCollateral(amount, amounts[1], now);
return amounts[1];
}
/// @dev Internal function to actually purchase the tokens.
function purchaseTokens(address _customerAddress, uint256 _incomingtokens)
internal
returns (uint256)
{
/* Members */
if (
stats[_customerAddress].invested == 0 &&
stats[_customerAddress].receivedTokens == 0
) {
players += 1;
}
totalTxs += 1;
// data setup
uint256 _undividedDividends = SafeMath.mul(_incomingtokens, entryFee_) /
100;
uint256 _amountOfTokens = SafeMath.sub(
_incomingtokens,
_undividedDividends
);
// fire event
emit onTokenPurchase(
_customerAddress,
_incomingtokens,
_amountOfTokens,
now
);
// yes we know that the safemath function automatically rules out the "greater then" equation.
require(
_amountOfTokens > 0 &&
SafeMath.add(_amountOfTokens, tokenSupply_) > tokenSupply_,
"Tokens need to be positive"
);
// we can't give people infinite eth
if (tokenSupply_ > 0) {
// add tokens to the pool
tokenSupply_ += _amountOfTokens;
} else {
// add tokens to the pool
tokenSupply_ = _amountOfTokens;
}
// update circulating supply & the ledger address for the customer
tokenBalanceLedger_[_customerAddress] = SafeMath.add(
tokenBalanceLedger_[_customerAddress],
_amountOfTokens
);
// Tells the contract that the buyer doesn't deserve dividends for the tokens before they owned them;
// really i know you think you do but you don't
int256 _updatedPayouts = (int256)(profitPerShare_ * _amountOfTokens);
payoutsTo_[_customerAddress] += _updatedPayouts;
//drip and buybacks; instant requires being called after supply is updated
allocateFees(_undividedDividends);
//Stats
stats[_customerAddress].invested += _incomingtokens;
stats[_customerAddress].xInvested += 1;
return _amountOfTokens;
}
/*==========================================
= ADMIN FUNCTIONS =
==========================================*/
/**
* @dev Update the router address to account for movement in liquidity long term
*/
function updateSwapRouter(address _swapAddress) public onlyOwner() {
emit onRouterUpdate(swapAddress, _swapAddress);
swapAddress = _swapAddress;
swap = UniSwapV2LiteRouter(_swapAddress);
}
/**
* @dev Update the flushSize (how often buy backs happen in terms of amount of ETH accumulated)
*/
function updateFlushSize(uint256 _flushSize) public onlyOwner() {
require(
_flushSize >= 0.01 ether && _flushSize <= 5 ether,
"Flush size is out of range"
);
emit onFlushUpdate(flushSize, _flushSize);
flushSize = _flushSize;
}
/**
* @dev Update Intervals
*/
function updateIntervals(uint256 _payout, uint256 _fund)
public
onlyOwner()
{
require(
_payout >= 2 seconds && _payout <= 24 hours,
"Interval out of range"
);
require(
_fund >= 2 seconds && _fund <= 24 hours,
"Interval out of range"
);
payoutInterval = _payout;
fundingInterval = _fund;
emit onUpdateIntervals(_payout, _fund);
}
}
/**
* @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 c) {
if (a == 0) {
return 0;
}
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 a / b;
}
/**
* @dev Subtracts 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 Subtracts two numbers, else returns zero */
function safeSub(uint256 a, uint256 b) internal pure returns (uint256) {
if (b > a) {
return 0;
} else {
return a - b;
}
}
/**
* @dev Adds two numbers, throws on overflow.
*/
function add(uint256 a, uint256 b) internal pure returns (uint256 c) {
c = a + b;
assert(c >= a);
return c;
}
function max(uint256 a, uint256 b) internal pure returns (uint256) {
return a >= b ? a : b;
}
function min(uint256 a, uint256 b) internal pure returns (uint256) {
return a < b ? a : b;
}
}
{
"compilationTarget": {
"BankrollNetworkMoon.sol": "BankrollNetworkMoon"
},
"evmVersion": "byzantium",
"libraries": {},
"optimizer": {
"enabled": true,
"runs": 200
},
"remappings": []
}
[{"constant":true,"inputs":[{"name":"_customerAddress","type":"address"}],"name":"dividendsOf","outputs":[{"name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"payoutInterval","outputs":[{"name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"name":"_ethToSpend","type":"uint256"}],"name":"calculateTokensReceived","outputs":[{"name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"name":"_customerAddress","type":"address"}],"name":"statsOf","outputs":[{"name":"","type":"uint256[14]"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"totalSupply","outputs":[{"name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"myDividends","outputs":[{"name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"collateralBuffer_","outputs":[{"name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[],"name":"withdraw","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[],"name":"totalTokenBalance","outputs":[{"name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"totalClaims","outputs":[{"name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"collateralAddress","outputs":[{"name":"","type":"address"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"sellPrice","outputs":[{"name":"","type":"uint256"}],"payable":false,"stateMutability":"pure","type":"function"},{"constant":true,"inputs":[],"name":"totalTxs","outputs":[{"name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"totalRewardTokenBalance","outputs":[{"name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"name":"_customerAddress","type":"address"}],"name":"buyFor","outputs":[{"name":"","type":"uint256"}],"payable":true,"stateMutability":"payable","type":"function"},{"constant":false,"inputs":[{"name":"_flushSize","type":"uint256"}],"name":"updateFlushSize","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[{"name":"_customerAddress","type":"address"}],"name":"balanceOf","outputs":[{"name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"totalDeposits","outputs":[{"name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"swapAddress","outputs":[{"name":"","type":"address"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"buyPrice","outputs":[{"name":"","type":"uint256"}],"payable":false,"stateMutability":"pure","type":"function"},{"constant":false,"inputs":[{"name":"_payout","type":"uint256"},{"name":"_fund","type":"uint256"}],"name":"updateIntervals","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[],"name":"rewardAddress","outputs":[{"name":"","type":"address"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"owner","outputs":[{"name":"","type":"address"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"name":"_tokensToSell","type":"uint256"}],"name":"calculateethReceived","outputs":[{"name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"myTokens","outputs":[{"name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"fundingInterval","outputs":[{"name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[],"name":"buy","outputs":[{"name":"","type":"uint256"}],"payable":true,"stateMutability":"payable","type":"function"},{"constant":false,"inputs":[{"name":"_toAddress","type":"address"},{"name":"_amountOfTokens","type":"uint256"}],"name":"transfer","outputs":[{"name":"","type":"bool"}],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"name":"_swapAddress","type":"address"}],"name":"updateSwapRouter","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[],"name":"lastPayout","outputs":[{"name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"players","outputs":[{"name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"name":"_amountOfTokens","type":"uint256"}],"name":"sell","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[{"name":"_customerAddress","type":"address"}],"name":"tokenBalance","outputs":[{"name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"name":"newOwner","type":"address"}],"name":"transferOwnership","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[{"name":"_customerAddress","type":"address"}],"name":"dailyEstimate","outputs":[{"name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"balanceInterval","outputs":[{"name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"flushSize","outputs":[{"name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"lastFunding","outputs":[{"name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[],"name":"reinvest","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"inputs":[{"name":"_collateralAddress","type":"address"},{"name":"_rewardAddress","type":"address"},{"name":"_swapAddress","type":"address"}],"payable":false,"stateMutability":"nonpayable","type":"constructor"},{"payable":true,"stateMutability":"payable","type":"fallback"},{"anonymous":false,"inputs":[{"indexed":true,"name":"customerAddress","type":"address"},{"indexed":false,"name":"invested","type":"uint256"},{"indexed":false,"name":"tokens","type":"uint256"},{"indexed":false,"name":"soldTokens","type":"uint256"},{"indexed":false,"name":"timestamp","type":"uint256"}],"name":"onLeaderBoard","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"name":"customerAddress","type":"address"},{"indexed":false,"name":"incomingeth","type":"uint256"},{"indexed":false,"name":"tokensMinted","type":"uint256"},{"indexed":false,"name":"timestamp","type":"uint256"}],"name":"onTokenPurchase","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"name":"customerAddress","type":"address"},{"indexed":false,"name":"tokensBurned","type":"uint256"},{"indexed":false,"name":"ethEarned","type":"uint256"},{"indexed":false,"name":"timestamp","type":"uint256"}],"name":"onTokenSell","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"name":"customerAddress","type":"address"},{"indexed":false,"name":"ethReinvested","type":"uint256"},{"indexed":false,"name":"tokensMinted","type":"uint256"},{"indexed":false,"name":"timestamp","type":"uint256"}],"name":"onReinvestment","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"name":"customerAddress","type":"address"},{"indexed":false,"name":"ethWithdrawn","type":"uint256"},{"indexed":false,"name":"timestamp","type":"uint256"}],"name":"onWithdraw","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"name":"customerAddress","type":"address"},{"indexed":false,"name":"tokens","type":"uint256"},{"indexed":false,"name":"timestamp","type":"uint256"}],"name":"onClaim","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"name":"from","type":"address"},{"indexed":true,"name":"to","type":"address"},{"indexed":false,"name":"tokens","type":"uint256"},{"indexed":false,"name":"timestamp","type":"uint256"}],"name":"onTransfer","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"name":"payout","type":"uint256"},{"indexed":false,"name":"fund","type":"uint256"}],"name":"onUpdateIntervals","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"name":"collateralAmount","type":"uint256"},{"indexed":false,"name":"rewardAmount","type":"uint256"},{"indexed":false,"name":"timestamp","type":"uint256"}],"name":"onCollateraltoReward","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"name":"ethAmount","type":"uint256"},{"indexed":false,"name":"tokenAmount","type":"uint256"},{"indexed":false,"name":"timestamp","type":"uint256"}],"name":"onEthtoCollateral","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"name":"ethAmount","type":"uint256"},{"indexed":false,"name":"tokenAmount","type":"uint256"},{"indexed":false,"name":"timestamp","type":"uint256"}],"name":"onRewardtoCollateral","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"name":"balance","type":"uint256"},{"indexed":false,"name":"rewardBalance","type":"uint256"},{"indexed":false,"name":"timestamp","type":"uint256"}],"name":"onBalance","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"name":"from","type":"address"},{"indexed":false,"name":"amount","type":"uint256"},{"indexed":false,"name":"timestamp","type":"uint256"}],"name":"onDonation","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"name":"oldAddress","type":"address"},{"indexed":false,"name":"newAddress","type":"address"}],"name":"onRouterUpdate","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"name":"oldFlushSize","type":"uint256"},{"indexed":false,"name":"newFlushSize","type":"uint256"}],"name":"onFlushUpdate","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"name":"previousOwner","type":"address"},{"indexed":true,"name":"newOwner","type":"address"}],"name":"OwnershipTransferred","type":"event"}]