Skip to content

Commit 6ffb319

Browse files
author
Spencer Graham
authored
Merge pull request #11 from CommitPool/fix_activity_constructor
Fix activity constructor CU-emx4r3
2 parents 25a237a + ca3cebd commit 6ffb319

File tree

6 files changed

+2324
-230
lines changed

6 files changed

+2324
-230
lines changed

README.md

Lines changed: 2 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -16,28 +16,13 @@ Currently Ganache and Node 14 are not playing well together. To get started:
1616

1717
## Features
1818

19-
Single Player mode features:
20-
21-
- [x] Creation of Commitment
22-
- [ ] Management of Activities
23-
- [ ] Management of Measures
24-
- [x] Execution of commitment settlement
25-
2619
#### Creation of Commitment
2720

28-
A commitment consists of an ```activity```, a ```measure``` for given activity, a ```start time```, and ```stake```. We will set the ```end date``` 7 days after the startdate.
21+
A commitment consists of an ```activity```, a ```goalValue``` for given activity, a ```startTime```, and ```stake```. We will automagically set the ```endTime``` 7 days after the startdate.
2922

3023
#### Management of Activities
3124

32-
An activity consists of a ```name```, a ```measure``` to express activity metrics, an array of accepted ```ranges```, and the ```oracle``` address. Activities can be enabled by setting it to ```allowed```.
33-
34-
For the Single Player mode ```biking``` is the only available activity, as declared in ```scripts/deploy.ts```
35-
36-
#### Management of Measures
37-
38-
A measure has a ```name``` and can be enabled by setting it to ```allowed```.
39-
40-
For the Single Player mode ```km``` is the only available measure, as declared in ```scripts/deploy.ts```
25+
An activity consists of a ```name``` and the ```oracle``` address. Activities can be enabled by setting it to ```allowed```.
4126

4227
#### Execution of commitment settlement
4328

contracts/SinglePlayerCommit.sol

Lines changed: 54 additions & 134 deletions
Original file line numberDiff line numberDiff line change
@@ -7,8 +7,6 @@ import "@openzeppelin/contracts/access/Ownable.sol";
77
import "@openzeppelin/contracts/math/SafeMath.sol";
88
import "@openzeppelin/contracts/token/ERC20/IERC20.sol";
99

