Skip to content

Commit

Permalink
Merge pull request #845 from JoinColony/feat/arbitration-penalties
Browse files Browse the repository at this point in the history
Arbitration Reputation Penalties
  • Loading branch information
area authored Jun 9, 2020
2 parents 07f21f5 + 6a3f770 commit 0e2338e
Show file tree
Hide file tree
Showing 5 changed files with 97 additions and 8 deletions.
36 changes: 29 additions & 7 deletions contracts/colony/Colony.sol
Original file line number Diff line number Diff line change
Expand Up @@ -117,6 +117,25 @@ contract Colony is ColonyStorage, PatriciaTreeProofs {
return token;
}

function emitDomainReputationPenalty(
uint256 _permissionDomainId,
uint256 _childSkillIndex,
uint256 _domainId,
address _user,
int256 _amount
) public stoppable authDomain(_permissionDomainId, _childSkillIndex, _domainId)
{
require(_amount <= 0, "colony-penalty-cannot-be-positive");
IColonyNetwork(colonyNetworkAddress).appendReputationUpdateLog(_user, _amount, domains[_domainId].skillId);
}

function emitSkillReputationPenalty(uint256 _skillId, address _user, int256 _amount)
public stoppable auth validGlobalSkill(_skillId)
{
require(_amount <= 0, "colony-penalty-cannot-be-positive");
IColonyNetwork(colonyNetworkAddress).appendReputationUpdateLog(_user, _amount, _skillId);
}

