1
+ pragma solidity ^ 0.4.24 ;
2
+ pragma experimental ABIEncoderV2;
3
+
4
+ contract ribbonincentive {
5
+ address private ribbonOwner;
6
+
7
+ struct Donation {
8
+ uint amount;
9
+ uint timeStamp;
10
+ }
11
+
12
+ struct Practitioner {
13
+ uint allowance;
14
+ uint pastSentTokens;
15
+ uint arrayPosition;
16
+ }
17
+
18
+ struct User {
19
+ bool registered;
20
+ uint balance;
21
+ uint totalEarned;
22
+ uint arrayPosition;
23
+ }
24
+
25
+ struct Program {
26
+ string name;
27
+ address owner;
28
+ mapping (address => Donation[]) sponsors;
29
+ address [] allSponsors;
30
+ mapping (address => Practitioner) practitioners;
31
+ address [] allPractitioners;
32
+ mapping (address => User) users;
33
+ address [] allUsers;
34
+ uint balance;
35
+ uint totalDonated;
36
+ }
37
+
38
+ Program[] allPrograms;
39
+ uint [] allDonationAmounts;
40
+ uint [] allDonationTimeStamps;
41
+
42
+ modifier onlyOwnerOfProgram (uint _programID ) {
43
+ require (msg .sender == allPrograms[_programID].owner, "Function is only accessable by program owner " );
44
+ _;
45
+ }
46
+
47
+ modifier onlyRibbon () {
48
+ require (msg .sender == ribbonOwner, "Function is only accessable by Ribbon owner " );
49
+ _;
50
+ }
51
+
52
+ constructor ()
53
+ public
54
+ {
55
+ ribbonOwner = msg .sender ;
56
+ }
57
+
58
+ //PROGRAM functions
59
+
60
+ function createProgram (string _name , address _owner )
61
+ public
62
+ payable
63
+ onlyRibbon ()
64
+ returns (uint programID )
65
+ {
66
+ address [] memory _allSponsors;
67
+ address [] memory _allPractitioners;
68
+ address [] memory _allUsers;
69
+ programID = allPrograms.push (Program ({
70
+ name: _name,
71
+ owner: _owner,
72
+ allSponsors: _allSponsors,
73
+ allPractitioners: _allPractitioners,
74
+ allUsers: _allUsers,
75
+ balance: msg .value ,
76
+ totalDonated: 0
77
+ }));
78
+ }
79
+
80
+ function getProgramDetails (uint _programID )
81
+ public
82
+ view
83
+ returns (
84
+ string name ,
85
+ address owner ,
86
+ address [] allSponsors ,
87
+ address [] allPractitioners ,
88
+ address [] allUsers ,
89
+ uint balance ,
90
+ uint totalDonated
91
+ )
92
+ {
93
+ name = allPrograms[_programID].name;
94
+ owner = allPrograms[_programID].owner;
95
+ allSponsors = allPrograms[_programID].allSponsors;
96
+ allPractitioners = allPrograms[_programID].allPractitioners;
97
+ allUsers = allPrograms[_programID].allUsers;
98
+ balance = allPrograms[_programID].balance;
99
+ totalDonated = allPrograms[_programID].totalDonated;
100
+ }
101
+
102
+ function deleteProgram (uint _programID )
103
+ public
104
+ onlyOwnerOfProgram (_programID)
105
+ {
106
+ delete allPrograms[_programID];
107
+ }
108
+
109
+ function changeProgramName (uint _projectID , string _newName )
110
+ public
111
+ onlyOwnerOfProgram (_projectID)
112
+ returns (string projectName )
113
+ {
114
+ allPrograms[_projectID].name = _newName;
115
+ return _newName;
116
+ }
117
+
118
+ function changeProgramOwner (uint _projectID , address _newOwner )
119
+ public
120
+ onlyOwnerOfProgram (_projectID)
121
+ returns (address newOwner )
122
+ {
123
+ allPrograms[_projectID].owner = _newOwner;
124
+ return _newOwner;
125
+ }
126
+
127
+ //DONOR functions
128
+
129
+ function donate (uint _programID )
130
+ public
131
+ payable
132
+ {
133
+ uint donationAmount = msg .value ;
134
+ require (allPrograms[_programID].owner != 0x0 , "Invalid program ID " );
135
+ if (allPrograms[_programID].sponsors[msg .sender ].length == 0 ){
136
+ allPrograms[_programID].allSponsors.push (msg .sender );
137
+ }
138
+ allPrograms[_programID].sponsors[msg .sender ].push (Donation ({
139
+ amount: donationAmount,
140
+ timeStamp: now
141
+ }));
142
+ allPrograms[_programID].balance += donationAmount;
143
+ allPrograms[_programID].totalDonated += donationAmount;
144
+ }
145
+
146
+ function getAllDonations (uint _programID )
147
+ public
148
+ view
149
+ returns (uint )
150
+ {
151
+ return allPrograms[_programID].totalDonated;
152
+ }
153
+
154
+ function getDonations (uint _programID , address _donor )
155
+ public
156
+ view
157
+ returns (
158
+ uint [],
159
+ uint []
160
+ )
161
+ {
162
+ for (uint i = 0 ; i < allPrograms[_programID].sponsors[_donor].length ; i++ ){
163
+ allDonationAmounts.push ((uint )(allPrograms[_programID].sponsors[_donor][i].amount));
164
+ allDonationTimeStamps.push ((uint )(allPrograms[_programID].sponsors[_donor][i].timeStamp));
165
+ }
166
+ return (allDonationAmounts, allDonationTimeStamps);
167
+ }
168
+
169
+ //USER functions
170
+
171
+ function addUsers (uint _programID , address [] _users )
172
+ public
173
+ onlyOwnerOfProgram (_programID)
174
+ returns (address [])
175
+ {
176
+ for (uint i = 0 ; i < _users.length ; i++ ){
177
+ allPrograms[_programID].users[_users[i]] = User ({
178
+ registered: true ,
179
+ balance: 0 ,
180
+ totalEarned: 0 ,
181
+ arrayPosition: i
182
+ });
183
+ allPrograms[_programID].allUsers.push (_users[i]);
184
+ }
185
+ return allPrograms[_programID].allUsers;
186
+ }
187
+
188
+ function getAllUsers (uint _programID )
189
+ public
190
+ view
191
+ returns (address [])
192
+ {
193
+ return allPrograms[_programID].allUsers;
194
+ }
195
+
196
+ function getUser (uint _programID , address _user )
197
+ public
198
+ view
199
+ returns (
200
+ bool registered ,
201
+ uint balance ,
202
+ uint totalEarned ,
203
+ uint arrayPosition
204
+ )
205
+ {
206
+ registered = allPrograms[_programID].users[_user].registered;
207
+ balance = allPrograms[_programID].users[_user].balance;
208
+ totalEarned = allPrograms[_programID].users[_user].totalEarned;
209
+ arrayPosition = allPrograms[_programID].users[_user].arrayPosition;
210
+ }
211
+
212
+ function userEarned (
213
+ uint _programID ,
214
+ address _user ,
215
+ uint _amountEarned ,
216
+ address _practitioner
217
+ )
218
+ public
219
+ {
220
+ require (msg .sender == _practitioner);
221
+ require (allPrograms[_programID].practitioners[_practitioner].allowance != 0 );
222
+ require (_amountEarned <= allPrograms[_programID].practitioners[_practitioner].allowance,"Exceeds your practitioner limit. Please request a rest " );
223
+ allPrograms[_programID].users[_user].balance += _amountEarned;
224
+ allPrograms[_programID].users[_user].totalEarned += _amountEarned;
225
+ allPrograms[_programID].practitioners[_practitioner].allowance -= _amountEarned;
226
+ allPrograms[_programID].practitioners[_practitioner].pastSentTokens += _amountEarned;
227
+ allPrograms[_programID].balance -= _amountEarned;
228
+ }
229
+
230
+ function userWithdraw (uint _programID , uint _amount )
231
+ public
232
+ {
233
+ require (allPrograms[_programID].users[msg .sender ].registered == true , "You are not registered " );
234
+ require ( allPrograms[_programID].users[msg .sender ].balance >= _amount, "Insufficient funds " );
235
+ allPrograms[_programID].users[msg .sender ].balance -= _amount;
236
+ }
237
+
238
+ function removeUser (uint _programID , address _user )
239
+ public
240
+ onlyOwnerOfProgram (_programID)
241
+ {
242
+ require (allPrograms[_programID].users[_user].balance == 0 , "Please withdraw remaining balance before removing user. " );
243
+ delete allPrograms[_programID].allUsers[allPrograms[_programID].users[_user].arrayPosition];
244
+ allPrograms[_programID].users[_user] = User ({
245
+ registered: false ,
246
+ balance: 0 ,
247
+ totalEarned: 0 ,
248
+ arrayPosition: 999
249
+ });
250
+ //could refractor to move last position to removed position.
251
+ }
252
+
253
+ //PRACTITIONERS functions
254
+
255
+ function addPractitioners (uint _programID , address [] _practitioners , uint _practitionerAllowance )
256
+ public
257
+ onlyOwnerOfProgram (_programID)
258
+ returns (address [])
259
+ {
260
+ for (uint i = 0 ; i < _practitioners.length ; i++ ){
261
+ allPrograms[_programID].practitioners[_practitioners[i]] = Practitioner ({
262
+ allowance: _practitionerAllowance,
263
+ pastSentTokens: 0 ,
264
+ arrayPosition: i
265
+ });
266
+ allPrograms[_programID].allPractitioners.push (_practitioners[i]);
267
+ }
268
+ return allPrograms[_programID].allPractitioners;
269
+ }
270
+
271
+ function changePractitionersAllowance (uint _programID , address _practitioner , uint _newAllowance )
272
+ public
273
+ onlyOwnerOfProgram (_programID)
274
+ {
275
+ allPrograms[_programID].practitioners[_practitioner].allowance += _newAllowance;
276
+ }
277
+
278
+ function removePractitioner (uint _programID , address _practitioner )
279
+ public
280
+ onlyOwnerOfProgram (_programID)
281
+ {
282
+ delete allPrograms[_programID].allPractitioners[allPrograms[_programID].practitioners[_practitioner].arrayPosition];
283
+ allPrograms[_programID].practitioners[_practitioner] = Practitioner ({
284
+ allowance: 0 ,
285
+ pastSentTokens: 0 ,
286
+ arrayPosition: 999
287
+ });
288
+ }
289
+
290
+ function getAllPractitioners (uint _programID )
291
+ public
292
+ view
293
+ returns (address [])
294
+ {
295
+ return allPrograms[_programID].allPractitioners;
296
+ }
297
+
298
+ function getPractitioner (uint _programID , address _practitioner )
299
+ public
300
+ view
301
+ returns (
302
+ uint allowance ,
303
+ uint pastSentTokens ,
304
+ uint arrayPosition
305
+ )
306
+ {
307
+ allowance = allPrograms[_programID].practitioners[_practitioner].allowance;
308
+ pastSentTokens = allPrograms[_programID].practitioners[_practitioner].pastSentTokens;
309
+ arrayPosition = allPrograms[_programID].practitioners[_practitioner].arrayPosition;
310
+ }
311
+ }
0 commit comments