10-
//TODO Do we want console.log logging, start with Activity constructor?..
11-
1210
contract SinglePlayerCommit is Ownable {
1311
using SafeMath for uint256;
1412

@@ -21,26 +19,18 @@ contract SinglePlayerCommit is Ownable {
2119
/***************
2220
DATA TYPES
2321
***************/
24-
struct Measure {
25-
string name;
26-
bool allowed;
27-
}
28-
2922
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
3324
address oracle;
3425
bool allowed;
3526
}
3627

3728
struct Commitment {
3829
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;
4434
uint256 stake; // amount of token staked, scaled by token decimals
4535
bool exists; // flag to help check if commitment exists
4636
uint256 reportedValue; // as reported by oracle
@@ -52,8 +42,8 @@ contract SinglePlayerCommit is Ownable {
5242
***************/
5343
event NewCommitment(
5444
address committer,
55-
string activity,
56-
string measure,
45+
string activityName,
46+
uint256 goalValue,
5747
uint256 startTime,
5848
uint256 endTime,
5949
uint256 stake
@@ -68,11 +58,8 @@ contract SinglePlayerCommit is Ownable {
6858
mapping(bytes32 => Activity) public allowedActivities;
6959
bytes32[] public activityList;
7060

71-
mapping(bytes32 => Measure) public allowedMeasures;
72-
bytes32[] public measureList;
73-
7461
mapping(address => Commitment) public commitments; // active commitments
75-
// address[] public committers; // addresses with active commitments
62+
address[] public userCommitments; // addresses with active commitments
7663

7764
mapping(address => uint256) public balances; // current token balances
7865
uint256 public committerBalance; // sum of current token balances
@@ -82,71 +69,35 @@ contract SinglePlayerCommit is Ownable {
8269
********/
8370
// constructor
8471
constructor(
85-
string memory _activity,
86-
string[] memory _measures,
87-
uint256[2][] memory _ranges,
88-
address _oracle,
72+
string[] memory _activityList,
73+
address _oracleAddress,
8974
address _token
9075
) public {
9176
console.log("Constructor called for SinglePlayerCommit contract");
9277
// set up token interface
9378
token = IERC20(_token);
79+
require(_activityList.length >= 1, "SPC::constructor - activityList empty");
9480

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);
10983
}
11084

111-
// fallback function (if exists)
112-
// TODO
113-
11485
// view functions
11586

11687
function getActivityName(bytes32 _activityKey) public view returns (string memory) {
11788
return allowedActivities[_activityKey].name;
11889
}
11990

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-
13591
// other public functions
13692
function depositAndCommit(
137-
bytes32 _activity,
138-
uint256 _measureIndex,
139-
uint256 _goal,
93+
bytes32 _activityKey,
94+
uint256 _goalValue,
14095
uint256 _startTime,
14196
uint256 _stake,
14297
uint256 _depositAmount
14398
) public returns (bool) {
14499
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");
150101

151102
return true;
152103
}
@@ -165,39 +116,31 @@ contract SinglePlayerCommit is Ownable {
165116
}
166117

167118
function makeCommitment(
168-
bytes32 _activity,
169-
uint256 _measureIndex, // index of the Activity.measures array
170-
uint256 _goal,
119+
bytes32 _activityKey,
120+
uint256 _goalValue,
171121
uint256 _startTime,
172122
uint256 _stake
173123
) public returns (bool) {
174124
console.log("makeCommitment called by %s", msg.sender);
175125

176126
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+
);
183131
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");
189133
require(balances[msg.sender] >= _stake, "SPC::makeCommitment - insufficient token balance");
190134

191135
uint256 endTime = _startTime.add(7 days);
192136

193137
// create commitment...
194138
Commitment memory commitment = Commitment({
195139
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,
201144
stake: _stake,
202145
exists: true,
203146
reportedValue: 0,
@@ -206,16 +149,8 @@ contract SinglePlayerCommit is Ownable {
206149

207150
// ...and add it to storage
208151
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);
219154

220155
return true;
221156
}
@@ -247,16 +182,13 @@ contract SinglePlayerCommit is Ownable {
247182
Commitment memory commitment = commitments[committer];
248183

249184
// 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");
251186

252187
bool met = commitment.met;
253188
uint256 stake = commitment.stake;
254189

255190
// "delete" the expired commitment
256191
commitments[committer].exists = false;
257-
// remove the committer from the list of committers
258-
// committers[committer] = committers[committers.length.sub(1)];
259-
// committers.pop();
260192

261193
uint256 penalty;
262194

@@ -271,58 +203,46 @@ contract SinglePlayerCommit is Ownable {
271203
emit CommitmentEnded(committer, met, penalty);
272204
}
273205

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-
282206
function ownerWithdraw(uint256 amount) public onlyOwner returns (bool) {
283207
uint256 available = token.balanceOf(address(this)).sub(committerBalance);
284208

285209
require(amount <= available, "SPC::ownerWithdraw - not enough available balance");
286-
287210
require(token.transfer(msg.sender, amount), "SPC::ownerWithdraw - token transfer failed");
288211

289212
return true;
290213
}
291214

292215
// internal functions
216+
function _addActivities(string[] memory _activityList, address oracleAddress) internal {
217+
uint256 arrayLength = _activityList.length;
293218

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+
}
300222

301-
return measureKey;
223+
console.log("All provided activities added");
302224
}
303225

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;
319235
activity.allowed = true;
320236

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+
);
324243

325-
return activityKey;
244+
activityList.push(_activityKey);
245+
return _activityKey;
326246
}
327247

328248
function _changeCommitterBalance(uint256 amount, bool add) internal returns (bool) {
@@ -340,4 +260,4 @@ contract SinglePlayerCommit is Ownable {
340260

341261
return true;
342262
}
343-
}
263+
}

0 commit comments

Comments
 (0)