Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Reputation Voting #644

Merged
merged 61 commits into from
Sep 4, 2020
Merged
Show file tree
Hide file tree
Changes from 60 commits
Commits
Show all changes
61 commits
Select commit Hold shift + click to select a range
7c2bc22
Create VotingBase and VotingReputation
kronosapiens Jun 12, 2019
5bd6de6
Add support for vote actions
kronosapiens Jun 19, 2019
c99f70a
Add VotingReputationFactory
kronosapiens Jun 21, 2019
a90996f
Make polls binary
kronosapiens Jun 26, 2019
df4189f
Add ability to create root and domain polls
kronosapiens Jan 9, 2020
6374b71
Delete VotingBase and add support for staking
kronosapiens Jan 19, 2020
8b8da00
Set voting window to 2 days, clean up tests
kronosapiens Jan 26, 2020
d422dc2
Add support for tracking prior votes on variables
kronosapiens Jan 28, 2020
ef4f3d8
Rename userVotes to voteSecrets
kronosapiens Mar 10, 2020
c61979f
Add staking flow!
kronosapiens Mar 15, 2020
60cccd9
Add events and support for claiming voter comp by colony
kronosapiens Mar 25, 2020
2a610ee
Conform to new linting rules
kronosapiens Mar 27, 2020
cd0e11a
Add escalation flow
kronosapiens May 8, 2020
472472f
Add loser penalty, remove leads
kronosapiens May 22, 2020
6d0f9b2
Create activePolls to track ongoing polls
kronosapiens Jun 9, 2020
d0b589a
Extend claimDelay for expenditure state polls
kronosapiens Jun 12, 2020
679137c
Add fold & call
kronosapiens Jun 17, 2020
8346a6f
Add target
kronosapiens Jun 23, 2020
0aa118f
Add initialise and deprecate functionality
kronosapiens Jun 23, 2020
ed1c4b1
Add crowdfunding option
kronosapiens Jun 23, 2020
7ff395d
Respond to review comments
kronosapiens Jun 29, 2020
e1d77ae
Convert votes from bool to uint256
kronosapiens Jul 1, 2020
3bbddcf
Respond to review comments II
kronosapiens Jul 1, 2020
0a4a2a0
Respond to review comments III
kronosapiens Jul 7, 2020
0631f90
Remove stake responses
kronosapiens Jul 17, 2020
2f2be73
Remove activePoll, add unstakePoll logic
kronosapiens Jul 17, 2020
aadcbb3
Add stake withdraw restriction
kronosapiens Jul 20, 2020
22d8cb0
Limit locking to expenditure state changes
kronosapiens Jul 21, 2020
8338d85
Disallow staking after commit cutoff unless other side is staked
kronosapiens Jul 21, 2020
b8398e3
Improve timestamp handling
kronosapiens Jul 24, 2020
f4c68a7
Respond to review comments IV
kronosapiens Jul 24, 2020
9a0f739
Rename executed to finalized
kronosapiens Jul 30, 2020
687d89c
Updates to comments, and one rename of a variable
area Jul 30, 2020
292b039
Respond to review comments V
kronosapiens Jul 30, 2020
8a8b738
Respond to reviewer feedback VI
kronosapiens Jul 31, 2020
1cbbf5f
Update reward accounting for escalations
kronosapiens Aug 4, 2020
0680d88
Correctly hash expenditure slots
kronosapiens Aug 4, 2020
209b753
Rename poll to motion
kronosapiens Aug 5, 2020
15d50c4
Make ties a non-executing outcome
kronosapiens Aug 5, 2020
c06f414
Response to review comments VII
kronosapiens Aug 7, 2020
6ae3341
Allow setExpenditureState to edit globalClaimDelay
area Aug 14, 2020
ae184a0
Make globalClaimDelay relevant
kronosapiens Aug 18, 2020
ffdbe57
Add check for valid motionId in Voting
kronosapiens Aug 18, 2020
e7a99b5
Respond to reviewer comments VIII
kronosapiens Aug 18, 2020
7f475f1
Update setExpenditureState to explicitly check offsets
kronosapiens Aug 19, 2020
565caf9
Update expenditure locking and add an interaction test
kronosapiens Aug 19, 2020
9be918c
Adjust remaining tests for new delay value
area Aug 20, 2020
a171b89
Respond to reviewer comments IX
kronosapiens Aug 21, 2020
9ae28ef
Update voting tests for new mining requirements
area Aug 21, 2020
6fb170a
Rename target to altTarget
kronosapiens Aug 24, 2020
a0166dd
Respond to reviewer comments X
kronosapiens Aug 25, 2020
ecc833c
No escalation from root domain, add both domains to MotionEscalated
kronosapiens Aug 27, 2020
37a9133
Respond to review comments XI
kronosapiens Aug 31, 2020
46a80b4
Add test demonstrating escalation with no stake
kronosapiens Sep 1, 2020
3b954cb
Remove expenditure locking for alternative targets
kronosapiens Sep 1, 2020
835848e
Cannot create domain motions with non-permissioned functions
kronosapiens Sep 2, 2020
fcf80fe
Prevent domain motions for non- or root-permissioned functions
kronosapiens Sep 2, 2020
83b278b
Refactor conditional logic in setExpenditureState
kronosapiens Sep 2, 2020
6ab7cb8
Fix eslint issues
kronosapiens Sep 3, 2020
dc95acc
Update smoke test expected stateRoot
area Sep 4, 2020
0d0a788
Respond to review comments XII
kronosapiens Sep 4, 2020
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 6 additions & 2 deletions contracts/colony/Colony.sol
Original file line number Diff line number Diff line change
Expand Up @@ -105,8 +105,12 @@ contract Colony is ColonyStorage, PatriciaTreeProofs {
);
}