function initialiseColony(address _colonyNetworkAddress, address _token) public stoppable {
require(colonyNetworkAddress == address(0x0), "colony-already-initialised-network");
require(token == address(0x0), "colony-already-initialised-token");
Expand Down Expand Up @@ -302,14 +321,17 @@ contract Colony is ColonyStorage, PatriciaTreeProofs {
// v4 to v5
function finishUpgrade() public always {
ColonyAuthority colonyAuthority = ColonyAuthority(address(authority));
bytes4 sig;

// Add stake management functionality
colonyAuthority.setRoleCapability(
uint8(ColonyRole.Arbitration),
address(this),
bytes4(keccak256("transferStake(uint256,uint256,address,address,uint256,uint256,address)")),
true
);
// Add stake management functionality (colonyNetwork#757)
sig = bytes4(keccak256("transferStake(uint256,uint256,address,address,uint256,uint256,address)"));
colonyAuthority.setRoleCapability(uint8(ColonyRole.Arbitration), address(this), sig, true);

// Add reputation penalty functionality (colonyNetwork#845)
sig = bytes4(keccak256("emitDomainReputationPenalty(uint256,uint256,uint256,address,int256)"));
colonyAuthority.setRoleCapability(uint8(ColonyRole.Arbitration), address(this), sig, true);
sig = bytes4(keccak256("emitSkillReputationPenalty(uint256,address,int256)"));
colonyAuthority.setRoleCapability(uint8(ColonyRole.Arbitration), address(this), sig, true);
}

function checkNotAdditionalProtectedVariable(uint256 _slot) public view recovery {
Expand Down
4 changes: 3 additions & 1 deletion contracts/colony/ColonyAuthority.sol
Original file line number Diff line number Diff line change
Expand Up @@ -85,8 +85,10 @@ contract ColonyAuthority is CommonAuthority {
addRoleCapability(ARBITRATION_ROLE, "setExpenditurePayoutModifier(uint256,uint256,uint256,uint256,int256)");
addRoleCapability(ARBITRATION_ROLE, "setExpenditureClaimDelay(uint256,uint256,uint256,uint256,uint256)");

// Added in colony v5
// Added in colony v5 (current version)
addRoleCapability(ARBITRATION_ROLE, "transferStake(uint256,uint256,address,address,uint256,uint256,address)");
addRoleCapability(ARBITRATION_ROLE, "emitDomainReputationPenalty(uint256,uint256,uint256,address,int256)");
addRoleCapability(ARBITRATION_ROLE, "emitSkillReputationPenalty(uint256,address,int256)");
}

function addRoleCapability(uint8 role, bytes memory sig) private {
Expand Down
20 changes: 20 additions & 0 deletions contracts/colony/IColony.sol
Original file line number Diff line number Diff line change
Expand Up @@ -127,6 +127,26 @@ contract IColony is ColonyDataTypes, IRecovery {
/// @return roles bytes32 representation of the roles
function getUserRoles(address who, uint256 where) public view returns (bytes32 roles);

/// @notice Emit a negative domain reputation update. Available only to Arbitration role holders
/// @param _permissionDomainId The domainId in which I hold the Arbitration role
/// @param _childSkillIndex The index that the `_domainId` is relative to `_permissionDomainId`
/// @param _domainId The domain where the user will lose reputation
/// @param _user The user who will lose reputation
/// @param _amount The (negative) amount of reputation to lose
function emitDomainReputationPenalty(
uint256 _permissionDomainId,
uint256 _childSkillIndex,
uint256 _domainId,
address _user,
int256 _amount
) public;

/// @notice Emit a negative skill reputation update. Available only to Arbitration role holders in the root domain
/// @param _skillId The skill where the user will lose reputation
/// @param _user The user who will lose reputation
/// @param _amount The (negative) amount of reputation to lose
function emitSkillReputationPenalty(uint256 _skillId, address _user, int256 _amount) public;

/// @notice Called once when the colony is created to initialise certain storage slot values.
/// @dev Sets the reward inverse to the uint max 2**256 - 1.
/// @param _colonyNetworkAddress Address of the colony network
Expand Down
30 changes: 30 additions & 0 deletions docs/_Interface_IColony.md
Original file line number Diff line number Diff line change
Expand Up @@ -206,6 +206,36 @@ Deobligate the user some amount of tokens, releasing the stake.
|_amount|uint256|Amount of internal token we are deobligating.


### `emitDomainReputationPenalty`

Emit a negative domain reputation update. Available only to Arbitration role holders


**Parameters**

|Name|Type|Description|
|---|---|---|
|_permissionDomainId|uint256|The domainId in which I hold the Arbitration role
|_childSkillIndex|uint256|The index that the `_domainId` is relative to `_permissionDomainId`
|_domainId|uint256|The domain where the user will lose reputation
|_user|address|The user who will lose reputation
|_amount|int256|The (negative) amount of reputation to lose


### `emitSkillReputationPenalty`

Emit a negative skill reputation update. Available only to Arbitration role holders in the root domain


**Parameters**

|Name|Type|Description|
|---|---|---|
|_skillId|uint256|The skill where the user will lose reputation
|_user|address|The user who will lose reputation
|_amount|int256|The (negative) amount of reputation to lose


### `executeTaskChange`

Executes a task update transaction `_data` which is approved and signed by two of its roles (e.g. manager and worker) using the detached signatures for these users.
Expand Down
15 changes: 15 additions & 0 deletions test/contracts-network/colony-permissions.js
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ import {
ADMINISTRATION_ROLE,
INITIAL_FUNDING,
SPECIFICATION_HASH,
GLOBAL_SKILL_ID,
} from "../../helpers/constants";

import { fundColonyWithTokens, makeTask, setupRandomColony } from "../../helpers/test-data-generator";
Expand Down Expand Up @@ -278,6 +279,20 @@ contract("ColonyPermissions", (accounts) => {
await colony.setAdministrationRole(1, 1, USER2, 3, true, { from: USER1 });
});

it("should allow users with arbitration permission to emit negative reputation penalties", async () => {
await colony.setArbitrationRole(1, UINT256_MAX, USER1, 1, true);
await colony.setArbitrationRole(1, 0, USER2, 2, true);

// Domain penalties
await colony.emitDomainReputationPenalty(1, 1, 3, USER2, -100, { from: USER1 });
await checkErrorRevert(colony.emitDomainReputationPenalty(1, 1, 3, USER2, 100, { from: USER1 }), "colony-penalty-cannot-be-positive");

// Skill penalties (root domain only)
await colony.emitSkillReputationPenalty(GLOBAL_SKILL_ID, USER2, -100, { from: USER1 });
await checkErrorRevert(colony.emitSkillReputationPenalty(GLOBAL_SKILL_ID, USER2, 100, { from: USER1 }), "colony-penalty-cannot-be-positive");
await checkErrorRevert(colony.emitSkillReputationPenalty(GLOBAL_SKILL_ID, USER2, -100, { from: USER2 }), "ds-auth-unauthorized");
});

it("should allow permissions to propagate to subdomains", async () => {
// Give User 2 funding permissions in domain 1
await colony.setFundingRole(1, UINT256_MAX, USER2, 1, true);
Expand Down

0 comments on commit 0e2338e

Please sign in to comment.