-
Notifications
You must be signed in to change notification settings - Fork 2
/
Copy pathMarketingReferral.sol
162 lines (139 loc) · 5.35 KB
/
MarketingReferral.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
// SPDX-License-Identifier: UNLICENSED
pragma solidity ^0.8.9;
// Belongs to muratcan-yuksel and it's part of their video tutorial -- https://www.youtube.com/watch?v=jr7MoX30IAQ&t=2903s
// Github: https://github.com/muratcan-yuksel/marketing-referral/blob/main/backend/contracts/Referral.sol
import "@openzeppelin/contracts/utils/math/SafeMath.sol";
import "@openzeppelin/contracts/security/ReentrancyGuard.sol";
//import hardhat console log
import "hardhat/console.sol";
contract Referral is ReentrancyGuard {
using SafeMath for uint256;
struct User {
address referrer;
uint8 totalReferrals;
uint8 level;
uint256 earnings;
}
address public owner;
mapping(address => User) public users;
uint256 public constant REGISTRATION_FEE = 0.25 ether;
uint8 public constant REFERRAL_PERCENTAGE = 70;
uint8 public constant BONUS_REFERRALS = 2;
uint8 public constant BONUS_PERCENTAGE = 50;
constructor() {
owner = msg.sender;
// User storage firstUser = users[owner];
//set the first user as deployer
users[owner] = User(address(0), 0, 1, 0);
// firstUser.referrer = address(0);
// firstUser.totalReferrals = 0;
// firstUser.level = 1;
// firstUser.earnings = 0;
}
modifier validRegistration(address _referrer) {
require(
msg.value == REGISTRATION_FEE,
"Registration fee is 0.25 ether"
);
require(
users[msg.sender].referrer == address(0),
"User already registered"
);
require(
_referrer != address(0) && _referrer != msg.sender,
"Invalid referrer"
);
if (_referrer != owner) {
require(
users[_referrer].referrer != address(0),
"Referrer does not exist"
);
}
require(
users[_referrer].referrer != msg.sender,
"Referrer cannot be the sender"
);
//require that the referrer has referrer less than 9 people
require(
users[_referrer].totalReferrals < 9,
"Referrer has already referred 9 people"
);
//require that the referrer is less than 10 levels
require(users[_referrer].level < 10, "Referrer is already at level 10");
_;
}
function register(
address _referrer
) public payable validRegistration(_referrer) {
User storage newUser = users[msg.sender];
newUser.referrer = _referrer;
newUser.totalReferrals = 0;
newUser.level = 1;
// console.log("User registered: %s", msg.sender);
// console.log("Referrer: %s", _referrer);
// console.log(msg.value);
transferPayment(_referrer, msg.value);
updateReferralCount(_referrer);
}
function transferPayment(address _referrer, uint256 _amount) private {
uint256 referralAmount = (_amount * REFERRAL_PERCENTAGE) / 100;
uint256 businessAmount = _amount - referralAmount;
// console.log("referral", referralAmount);
// console.log("biz", businessAmount);
if (
users[_referrer].totalReferrals > 1 &&
(users[_referrer].totalReferrals + 1) % 3 == 0
) {
referralAmount = (_amount * BONUS_PERCENTAGE) / 100;
businessAmount = _amount - referralAmount;
}
payable(_referrer).transfer(referralAmount);
//update earnings
users[_referrer].earnings += referralAmount;
//business amount should be sent to the owner/ no, it should be sent to the contract
// payable(owner).transfer(businessAmount);
}
function updateReferralCount(address _referrer) private {
users[_referrer].totalReferrals++;
}
function getUserBalance(address userAddress) public view returns (uint256) {
return users[userAddress].earnings;
}
function getUserLevel(address userAddress) public view returns (uint8) {
return users[userAddress].level;
}
function getUserReferrals(address userAddress) public view returns (uint8) {
return users[userAddress].totalReferrals;
}
function getUserReferrer(
address userAddress
) public view returns (address) {
return users[userAddress].referrer;
}
//if the user has referred 9 people, they can call this function to pay 0.5 eth to the contract and level up
function levelUp() public payable {
//require that the user has referred 9 people
require(
users[msg.sender].totalReferrals == 9,
"User has not referred 9 people"
);
//require that the user has paid 0.5 eth to the contract
require(msg.value == 0.5 ether, "User has not paid 0.5 ether");
//require that the user is less than 9 levels
require(users[msg.sender].level < 10, "User is already at level 10");
//update the user's level
users[msg.sender].level++;
//update the user's total referrals
users[msg.sender].totalReferrals = 0;
}
function withdraw() public {
require(msg.sender == owner, "Only owner can withdraw");
payable(owner).transfer(address(this).balance);
}
fallback() external payable {
revert("Invalid function call");
}
receive() external payable {
revert("Received ether without a function call");
}
}