function getUserRoles(address who, uint256 where) public view returns (bytes32) {
return ColonyAuthority(address(authority)).getUserRoles(who, where);
function getUserRoles(address _user, uint256 _domainId) public view returns (bytes32) {
return ColonyAuthority(address(authority)).getUserRoles(_user, _domainId);
}

function getCapabilityRoles(bytes4 _sig) public view returns (bytes32) {
return ColonyAuthority(address(authority)).getCapabilityRoles(address(this), _sig);
}

function getColonyNetwork() public view returns (address) {
Expand Down
1 change: 1 addition & 0 deletions contracts/colony/ColonyDataTypes.sol
Original file line number Diff line number Diff line change
Expand Up @@ -210,6 +210,7 @@ contract ColonyDataTypes {
uint256 fundingPotId;
uint256 domainId;
uint256 finalizedTimestamp;
uint256 globalClaimDelay;
kronosapiens marked this conversation as resolved.
Show resolved Hide resolved
}

struct ExpenditureSlot {
Expand Down
38 changes: 23 additions & 15 deletions contracts/colony/ColonyExpenditure.sol
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,8 @@ contract ColonyExpenditure is ColonyStorage {
owner: msg.sender,
fundingPotId: fundingPotCount,
domainId: _domainId,
finalizedTimestamp: 0
finalizedTimestamp: 0,
globalClaimDelay: 0
});

emit FundingPotAdded(fundingPotCount);
Expand Down Expand Up @@ -144,6 +145,7 @@ contract ColonyExpenditure is ColonyStorage {
emit ExpenditureSkillSet(_id, _slot, _skillId);
}

// Deprecated
function setExpenditurePayoutModifier(
uint256 _permissionDomainId,
uint256 _childSkillIndex,
Expand All @@ -161,6 +163,7 @@ contract ColonyExpenditure is ColonyStorage {
expenditureSlots[_id][_slot].payoutModifier = _payoutModifier;
}

// Deprecated
function setExpenditureClaimDelay(
uint256 _permissionDomainId,
uint256 _childSkillIndex,
Expand All @@ -183,7 +186,7 @@ contract ColonyExpenditure is ColonyStorage {
uint256 _permissionDomainId,
uint256 _childSkillIndex,
uint256 _id,
uint256 _slot,
uint256 _storageSlot,
kronosapiens marked this conversation as resolved.
Show resolved Hide resolved
bool[] memory _mask,
bytes32[] memory _keys,
bytes32 _value
Expand All @@ -193,23 +196,28 @@ contract ColonyExpenditure is ColonyStorage {
expenditureExists(_id)
authDomain(_permissionDomainId, _childSkillIndex, expenditures[_id].domainId)
{
require(_keys.length > 0, "colony-expenditure-no-keys");

require(
_slot == EXPENDITURES_SLOT ||
_slot == EXPENDITURESLOTS_SLOT ||
_slot == EXPENDITURESLOTPAYOUTS_SLOT,
"colony-expenditure-bad-slot"
);

// Only allow editing expenditure status, owner, and finalizedTimestamp
// Note that status + owner occupy one slot
if (_slot == EXPENDITURES_SLOT) {
uint256 offset = uint256(_keys[_keys.length - 1]);
require(offset == 0 || offset == 3, "colony-expenditure-bad-offset");
if (_storageSlot == EXPENDITURES_SLOT) {
kronosapiens marked this conversation as resolved.
Show resolved Hide resolved
require(_keys.length == 1, "colony-expenditure-bad-keys");
uint256 offset = uint256(_keys[0]);
require(offset == 0 || offset == 3 || offset == 4, "colony-expenditure-bad-offset");

// Explicitly whitelist all slots, in case we add new slots in the future
} else if (_storageSlot == EXPENDITURESLOTS_SLOT) {
require(_keys.length >= 2, "colony-expenditure-bad-keys");
uint256 offset = uint256(_keys[1]);
require(offset <= 3, "colony-expenditure-bad-offset");

// Should always be two mappings
} else if (_storageSlot == EXPENDITURESLOTPAYOUTS_SLOT) {
require(_keys.length == 2, "colony-expenditure-bad-keys");

} else {
require(false, "colony-expenditure-bad-slot");
}

executeStateChange(keccak256(abi.encode(_id, _slot)), _mask, _keys, _value);
executeStateChange(keccak256(abi.encode(_id, _storageSlot)), _mask, _keys, _value);
}

// Public view functions
Expand Down
16 changes: 13 additions & 3 deletions contracts/colony/ColonyFunding.sol
Original file line number Diff line number Diff line change
Expand Up @@ -95,24 +95,34 @@ contract ColonyFunding is ColonyStorage, PatriciaTreeProofs { // ignore-swc-123
}
}

int256 constant MAX_PAYOUT_MODIFIER = int256(WAD);
int256 constant MIN_PAYOUT_MODIFIER = -int256(WAD);

function claimExpenditurePayout(uint256 _id, uint256 _slot, address _token) public
stoppable
expenditureExists(_id)
expenditureFinalized(_id)
{
Expenditure storage expenditure = expenditures[_id];
ExpenditureSlot storage slot = expenditureSlots[_id][_slot];
require(add(expenditure.finalizedTimestamp, slot.claimDelay) <= now, "colony-expenditure-cannot-claim");

require(
add(expenditure.finalizedTimestamp, add(expenditure.globalClaimDelay, slot.claimDelay)) <= now,
"colony-expenditure-cannot-claim"
kronosapiens marked this conversation as resolved.
Show resolved Hide resolved
);

FundingPot storage fundingPot = fundingPots[expenditure.fundingPotId];
assert(fundingPot.balance[_token] >= fundingPot.payouts[_token]);

uint256 initialPayout = expenditureSlotPayouts[_id][_slot][_token];
uint256 payoutScalar = uint256(slot.payoutModifier + int256(WAD));
delete expenditureSlotPayouts[_id][_slot][_token];
kronosapiens marked this conversation as resolved.
Show resolved Hide resolved

int256 payoutModifier = imin(imax(slot.payoutModifier, MIN_PAYOUT_MODIFIER), MAX_PAYOUT_MODIFIER);
kronosapiens marked this conversation as resolved.
Show resolved Hide resolved
uint256 payoutScalar = uint256(payoutModifier + int256(WAD));

uint256 repPayout = wmul(initialPayout, payoutScalar);
uint256 tokenPayout = min(initialPayout, repPayout);
uint256 tokenSurplus = sub(initialPayout, tokenPayout);
expenditureSlotPayouts[_id][_slot][_token] = 0;

// Process reputation updates if own token
if (_token == token) {
Expand Down
28 changes: 18 additions & 10 deletions contracts/colony/IColony.sol
Original file line number Diff line number Diff line change
Expand Up @@ -122,10 +122,15 @@ contract IColony is ColonyDataTypes, IRecovery {
public view returns (bool hasRole);

/// @notice Gets the bytes32 representation of the roles for a user in a given domain
/// @param who The user whose roles we want to get
/// @param where The domain where we want to get roles for
/// @return roles bytes32 representation of the roles
function getUserRoles(address who, uint256 where) public view returns (bytes32 roles);
/// @param _user The user whose roles we want to get
/// @param _domain The_domain domain where we want to get roles for
kronosapiens marked this conversation as resolved.
Show resolved Hide resolved
/// @return roles bytes32 representation of the held roles
function getUserRoles(address _user, uint256 _domain) public view returns (bytes32 roles);

/// @notice Gets the bytes32 representation of the roles authorized to call a function
/// @param _sig The function signature
/// @return roles bytes32 representation of the authorized roles
function getCapabilityRoles(bytes4 _sig) 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
Expand Down Expand Up @@ -223,6 +228,7 @@ contract IColony is ColonyDataTypes, IRecovery {
function transferExpenditure(uint256 _id, address _newOwner) public;

/// @notice DEPRECATED Updates the expenditure owner. Can only be called by Arbitration role.
/// @dev This is now deprecated and will be removed in a future version
/// @param _permissionDomainId The domainId in which I have the permission to take this action
/// @param _childSkillIndex The index that the `_domainId` is relative to `_permissionDomainId`,
/// (only used if `_permissionDomainId` is different to `_domainId`)
Expand Down Expand Up @@ -257,7 +263,8 @@ contract IColony is ColonyDataTypes, IRecovery {
/// @param _skillId Id of the new skill to set
function setExpenditureSkill(uint256 _id, uint256 _slot, uint256 _skillId) public;

/// @notice Set the payout modifier on an expenditure slot. Can only be called by Arbitration role.
/// @notice DEPRECATED Set the payout modifier on an expenditure slot. Can only be called by Arbitration role.
/// @dev This is now deprecated and will be removed in a future version
/// @dev Note that when determining payouts the payoutModifier is incremented by WAD and converted into payoutScalar
/// @param _permissionDomainId The domainId in which I have the permission to take this action
/// @param _childSkillIndex The index that the `_domainId` is relative to `_permissionDomainId`,
Expand All @@ -273,7 +280,8 @@ contract IColony is ColonyDataTypes, IRecovery {
int256 _payoutModifier
) public;

/// @notice Set the claim delay on an expenditure slot. Can only be called by Arbitration role.
/// @notice DEPRECATED Set the claim delay on an expenditure slot. Can only be called by Arbitration role.
/// @dev This is now deprecated and will be removed in a future version
/// @param _permissionDomainId The domainId in which I have the permission to take this action
/// @param _childSkillIndex The index that the `_domainId` is relative to `_permissionDomainId`,
/// (only used if `_permissionDomainId` is different to `_domainId`)
Expand All @@ -293,15 +301,15 @@ contract IColony is ColonyDataTypes, IRecovery {
/// @param _childSkillIndex The index that the `_domainId` is relative to `_permissionDomainId`,
/// (only used if `_permissionDomainId` is different to `_domainId`)
/// @param _id Expenditure identifier
/// @param _slot Number of the top-level storage slot
/// @param _mask Array of booleans indicated whether a key is a mapping (F) or offset (T).
/// @param _keys Array of additional keys (mappings & offsets)
/// @param _storageSlot Number of the top-level storage slot (25, 26, or 27)
/// @param _mask Array of booleans indicated whether a key is a mapping (F) or an array index (T).
/// @param _keys Array of additional keys (for mappings & arrays)
/// @param _value Value to set at location
function setExpenditureState(
uint256 _permissionDomainId,
uint256 _childSkillIndex,
uint256 _id,
uint256 _slot,
uint256 _storageSlot,
bool[] memory _mask,
bytes32[] memory _keys,
bytes32 _value
Expand Down
Loading