//pragma solidity >=0.4.21 <0.7.0;
pragma solidity 0.7.0;
library SafeMath {
function mul(uint256 a, uint256 b) internal pure returns (uint256) {
if (a == 0) {
return 0;
}
uint256 c = a * b;
require(c / a == b);
return c;
}
function div(uint256 a, uint256 b) internal pure returns (uint256) {
return _div(a, b, "SafeMath: division by zero");
}
function _div(uint256 a, uint256 b, string memory errorMessage) internal pure returns (uint256) {
require(b > 0, errorMessage);
uint256 c = a / b;
return c;
}
function sub(uint256 a, uint256 b) internal pure returns (uint256) {
return _sub(a, b, "SafeMath: subtraction overflow");
}
function _sub(uint256 a, uint256 b, string memory errorMessage) internal pure returns (uint256) {
require(b <= a, errorMessage);
uint256 c = a - b;
return c;
}
function add(uint256 a, uint256 b) internal pure returns (uint256) {
uint256 c = a + b;
require(c >= a, "SafeMath: addition overflow");
return c;
}
function mod(uint256 a, uint256 b) internal pure returns (uint256) {
return _mod(a, b, "SafeMath: modulo by zero");
}
function _mod(
uint256 a,
uint256 b,
string memory errorMessage
) internal pure returns (uint256) {
require(b != 0, errorMessage);
return a % b;
}
}
//The main block of the contract starts here
contract TrustTrade {
//###########################GLOBAL VARIABLES##########################
uint16 public planId;
uint256 public referrerId;
// The total number of customers have insvested in our bank
uint256 totalCustomers;
// The total amount of investment in our bank
uint256 totalInvestmentAmount;
// The total amount of withdrawal from our bank
uint256 totalWithdrawAmount;
// The total amount of payments to our referrals
uint256 totalReferalPayments;
//###########################GLOBAL VARIABLES##########################
//###########################PREDEFINED ADDRESSES##########################
address public contractOwner;
address public bankOwner;
//#####################################################################
//#############################STRUCTS######################################
// struct for storing plan information
struct Plan {
uint256 period;
uint256 interest;
}
// struct for storing investment information
struct Invest {
uint16 plan_id;
uint256 amount;
uint256 investTime;
}
// struct for customers information
struct Customer {
bool isInvested;
uint256 lastWidthdrawal;
uint256 totalWidtdraw;
uint256 investCount;
uint256 numReferral;
uint256 totalRefPayment;
uint256 userReferrerId;
}
//#########################################################################
//#############################MAPPINGS#####################################
mapping(address => Customer) public customers;
mapping(address => Invest) public customers_invests;
mapping(uint16 => Plan) public plans;
mapping(uint256 => uint256) public PLAN_PRICE;
mapping(uint256 => uint256) public REFERRER_PROFIT;
mapping(uint256 => address) referral_holder;
//############################################################################
//###################################EVENTS##################################
event ReferralPayment(
address indexed _referrer,
uint256 refProfit,
uint256 _refPaymentDate
);
event AdminDeposit(
uint256 _value,
address _bankOwner,
uint256 _depositDate
);
event NewInvestment(
address indexed addr,
uint16 plan_id,
uint256 _value,
uint256 _investDate
);
event NewCustomerWidthdraw(
address indexed addr,
uint256 profit,
uint256 _customerWithdrawDate
);
event NewAdminWidtdraw(
address indexed AdminAddr,
uint256 value,
uint256 _ownerWithdrawDate
);
event CalledForUserInfo(
address indexed userAddr,
bool isReg,
uint256 _askInfoDate
);
//###########################################################################
constructor() {
contractOwner = msg.sender;
bankOwner = 0xdcBC9ae4dBF722148a3553fd85E72a7eb67c928F;
PLAN_PRICE[0] = 0.5 ether;
PLAN_PRICE[1] = 0.2 ether;
PLAN_PRICE[2] = 0.15 ether;
PLAN_PRICE[3] = 0.1 ether;
PLAN_PRICE[4] = 0.08 ether;
// referrer interest
REFERRER_PROFIT[1100] = 10;
REFERRER_PROFIT[1101] = 10;
REFERRER_PROFIT[1102] = 8;
REFERRER_PROFIT[1103] = 6;
REFERRER_PROFIT[1104] = 5;
plans[1100] = Plan(7, 30);
plans[1101] = Plan(7, 25);
plans[1102] = Plan(15, 40);
plans[1103] = Plan(30, 60);
plans[1104] = Plan(30, 50);
referrerId = 2020;
totalCustomers = 0;
totalInvestmentAmount = 0;
totalWithdrawAmount = 0;
totalReferalPayments = 0;
}
////////////////////MODIFIERS/////////////////////
fallback() external payable {
if (msg.sender == bankOwner) {
emit AdminDeposit(msg.value, bankOwner, block.timestamp);
} else {
address _referrer = bytesToAddress(msg.data);
_init(msg.sender, msg.value, _referrer);
}
}
function _init (
address payable _investor,
uint256 _investValue,
address _referrer
) private {
bool doInvest = true;
if (_investValue >= PLAN_PRICE[0]) {
planId = 1100;
} else if (_investValue == PLAN_PRICE[1]) {
planId = 1101;
} else if (_investValue == PLAN_PRICE[2]) {
planId = 1102;
} else if (_investValue == PLAN_PRICE[3]) {
planId = 1103;
} else if (_investValue == PLAN_PRICE[4]) {
planId = 1104;
} else {
doInvest = false;
}
if (doInvest == true) {
invest(_investValue, _investor, planId, _referrer);
} else {
revert("Incorrect value sent!");
}
}
function getContBalance() public view returns (uint256)
{
return
(
address(this).balance
);
}
//very critical function. Consider revising
function ownerWidthdraw(uint256 amount) external payable {
require(msg.sender == bankOwner);
require(
amount < this.getContBalance(),
"The amount of dividend to be paid is larger than the contract's balance!"
);
//msg.sender.transfer(amount);
(bool success, ) = msg.sender.call{value: amount}("");
require(success, "Owner's payment was not successful!");
emit NewAdminWidtdraw(msg.sender, amount, block.timestamp);
}
function calculateDividents(address _userAddr)
private
view
returns (uint256)
{
uint256 num = SafeMath.mul(
plans[customers_invests[_userAddr].plan_id].interest,
customers_invests[_userAddr].amount);
return SafeMath.div(num, 1000);
}
function calculateClaim(
address _userAddr
)
public
view
returns (
uint256,
uint256,
uint256
)
{
//newStart
uint256 newStart = SafeMath.div(customers[_userAddr].lastWidthdrawal, SafeMath.mul(24, 3600));
//now
uint256 current_time = SafeMath.div(block.timestamp, SafeMath.mul(24, 3600));
// _mod
uint256 _mod = SafeMath.mod(SafeMath.sub(current_time, newStart),
plans[customers_invests[_userAddr].plan_id].period
);
//_profit
uint256 _profit = SafeMath.div(SafeMath.sub(current_time, newStart), plans[customers_invests[_userAddr].plan_id].period);
newStart = block.timestamp;
//res
uint256 res = calculateDividents(_userAddr);
uint256 amount_paid = SafeMath.mul(_profit, res);
return (amount_paid, newStart, _mod);
}
function _widthDraw(
address payable _userAddr
) private {
(uint256 _amount, uint256 newStart, uint256 mod) = calculateClaim(_userAddr);
uint256 contractBalance = this.getContBalance();
require(
_amount < contractBalance,
"The amount of dividend to be paid is larger than the contract's balance!"
);
if (_amount > 0) {
(bool success, ) = _userAddr.call{value: _amount}("");
require(success == true, "Customer withdrawal failed!");
customers[_userAddr].totalWidtdraw = SafeMath.add(customers[_userAddr].totalWidtdraw, _amount);
customers[_userAddr].lastWidthdrawal = SafeMath.sub(newStart, SafeMath.mul(mod, 86400));
totalWithdrawAmount = SafeMath.add(totalWithdrawAmount, _amount);
emit NewCustomerWidthdraw(
msg.sender,
_amount,
block.timestamp
);
}
}
function widthdraw()
external
payable
{
require(
customers[msg.sender].isInvested == true,
"You cannot widthdraw because you haven't invested!"
);
require(
address(this).balance > 0,
"We do not have enough balance for payment at the moment. Please try later!"
);
_widthDraw(msg.sender);
}
function _invest(
address payable _userAddr,
uint16 _pid,
uint256 _value,
address _referrer
) private returns (bool) {
referral_holder[referrerId] = _userAddr;
customers[_userAddr].isInvested = true;
customers[_userAddr].investCount = SafeMath.add(
customers[_userAddr].investCount,
1
);
require(
customers[_userAddr].investCount == 1,
"You are not allow to have more than one investment!"
);
require(_value > 0, "Please specify a value of your investment!");
customers_invests[_userAddr] = Invest({
plan_id: _pid,
amount: _value,
investTime: block.timestamp
});
customers[_userAddr].lastWidthdrawal = block.timestamp;
totalCustomers = SafeMath.add(totalCustomers, 1);
totalInvestmentAmount = SafeMath.add(totalInvestmentAmount, _value);
require(
_referrer != _userAddr,
"The referrer can not be the investor itself."
);
require(
_referrer != contractOwner,
"The referrer can not be the contract owner."
);
require(
_referrer != bankOwner,
"The referrer can not be the bank owner."
);
_payReferrer(_referrer, _value);
customers[_userAddr].userReferrerId = referrerId;
referrerId = SafeMath.add(referrerId, 5);
return true;
}
function invest(
uint256 _value,
address payable _userAddr,
uint16 _pid,
address _referrer
) private {
if (_invest(_userAddr, _pid, _value, _referrer)) {
emit NewInvestment(_userAddr, _pid, _value, block.timestamp);
}
}
function getCustomerInfo(address _userAddr)
public
view
returns (
uint256,
uint256,
uint256,
uint256,
uint256,
uint256
)
{
return (
customers[_userAddr].totalWidtdraw,
customers[_userAddr].lastWidthdrawal,
customers_invests[_userAddr].investTime,
customers[_userAddr].numReferral,
customers[_userAddr].totalRefPayment,
customers[_userAddr].userReferrerId
);
}
function getPlanInfo(address _userAddr) public view returns (uint16, uint256)
{
return (customers_invests[_userAddr].plan_id, customers_invests[_userAddr].amount);
}
function checkIfReferrerExist(uint32 _referrerCode)
public
view
returns (address)
{
return referral_holder[_referrerCode];
}
function getUserRegistrationStatus(address _userAddr)
public
view
returns (bool)
{
return customers[_userAddr].isInvested;
}
function statistics() public view returns (uint256, uint256, uint256, uint256)
{
return (totalCustomers, totalInvestmentAmount, totalWithdrawAmount, totalReferalPayments);
}
function bytesToAddress(bytes memory bys)
private
pure
returns (address addr)
{
assembly {
addr := mload(add(bys, 20))
}
}
function _payReferrer(address _referrer, uint256 _value) private {
if (customers[_referrer].isInvested) {
uint256 refProfit = SafeMath.div(SafeMath.mul(REFERRER_PROFIT[customers_invests[_referrer].plan_id],_value), 100);
address payable add3 = address(uint160(_referrer));
(bool refSuccess, ) = add3.call{value: refProfit}("");
require(refSuccess, "Referral payment was not successfull!");
//add3.transfer(refProfit);
customers[_referrer].numReferral = SafeMath.add(
customers[_referrer].numReferral,
1
);
customers[_referrer].totalRefPayment = SafeMath.add(
customers[_referrer].totalRefPayment,
refProfit
);
totalReferalPayments = SafeMath.add(totalReferalPayments, refProfit);
emit ReferralPayment(
_referrer,
//refSuccess,
refProfit,
block.timestamp
);
}
}
}
{
"compilationTarget": {
"browser/contracts/TrustTrade.sol": "TrustTrade"
},
"evmVersion": "istanbul",
"libraries": {},
"metadata": {
"bytecodeHash": "ipfs"
},
"optimizer": {
"enabled": false,
"runs": 200
},
"remappings": []
}
[{"inputs":[],"stateMutability":"nonpayable","type":"constructor"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"_value","type":"uint256"},{"indexed":false,"internalType":"address","name":"_bankOwner","type":"address"},{"indexed":false,"internalType":"uint256","name":"_depositDate","type":"uint256"}],"name":"AdminDeposit","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"userAddr","type":"address"},{"indexed":false,"internalType":"bool","name":"isReg","type":"bool"},{"indexed":false,"internalType":"uint256","name":"_askInfoDate","type":"uint256"}],"name":"CalledForUserInfo","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"AdminAddr","type":"address"},{"indexed":false,"internalType":"uint256","name":"value","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"_ownerWithdrawDate","type":"uint256"}],"name":"NewAdminWidtdraw","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"addr","type":"address"},{"indexed":false,"internalType":"uint256","name":"profit","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"_customerWithdrawDate","type":"uint256"}],"name":"NewCustomerWidthdraw","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"addr","type":"address"},{"indexed":false,"internalType":"uint16","name":"plan_id","type":"uint16"},{"indexed":false,"internalType":"uint256","name":"_value","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"_investDate","type":"uint256"}],"name":"NewInvestment","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"_referrer","type":"address"},{"indexed":false,"internalType":"uint256","name":"refProfit","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"_refPaymentDate","type":"uint256"}],"name":"ReferralPayment","type":"event"},{"stateMutability":"payable","type":"fallback"},{"inputs":[{"internalType":"uint256","name":"","type":"uint256"}],"name":"PLAN_PRICE","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"","type":"uint256"}],"name":"REFERRER_PROFIT","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"bankOwner","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_userAddr","type":"address"}],"name":"calculateClaim","outputs":[{"internalType":"uint256","name":"","type":"uint256"},{"internalType":"uint256","name":"","type":"uint256"},{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint32","name":"_referrerCode","type":"uint32"}],"name":"checkIfReferrerExist","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"contractOwner","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"customers","outputs":[{"internalType":"bool","name":"isInvested","type":"bool"},{"internalType":"uint256","name":"lastWidthdrawal","type":"uint256"},{"internalType":"uint256","name":"totalWidtdraw","type":"uint256"},{"internalType":"uint256","name":"investCount","type":"uint256"},{"internalType":"uint256","name":"numReferral","type":"uint256"},{"internalType":"uint256","name":"totalRefPayment","type":"uint256"},{"internalType":"uint256","name":"userReferrerId","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"customers_invests","outputs":[{"internalType":"uint16","name":"plan_id","type":"uint16"},{"internalType":"uint256","name":"amount","type":"uint256"},{"internalType":"uint256","name":"investTime","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getContBalance","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_userAddr","type":"address"}],"name":"getCustomerInfo","outputs":[{"internalType":"uint256","name":"","type":"uint256"},{"internalType":"uint256","name":"","type":"uint256"},{"internalType":"uint256","name":"","type":"uint256"},{"internalType":"uint256","name":"","type":"uint256"},{"internalType":"uint256","name":"","type":"uint256"},{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_userAddr","type":"address"}],"name":"getPlanInfo","outputs":[{"internalType":"uint16","name":"","type":"uint16"},{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_userAddr","type":"address"}],"name":"getUserRegistrationStatus","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"ownerWidthdraw","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[],"name":"planId","outputs":[{"internalType":"uint16","name":"","type":"uint16"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint16","name":"","type":"uint16"}],"name":"plans","outputs":[{"internalType":"uint256","name":"period","type":"uint256"},{"internalType":"uint256","name":"interest","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"referrerId","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"statistics","outputs":[{"internalType":"uint256","name":"","type":"uint256"},{"internalType":"uint256","name":"","type":"uint256"},{"internalType":"uint256","name":"","type":"uint256"},{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"widthdraw","outputs":[],"stateMutability":"payable","type":"function"}]