@@ -33,6 +33,11 @@ contract Tasks is DSMath {
33
33
/// @param taskId The newly added task id
34
34
event TaskAdded (uint256 taskId );
35
35
36
+ /// @notice Event logged when a task's security status changes (secure vs. managed)
37
+ /// @param taskId Id of the task
38
+ /// @param secure Boolean of security status (true: secure, false: managed)
39
+ event TaskSecuritySet (uint256 indexed taskId , bool secure );
40
+
36
41
/// @notice Event logged when a task's specification hash changes
37
42
/// @param taskId Id of the task
38
43
/// @param specificationHash New specification hash of the task
@@ -69,6 +74,7 @@ contract Tasks is DSMath {
69
74
uint256 dueDate;
70
75
uint256 completionTimestamp;
71
76
uint256 changeNonce;
77
+ bool secure;
72
78
}
73
79
74
80
struct Role {
@@ -103,6 +109,7 @@ contract Tasks is DSMath {
103
109
roleAssignmentSigs[bytes4 (keccak256 ("setTaskWorkerRole(uint256,address) " ))] = true ;
104
110
105
111
// Initialise the task update reviewers
112
+ reviewers[bytes4 (keccak256 ("setTaskSecurity(uint256,bool) " ))] = [TaskRole.Manager, TaskRole.Worker];
106
113
reviewers[bytes4 (keccak256 ("setTaskBrief(uint256,bytes32) " ))] = [TaskRole.Manager, TaskRole.Worker];
107
114
reviewers[bytes4 (keccak256 ("setTaskDueDate(uint256,uint256) " ))] = [TaskRole.Manager, TaskRole.Worker];
108
115
reviewers[bytes4 (keccak256 ("setTaskSkill(uint256,uint256) " ))] = [TaskRole.Manager, TaskRole.Worker];
@@ -115,8 +122,8 @@ contract Tasks is DSMath {
115
122
reviewers[bytes4 (keccak256 ("cancelTask(uint256) " ))] = [TaskRole.Manager, TaskRole.Worker];
116
123
}
117
124
118
- modifier self () {
119
- require (address (this ) == msg .sender , "task-not-self " );
125
+ modifier self (uint256 _id ) {
126
+ require (managerCanCall (_id) || address (this ) == msg .sender , "task-not-self " );
120
127
_;
121
128
}
122
129
@@ -131,6 +138,16 @@ contract Tasks is DSMath {
131
138
_;
132
139
}
133
140
141
+ modifier taskSecure (uint256 _id ) {
142
+ require (isTaskSecure (_id), "task-not-secure " );
143
+ _;
144
+ }
145
+
146
+ modifier taskManaged (uint256 _id ) {
147
+ require (! isTaskSecure (_id), "task-not-managed " );
148
+ _;
149
+ }
150
+
134
151
modifier taskComplete (uint256 _id ) {
135
152
require (isTaskComplete (_id), "task-not-complete " );
136
153
_;
@@ -162,12 +179,10 @@ contract Tasks is DSMath {
162
179
bytes4 sig;
163
180
uint256 taskId;
164
181
(sig, taskId) = deconstructCall (_data);
165
- require (taskId > 0 && taskId <= taskCount, "task-does-not-exist " );
182
+ require (doesTaskExist (taskId), "task-does-not-exist " );
183
+ require (! isTaskComplete (taskId), "task-complete " );
166
184
require (! roleAssignmentSigs[sig], "task-change-is-role-assign " );
167
185
168
- ColonyDataTypes.ExpenditureStatus status = colony.getExpenditure (tasks[taskId].expenditureId).status;
169
- require (status != ColonyDataTypes.ExpenditureStatus.Finalized, "task-finalized " );
170
-
171
186
uint8 nSignaturesRequired;
172
187
address taskRole1User = getTaskRoleUser (taskId, TaskRole (reviewers[sig][0 ]));
173
188
address taskRole2User = getTaskRoleUser (taskId, TaskRole (reviewers[sig][1 ]));
@@ -219,12 +234,10 @@ contract Tasks is DSMath {
219
234
uint256 taskId;
220
235
address userAddress;
221
236
(sig, taskId, userAddress) = deconstructRoleChangeCall (_data);
222
- require (taskId > 0 && taskId <= taskCount, "task-does-not-exist " );
237
+ require (doesTaskExist (taskId), "task-does-not-exist " );
238
+ require (! isTaskComplete (taskId), "task-complete " );
223
239
require (roleAssignmentSigs[sig], "task-change-is-not-role-assign " );
224
240
225
- ColonyDataTypes.ExpenditureStatus status = colony.getExpenditure (tasks[taskId].expenditureId).status;
226
- require (status != ColonyDataTypes.ExpenditureStatus.Finalized, "task-finalized " );
227
-
228
241
uint8 nSignaturesRequired;
229
242
address manager = getTaskRoleUser (taskId, TaskRole.Manager);
230
243
// If manager wants to set himself to a role
@@ -274,7 +287,8 @@ contract Tasks is DSMath {
274
287
bytes32 _specificationHash ,
275
288
uint256 _domainId ,
276
289
uint256 _skillId ,
277
- uint256 _dueDate
290
+ uint256 _dueDate ,
291
+ bool _secure
278
292
)
279
293
public
280
294
isAdmin (msg .sender , _callerPermissionDomainId, _callerChildSkillIndex, _domainId)
@@ -285,9 +299,13 @@ contract Tasks is DSMath {
285
299
tasks[taskCount].expenditureId = expenditureId;
286
300
tasks[taskCount].specificationHash = _specificationHash;
287
301
tasks[taskCount].dueDate = (_dueDate > 0 ) ? _dueDate : now + 90 days ; // Note: can set dueDate in past?
302
+ tasks[taskCount].secure = _secure;
288
303
289
304
setTaskRoleUser (taskCount, TaskRole.Manager, msg .sender );
290
- setTaskRoleUser (taskCount, TaskRole.Evaluator, msg .sender );
305
+
306
+ if (_secure) {
307
+ setTaskRoleUser (taskCount, TaskRole.Evaluator, msg .sender );
308
+ }
291
309
292
310
if (_skillId > 0 ) {
293
311
this .setTaskSkill (taskCount, _skillId);
@@ -299,6 +317,8 @@ contract Tasks is DSMath {
299
317
300
318
function submitTaskWorkRating (uint256 _id , TaskRole _role , bytes32 _secret )
301
319
public
320
+ taskExists (_id)
321
+ taskSecure (_id)
302
322
taskComplete (_id)
303
323
{
304
324
if (_role == TaskRole.Manager) { // Manager rated by worker
@@ -355,46 +375,56 @@ contract Tasks is DSMath {
355
375
return ratingSecrets[_id].secret[_role];
356
376
}
357
377
378
+ function setTaskSecurity (uint256 _id , bool _secure ) public self (_id) {
379
+ tasks[_id].secure = _secure;
380
+
381
+ if (! _secure) {
382
+ removeTaskEvaluatorRole (_id);
383
+ }
384
+
385
+ emit TaskSecuritySet (_id, _secure);
386
+ }
387
+
358
388
// Note: the domain permissions arguments are placed at the end for consistency with the other role change functions
359
389
function setTaskManagerRole (uint256 _id , address payable _user , uint256 _permissionDomainId , uint256 _childSkillIndex )
360
390
public
361
- self
391
+ self (_id)
362
392
isAdmin (_user, _permissionDomainId, _childSkillIndex, colony.getExpenditure (tasks[_id].expenditureId).domainId)
363
393
{
364
394
setTaskRoleUser (_id, TaskRole.Manager, _user);
365
395
}
366
396
367
- function setTaskEvaluatorRole (uint256 _id , address payable _user ) public self {
397
+ function setTaskEvaluatorRole (uint256 _id , address payable _user ) public self (_id) taskSecure (_id) {
368
398
// Can only assign role if no one is currently assigned to it
369
399
require (getTaskRoleUser (_id, TaskRole.Evaluator) == address (0x0 ), "task-evaluator-role-assigned " );
370
400
setTaskRoleUser (_id, TaskRole.Evaluator, _user);
371
401
}
372
402
373
- function setTaskWorkerRole (uint256 _id , address payable _user ) public self {
403
+ function setTaskWorkerRole (uint256 _id , address payable _user ) public self (_id) {
374
404
// Can only assign role if no one is currently assigned to it
375
405
require (getTaskRoleUser (_id, TaskRole.Worker) == address (0x0 ), "task-worker-role-assigned " );
376
406
uint256 [] memory skills = colony.getExpenditureSlot (tasks[_id].expenditureId, uint256 (TaskRole.Worker)).skills;
377
407
require (skills.length > 0 && skills[0 ] > 0 , "task-skill-not-set " ); // ignore-swc-110
378
408
setTaskRoleUser (_id, TaskRole.Worker, _user);
379
409
}
380
410
381
- function removeTaskEvaluatorRole (uint256 _id ) public self {
411
+ function removeTaskEvaluatorRole (uint256 _id ) public self (_id) {
382
412
setTaskRoleUser (_id, TaskRole.Evaluator, address (0x0 ));
383
413
}
384
414
385
- function removeTaskWorkerRole (uint256 _id ) public self {
415
+ function removeTaskWorkerRole (uint256 _id ) public self (_id) {
386
416
setTaskRoleUser (_id, TaskRole.Worker, address (0x0 ));
387
417
}
388
418
389
- function setTaskManagerPayout (uint256 _id , address _token , uint256 _amount ) public self {
419
+ function setTaskManagerPayout (uint256 _id , address _token , uint256 _amount ) public self (_id) {
390
420
colony.setExpenditurePayout (_id, uint256 (TaskRole.Manager), _token, _amount);
391
421
}
392
422
393
- function setTaskEvaluatorPayout (uint256 _id , address _token , uint256 _amount ) public self {
423
+ function setTaskEvaluatorPayout (uint256 _id , address _token , uint256 _amount ) public self (_id) {
394
424
colony.setExpenditurePayout (_id, uint256 (TaskRole.Evaluator), _token, _amount);
395
425
}
396
426
397
- function setTaskWorkerPayout (uint256 _id , address _token , uint256 _amount ) public self {
427
+ function setTaskWorkerPayout (uint256 _id , address _token , uint256 _amount ) public self (_id) {
398
428
colony.setExpenditurePayout (_id, uint256 (TaskRole.Worker), _token, _amount);
399
429
}
400
430
@@ -421,15 +451,14 @@ contract Tasks is DSMath {
421
451
this .setTaskWorkerPayout (_id, _token, _workerAmount);
422
452
}
423
453
424
- function setTaskSkill (uint256 _id , uint256 _skillId ) public self {
454
+ function setTaskSkill (uint256 _id , uint256 _skillId ) public self (_id) {
425
455
colony.setExpenditureSkill (tasks[_id].expenditureId, uint256 (TaskRole.Worker), _skillId);
426
456
}
427
457
428
458
function setTaskBrief (uint256 _id , bytes32 _specificationHash )
429
459
public
430
- self
460
+ self (_id)
431
461
taskExists (_id)
432
- taskNotComplete (_id)
433
462
{
434
463
tasks[_id].specificationHash = _specificationHash;
435
464
@@ -438,9 +467,8 @@ contract Tasks is DSMath {
438
467
439
468
function setTaskDueDate (uint256 _id , uint256 _dueDate )
440
469
public
441
- self
470
+ self (_id)
442
471
taskExists (_id)
443
- taskNotComplete (_id)
444
472
{
445
473
tasks[_id].dueDate = _dueDate;
446
474
@@ -450,6 +478,7 @@ contract Tasks is DSMath {
450
478
function submitTaskDeliverable (uint256 _id , bytes32 _deliverableHash )
451
479
public
452
480
taskExists (_id)
481
+ taskSecure (_id)
453
482
taskNotComplete (_id)
454
483
confirmTaskRoleIdentity (_id, msg .sender , TaskRole.Worker)
455
484
{
@@ -468,6 +497,7 @@ contract Tasks is DSMath {
468
497
function completeTask (uint256 _id )
469
498
public
470
499
taskExists (_id)
500
+ taskSecure (_id)
471
501
taskNotComplete (_id)
472
502
confirmTaskRoleIdentity (_id, msg .sender , TaskRole.Manager)
473
503
{
@@ -479,17 +509,17 @@ contract Tasks is DSMath {
479
509
480
510
function cancelTask (uint256 _id )
481
511
public
482
- self
512
+ self (_id)
483
513
taskExists (_id)
484
- taskNotComplete (_id)
485
514
{
486
515
colony.cancelExpenditure (tasks[_id].expenditureId);
487
516
}
488
517
489
518
// Permissions pertain to the Arbitration role here
490
- function finalizeTask (uint256 _permissionDomainId , uint256 _childSkillIndex , uint256 _id )
519
+ function finalizeSecureTask (uint256 _permissionDomainId , uint256 _childSkillIndex , uint256 _id )
491
520
public
492
521
taskExists (_id)
522
+ taskSecure (_id)
493
523
taskComplete (_id)
494
524
{
495
525
colony.finalizeExpenditure (tasks[_id].expenditureId);
@@ -510,6 +540,15 @@ contract Tasks is DSMath {
510
540
}
511
541
}
512
542
543
+ function finalizeManagedTask (uint256 _id )
544
+ public
545
+ taskExists (_id)
546
+ taskManaged (_id)
547
+ confirmTaskRoleIdentity (_id, msg .sender , TaskRole.Manager)
548
+ {
549
+ colony.finalizeExpenditure (tasks[_id].expenditureId);
550
+ }
551
+
513
552
function getTaskCount () public view returns (uint256 ) {
514
553
return taskCount;
515
554
}
@@ -629,12 +668,14 @@ contract Tasks is DSMath {
629
668
function taskWorkRatingsAssigned (uint256 _id ) internal view returns (bool ) {
630
669
Role storage workerRole = taskRoles[_id][uint8 (TaskRole.Worker)];
631
670
Role storage managerRole = taskRoles[_id][uint8 (TaskRole.Manager)];
671
+
632
672
return (workerRole.rating != TaskRatings.None) && (managerRole.rating != TaskRatings.None);
633
673
}
634
674
635
675
function taskWorkRatingsClosed (uint256 _id ) internal view returns (bool ) {
636
676
assert (tasks[_id].completionTimestamp > 0 );
637
677
assert (ratingSecrets[_id].count <= 2 );
678
+
638
679
if (ratingSecrets[_id].count == 2 ) {
639
680
return sub (now , ratingSecrets[_id].timestamp) > RATING_REVEAL_TIMEOUT;
640
681
} else {
@@ -667,15 +708,8 @@ contract Tasks is DSMath {
667
708
}
668
709
}
669
710
670
- function setTaskRoleUser (uint256 _id , TaskRole _role , address payable _user )
671
- internal
672
- taskExists (_id)
673
- taskNotComplete (_id)
674
- {
675
- taskRoles[_id][uint8 (_role)] = Role ({
676
- rateFail: false ,
677
- rating: TaskRatings.None
678
- });
711
+ function setTaskRoleUser (uint256 _id , TaskRole _role , address payable _user ) internal {
712
+ taskRoles[_id][uint8 (_role)] = Role ({ rateFail: false , rating: TaskRatings.None });
679
713
680
714
colony.setExpenditureRecipient (tasks[_id].expenditureId, uint256 (_role), _user);
681
715
}
@@ -684,7 +718,15 @@ contract Tasks is DSMath {
684
718
return _id > 0 && _id <= taskCount;
685
719
}
686
720
721
+ function isTaskSecure (uint256 _id ) internal view returns (bool ) {
722
+ return tasks[_id].secure;
723
+ }
724
+
687
725
function isTaskComplete (uint256 _id ) internal view returns (bool ) {
688
726
return tasks[_id].completionTimestamp > 0 ;
689
727
}
728
+
729
+ function managerCanCall (uint256 _id ) internal view returns (bool ) {
730
+ return ! tasks[_id].secure && getTaskRoleUser (_id, TaskRole.Manager) == msg .sender ;
731
+ }
690
732
}
0 commit comments