@@ -7,8 +7,6 @@ import "@openzeppelin/contracts/access/Ownable.sol";
7
7
import "@openzeppelin/contracts/math/SafeMath.sol " ;
8
8
import "@openzeppelin/contracts/token/ERC20/IERC20.sol " ;
9
9
10
- //TODO Do we want console.log logging, start with Activity constructor?..
11
-
12
10
contract SinglePlayerCommit is Ownable {
13
11
using SafeMath for uint256 ;
14
12
@@ -21,26 +19,18 @@ contract SinglePlayerCommit is Ownable {
21
19
/***************
22
20
DATA TYPES
23
21
***************/
24
- struct Measure {
25
- string name;
26
- bool allowed;
27
- }
28
-
29
22
struct Activity {
30
- string name; // e.g. "cycling"
31
- bytes32 [] measures; // keys from allowedMeasures
32
- uint256 [2 ][] ranges; // array of [min,max] goal values
23
+ string name; // e.g. "cycling" with list scoped to activities supported by Strava
33
24
address oracle;
34
25
bool allowed;
35
26
}
36
27
37
28
struct Commitment {
38
29
address committer; // user
39
- bytes32 activity; // key from allowedActivities
40
- bytes32 measure; // key from allowedMeasures
41
- uint256 goalValue; // must be within range of Activity.measures[measureIndex]
42
- uint256 start;
43
- uint256 end;
30
+ bytes32 activityKey;
31
+ uint256 goalValue;
32
+ uint256 startTime;
33
+ uint256 endTime;
44
34
uint256 stake; // amount of token staked, scaled by token decimals
45
35
bool exists; // flag to help check if commitment exists
46
36
uint256 reportedValue; // as reported by oracle
@@ -52,8 +42,8 @@ contract SinglePlayerCommit is Ownable {
52
42
***************/
53
43
event NewCommitment (
54
44
address committer ,
55
- string activity ,
56
- string measure ,
45
+ string activityName ,
46
+ uint256 goalValue ,
57
47
uint256 startTime ,
58
48
uint256 endTime ,
59
49
uint256 stake
@@ -68,11 +58,8 @@ contract SinglePlayerCommit is Ownable {
68
58
mapping (bytes32 => Activity) public allowedActivities;
69
59
bytes32 [] public activityList;
70
60
71
- mapping (bytes32 => Measure) public allowedMeasures;
72
- bytes32 [] public measureList;
73
-
74
61
mapping (address => Commitment) public commitments; // active commitments
75
- // address[] public committers ; // addresses with active commitments
62
+ address [] public userCommitments ; // addresses with active commitments
76
63
77
64
mapping (address => uint256 ) public balances; // current token balances
78
65
uint256 public committerBalance; // sum of current token balances
@@ -82,71 +69,35 @@ contract SinglePlayerCommit is Ownable {
82
69
********/
83
70
// constructor
84
71
constructor (
85
- string memory _activity ,
86
- string [] memory _measures ,
87
- uint256 [2 ][] memory _ranges ,
88
- address _oracle ,
72
+ string [] memory _activityList ,
73
+ address _oracleAddress ,
89
74
address _token
90
75
) public {
91
76
console.log ("Constructor called for SinglePlayerCommit contract " );
92
77
// set up token interface
93
78
token = IERC20 (_token);
79
+ require (_activityList.length >= 1 , "SPC::constructor - activityList empty " );
94
80
95
- // need to create fixed length bytes32 array to pass to _addActivity
96
- uint256 len = _measures.length ;
97
- bytes32 [] memory measureKeys = new bytes32 [](len);
98
-
99
- // register measures
100
- for (uint256 i = 0 ; i < len; i++ ) {
101
- // register the measure
102
- bytes32 measureKey = _addMeasure (_measures[i]);
103
- // add its key to the array to be passed to _addActivity
104
- measureKeys[i] = measureKey;
105
- }
106
-
107
- // register activity
108
- _addActivity (_activity, measureKeys, _ranges, _oracle);
81
+ // register allowed activities with corresponding oracle
82
+ _addActivities (_activityList, _oracleAddress);
109
83
}
110
84
111
- // fallback function (if exists)
112
- // TODO
113
-
114
85
// view functions
115
86
116
87
function getActivityName (bytes32 _activityKey ) public view returns (string memory ) {
117
88
return allowedActivities[_activityKey].name;
118
89
}
119
90
120
- function getActivityMeasures (bytes32 _activityKey ) public view returns (string [] memory measureNames ) {
121
- bytes32 [] memory measures = allowedActivities[_activityKey].measures;
122
- uint256 len = measures.length ;
123
- measureNames = new string [](len);
124
- for (uint256 i = 0 ; i < len; i++ ) {
125
- measureNames[i] = getMeasureName (measures[i]);
126
- }
127
-
128
- return measureNames;
129
- }
130
-
131
- function getMeasureName (bytes32 _measureKey ) public view returns (string memory ) {
132
- return allowedMeasures[_measureKey].name;
133
- }
134
-
135
91
// other public functions
136
92
function depositAndCommit (
137
- bytes32 _activity ,
138
- uint256 _measureIndex ,
139
- uint256 _goal ,
93
+ bytes32 _activityKey ,
94
+ uint256 _goalValue ,
140
95
uint256 _startTime ,
141
96
uint256 _stake ,
142
97
uint256 _depositAmount
143
98
) public returns (bool ) {
144
99
require (deposit (_depositAmount), "SPC::depositAndCommit - deposit failed " );
145
-
146
- require (
147
- makeCommitment (_activity, _measureIndex, _goal, _startTime, _stake),
148
- "SPC::depositAndCommit - commitment failed "
149
- );
100
+ require (makeCommitment (_activityKey, _goalValue, _startTime, _stake), "SPC::depositAndCommit - commitment failed " );
150
101
151
102
return true ;
152
103
}
@@ -165,39 +116,31 @@ contract SinglePlayerCommit is Ownable {
165
116
}
166
117
167
118
function makeCommitment (
168
- bytes32 _activity ,
169
- uint256 _measureIndex , // index of the Activity.measures array
170
- uint256 _goal ,
119
+ bytes32 _activityKey ,
120
+ uint256 _goalValue ,
171
121
uint256 _startTime ,
172
122
uint256 _stake
173
123
) public returns (bool ) {
174
124
console.log ("makeCommitment called by %s " , msg .sender );
175
125
176
126
require (! commitments[msg .sender ].exists, "SPC::makeCommitment - msg.sender already has a commitment " );
177
- require (allowedActivities[_activity].allowed, "SPC::makeCommitment - activity doesn't exist or isn't allowed " );
178
- require (allowedActivities[_activity].measures.length >= _measureIndex+1 , "SPC::makeCommitment - measure index out of bounds " );
179
-
180
- bytes32 measure = allowedActivities[_activity].measures[_measureIndex];
181
-
182
- require (allowedMeasures[measure].allowed, "SPC::makeCommitment - measure doesn't exist or isn't allowed " );
127
+ require (
128
+ allowedActivities[_activityKey].allowed,
129
+ "SPC::makeCommitment - activity doesn't exist or isn't allowed "
130
+ );
183
131
require (_startTime > block .timestamp , "SPC::makeCommitment - commitment cannot start in the past " );
184
-
185
- uint256 [2 ] storage range = allowedActivities[_activity].ranges[_measureIndex];
186
- require (_goal >= range[0 ], "SPC::makeCommitment - goal is too low " );
187
- require (_goal <= range[1 ], "SPC::makeCommitment - goal is too high " );
188
-
132
+ require (_goalValue > 1 , "SPC::makeCommitment - goal is too low " );
189
133
require (balances[msg .sender ] >= _stake, "SPC::makeCommitment - insufficient token balance " );
190
134
191
135
uint256 endTime = _startTime.add (7 days);
192
136
193
137
// create commitment...
194
138
Commitment memory commitment = Commitment ({
195
139
committer: msg .sender ,
196
- activity: _activity,
197
- measure: measure,
198
- goalValue: _goal,
199
- start: _startTime,
200
- end: endTime,
140
+ activityKey: _activityKey,
141
+ goalValue: _goalValue,
142
+ startTime: _startTime,
143
+ endTime: endTime,
201
144
stake: _stake,
202
145
exists: true ,
203
146
reportedValue: 0 ,
@@ -206,16 +149,8 @@ contract SinglePlayerCommit is Ownable {
206
149
207
150
// ...and add it to storage
208
151
commitments[msg .sender ] = commitment;
209
- // committers.push(msg.sender);
210
-
211
- emit NewCommitment (
212
- msg .sender ,
213
- allowedActivities[_activity].name,
214
- allowedMeasures[measure].name,
215
- _startTime,
216
- endTime,
217
- _stake
218
- );
152
+
153
+ emit NewCommitment (msg .sender , allowedActivities[_activityKey].name, _goalValue, _startTime, endTime, _stake);
219
154
220
155
return true ;
221
156
}
@@ -247,16 +182,13 @@ contract SinglePlayerCommit is Ownable {
247
182
Commitment memory commitment = commitments[committer];
248
183
249
184
// check if commitment has ended
250
- require (commitment.end < block .timestamp , "SPC::processCommitment - commitment is still active " );
185
+ require (commitment.endTime < block .timestamp , "SPC::processCommitment - commitment is still active " );
251
186
252
187
bool met = commitment.met;
253
188
uint256 stake = commitment.stake;
254
189
255
190
// "delete" the expired commitment
256
191
commitments[committer].exists = false ;
257
- // remove the committer from the list of committers
258
- // committers[committer] = committers[committers.length.sub(1)];
259
- // committers.pop();
260
192
261
193
uint256 penalty;
262
194
@@ -271,58 +203,46 @@ contract SinglePlayerCommit is Ownable {
271
203
emit CommitmentEnded (committer, met, penalty);
272
204
}
273
205
274
- // function processCommitments() public returns (bool) {
275
- // for (uint256 i = 0; i < committers.length; i.add(1)) {
276
- // processCommitment(committers[i]);
277
- // }
278
-
279
- // return true;
280
- // }
281
-
282
206
function ownerWithdraw (uint256 amount ) public onlyOwner returns (bool ) {
283
207
uint256 available = token.balanceOf (address (this )).sub (committerBalance);
284
208
285
209
require (amount <= available, "SPC::ownerWithdraw - not enough available balance " );
286
-
287
210
require (token.transfer (msg .sender , amount), "SPC::ownerWithdraw - token transfer failed " );
288
211
289
212
return true ;
290
213
}
291
214
292
215
// internal functions
216
+ function _addActivities (string [] memory _activityList , address oracleAddress ) internal {
217
+ uint256 arrayLength = _activityList.length ;
293
218
294
- function _addMeasure (string memory _name ) internal returns (bytes32 measureKey ) {
295
- Measure memory measure = Measure ({ name: _name, allowed: true });
296
-
297
- measureKey = keccak256 (abi.encode (_name));
298
- allowedMeasures[measureKey] = measure;
299
- measureList.push (measureKey);
219
+ for (uint256 i = 0 ; i < arrayLength; i++ ) {
220
+ _addActivity (_activityList[i], oracleAddress);
221
+ }
300
222
301
- return measureKey ;
223
+ console. log ( " All provided activities added " ) ;
302
224
}
303
225
304
- function _addActivity (
305
- string memory _name ,
306
- bytes32 [] memory _measures ,
307
- uint256 [2 ][] memory _ranges ,
308
- address _oracle
309
- ) internal returns (bytes32 activityKey ) {
310
- uint256 measuresLength = _measures.length ;
311
- require (measuresLength == _ranges.length , "SPC::_addActivity - measures and ranges must have same length " );
312
-
313
- Activity memory activity;
314
-
315
- activity.name = _name;
316
- activity.oracle = _oracle;
317
- activity.measures = _measures;
318
- activity.ranges = _ranges;
226
+ function _addActivity (string memory _activityName , address _oracleAddress ) internal returns (bytes32 activityKey ) {
227
+ bytes memory activityNameBytes = bytes (_activityName);
228
+ require (activityNameBytes.length > 0 , "SPC::_addActivity - _activityName empty " );
229
+
230
+ bytes32 _activityKey = keccak256 (abi.encode (_activityName));
231
+
232
+ Activity storage activity = allowedActivities[_activityKey];
233
+ activity.name = _activityName;
234
+ activity.oracle = _oracleAddress;
319
235
activity.allowed = true ;
320
236
321
- activityKey = keccak256 (abi.encode (_name));
322
- allowedActivities[activityKey] = activity;
323
- activityList.push (activityKey);
237
+ console.log (
238
+ "Registered activity %s, oracle %s, allowed %s " ,
239
+ allowedActivities[_activityKey].name,
240
+ allowedActivities[_activityKey].oracle,
241
+ allowedActivities[_activityKey].allowed
242
+ );
324
243
325
- return activityKey;
244
+ activityList.push (_activityKey);
245
+ return _activityKey;
326
246
}
327
247
328
248
function _changeCommitterBalance (uint256 amount , bool add ) internal returns (bool ) {
@@ -340,4 +260,4 @@ contract SinglePlayerCommit is Ownable {
340
260
341
261
return true ;
342
262
}
343
- }
263
+ }
0 commit comments