Skip to content

Commit

Permalink
Introduce secure vs. managed tasks
Browse files Browse the repository at this point in the history
  • Loading branch information
kronosapiens committed Sep 24, 2019
1 parent 3bdf6c1 commit b00ef43
Show file tree
Hide file tree
Showing 2 changed files with 274 additions and 137 deletions.
72 changes: 55 additions & 17 deletions contracts/extensions/Tasks.sol
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,11 @@ contract Tasks is DSMath {
/// @param taskId The newly added task id
event TaskAdded(uint256 taskId);

/// @notice Event logged when a task's security status changes (secure vs. managed)
/// @param taskId Id of the task
/// @param secure Boolean of security status (true: secure, false: managed)
event TaskSecuritySet(uint256 indexed taskId, bool secure);

/// @notice Event logged when a task's specification hash changes
/// @param taskId Id of the task
/// @param specificationHash New specification hash of the task
Expand Down Expand Up @@ -69,6 +74,7 @@ contract Tasks is DSMath {
uint256 dueDate;
uint256 completionTimestamp;
uint256 changeNonce;
bool secure;
}

struct Role {
Expand Down Expand Up @@ -103,6 +109,7 @@ contract Tasks is DSMath {
roleAssignmentSigs[bytes4(keccak256("setTaskWorkerRole(uint256,address)"))] = true;

// Initialise the task update reviewers
reviewers[bytes4(keccak256("setTaskSecurity(uint256,bool)"))] = [TaskRole.Manager, TaskRole.Worker];
reviewers[bytes4(keccak256("setTaskBrief(uint256,bytes32)"))] = [TaskRole.Manager, TaskRole.Worker];
reviewers[bytes4(keccak256("setTaskDueDate(uint256,uint256)"))] = [TaskRole.Manager, TaskRole.Worker];
reviewers[bytes4(keccak256("setTaskSkill(uint256,uint256)"))] = [TaskRole.Manager, TaskRole.Worker];
Expand All @@ -115,8 +122,8 @@ contract Tasks is DSMath {
reviewers[bytes4(keccak256("cancelTask(uint256)"))] = [TaskRole.Manager, TaskRole.Worker];
}

modifier self() {
require(address(this) == msg.sender, "task-not-self");
modifier self(uint256 _id) {
require(managerCanCall(_id) || address(this) == msg.sender, "task-not-self");
_;
}

Expand Down Expand Up @@ -274,7 +281,8 @@ contract Tasks is DSMath {
bytes32 _specificationHash,
uint256 _domainId,
uint256 _skillId,
uint256 _dueDate
uint256 _dueDate,
bool _secure
)
public
isAdmin(msg.sender, _callerPermissionDomainId, _callerChildSkillIndex, _domainId)
Expand All @@ -285,9 +293,13 @@ contract Tasks is DSMath {
tasks[taskCount].expenditureId = expenditureId;
tasks[taskCount].specificationHash = _specificationHash;
tasks[taskCount].dueDate = (_dueDate > 0) ? _dueDate : now + 90 days; // Note: can set dueDate in past?
tasks[taskCount].secure = _secure;

setTaskRoleUser(taskCount, TaskRole.Manager, msg.sender);
setTaskRoleUser(taskCount, TaskRole.Evaluator, msg.sender);

if (_secure) {
setTaskRoleUser(taskCount, TaskRole.Evaluator, msg.sender);
}

if (_skillId > 0) {
this.setTaskSkill(taskCount, _skillId);
Expand Down Expand Up @@ -355,46 +367,56 @@ contract Tasks is DSMath {
return ratingSecrets[_id].secret[_role];
}

function setTaskSecurity(uint256 _id, bool _secure) public self(_id) {
tasks[_id].secure = _secure;

if (!_secure) {
removeTaskEvaluatorRole(_id);
}

emit TaskSecuritySet(_id, _secure);
}

// Note: the domain permissions arguments are placed at the end for consistency with the other role change functions
function setTaskManagerRole(uint256 _id, address payable _user, uint256 _permissionDomainId, uint256 _childSkillIndex)
public
self
self(_id)
isAdmin(_user, _permissionDomainId, _childSkillIndex, colony.getExpenditure(tasks[_id].expenditureId).domainId)
{
setTaskRoleUser(_id, TaskRole.Manager, _user);
}

function setTaskEvaluatorRole(uint256 _id, address payable _user) public self {
function setTaskEvaluatorRole(uint256 _id, address payable _user) public self(_id) {
// Can only assign role if no one is currently assigned to it
require(getTaskRoleUser(_id, TaskRole.Evaluator) == address(0x0), "task-evaluator-role-assigned");
setTaskRoleUser(_id, TaskRole.Evaluator, _user);
}

function setTaskWorkerRole(uint256 _id, address payable _user) public self {
function setTaskWorkerRole(uint256 _id, address payable _user) public self(_id) {
// Can only assign role if no one is currently assigned to it
require(getTaskRoleUser(_id, TaskRole.Worker) == address(0x0), "task-worker-role-assigned");
uint256[] memory skills = colony.getExpenditureSlot(tasks[_id].expenditureId, uint256(TaskRole.Worker)).skills;
require(skills.length > 0 && skills[0] > 0, "task-skill-not-set"); // ignore-swc-110
setTaskRoleUser(_id, TaskRole.Worker, _user);
}

function removeTaskEvaluatorRole(uint256 _id) public self {
function removeTaskEvaluatorRole(uint256 _id) public self(_id) {
setTaskRoleUser(_id, TaskRole.Evaluator, address(0x0));
}

function removeTaskWorkerRole(uint256 _id) public self {
function removeTaskWorkerRole(uint256 _id) public self(_id) {
setTaskRoleUser(_id, TaskRole.Worker, address(0x0));
}

function setTaskManagerPayout(uint256 _id, address _token, uint256 _amount) public self {
function setTaskManagerPayout(uint256 _id, address _token, uint256 _amount) public self(_id) {
colony.setExpenditurePayout(_id, uint256(TaskRole.Manager), _token, _amount);
}

function setTaskEvaluatorPayout(uint256 _id, address _token, uint256 _amount) public self {
function setTaskEvaluatorPayout(uint256 _id, address _token, uint256 _amount) public self(_id) {
colony.setExpenditurePayout(_id, uint256(TaskRole.Evaluator), _token, _amount);
}

function setTaskWorkerPayout(uint256 _id, address _token, uint256 _amount) public self {
function setTaskWorkerPayout(uint256 _id, address _token, uint256 _amount) public self(_id) {
colony.setExpenditurePayout(_id, uint256(TaskRole.Worker), _token, _amount);
}

Expand All @@ -421,13 +443,13 @@ contract Tasks is DSMath {
this.setTaskWorkerPayout(_id, _token, _workerAmount);
}

function setTaskSkill(uint256 _id, uint256 _skillId) public self {
function setTaskSkill(uint256 _id, uint256 _skillId) public self(_id) {
colony.setExpenditureSkill(tasks[_id].expenditureId, uint256(TaskRole.Worker), _skillId);
}

function setTaskBrief(uint256 _id, bytes32 _specificationHash)
public
self
self(_id)
taskExists(_id)
taskNotComplete(_id)
{
Expand All @@ -438,7 +460,7 @@ contract Tasks is DSMath {

function setTaskDueDate(uint256 _id, uint256 _dueDate)
public
self
self(_id)
taskExists(_id)
taskNotComplete(_id)
{
Expand Down Expand Up @@ -479,19 +501,21 @@ contract Tasks is DSMath {

function cancelTask(uint256 _id)
public
self
self(_id)
taskExists(_id)
taskNotComplete(_id)
{
colony.cancelExpenditure(tasks[_id].expenditureId);
}

// Permissions pertain to the Arbitration role here
function finalizeTask(uint256 _permissionDomainId, uint256 _childSkillIndex, uint256 _id)
function finalizeSecureTask(uint256 _permissionDomainId, uint256 _childSkillIndex, uint256 _id)
public
taskExists(_id)
taskComplete(_id)
{
require(tasks[_id].secure, "task-not-secure");

colony.finalizeExpenditure(tasks[_id].expenditureId);

assignWorkRatings(_id);
Expand All @@ -510,6 +534,16 @@ contract Tasks is DSMath {
}
}

function finalizeManagedTask(uint256 _id)
public
taskExists(_id)
confirmTaskRoleIdentity(_id, msg.sender, TaskRole.Manager)
{
require(!tasks[_id].secure, "task-not-managed");

colony.finalizeExpenditure(tasks[_id].expenditureId);
}

function getTaskCount() public view returns (uint256) {
return taskCount;
}
Expand Down Expand Up @@ -687,4 +721,8 @@ contract Tasks is DSMath {
function isTaskComplete(uint256 _id) internal view returns (bool) {
return tasks[_id].completionTimestamp > 0;
}

function managerCanCall(uint256 _id) internal view returns (bool) {
return !tasks[_id].secure && getTaskRoleUser(_id, TaskRole.Manager) == msg.sender;
}
}
Loading

0 comments on commit b00ef43

Please sign in to comment.