Skip to content

Commit

Permalink
Move checkReputation to ColonyExtension
Browse files Browse the repository at this point in the history
  • Loading branch information
kronosapiens committed Aug 21, 2022
1 parent 2e5474d commit b9a272c
Show file tree
Hide file tree
Showing 7 changed files with 91 additions and 136 deletions.
39 changes: 38 additions & 1 deletion contracts/extensions/ColonyExtension.sol
Original file line number Diff line number Diff line change
Expand Up @@ -22,9 +22,11 @@ import "./../../lib/dappsys/math.sol";
import "./../common/EtherRouter.sol";
import "./../colony/IColony.sol";
import "./../colony/ColonyDataTypes.sol";
import "./../colonyNetwork/IColonyNetwork.sol";
import "./../patriciaTree/PatriciaTreeProofs.sol";


abstract contract ColonyExtension is DSAuth, DSMath {
abstract contract ColonyExtension is DSAuth, DSMath, PatriciaTreeProofs {

uint256 constant UINT256_MAX = 2**256 - 1;

Expand Down Expand Up @@ -59,4 +61,39 @@ abstract contract ColonyExtension is DSAuth, DSMath {
return address(colony);
}

function checkReputation(
bytes32 _rootHash,
uint256 _skillId,
address _user,
bytes memory _key,
bytes memory _value,
uint256 _branchMask,
bytes32[] memory _siblings
)
internal
view
returns (uint256)
{
bytes32 impliedRoot = getImpliedRootHashKey(_key, _value, _branchMask, _siblings);
require(_rootHash == impliedRoot, "colony-extension-invalid-root-hash");

uint256 reputationValue;
address keyColonyAddress;
uint256 keySkillId;
address keyUserAddress;

assembly {
reputationValue := mload(add(_value, 32))
keyColonyAddress := mload(add(_key, 20))
keySkillId := mload(add(_key, 52))
keyUserAddress := mload(add(_key, 72))
}

require(keyColonyAddress == address(colony), "colony-extension-invalid-colony-address");
// slither-disable-next-line incorrect-equality
require(keySkillId == _skillId, "colony-extension-invalid-skill-id");
require(keyUserAddress == _user, "colony-extension-invalid-user-address");

return reputationValue;
}
}
61 changes: 21 additions & 40 deletions contracts/extensions/FundingQueue.sol
Original file line number Diff line number Diff line change
Expand Up @@ -22,11 +22,10 @@ import "./../colony/ColonyDataTypes.sol";
import "./../colonyNetwork/IColonyNetwork.sol";
import "./../common/BasicMetaTransaction.sol";
import "./../common/ERC20Extended.sol";
import "./../patriciaTree/PatriciaTreeProofs.sol";
import "./../tokenLocking/ITokenLocking.sol";
import "./ColonyExtension.sol";

contract FundingQueue is ColonyExtension, PatriciaTreeProofs, BasicMetaTransaction {
contract FundingQueue is ColonyExtension, BasicMetaTransaction {

// Events
event ProposalCreated(uint256 id, uint256 indexed fromPot, uint256 indexed toPot, address indexed token, uint256 amount);
Expand Down Expand Up @@ -90,7 +89,7 @@ contract FundingQueue is ColonyExtension, PatriciaTreeProofs, BasicMetaTransacti

/// @notice Returns the version of the extension
function version() public override pure returns (uint256) {
return 3;
return 4;
}

/// @notice Configures the extension
Expand Down Expand Up @@ -203,8 +202,8 @@ contract FundingQueue is ColonyExtension, PatriciaTreeProofs, BasicMetaTransacti
require(proposal.state == ProposalState.Inactive, "funding-queue-not-inactive");
require(proposal.creator == msgSender(), "funding-queue-not-creator");

proposal.domainTotalRep = doCheckReputation(proposals[_id].domainId, address(0x0), _key, _value, _branchMask, _siblings);
proposal.state = ProposalState.Active;
proposal.domainTotalRep = checkReputation(_id, address(0x0), _key, _value, _branchMask, _siblings);

uint256 stake = wmul(proposal.domainTotalRep, STAKE_FRACTION);
colony.obligateStake(msgSender(), proposal.domainId, stake);
Expand All @@ -229,7 +228,7 @@ contract FundingQueue is ColonyExtension, PatriciaTreeProofs, BasicMetaTransacti
require(proposal.state == ProposalState.Active, "funding-queue-proposal-not-active");
require(_id != _newPrevId, "funding-queue-cannot-insert-after-self"); // NOTE: this may be redundant

uint256 userRep = checkReputation(_id, msgSender(), _key, _value, _branchMask, _siblings);
uint256 userRep = doCheckReputation(proposals[_id].domainId, msgSender(), _key, _value, _branchMask, _siblings);
require(_backing <= userRep, "funding-queue-insufficient-reputation");

// Update the user's reputation backing
Expand Down Expand Up @@ -356,6 +355,23 @@ contract FundingQueue is ColonyExtension, PatriciaTreeProofs, BasicMetaTransacti

// Internal functions

function doCheckReputation(
uint256 _domainId,
address _user,
bytes memory _key,
bytes memory _value,
uint256 _branchMask,
bytes32[] memory _siblings
)
internal
view
returns (uint256)
{
bytes32 rootHash = IColonyNetwork(colony.getColonyNetwork()).getReputationRootHash();
uint256 domainSkillId = colony.getDomain(_domainId).skillId;
return checkReputation(rootHash, domainSkillId, _user, _key, _value, _branchMask, _siblings);
}

function calculateFundingToTransfer(uint256 _id) internal view returns (uint256) {
Proposal storage proposal = proposals[_id];

Expand Down Expand Up @@ -421,41 +437,6 @@ contract FundingQueue is ColonyExtension, PatriciaTreeProofs, BasicMetaTransacti
}
}

function checkReputation(
uint256 _id,
address _who,
bytes memory _key,
bytes memory _value,
uint256 _branchMask,
bytes32[] memory _siblings
)
internal view returns (uint256)
{
bytes32 impliedRoot = getImpliedRootHashKey(_key, _value, _branchMask, _siblings);
require(colonyNetwork.getReputationRootHash() == impliedRoot, "funding-queue-invalid-root-hash");

uint256 reputationValue;
address keyColonyAddress;
uint256 keySkill;
address keyUserAddress;

assembly {
reputationValue := mload(add(_value, 32))
keyColonyAddress := mload(add(_key, 20))
keySkill := mload(add(_key, 52))
keyUserAddress := mload(add(_key, 72))
}

require(keyColonyAddress == address(colony), "funding-queue-invalid-colony-address");
// This is the 'dangerous' strict equality.
// This equality is numerical, but does have to be exact. It is therefore necessary to be disabled.
// slither-disable-next-line incorrect-equality
require(keySkill == colony.getDomain(proposals[_id].domainId).skillId, "funding-queue-invalid-skill-id");
require(keyUserAddress == _who, "funding-queue-invalid-user-address");

return reputationValue;
}

function wpow(uint256 x, uint256 n) internal pure returns (uint256) {
// Must convert WAD (10 ** 18) to RAY (10 ** 27) and back
return rpow(x * (10 ** 9), n) / (10 ** 9);
Expand Down
42 changes: 4 additions & 38 deletions contracts/extensions/StakedExpenditure.sol
Original file line number Diff line number Diff line change
Expand Up @@ -20,13 +20,12 @@ pragma experimental ABIEncoderV2;

import "./../colony/ColonyDataTypes.sol";
import "./../colonyNetwork/IColonyNetwork.sol";
import "./../patriciaTree/PatriciaTreeProofs.sol";
import "./ColonyExtensionMeta.sol";

// ignore-file-swc-108


contract StakedExpenditure is ColonyExtensionMeta, PatriciaTreeProofs {
contract StakedExpenditure is ColonyExtensionMeta {

// Events

Expand Down Expand Up @@ -119,7 +118,9 @@ contract StakedExpenditure is ColonyExtensionMeta, PatriciaTreeProofs {
public
notDeprecated
{
uint256 domainRep = getReputationFromProof(_domainId, _key, _value, _branchMask, _siblings);
bytes32 rootHash = IColonyNetwork(colony.getColonyNetwork()).getReputationRootHash();
uint256 domainSkillId = colony.getDomain(_domainId).skillId;
uint256 domainRep = checkReputation(rootHash, domainSkillId, address(0x0), _key, _value, _branchMask, _siblings);
uint256 stakeAmount = wmul(domainRep, stakeFraction);

colony.obligateStake(msgSender(), _domainId, stakeAmount);
Expand Down Expand Up @@ -301,39 +302,4 @@ contract StakedExpenditure is ColonyExtensionMeta, PatriciaTreeProofs {

emit ExpenditureCancelled(_expenditureId);
}

function getReputationFromProof(
uint256 _domainId,
bytes memory _key,
bytes memory _value,
uint256 _branchMask,
bytes32[] memory _siblings
)
internal
view
returns (uint256)
{
bytes32 rootHash = IColonyNetwork(colony.getColonyNetwork()).getReputationRootHash();
bytes32 impliedRoot = getImpliedRootHashKey(_key, _value, _branchMask, _siblings);
require(rootHash == impliedRoot, "staked-expenditure-invalid-root-hash");


uint256 reputationValue;
address keyColonyAddress;
uint256 keySkillId;
address keyUserAddress;

assembly {
reputationValue := mload(add(_value, 32))
keyColonyAddress := mload(add(_key, 20))
keySkillId := mload(add(_key, 52))
keyUserAddress := mload(add(_key, 72))
}

require(keyColonyAddress == address(colony), "staked-expenditure-invalid-colony-address");
require(keySkillId == colony.getDomain(_domainId).skillId, "staked-expenditure-invalid-skill-id");
require(keyUserAddress == address(0x0), "staked-expenditure-invalid-user-address");

return reputationValue;
}
}
45 changes: 6 additions & 39 deletions contracts/extensions/VotingReputation.sol
Original file line number Diff line number Diff line change
Expand Up @@ -22,12 +22,11 @@ import "./../colonyNetwork/IColonyNetwork.sol";
import "./../colony/ColonyRoles.sol";
import "./../common/BasicMetaTransaction.sol";
import "./../common/ERC20Extended.sol";
import "./../patriciaTree/PatriciaTreeProofs.sol";
import "./../tokenLocking/ITokenLocking.sol";
import "./ColonyExtension.sol";


contract VotingReputation is ColonyExtension, PatriciaTreeProofs, BasicMetaTransaction {
contract VotingReputation is ColonyExtension, BasicMetaTransaction {

// Events
event MotionCreated(uint256 indexed motionId, address creator, uint256 indexed domainId);
Expand Down Expand Up @@ -295,7 +294,7 @@ contract VotingReputation is ColonyExtension, PatriciaTreeProofs, BasicMetaTrans
motion.domainId = _domainId;
motion.skillId = skillId;

motion.skillRep = getReputationFromProof(motionCount, address(0x0), _key, _value, _branchMask, _siblings);
motion.skillRep = checkReputation(motion.rootHash, skillId, address(0x0), _key, _value, _branchMask, _siblings);
motion.altTarget = _altTarget;
motion.action = _action;

Expand Down Expand Up @@ -380,7 +379,7 @@ contract VotingReputation is ColonyExtension, PatriciaTreeProofs, BasicMetaTrans
uint256 stakerTotalAmount = add(stakes[_motionId][msgSender()][_vote], amount);

require(
stakerTotalAmount <= getReputationFromProof(_motionId, msgSender(), _key, _value, _branchMask, _siblings),
stakerTotalAmount <= checkReputation(motion.rootHash, motion.skillId, msgSender(), _key, _value, _branchMask, _siblings),
"voting-rep-insufficient-rep"
);
require(
Expand Down Expand Up @@ -462,7 +461,7 @@ contract VotingReputation is ColonyExtension, PatriciaTreeProofs, BasicMetaTrans
require(getMotionState(_motionId) == MotionState.Submit, "voting-rep-motion-not-open");
require(_voteSecret != bytes32(0), "voting-rep-invalid-secret");

uint256 userRep = getReputationFromProof(_motionId, msgSender(), _key, _value, _branchMask, _siblings);
uint256 userRep = checkReputation(motion.rootHash, motion.skillId, msgSender(), _key, _value, _branchMask, _siblings);

// Count reputation if first submission
if (voteSecrets[_motionId][msgSender()] == bytes32(0)) {
Expand Down Expand Up @@ -504,7 +503,7 @@ contract VotingReputation is ColonyExtension, PatriciaTreeProofs, BasicMetaTrans
require(getMotionState(_motionId) == MotionState.Reveal, "voting-rep-motion-not-reveal");
require(_vote <= 1, "voting-rep-bad-vote");

uint256 userRep = getReputationFromProof(_motionId, msgSender(), _key, _value, _branchMask, _siblings);
uint256 userRep = checkReputation(motion.rootHash, motion.skillId, msgSender(), _key, _value, _branchMask, _siblings);
motion.votes[_vote] = add(motion.votes[_vote], userRep);

bytes32 voteSecret = voteSecrets[_motionId][msgSender()];
Expand Down Expand Up @@ -555,7 +554,7 @@ contract VotingReputation is ColonyExtension, PatriciaTreeProofs, BasicMetaTrans
uint256 domainId = motion.domainId;
motion.domainId = _newDomainId;
motion.skillId = newDomainSkillId;
motion.skillRep = getReputationFromProof(_motionId, address(0x0), _key, _value, _branchMask, _siblings);
motion.skillRep = checkReputation(motion.rootHash, motion.skillId, address(0x0), _key, _value, _branchMask, _siblings);

uint256 loser = (motion.votes[NAY] < motion.votes[YAY]) ? NAY : YAY;
motion.stakes[loser] = sub(motion.stakes[loser], motion.paidVoterComp);
Expand Down Expand Up @@ -979,38 +978,6 @@ contract VotingReputation is ColonyExtension, PatriciaTreeProofs, BasicMetaTrans
return sub(1, _vote);
}

function getReputationFromProof(
uint256 _motionId,
address _who,
bytes memory _key,
bytes memory _value,
uint256 _branchMask,
bytes32[] memory _siblings
)
internal view returns (uint256)
{
bytes32 impliedRoot = getImpliedRootHashKey(_key, _value, _branchMask, _siblings);
require(motions[_motionId].rootHash == impliedRoot, "voting-rep-invalid-root-hash");

uint256 reputationValue;
address keyColonyAddress;
uint256 keySkill;
address keyUserAddress;

assembly {
reputationValue := mload(add(_value, 32))
keyColonyAddress := mload(add(_key, 20))
keySkill := mload(add(_key, 52))
keyUserAddress := mload(add(_key, 72))
}

require(keyColonyAddress == address(colony), "voting-rep-invalid-colony-address");
require(keySkill == motions[_motionId].skillId, "voting-rep-invalid-skill-id");
require(keyUserAddress == _who, "voting-rep-invalid-user-address");

return reputationValue;
}

function getActionDomainSkillId(bytes memory _action) internal view returns (uint256) {
uint256 permissionDomainId;
uint256 childSkillIndex;
Expand Down
8 changes: 4 additions & 4 deletions test/extensions/funding-queue.js
Original file line number Diff line number Diff line change
Expand Up @@ -375,14 +375,14 @@ contract("Funding Queues", (accounts) => {
it("cannot back a basic proposal with a bad reputation proof", async () => {
await checkErrorRevert(
fundingQueue.backProposal(proposalId, WAD, proposalId, HEAD, "0x0", "0x0", "0x0", [], { from: USER0 }),
"funding-queue-invalid-root-hash"
"colony-extension-invalid-root-hash"
);
});

it("cannot back a basic proposal with the wrong user address", async () => {
await checkErrorRevert(
fundingQueue.backProposal(proposalId, WAD, proposalId, HEAD, user0Key, user0Value, user0Mask, user0Siblings, { from: USER1 }),
"funding-queue-invalid-user-address"
"colony-extension-invalid-user-address"
);
});

Expand All @@ -393,7 +393,7 @@ contract("Funding Queues", (accounts) => {

await checkErrorRevert(
fundingQueue.backProposal(proposalId, WAD, proposalId, HEAD, key, value, mask, siblings, { from: USER0 }),
"funding-queue-invalid-skill-id"
"colony-extension-invalid-skill-id"
);
});

Expand All @@ -404,7 +404,7 @@ contract("Funding Queues", (accounts) => {

await checkErrorRevert(
fundingQueue.backProposal(proposalId, WAD, proposalId, HEAD, key, value, mask, siblings, { from: USER0 }),
"funding-queue-invalid-colony-address"
"colony-extension-invalid-colony-address"
);
});

Expand Down
8 changes: 4 additions & 4 deletions test/extensions/staked-expenditure.js
Original file line number Diff line number Diff line change
Expand Up @@ -201,31 +201,31 @@ contract("StakedExpenditure", (accounts) => {
[mask, siblings] = await reputationTree.getProof(key);
await checkErrorRevert(
stakedExpenditure.makeExpenditureWithStake(1, UINT256_MAX, 1, key, value, mask, siblings),
"staked-expenditure-invalid-root-hash"
"colony-extension-invalid-root-hash"
);

key = makeReputationKey(ADDRESS_ZERO, domain1.skillId);
value = makeReputationValue(WAD, 2);
[mask, siblings] = await reputationTree.getProof(key);
await checkErrorRevert(
stakedExpenditure.makeExpenditureWithStake(1, UINT256_MAX, 1, key, value, mask, siblings),
"staked-expenditure-invalid-colony-address"
"colony-extension-invalid-colony-address"
);

key = makeReputationKey(colony.address, 100);
value = makeReputationValue(WAD, 3);
[mask, siblings] = await reputationTree.getProof(key);
await checkErrorRevert(
stakedExpenditure.makeExpenditureWithStake(1, UINT256_MAX, 1, key, value, mask, siblings),
"staked-expenditure-invalid-skill-id"
"colony-extension-invalid-skill-id"
);

key = makeReputationKey(colony.address, domain1.skillId, USER0);
value = makeReputationValue(WAD, 4);
[mask, siblings] = await reputationTree.getProof(key);
await checkErrorRevert(
stakedExpenditure.makeExpenditureWithStake(1, UINT256_MAX, 1, key, value, mask, siblings),
"staked-expenditure-invalid-user-address"
"colony-extension-invalid-user-address"
);
});

Expand Down
Loading

0 comments on commit b9a272c

Please sign in to comment.