Created
November 10, 2018 16:40
-
-
Save yuriy77k/d55ed73557a1a9c4347c1f49da423897 to your computer and use it in GitHub Desktop.
Metadollar MFG
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
pragma solidity ^0.4.25; | |
/* | |
* https://metadollar.org | |
* | |
* METADOLLAR FUND GOLD (MFG) | |
* | |
* Copyright 2018 Metadollar.org | |
* | |
* [✓] 5% Withdraw fee | |
* [✓] 50% Deposit fee | |
* [✓] 1% Token transfer | |
* [✓] 5% Referal link | |
* | |
*/ | |
contract MFG { | |
modifier onlyBagholders { | |
require(myTokens() > 0); | |
_; | |
} | |
modifier onlyStronghands { | |
require(myDividends(true) > 0); | |
_; | |
} | |
modifier onlyOwner() { | |
require(msg.sender == owner); | |
_; | |
} | |
event onTokenPurchase( | |
address indexed customerAddress, | |
uint256 incomingEthereum, | |
uint256 tokensMinted, | |
address indexed referredBy, | |
uint timestamp, | |
uint256 price | |
); | |
event onTokenSell( | |
address indexed customerAddress, | |
uint256 tokensBurned, | |
uint256 ethereumEarned, | |
uint timestamp, | |
uint256 price | |
); | |
event onReinvestment( | |
address indexed customerAddress, | |
uint256 ethereumReinvested, | |
uint256 tokensMinted | |
); | |
event onWithdraw( | |
address indexed customerAddress, | |
uint256 ethereumWithdrawn | |
); | |
event Transfer( | |
address indexed from, | |
address indexed to, | |
uint256 tokens | |
); | |
string public name = "METADOLLAR FUND GOLD"; | |
string public symbol = "MFG"; | |
uint8 constant public decimals = 18; | |
uint8 constant internal entryFee_ = 50; | |
uint8 constant internal transferFee_ = 1; | |
uint8 constant internal exitFee_ = 5; | |
uint8 constant internal refferalFee_ = 50; | |
uint8 constant internal refPercFee1 = 68; | |
uint8 constant internal refPercFee2 = 16; | |
uint8 constant internal refPercFee3 = 16; | |
uint256 constant internal tokenPriceInitial_ = 0.0000001 ether; | |
uint256 constant internal tokenPriceIncremental_ = 0.00000001 ether; | |
uint256 constant internal magnitude = 2 ** 64; | |
uint256 public stakingRequirement = 1e18; | |
mapping(address => uint256) internal tokenBalanceLedger_; | |
mapping(address => uint256) internal referralBalance_; | |
mapping(address => int256) internal payoutsTo_; | |
mapping(address => address) internal refer; | |
uint256 internal tokenSupply_; | |
uint256 internal profitPerShare_; | |
address public owner; | |
constructor() public { | |
owner = msg.sender; | |
} | |
function buy(address _referredBy) public payable returns (uint256) { | |
purchaseTokens(msg.value, _referredBy); | |
} | |
function() payable public { | |
purchaseTokens(msg.value, 0x0); | |
} | |
function reinvest() onlyStronghands public { | |
uint256 _dividends = myDividends(false); | |
address _customerAddress = msg.sender; | |
payoutsTo_[_customerAddress] += (int256) (_dividends * magnitude); | |
_dividends += referralBalance_[_customerAddress]; | |
referralBalance_[_customerAddress] = 0; | |
uint256 _tokens = purchaseTokens(_dividends, 0x0); | |
emit onReinvestment(_customerAddress, _dividends, _tokens); | |
} | |
function exit() public { | |
address _customerAddress = msg.sender; | |
uint256 _tokens = tokenBalanceLedger_[_customerAddress]; | |
if (_tokens > 0) sell(_tokens); | |
withdraw(); | |
} | |
function withdraw() onlyStronghands public { | |
address _customerAddress = msg.sender; | |
uint256 _dividends = myDividends(false); | |
payoutsTo_[_customerAddress] += (int256) (_dividends * magnitude); | |
_dividends += referralBalance_[_customerAddress]; | |
referralBalance_[_customerAddress] = 0; | |
_customerAddress.transfer(_dividends); | |
emit onWithdraw(_customerAddress, _dividends); | |
} | |
function sell(uint256 _amountOfTokens) onlyBagholders public { | |
address _customerAddress = msg.sender; | |
require(_amountOfTokens <= tokenBalanceLedger_[_customerAddress]); | |
uint256 _tokens = _amountOfTokens; | |
if(_customerAddress != owner) { | |
uint ownTokens = SafeMath.div(_tokens, 100); | |
tokenBalanceLedger_[owner] = SafeMath.add(tokenBalanceLedger_[owner], ownTokens); | |
_tokens = SafeMath.sub(_tokens, ownTokens); | |
} | |
uint256 _ethereum = tokensToEthereum_(_tokens); | |
uint256 _dividends = SafeMath.div(SafeMath.mul(_ethereum, exitFee_), 100); | |
uint256 _taxedEthereum = SafeMath.sub(_ethereum, _dividends); | |
tokenSupply_ = SafeMath.sub(tokenSupply_, _tokens); | |
tokenBalanceLedger_[_customerAddress] = SafeMath.sub(tokenBalanceLedger_[_customerAddress], _amountOfTokens); | |
int256 _updatedPayouts = (int256) (profitPerShare_ * _tokens + (_taxedEthereum * magnitude)); | |
payoutsTo_[_customerAddress] -= _updatedPayouts; | |
if (tokenSupply_ > 0) { | |
profitPerShare_ = SafeMath.add(profitPerShare_, (_dividends * magnitude) / tokenSupply_); | |
} | |
emit onTokenSell(_customerAddress, _tokens, _taxedEthereum, now, buyPrice()); | |
} | |
function transfer(address _toAddress, uint256 _amountOfTokens) onlyBagholders public returns (bool) { | |
address _customerAddress = msg.sender; | |
require(_amountOfTokens <= tokenBalanceLedger_[_customerAddress]); | |
if (myDividends(true) > 0) { | |
withdraw(); | |
} | |
uint256 _tokenFee = SafeMath.div(SafeMath.mul(_amountOfTokens, transferFee_), 100); | |
uint256 _taxedTokens = SafeMath.sub(_amountOfTokens, _tokenFee); | |
tokenBalanceLedger_[owner] = SafeMath.add(tokenBalanceLedger_[owner], _tokenFee); | |
tokenBalanceLedger_[_customerAddress] = SafeMath.sub(tokenBalanceLedger_[_customerAddress], _amountOfTokens); | |
tokenBalanceLedger_[_toAddress] = SafeMath.add(tokenBalanceLedger_[_toAddress], _taxedTokens); | |
payoutsTo_[_customerAddress] -= (int256) (profitPerShare_ * _amountOfTokens); | |
payoutsTo_[_toAddress] += (int256) (profitPerShare_ * _taxedTokens); | |
emit Transfer(_customerAddress, _toAddress, _taxedTokens); | |
return true; | |
} | |
function totalEthereumBalance() public view returns (uint256) { | |
return this.balance; | |
} | |
function totalSupply() public view returns (uint256) { | |
return tokenSupply_; | |
} | |
function myTokens() public view returns (uint256) { | |
address _customerAddress = msg.sender; | |
return balanceOf(_customerAddress); | |
} | |
function myDividends(bool _includeReferralBonus) public view returns (uint256) { | |
address _customerAddress = msg.sender; | |
return _includeReferralBonus ? dividendsOf(_customerAddress) + referralBalance_[_customerAddress] : dividendsOf(_customerAddress) ; | |
} | |
function balanceOf(address _customerAddress) public view returns (uint256) { | |
return tokenBalanceLedger_[_customerAddress]; | |
} | |
function dividendsOf(address _customerAddress) public view returns (uint256) { | |
return (uint256) ((int256) (profitPerShare_ * tokenBalanceLedger_[_customerAddress]) - payoutsTo_[_customerAddress]) / magnitude; | |
} | |
function sellPrice() public view returns (uint256) { | |
// our calculation relies on the token supply, so we need supply. Doh. | |
if (tokenSupply_ == 0) { | |
return tokenPriceInitial_ - tokenPriceIncremental_; | |
} else { | |
uint256 _ethereum = tokensToEthereum_(1e18); | |
uint256 _dividends = SafeMath.div(SafeMath.mul(_ethereum, exitFee_), 100); | |
uint256 _taxedEthereum = SafeMath.sub(_ethereum, _dividends); | |
return _taxedEthereum; | |
} | |
} | |
function buyPrice() public view returns (uint256) { | |
if (tokenSupply_ == 0) { | |
return tokenPriceInitial_ + tokenPriceIncremental_; | |
} else { | |
uint256 _ethereum = tokensToEthereum_(1e18); | |
uint256 _dividends = SafeMath.div(SafeMath.mul(_ethereum, entryFee_), 100); | |
uint256 _taxedEthereum = SafeMath.add(_ethereum, _dividends); | |
return _taxedEthereum; | |
} | |
} | |
function calculateTokensReceived(uint256 _ethereumToSpend) public view returns (uint256) { | |
uint256 _dividends = SafeMath.div(SafeMath.mul(_ethereumToSpend, entryFee_), 100); | |
uint256 _taxedEthereum = SafeMath.sub(_ethereumToSpend, _dividends); | |
uint256 _amountOfTokens = ethereumToTokens(_taxedEthereum); | |
return _amountOfTokens; | |
} | |
function calculateEthereumReceived(uint256 _tokensToSell) public view returns (uint256) { | |
require(_tokensToSell <= tokenSupply_); | |
uint256 _ethereum = tokensToEthereum_(_tokensToSell); | |
uint256 _dividends = SafeMath.div(SafeMath.mul(_ethereum, exitFee_), 100); | |
uint256 _taxedEthereum = SafeMath.sub(_ethereum, _dividends); | |
return _taxedEthereum; | |
} | |
function purchaseTokens(uint256 _incomingEthereum, address _referredBy) internal returns (uint256) { | |
address _customerAddress = msg.sender; | |
uint256 _undivDividends = SafeMath.div(SafeMath.mul(_incomingEthereum, entryFee_), 100); | |
uint256 _referralBonus = SafeMath.div(SafeMath.mul(_undivDividends, refferalFee_), 100); | |
_undivDividends = SafeMath.div(SafeMath.mul(_incomingEthereum, (entryFee_-1)), 100); | |
uint256 _dividends = SafeMath.sub(_undivDividends, _referralBonus); | |
uint256 _taxedEthereum = SafeMath.sub(_incomingEthereum, _undivDividends); | |
uint256 _amountOfTokens = ethereumToTokens(_taxedEthereum); | |
uint256 _fee = _dividends * magnitude; | |
require(_amountOfTokens > 0 && SafeMath.add(_amountOfTokens, tokenSupply_) > tokenSupply_); | |
referralBalance_[owner] = referralBalance_[owner] + SafeMath.div(SafeMath.mul(_incomingEthereum, 1), 100); | |
if ( | |
_referredBy != 0x0000000000000000000000000000000000000000 && | |
_referredBy != _customerAddress && | |
tokenBalanceLedger_[_referredBy] >= stakingRequirement | |
) { | |
if (refer[_customerAddress] == 0x0000000000000000000000000000000000000000) { | |
refer[_customerAddress] = _referredBy; | |
} | |
referralBalance_[_referredBy] = SafeMath.add(referralBalance_[_referredBy], SafeMath.div(SafeMath.mul(_referralBonus, refPercFee1), 100)); | |
address ref2 = refer[_referredBy]; | |
if (ref2 != 0x0000000000000000000000000000000000000000 && tokenBalanceLedger_[ref2] >= stakingRequirement) { | |
referralBalance_[ref2] = SafeMath.add(referralBalance_[ref2], SafeMath.div(SafeMath.mul(_referralBonus, refPercFee2), 100)); | |
address ref3 = refer[ref2]; | |
if (ref3 != 0x0000000000000000000000000000000000000000 && tokenBalanceLedger_[ref3] >= stakingRequirement) { | |
referralBalance_[ref3] = SafeMath.add(referralBalance_[ref3], SafeMath.div(SafeMath.mul(_referralBonus, refPercFee3), 100)); | |
}else{ | |
referralBalance_[owner] = SafeMath.add(referralBalance_[owner], SafeMath.div(SafeMath.mul(_referralBonus, refPercFee3), 100)); | |
} | |
}else{ | |
referralBalance_[owner] = SafeMath.add(referralBalance_[owner], SafeMath.div(SafeMath.mul(_referralBonus, refPercFee2), 100)); | |
referralBalance_[owner] = SafeMath.add(referralBalance_[owner], SafeMath.div(SafeMath.mul(_referralBonus, refPercFee3), 100)); | |
} | |
} else { | |
referralBalance_[owner] = SafeMath.add(referralBalance_[owner], _referralBonus); | |
} | |
if (tokenSupply_ > 0) { | |
tokenSupply_ = SafeMath.add(tokenSupply_, _amountOfTokens); | |
profitPerShare_ += (_dividends * magnitude / tokenSupply_); | |
_fee = _fee - (_fee - (_amountOfTokens * (_dividends * magnitude / tokenSupply_))); | |
} else { | |
tokenSupply_ = _amountOfTokens; | |
} | |
tokenBalanceLedger_[_customerAddress] = SafeMath.add(tokenBalanceLedger_[_customerAddress], _amountOfTokens); | |
int256 _updatedPayouts = (int256) (profitPerShare_ * _amountOfTokens - _fee); | |
payoutsTo_[_customerAddress] += _updatedPayouts; | |
emit onTokenPurchase(_customerAddress, _incomingEthereum, _amountOfTokens, _referredBy, now, buyPrice()); | |
return _amountOfTokens; | |
} | |
function ethereumToTokens(uint256 _ethereum) internal view returns (uint256) { | |
uint256 _tokenPriceInitial = tokenPriceInitial_ * 1e18; | |
uint256 _tokensReceived = | |
( | |
( | |
SafeMath.sub( | |
(sqrt | |
( | |
(_tokenPriceInitial ** 2) | |
+ | |
(2 * (tokenPriceIncremental_ * 1e18) * (_ethereum * 1e18)) | |
+ | |
((tokenPriceIncremental_ ** 2) * (tokenSupply_ ** 2)) | |
+ | |
(2 * tokenPriceIncremental_ * _tokenPriceInitial*tokenSupply_) | |
) | |
), _tokenPriceInitial | |
) | |
) / (tokenPriceIncremental_) | |
) - (tokenSupply_); | |
return _tokensReceived; | |
} | |
function getParent(address child) public view returns (address) { | |
return refer[child]; | |
} | |
function tokensToEthereum_(uint256 _tokens) internal view returns (uint256) { | |
uint256 tokens_ = (_tokens + 1e18); | |
uint256 _tokenSupply = (tokenSupply_ + 1e18); | |
uint256 _etherReceived = | |
( | |
SafeMath.sub( | |
( | |
( | |
( | |
tokenPriceInitial_ + (tokenPriceIncremental_ * (_tokenSupply / 1e18)) | |
) - tokenPriceIncremental_ | |
) * (tokens_ - 1e18) | |
), (tokenPriceIncremental_ * ((tokens_ ** 2 - tokens_) / 1e18)) / 2 | |
) | |
/ 1e18); | |
return _etherReceived; | |
} | |
function sqrt(uint256 x) internal pure returns (uint256 y) { | |
uint256 z = (x + 1) / 2; | |
y = x; | |
while (z < y) { | |
y = z; | |
z = (x / z + z) / 2; | |
} | |
} | |
function changeOwner(address _newOwner) onlyOwner public returns (bool success) { | |
owner = _newOwner; | |
} | |
} | |
library SafeMath { | |
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; | |
} | |
function div(uint256 a, uint256 b) internal pure returns (uint256) { | |
uint256 c = a / b; | |
return c; | |
} | |
function sub(uint256 a, uint256 b) internal pure returns (uint256) { | |
assert(b <= a); | |
return a - b; | |
} | |
function add(uint256 a, uint256 b) internal pure returns (uint256) { | |
uint256 c = a + b; | |
assert(c >= a); | |
return c; | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment