/**
* ==========================================================
*
* The Friends Tree
* Why can't we be friends?
*
* Website : https://frndstree.io
* Telegram : https://t.me/thefriendstree_official
*
* ==========================================================
**/
pragma solidity >=0.5.12 <0.7.0;
contract TheFriendsTree {
struct Tree {
uint256 id;
uint256 referrerCount;
uint256 referrerId;
uint256 earnedFromRef;
uint256 earnedFromPayplan;
uint256 lastslottime;
address[] referrals;
}
struct PayPlan {
uint256 id;
uint256 referrerId;
uint256 reinvestCount;
}
struct Slots {
uint256 id;
address userAddress;
uint256 referrerId;
uint256 slottime;
uint8 eventsCount;
}
modifier validReferrerId(uint256 _referrerId) {
require((_referrerId > 0) && (_referrerId < newTreeId), "Invalid referrer ID");
_;
}
modifier onlyOwner {
require(
msg.sender == ownerWallet,
"Only owner can call this function."
);
_;
}
modifier isEligibleBuy {
require((now - entrance[msg.sender].lastslottime) > 60, "Allowed to buy slot once per minute!");
_;
}
event RegisterTreeEvent(uint256 _userid, address indexed _user, address indexed _referrerAddress, uint256 _amount, uint256 _time);
event RegisterPayPlanEvent(uint256 _userid, address indexed _user, address indexed _referrerAddress, uint256 _amount, uint256 _time);
event ReinvestSlotEvent(uint256 _userid, address indexed _user, address indexed _referrerAddress, uint256 _amount, uint256 _time);
event PayDirectRefBonusEvent(uint256 amount, address indexed _sponsorAddress, address indexed _fromAddress, uint256 _time);
event PaySponsorBonusEvent(uint256 amount, address indexed _sponsorAddress, address indexed _fromAddress, uint256 _time);
event PayPlanRefPaymentEvent(uint256 amount, address indexed _from, address indexed _to, uint256 _time);
event TreeRefPaymentEvent(uint256 amount, address indexed _sponsorAddress, address indexed _fromAddress, uint256 _level, uint256 _time);
mapping(address => Tree) public entrance;
mapping(address => PayPlan) public treePayPlan;
mapping(uint256 => Slots) public slots;
mapping(uint256 => address) private idToAddress;
mapping (uint8 => uint8) public uplineAmount;
uint256 public newTreeId = 1;
uint256 public newTreeIdPayPlan = 1;
uint256 public newSlotId = 1;
uint256 public activeSlot = 1;
address public owner;
address payable ownerWallet;
constructor(address _ownerAddress) public {
uplineAmount[1] = 10;
uplineAmount[2] = 10;
uplineAmount[3] = 10;
uplineAmount[4] = 10;
uplineAmount[5] = 10;
uplineAmount[6] = 10;
uplineAmount[7] = 10;
uplineAmount[8] = 10;
uplineAmount[9] = 10;
uplineAmount[10] = 10;
owner = _ownerAddress;
ownerWallet = msg.sender;
Tree memory user = Tree({
id: newTreeId,
referrerCount: uint256(0),
referrerId: uint256(0),
earnedFromRef: uint256(0),
earnedFromPayplan: uint256(0),
lastslottime: now,
referrals: new address[](0)
});
entrance[_ownerAddress] = user;
idToAddress[newTreeId] = _ownerAddress;
newTreeId++;
//////
PayPlan memory payPlanUser = PayPlan({
id: newSlotId,
referrerId: uint256(0),
reinvestCount: uint256(0)
});
treePayPlan[_ownerAddress] = payPlanUser;
Slots memory newSlot = Slots({
id: newSlotId,
userAddress: _ownerAddress,
referrerId: uint256(0),
slottime: now,
eventsCount: uint8(0)
});
slots[newSlotId] = newSlot;
newTreeIdPayPlan++;
newSlotId++;
}
function joinTree(uint256 _referrerId)
public
payable
validReferrerId(_referrerId)
{
require(msg.value == 0.15 ether, "Joining amount is 0.15 ETH");
require(!isTreeExists(msg.sender), "Already registered in a Tree");
address _userAddress = msg.sender;
address sponsorAddress = idToAddress[_referrerId];
uint32 size;
assembly {
size := extcodesize(_userAddress)
}
require(size == 0, "cannot be a contract");
entrance[_userAddress] = Tree({
id: newTreeId,
referrerCount: uint256(0),
referrerId: _referrerId,
earnedFromRef: uint256(0),
earnedFromPayplan: uint256(0),
lastslottime: now,
referrals: new address[](0)
});
idToAddress[newTreeId] = _userAddress;
emit RegisterTreeEvent(newTreeId, msg.sender, sponsorAddress, msg.value, now);
newTreeId++;
entrance[sponsorAddress].referrals.push(_userAddress);
entrance[sponsorAddress].referrerCount++;
if ( isTreeExists(sponsorAddress) ) {
payDirectRefBonus(sponsorAddress);
entrance[sponsorAddress].earnedFromRef += 0.05 ether;
} else {
payDirectRefBonus(idToAddress[1]);
entrance[idToAddress[1]].earnedFromRef += 0.05 ether;
}
uint256 amountToDistribute = 0.1 ether;
sponsorAddress = idToAddress[entrance[sponsorAddress].referrerId];
for (uint8 i = 1; i <= 10; i++) {
if ( isTreeExists(sponsorAddress) ) {
uint256 paid = payRefTree(sponsorAddress, i);
amountToDistribute -= paid;
entrance[sponsorAddress].earnedFromRef += paid;
address _nextSponsorAddress = idToAddress[entrance[sponsorAddress].referrerId];
sponsorAddress = _nextSponsorAddress;
}
}
if (amountToDistribute > 0) {
payDirectReferral(idToAddress[1], amountToDistribute);
entrance[idToAddress[1]].earnedFromRef += amountToDistribute;
}
}
function JoinPayPlan()
public
payable
isEligibleBuy()
{
require(msg.value == 1 ether, "Participation fee in Pay Plan is 1 ETH");
require(isTreeExists(msg.sender), "Not registered in Tree");
uint256 eventCount = slots[activeSlot].eventsCount;
uint256 newEventCount = eventCount + 1;
if (newEventCount == 3) {
require(reinvestSlot(
slots[activeSlot].userAddress,
slots[activeSlot].id,
idToAddress[entrance[slots[activeSlot].userAddress].referrerId]
));
slots[activeSlot].eventsCount++;
}
uint256 _referrerId = entrance[msg.sender].referrerId;
PayPlan memory payPlanUser = PayPlan({
id: newSlotId,
referrerId: _referrerId,
reinvestCount: uint256(0)
});
treePayPlan[msg.sender] = payPlanUser;
Slots memory _newSlot = Slots({
id: newSlotId,
userAddress: msg.sender,
referrerId: _referrerId,
slottime: now,
eventsCount: uint8(0)
});
entrance[msg.sender].lastslottime = now;
slots[newSlotId] = _newSlot;
newTreeIdPayPlan++;
emit RegisterPayPlanEvent(newSlotId, msg.sender, idToAddress[_referrerId], msg.value, now);
if (_referrerId > 0) {
paySponsorBonus(idToAddress[_referrerId]);
entrance[idToAddress[_referrerId]].earnedFromRef += 0.5 ether;
}
else{
paySponsorBonus(idToAddress[1]);
entrance[idToAddress[1]].earnedFromRef += 0.5 ether;
}
newSlotId++;
if (eventCount < 2) {
if(eventCount == 0) {
payUpline(slots[activeSlot].userAddress);
entrance[slots[activeSlot].userAddress].earnedFromPayplan += msg.value/2;
}
if(eventCount == 1) {
if (slots[activeSlot].referrerId > 0) {
payUpline(idToAddress[slots[activeSlot].referrerId]);
entrance[idToAddress[slots[activeSlot].referrerId]].earnedFromRef += msg.value/2;
}
else {
payUpline(idToAddress[1]);
entrance[idToAddress[1]].earnedFromRef += msg.value/2;
}
}
slots[activeSlot].eventsCount++;
}
}
function reinvestSlot(address _userAddress, uint256 _userId, address _sponsorAddress) private returns (bool _isReinvested) {
uint256 _referrerId = entrance[_userAddress].referrerId;
Slots memory _reinvestslot = Slots({
id: _userId,
userAddress: _userAddress,
referrerId: _referrerId,
slottime: now,
eventsCount: uint8(0)
});
treePayPlan[slots[activeSlot].userAddress].reinvestCount++;
slots[newSlotId] = _reinvestslot;
emit ReinvestSlotEvent(newSlotId, _userAddress, _sponsorAddress, msg.value, now);
newSlotId++;
slots[activeSlot].eventsCount = 3;
uint256 _nextActiveSlot = activeSlot+1;
payUpline(slots[_nextActiveSlot].userAddress);
entrance[slots[_nextActiveSlot].userAddress].earnedFromPayplan += msg.value/2;
activeSlot++;
_isReinvested = true;
return _isReinvested;
}
function payUpline(address _sponsorAddress) private returns (uint distributeAmount) {
distributeAmount = 0.5 ether;
if (address(uint160(_sponsorAddress)).send(distributeAmount)) {
emit PayPlanRefPaymentEvent(distributeAmount, msg.sender, _sponsorAddress, now);
}
return distributeAmount;
}
function paySponsorBonus(address _sponsorAddress) private {
uint256 distributeAmount = 0.5 ether;
if (address(uint160(_sponsorAddress)).send(distributeAmount)) {
emit PaySponsorBonusEvent(distributeAmount, _sponsorAddress, msg.sender, now);
}
}
// Pays to Ref LEvels from Tree
function payRefTree(address _sponsorAddress, uint8 _refLevel) private returns (uint256 distributeAmount) {
require( _refLevel <= 10);
distributeAmount = 0.1 ether / 100 * uplineAmount[_refLevel];
if (address(uint160(_sponsorAddress)).send(distributeAmount)) {
emit TreeRefPaymentEvent(distributeAmount, _sponsorAddress, msg.sender, _refLevel, now);
}
return distributeAmount;
}
// Pay direct ref bonus from Tree
function payDirectRefBonus(address _sponsorAddress) private {
uint256 distributeAmount = 0.05 ether;
if (address(uint160(_sponsorAddress)).send(distributeAmount)) {
emit PayDirectRefBonusEvent(distributeAmount, _sponsorAddress, msg.sender, now);
}
}
// Pay to ID 1 from Tree
function payDirectReferral(address _sponsorAddress, uint256 payAmount) private returns (uint256 distributeAmount) {
distributeAmount = payAmount;
if (address(uint160(_sponsorAddress)).send(distributeAmount)) {
emit PayDirectRefBonusEvent(distributeAmount, _sponsorAddress, msg.sender, now);
}
return distributeAmount;
}
function isTreeExists(address _userAddress) public view returns (bool) {
return (entrance[_userAddress].id != 0);
}
function getTreeReferrals(address _userAddress)
public
view
returns (address[] memory)
{
return entrance[_userAddress].referrals;
}
}
{
"compilationTarget": {
"TheFriendsTree.sol": "TheFriendsTree"
},
"evmVersion": "istanbul",
"libraries": {},
"metadata": {
"bytecodeHash": "ipfs"
},
"optimizer": {
"enabled": false,
"runs": 200
},
"remappings": []
}
[{"inputs":[{"internalType":"address","name":"_ownerAddress","type":"address"}],"stateMutability":"nonpayable","type":"constructor"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"},{"indexed":true,"internalType":"address","name":"_sponsorAddress","type":"address"},{"indexed":true,"internalType":"address","name":"_fromAddress","type":"address"},{"indexed":false,"internalType":"uint256","name":"_time","type":"uint256"}],"name":"PayDirectRefBonusEvent","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"},{"indexed":true,"internalType":"address","name":"_from","type":"address"},{"indexed":true,"internalType":"address","name":"_to","type":"address"},{"indexed":false,"internalType":"uint256","name":"_time","type":"uint256"}],"name":"PayPlanRefPaymentEvent","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"},{"indexed":true,"internalType":"address","name":"_sponsorAddress","type":"address"},{"indexed":true,"internalType":"address","name":"_fromAddress","type":"address"},{"indexed":false,"internalType":"uint256","name":"_time","type":"uint256"}],"name":"PaySponsorBonusEvent","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"_userid","type":"uint256"},{"indexed":true,"internalType":"address","name":"_user","type":"address"},{"indexed":true,"internalType":"address","name":"_referrerAddress","type":"address"},{"indexed":false,"internalType":"uint256","name":"_amount","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"_time","type":"uint256"}],"name":"RegisterPayPlanEvent","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"_userid","type":"uint256"},{"indexed":true,"internalType":"address","name":"_user","type":"address"},{"indexed":true,"internalType":"address","name":"_referrerAddress","type":"address"},{"indexed":false,"internalType":"uint256","name":"_amount","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"_time","type":"uint256"}],"name":"RegisterTreeEvent","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"_userid","type":"uint256"},{"indexed":true,"internalType":"address","name":"_user","type":"address"},{"indexed":true,"internalType":"address","name":"_referrerAddress","type":"address"},{"indexed":false,"internalType":"uint256","name":"_amount","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"_time","type":"uint256"}],"name":"ReinvestSlotEvent","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"},{"indexed":true,"internalType":"address","name":"_sponsorAddress","type":"address"},{"indexed":true,"internalType":"address","name":"_fromAddress","type":"address"},{"indexed":false,"internalType":"uint256","name":"_level","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"_time","type":"uint256"}],"name":"TreeRefPaymentEvent","type":"event"},{"inputs":[],"name":"JoinPayPlan","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[],"name":"activeSlot","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"entrance","outputs":[{"internalType":"uint256","name":"id","type":"uint256"},{"internalType":"uint256","name":"referrerCount","type":"uint256"},{"internalType":"uint256","name":"referrerId","type":"uint256"},{"internalType":"uint256","name":"earnedFromRef","type":"uint256"},{"internalType":"uint256","name":"earnedFromPayplan","type":"uint256"},{"internalType":"uint256","name":"lastslottime","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_userAddress","type":"address"}],"name":"getTreeReferrals","outputs":[{"internalType":"address[]","name":"","type":"address[]"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_userAddress","type":"address"}],"name":"isTreeExists","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"_referrerId","type":"uint256"}],"name":"joinTree","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[],"name":"newSlotId","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"newTreeId","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"newTreeIdPayPlan","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"owner","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"","type":"uint256"}],"name":"slots","outputs":[{"internalType":"uint256","name":"id","type":"uint256"},{"internalType":"address","name":"userAddress","type":"address"},{"internalType":"uint256","name":"referrerId","type":"uint256"},{"internalType":"uint256","name":"slottime","type":"uint256"},{"internalType":"uint8","name":"eventsCount","type":"uint8"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"treePayPlan","outputs":[{"internalType":"uint256","name":"id","type":"uint256"},{"internalType":"uint256","name":"referrerId","type":"uint256"},{"internalType":"uint256","name":"reinvestCount","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint8","name":"","type":"uint8"}],"name":"uplineAmount","outputs":[{"internalType":"uint8","name":"","type":"uint8"}],"stateMutability":"view","type":"function"}]