/**
* start 11.11.18
*
* ███─█───█─████─████─███─█───█─█───█─█───█───████─████─█───█
* █───██─██─█──█─█──█──█──██─██─██─██─██─██───█──█─█──█─██─██
* ███─█─█─█─████─████──█──█─█─█─█─█─█─█─█─█───█────█──█─█─█─█
* ──█─█───█─█──█─█─█───█──█───█─█───█─█───█───█──█─█──█─█───█
* ███─█───█─█──█─█─█───█──█───█─█───█─█───█─█─████─████─█───█
*
*
* - Contacts:
* -- t/me/Smart_MMM
* -- https://SmartMMM.com
*
* - GAIN PER 24 HOURS:
* -- Contract balance < 25 Ether: 1.0%
* -- Contract balance >= 25 Ether: 1.5%
* -- Contract balance >= 250 Ether: 2.0%
* -- Contract balance >= 2500 Ether: 2.5% max!
* -- Contract balance >= 25000 Ether: 2.0%
* -- Contract balance >= 50000 Ether: 1.5%
* -- Contract balance >= 100000 Ether: 1.0%
* -- Contract balance >= 150000 Ether: 0.8%
* -- Contract balance >= 200000 Ether: 0.6%
* -- Contract balance >= 250000 Ether: 0.4%
* -- Contract balance >= 300000 Ether: 0.2%
* -- Contract balance >= 500000 Ether: 0.1%
*
* -- Contract balance < 30% max Balance: "soft restart"
*
* - Minimal contribution 0.01 eth
*
* - Contribution allocation schemes:
* -- 90-95% payments to depositors and partners
* -- 1-3% technical support team
* -- 3-7% promotion
* depends on the contract balance. more on the website SmartMMM.com
*
* - How to use:
* 1. Send from your personal ETH wallet to the smart-contract address any amount more than or equal to 0.01 ETH
* 2. Add your refferer's wallet to a HEX data in your transaction to
* get a bonus amount back to your wallet
* if there is no referrer, you will not get any bonuses
* 3. Use etherscan.io to verify your transaction
* 4. Claim your dividents by sending 0 ether transaction (available anytime)
* 5. You can reinvest anytime you want
*
* Smart contract has a "soft restart" function, details on smartMMM.com
*
* If you want to check your dividends, you can use etherscan.io site I / o by following the" internal Txns " tab of your wallet
* Attention: do not use wallets exchanges - you will lose your money. Use your personal wallet only for transactions
*
* RECOMMENDED GAS LIMIT: 300000
* RECOMMENDED GAS PRICE: https://ethgasstation.info/
*/
pragma solidity ^0.4.24;
/**
* @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 private _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() internal {
_owner = msg.sender;
emit OwnershipTransferred(address(0), _owner);
}
/**
* @return the address of the owner.
*/
function owner() public view returns(address) {
return _owner;
}
/**
* @dev Throws if called by any account other than the owner.
*/
modifier onlyOwner() {
require(isOwner());
_;
}
/**
* @return true if `msg.sender` is the owner of the contract.
*/
function isOwner() public view returns(bool) {
return msg.sender == _owner;
}
/**
* @dev Allows the current owner to relinquish control of the contract.
* @notice Renouncing to ownership will leave the contract without an owner.
* It will not be possible to call the functions with the `onlyOwner`
* modifier anymore.
*/
function renounceOwnership() public onlyOwner {
emit OwnershipTransferred(_owner, address(0));
_owner = address(0);
}
/**
* @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 {
_transferOwnership(newOwner);
}
/**
* @dev Transfers control of the contract to a newOwner.
* @param newOwner The address to transfer ownership to.
*/
function _transferOwnership(address newOwner) internal {
require(newOwner != address(0));
emit OwnershipTransferred(_owner, newOwner);
_owner = newOwner;
}
}
contract SmartMMM is Ownable
{
struct DepositItem {
uint time;
uint sum;
uint withdrawalTime;
uint restartIndex;
uint invested;
uint payments;
uint referralPayments;
uint cashback;
uint referalsLevelOneCount;
uint referalsLevelTwoCount;
address referrerLevelOne;
address referrerLevelTwo;
}
address public techSupport = 0x799358af628240603A1ce05b7D9ea211b9D64304;
address public adsSupport = 0x8Fa6E56c844be9B96C30B72cC2a8ccF6465a99F9;
mapping(address => DepositItem) public deposits;
mapping(address => bool) public referrers;
mapping(address => uint) public waitingReferrers;
uint public referrerPrice = 70700000000000000; // 0.0707 ether
uint public referrerBeforeEndTime = 0;
uint public maxBalance = 0;
uint public invested;
uint public payments;
uint public referralPayments;
uint public investorsCount;
uint[] public historyOfRestarts;
event Deposit(address indexed from, uint256 value);
event Withdraw(address indexed to, uint256 value);
event PayBonus(address indexed to, uint256 value);
constructor () public
{
historyOfRestarts.push(now);
}
function bytesToAddress(bytes source) private pure returns(address parsedAddress)
{
assembly {
parsedAddress := mload(add(source,0x14))
}
return parsedAddress;
}
function getReferrersPercentsByBalance(uint balance) public pure returns(uint referrerLevelOnePercent, uint referrerLevelTwoPercent, uint cashBackPercent)
{
if(balance >= 0 && balance < 25000 ether) return (50, 10, 20);
else if(balance >= 25000 ether && balance < 100000 ether) return (30, 5, 15);
else if(balance >= 100000 ether && balance < 200000 ether) return (20, 0, 10);
else if(balance >= 200000 ether && balance < 500000 ether) return (10, 0, 5);
else return (6, 0, 3);
}
function getSupportsPercentsByBalance(uint balance) public pure returns(uint techSupportPercent, uint adsSupportPercent)
{
if(balance >= 0 && balance < 25000 ether) return (30, 70);
else if(balance >= 25000 ether && balance < 100000 ether) return (20, 50);
else if(balance >= 100000 ether && balance < 500000 ether) return (15, 40);
else return (10, 20);
}
function getPercentByBalance(uint balance) public pure returns(uint)
{
if(balance < 25 ether) return 69444444444;
else if(balance >= 25 ether && balance < 250 ether) return 104166666667;
else if(balance >= 250 ether && balance < 2500 ether ) return 138888888889;
else if(balance >= 2500 ether && balance < 25000 ether) return 173611111111;
else if(balance >= 25000 ether && balance < 50000 ether) return 138888888889;
else if(balance >= 50000 ether && balance < 100000 ether) return 104166666667;
else if(balance >= 100000 ether && balance < 150000 ether) return 69444444444;
else if(balance >= 150000 ether && balance < 200000 ether) return 55555555555;
else if(balance >= 200000 ether && balance < 250000 ether) return 416666666667;
else if(balance >= 250000 ether && balance < 300000 ether) return 277777777778;
else if(balance >= 300000 ether && balance < 500000 ether) return 138888888889;
else return 6944444444;
}
function () public payable
{
if(msg.value == 0)
{
payWithdraw(msg.sender);
return;
}
if(msg.value == referrerPrice && !referrers[msg.sender] && waitingReferrers[msg.sender] == 0 && deposits[msg.sender].sum != 0)
{
waitingReferrers[msg.sender] = now;
}
else
{
addDeposit(msg.sender, msg.value);
}
}
function isNeedRestart(uint balance) public returns (bool)
{
if(balance < maxBalance / 100 * 30) {
maxBalance = 0;
return true;
}
return false;
}
function calculateNewTime(uint oldTime, uint oldSum, uint newSum, uint currentTime) public pure returns (uint)
{
return oldTime + newSum / (newSum + oldSum) * (currentTime - oldTime);
}
function calculateNewDepositSum(uint minutesBetweenRestart, uint minutesWork, uint depositSum) public pure returns (uint)
{
if(minutesWork > minutesBetweenRestart) minutesWork = minutesBetweenRestart;
return (depositSum *(100-(uint(minutesWork) * 100 / minutesBetweenRestart)+7)/100);
}
function addDeposit(address investorAddress, uint weiAmount) private
{
checkReferrer(investorAddress, weiAmount);
DepositItem memory deposit = deposits[investorAddress];
if(deposit.sum == 0)
{
deposit.time = now;
investorsCount++;
}
else
{
uint sum = getWithdrawSum(investorAddress);
deposit.sum += sum;
deposit.time = calculateNewTime(deposit.time, deposit.sum, weiAmount, now);
}
deposit.withdrawalTime = now;
deposit.sum += weiAmount;
deposit.restartIndex = historyOfRestarts.length - 1;
deposit.invested += weiAmount;
deposits[investorAddress] = deposit;
emit Deposit(investorAddress, weiAmount);
payToSupport(weiAmount);
if (maxBalance < address(this).balance) {
maxBalance = address(this).balance;
}
invested += weiAmount;
}
function payToSupport(uint weiAmount) private {
(uint techSupportPercent, uint adsSupportPercent) = getSupportsPercentsByBalance(address(this).balance);
techSupport.transfer(weiAmount * techSupportPercent / 1000);
adsSupport.transfer(weiAmount * adsSupportPercent / 1000);
}
function checkReferrer(address investorAddress, uint weiAmount) private
{
if (deposits[investorAddress].sum == 0 && msg.data.length == 20) {
address referrerLevelOneAddress = bytesToAddress(bytes(msg.data));
if (referrerLevelOneAddress != investorAddress && referrerLevelOneAddress != address(0)) {
if (referrers[referrerLevelOneAddress] || waitingReferrers[referrerLevelOneAddress] != 0 && (now - waitingReferrers[referrerLevelOneAddress]) >= 7 days || now <= referrerBeforeEndTime) {
deposits[investorAddress].referrerLevelOne = referrerLevelOneAddress;
deposits[referrerLevelOneAddress].referalsLevelOneCount++;
address referrerLevelTwoAddress = deposits[referrerLevelOneAddress].referrerLevelOne;
if (referrerLevelTwoAddress != investorAddress && referrerLevelTwoAddress != address(0)) {
deposits[investorAddress].referrerLevelTwo = referrerLevelTwoAddress;
deposits[referrerLevelTwoAddress].referalsLevelTwoCount++;
}
}
}
}
if (deposits[investorAddress].referrerLevelOne != address(0)) {
(uint referrerLevelOnePercent, uint referrerLevelTwoPercent, uint cashBackPercent) = getReferrersPercentsByBalance(address(this).balance);
uint cashBackBonus = weiAmount * cashBackPercent / 1000;
uint referrerLevelOneBonus = weiAmount * referrerLevelOnePercent / 1000;
emit PayBonus(investorAddress, cashBackBonus);
emit PayBonus(referrerLevelOneAddress, referrerLevelOneBonus);
referralPayments += referrerLevelOneBonus;
deposits[referrerLevelOneAddress].referralPayments += referrerLevelOneBonus;
referrerLevelOneAddress.transfer(referrerLevelOneBonus);
deposits[investorAddress].cashback += cashBackBonus;
investorAddress.transfer(cashBackBonus);
if (deposits[investorAddress].referrerLevelTwo != address(0) && referrerLevelTwoPercent > 0) {
uint referrerLevelTwoBonus = weiAmount * referrerLevelTwoPercent / 1000;
emit PayBonus(referrerLevelTwoAddress, referrerLevelTwoBonus);
referralPayments += referrerLevelTwoBonus;
deposits[referrerLevelTwoAddress].referralPayments += referrerLevelTwoBonus;
referrerLevelTwoAddress.transfer(referrerLevelTwoBonus);
}
}
}
function payWithdraw(address to) private
{
require(deposits[to].sum > 0);
uint balance = address(this).balance;
if(isNeedRestart(balance))
{
historyOfRestarts.push(now);
}
uint lastRestartIndex = historyOfRestarts.length - 1;
if(lastRestartIndex - deposits[to].restartIndex >= 1)
{
uint minutesBetweenRestart = (historyOfRestarts[lastRestartIndex] - historyOfRestarts[deposits[to].restartIndex]) / 1 minutes;
uint minutesWork = (historyOfRestarts[lastRestartIndex] - deposits[to].time) / 1 minutes;
deposits[to].sum = calculateNewDepositSum(minutesBetweenRestart, minutesWork, deposits[to].sum);
deposits[to].restartIndex = lastRestartIndex;
deposits[to].time = now;
}
uint sum = getWithdrawSum(to);
require(sum > 0);
deposits[to].withdrawalTime = now;
deposits[to].payments += sum;
payments += sum;
to.transfer(sum);
emit Withdraw(to, sum);
}
function getWithdrawSum(address investorAddress) private view returns(uint sum) {
uint minutesCount = (now - deposits[investorAddress].withdrawalTime) / 1 minutes;
uint percent = getPercentByBalance(address(this).balance);
sum = deposits[investorAddress].sum * percent / 10000000000000000 * minutesCount;
}
function addReferrer(address referrerAddress) onlyOwner public
{
referrers[referrerAddress] = true;
}
function setReferrerPrice(uint newPrice) onlyOwner public
{
referrerPrice = newPrice;
}
function setReferrerBeforeEndTime(uint newTime) onlyOwner public
{
referrerBeforeEndTime = newTime;
}
function getDaysAfterStart() public constant returns(uint daysAfterStart) {
daysAfterStart = (now - historyOfRestarts[0]) / 1 days;
}
function getDaysAfterLastRestart() public constant returns(uint daysAfeterLastRestart) {
daysAfeterLastRestart = (now - historyOfRestarts[historyOfRestarts.length - 1]) / 1 days;
}
}
{
"compilationTarget": {
"SmartMMM.sol": "SmartMMM"
},
"evmVersion": "byzantium",
"libraries": {},
"optimizer": {
"enabled": true,
"runs": 200
},
"remappings": []
}
[{"constant":false,"inputs":[{"name":"newTime","type":"uint256"}],"name":"setReferrerBeforeEndTime","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[],"name":"referrerPrice","outputs":[{"name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"adsSupport","outputs":[{"name":"","type":"address"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"investorsCount","outputs":[{"name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"name":"balance","type":"uint256"}],"name":"getReferrersPercentsByBalance","outputs":[{"name":"referrerLevelOnePercent","type":"uint256"},{"name":"referrerLevelTwoPercent","type":"uint256"},{"name":"cashBackPercent","type":"uint256"}],"payable":false,"stateMutability":"pure","type":"function"},{"constant":true,"inputs":[],"name":"referralPayments","outputs":[{"name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"name":"","type":"address"}],"name":"referrers","outputs":[{"name":"","type":"bool"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"name":"balance","type":"uint256"}],"name":"getSupportsPercentsByBalance","outputs":[{"name":"techSupportPercent","type":"uint256"},{"name":"adsSupportPercent","type":"uint256"}],"payable":false,"stateMutability":"pure","type":"function"},{"constant":true,"inputs":[],"name":"getDaysAfterLastRestart","outputs":[{"name":"daysAfeterLastRestart","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"referrerBeforeEndTime","outputs":[{"name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[],"name":"renounceOwnership","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[],"name":"maxBalance","outputs":[{"name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"name":"oldTime","type":"uint256"},{"name":"oldSum","type":"uint256"},{"name":"newSum","type":"uint256"},{"name":"currentTime","type":"uint256"}],"name":"calculateNewTime","outputs":[{"name":"","type":"uint256"}],"payable":false,"stateMutability":"pure","type":"function"},{"constant":true,"inputs":[{"name":"","type":"address"}],"name":"waitingReferrers","outputs":[{"name":"","type":"uint256"}],"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":"isOwner","outputs":[{"name":"","type":"bool"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"name":"balance","type":"uint256"}],"name":"getPercentByBalance","outputs":[{"name":"","type":"uint256"}],"payable":false,"stateMutability":"pure","type":"function"},{"constant":true,"inputs":[{"name":"","type":"uint256"}],"name":"historyOfRestarts","outputs":[{"name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"getDaysAfterStart","outputs":[{"name":"daysAfterStart","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"payments","outputs":[{"name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"name":"balance","type":"uint256"}],"name":"isNeedRestart","outputs":[{"name":"","type":"bool"}],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[],"name":"invested","outputs":[{"name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"techSupport","outputs":[{"name":"","type":"address"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"name":"newPrice","type":"uint256"}],"name":"setReferrerPrice","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[{"name":"minutesBetweenRestart","type":"uint256"},{"name":"minutesWork","type":"uint256"},{"name":"depositSum","type":"uint256"}],"name":"calculateNewDepositSum","outputs":[{"name":"","type":"uint256"}],"payable":false,"stateMutability":"pure","type":"function"},{"constant":false,"inputs":[{"name":"newOwner","type":"address"}],"name":"transferOwnership","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[{"name":"","type":"address"}],"name":"deposits","outputs":[{"name":"time","type":"uint256"},{"name":"sum","type":"uint256"},{"name":"withdrawalTime","type":"uint256"},{"name":"restartIndex","type":"uint256"},{"name":"invested","type":"uint256"},{"name":"payments","type":"uint256"},{"name":"referralPayments","type":"uint256"},{"name":"cashback","type":"uint256"},{"name":"referalsLevelOneCount","type":"uint256"},{"name":"referalsLevelTwoCount","type":"uint256"},{"name":"referrerLevelOne","type":"address"},{"name":"referrerLevelTwo","type":"address"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"name":"referrerAddress","type":"address"}],"name":"addReferrer","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"inputs":[],"payable":false,"stateMutability":"nonpayable","type":"constructor"},{"payable":true,"stateMutability":"payable","type":"fallback"},{"anonymous":false,"inputs":[{"indexed":true,"name":"from","type":"address"},{"indexed":false,"name":"value","type":"uint256"}],"name":"Deposit","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"name":"to","type":"address"},{"indexed":false,"name":"value","type":"uint256"}],"name":"Withdraw","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"name":"to","type":"address"},{"indexed":false,"name":"value","type":"uint256"}],"name":"PayBonus","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"name":"previousOwner","type":"address"},{"indexed":true,"name":"newOwner","type":"address"}],"name":"OwnershipTransferred","type":"event"}]