Skip to content

Commit 88f3cd2

Browse files
authored
add autorizedProposerSenders mapping to votingMachines (#16)
* add autorizedProposerSender parameter bump version to 07 * add autorizedProposerSender mapping * Fix votingmachine.js * organizationId = hash of proposal msg.sender and organization address
1 parent 732af4d commit 88f3cd2

15 files changed

+400
-283
lines changed

contracts/VotingMachines/AbsoluteVote.sol

Lines changed: 14 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -3,8 +3,8 @@ pragma solidity ^0.4.24;
33
import "../Reputation.sol";
44
import "./IntVoteInterface.sol";
55
import "openzeppelin-solidity/contracts/math/SafeMath.sol";
6-
import "./GenesisProtocolCallbacksInterface.sol";
7-
import "./GenesisProtocolExecuteInterface.sol";
6+
import "./VotingMachineCallbacksInterface.sol";
7+
import "./ProposalExecuteInterface.sol";
88

99

1010
contract AbsoluteVote is IntVoteInterface {
@@ -23,7 +23,8 @@ contract AbsoluteVote is IntVoteInterface {
2323

2424
struct Proposal {
2525
address owner; // the proposal's owner
26-
address organization; // the address of the organization that owns the proposal
26+
bytes32 organization; // the address of the organization that owns the proposal
27+
address callbacks;
2728
uint numOfChoices;
2829
bytes32 paramsHash; // the hash of the parameters of the proposal
2930
uint totalVotes;
@@ -33,7 +34,7 @@ contract AbsoluteVote is IntVoteInterface {
3334
}
3435

3536
event AVVoteProposal(bytes32 indexed _proposalId, bool _isOwnerVote);
36-
event RefreshReputation(bytes32 indexed _proposalId, address indexed _organization, address indexed _voter,uint _reputation);
37+
event RefreshReputation(bytes32 indexed _proposalId, bytes32 indexed _organization, address indexed _voter,uint _reputation);
3738

3839

3940
mapping(bytes32=>Parameters) public parameters; // A mapping from hashes to parameters
@@ -63,9 +64,10 @@ contract AbsoluteVote is IntVoteInterface {
6364
* generated by calculating keccak256 of a incremented counter.
6465
* @param _numOfChoices number of voting choices
6566
* @param _paramsHash defined the parameters of the voting machine used for this proposal
67+
* @param _organization address
6668
* @return proposal's id.
6769
*/
68-
function propose(uint _numOfChoices, bytes32 _paramsHash,address)
70+
function propose(uint _numOfChoices, bytes32 _paramsHash, address, address _organization)
6971
external
7072
returns(bytes32)
7173
{
@@ -79,11 +81,12 @@ contract AbsoluteVote is IntVoteInterface {
7981
Proposal memory proposal;
8082
proposal.numOfChoices = _numOfChoices;
8183
proposal.paramsHash = _paramsHash;
82-
proposal.organization = msg.sender;
84+
proposal.callbacks = msg.sender;
85+
proposal.organization = keccak256(abi.encodePacked(msg.sender,_organization));
8386
proposal.owner = msg.sender;
8487
proposal.open = true;
8588
proposals[proposalId] = proposal;
86-
emit NewProposal(proposalId, msg.sender, _numOfChoices, msg.sender, _paramsHash);
89+
emit NewProposal(proposalId, proposal.organization, _numOfChoices, msg.sender, _paramsHash);
8790
return proposalId;
8891
}
8992

@@ -95,7 +98,7 @@ contract AbsoluteVote is IntVoteInterface {
9598
if (! parameters[proposals[_proposalId].paramsHash].allowOwner) {
9699
return false;
97100
}
98-
address organization = proposals[_proposalId].organization;
101+
bytes32 organization = proposals[_proposalId].organization;
99102
deleteProposal(_proposalId);
100103
emit CancelProposal(_proposalId, organization);
101104
return true;
@@ -257,16 +260,15 @@ contract AbsoluteVote is IntVoteInterface {
257260
*/
258261
function _execute(bytes32 _proposalId) internal votable(_proposalId) returns(bool) {
259262
Proposal storage proposal = proposals[_proposalId];
260-
uint totalReputation = GenesisProtocolCallbacksInterface(proposal.organization).getTotalReputationSupply(_proposalId);
263+
uint totalReputation = VotingMachineCallbacksInterface(proposal.callbacks).getTotalReputationSupply(_proposalId);
261264
uint precReq = parameters[proposal.paramsHash].precReq;
262265
// Check if someone crossed the bar:
263266
for (uint cnt = 0; cnt <= proposal.numOfChoices; cnt++) {
264267
if (proposal.votes[cnt] > totalReputation*precReq/100) {
265268
Proposal memory tmpProposal = proposal;
266269
deleteProposal(_proposalId);
267270
emit ExecuteProposal(_proposalId, tmpProposal.organization, cnt, totalReputation);
268-
GenesisProtocolExecuteInterface(tmpProposal.organization).executeProposal(_proposalId,int(cnt));
269-
//(tmpProposal.executable).execute(_proposalId, tmpProposal.organization, int(cnt));
271+
ProposalExecuteInterface(tmpProposal.callbacks).executeProposal(_proposalId,int(cnt));
270272
return true;
271273
}
272274
}
@@ -287,7 +289,7 @@ contract AbsoluteVote is IntVoteInterface {
287289
// Check valid vote:
288290
require(_vote <= proposal.numOfChoices);
289291
// Check voter has enough reputation:
290-
uint reputation = GenesisProtocolCallbacksInterface(proposal.organization).reputationOf(_voter,_proposalId);
292+
uint reputation = VotingMachineCallbacksInterface(proposal.callbacks).reputationOf(_voter,_proposalId);
291293
require(reputation >= _rep);
292294
uint rep = _rep;
293295
if (rep == 0) {

contracts/VotingMachines/GenesisProtocol.sol

Lines changed: 38 additions & 45 deletions
Original file line numberDiff line numberDiff line change
@@ -2,8 +2,8 @@ pragma solidity ^0.4.24;
22

33
import "./IntVoteInterface.sol";
44
import { RealMath } from "../libs/RealMath.sol";
5-
import "./GenesisProtocolCallbacksInterface.sol";
6-
import "./GenesisProtocolExecuteInterface.sol";
5+
import "./VotingMachineCallbacksInterface.sol";
6+
import "./ProposalExecuteInterface.sol";
77
import "openzeppelin-solidity/contracts/math/SafeMath.sol";
88
import "openzeppelin-solidity/contracts/token/ERC20/StandardToken.sol";
99
import "openzeppelin-solidity/contracts/ECRecovery.sol";
@@ -47,7 +47,7 @@ contract GenesisProtocol is IntVoteInterface {
4747
//and daoBountyConst is a constant factor that is configurable and changeable by the DAO given.
4848
// daoBountyConst should be greater than stakerFeeRatioForVoters and less than 2 * stakerFeeRatioForVoters.
4949
//daoBountyParams[1] = daoBountyLimit The daoBounty cannot be greater than daoBountyLimit.
50-
address voteOnBehalf; //this address is allowd to vote of behalf of someone else.
50+
address voteOnBehalf; //this address is allowed to vote of behalf of someone else.
5151
}
5252
struct Voter {
5353
uint vote; // YES(1) ,NO(2)
@@ -62,7 +62,8 @@ contract GenesisProtocol is IntVoteInterface {
6262
}
6363

6464
struct Proposal {
65-
address organization; // the organization's address the proposal is target to. fullfill genesisProtocol callbacks interface.
65+
bytes32 organization; // the organization unique identifier the proposal is target to.
66+
address callbacks; // should fulfill voting callbacks interface.
6667
uint numOfChoices;
6768
uint votersStakes;
6869
uint submittedTime;
@@ -87,10 +88,10 @@ contract GenesisProtocol is IntVoteInterface {
8788
mapping(address => Staker ) stakers;
8889
}
8990

90-
event Stake(bytes32 indexed _proposalId, address indexed _organization, address indexed _staker,uint _vote,uint _amount);
91-
event Redeem(bytes32 indexed _proposalId, address indexed _organization, address indexed _beneficiary,uint _amount);
92-
event RedeemDaoBounty(bytes32 indexed _proposalId, address indexed _organization, address indexed _beneficiary,uint _amount);
93-
event RedeemReputation(bytes32 indexed _proposalId, address indexed _organization, address indexed _beneficiary,uint _amount);
91+
event Stake(bytes32 indexed _proposalId, bytes32 indexed _organization, address indexed _staker,uint _vote,uint _amount);
92+
event Redeem(bytes32 indexed _proposalId, bytes32 indexed _organization, address indexed _beneficiary,uint _amount);
93+
event RedeemDaoBounty(bytes32 indexed _proposalId, bytes32 indexed _organization, address indexed _beneficiary,uint _amount);
94+
event RedeemReputation(bytes32 indexed _proposalId, bytes32 indexed _organization, address indexed _beneficiary,uint _amount);
9495
event GPExecuteProposal(bytes32 indexed _proposalId, ExecutionState _executionState);
9596

9697
mapping(bytes32=>Parameters) public parameters; // A mapping from hashes to parameters
@@ -100,25 +101,27 @@ contract GenesisProtocol is IntVoteInterface {
100101
uint constant public NO = 2;
101102
uint constant public YES = 1;
102103
uint public proposalsCnt; // Total number of proposals
103-
mapping(address=>uint) public orgBoostedProposalsCnt;
104+
mapping(bytes32=>uint) public orgBoostedProposalsCnt;
104105
StandardToken public stakingToken;
105106
mapping(bytes=>bool) stakeSignatures; //stake signatures
106107
address constant GEN_TOKEN_ADDRESS = 0x543Ff227F64Aa17eA132Bf9886cAb5DB55DCAddf;
107-
mapping(address=>OrderStatisticTree.Tree) proposalsExpiredTimes; //proposals expired times
108+
mapping(bytes32=>OrderStatisticTree.Tree) proposalsExpiredTimes; //proposals expired times
108109

109110
// Digest describing the data the user signs according EIP 712.
110111
// Needs to match what is passed to Metamask.
111112
bytes32 public constant DELEGATION_HASH_EIP712 =
112113
keccak256(abi.encodePacked("address GenesisProtocolAddress","bytes32 ProposalId", "uint Vote","uint AmountToStake","uint Nonce"));
113114
// web3.eth.sign prefix
114115
string public constant ETH_SIGN_PREFIX= "\x19Ethereum Signed Message:\n32";
115-
116116
/**
117117
* @dev Constructor
118118
*/
119119
constructor(StandardToken _stakingToken) public
120120
{
121-
121+
//The GEN token (staking token) address is hard coded in the contract by GEN_TOKEN_ADDRESS .
122+
//This will work for a network which already hosted the GEN token on this address (e.g mainnet).
123+
//If such contract address does not exist in the network (e.g ganache) the contract will use the _stakingToken param as the
124+
//staking token address.
122125
if (isContract(address(GEN_TOKEN_ADDRESS))) {
123126
stakingToken = StandardToken(GEN_TOKEN_ADDRESS);
124127
} else {
@@ -140,9 +143,9 @@ contract GenesisProtocol is IntVoteInterface {
140143
* @param _numOfChoices number of voting choices
141144
* @param _paramsHash parameters hash
142145
* @param _proposer address
143-
* @return proposal's id.
146+
* @param _organization address
144147
*/
145-
function propose(uint _numOfChoices, bytes32 _paramsHash,address _proposer)
148+
function propose(uint _numOfChoices, bytes32 _paramsHash,address _proposer,address _organization)
146149
external
147150
returns(bytes32)
148151
{
@@ -156,7 +159,9 @@ contract GenesisProtocol is IntVoteInterface {
156159
// Open proposal:
157160
Proposal memory proposal;
158161
proposal.numOfChoices = _numOfChoices;
159-
proposal.organization = msg.sender;
162+
proposal.callbacks = msg.sender;
163+
proposal.organization = keccak256(abi.encodePacked(msg.sender,_organization));
164+
160165
proposal.state = ProposalState.PreBoosted;
161166
// solium-disable-next-line security/no-block-members
162167
proposal.submittedTime = now;
@@ -165,7 +170,6 @@ contract GenesisProtocol is IntVoteInterface {
165170
proposal.winningVote = NO;
166171
proposal.paramsHash = _paramsHash;
167172
proposals[proposalId] = proposal;
168-
//GenesisProtocolCallbacksInterface(proposal.organization).setProposal(proposalId);
169173
emit NewProposal(proposalId, proposal.organization, _numOfChoices, _proposer, _paramsHash);
170174
return proposalId;
171175
}
@@ -365,25 +369,12 @@ contract GenesisProtocol is IntVoteInterface {
365369
/**
366370
* @dev getProposalOrganization return the organization for a given proposal
367371
* @param _proposalId the ID of the proposal
368-
* @return uint total reputation supply
372+
* @return bytes32 organization identifier
369373
*/
370-
function getProposalOrganization(bytes32 _proposalId) external view returns(address) {
374+
function getProposalOrganization(bytes32 _proposalId) external view returns(bytes32) {
371375
return (proposals[_proposalId].organization);
372376
}
373377

374-
/**
375-
* @dev scoreThresholdParams return the score threshold params for a given
376-
* organization.
377-
* @param _organization the organization's organization
378-
* @return uint thresholdConstA
379-
* @return uint thresholdConstB
380-
*/
381-
/*function scoreThresholdParams(address _organization) external view returns(uint,uint) {
382-
bytes32 paramsHash = GenesisProtocolCallbacksInterface(_organization).getParametersHash();
383-
Parameters memory params = parameters[paramsHash];
384-
return (params.thresholdConstA,params.thresholdConstB);
385-
}*/
386-
387378
/**
388379
* @dev getStaker return the vote and stake amount for a given proposal and staker
389380
* @param _proposalId the ID of the proposal
@@ -519,7 +510,7 @@ contract GenesisProtocol is IntVoteInterface {
519510
emit Redeem(_proposalId,proposal.organization,_beneficiary,amount);
520511
}
521512
if (reputation != 0 ) {
522-
GenesisProtocolCallbacksInterface(proposal.organization).mintReputation(reputation,_beneficiary,_proposalId);
513+
VotingMachineCallbacksInterface(proposal.callbacks).mintReputation(reputation,_beneficiary,_proposalId);
523514
emit RedeemReputation(_proposalId,proposal.organization,_beneficiary,reputation);
524515
}
525516
}
@@ -552,9 +543,11 @@ contract GenesisProtocol is IntVoteInterface {
552543
potentialAmount = beneficiaryLimit;
553544
}
554545
}
555-
if ((potentialAmount != 0)&&(stakingToken.balanceOf(proposal.organization) >= potentialAmount)) {
546+
if ((potentialAmount != 0)&&
547+
(VotingMachineCallbacksInterface(proposal.callbacks).balanceOfStakingToken(stakingToken,_proposalId) >= potentialAmount))
548+
{
556549
proposal.daoBountyRemain = proposal.daoBountyRemain.sub(potentialAmount);
557-
require(GenesisProtocolCallbacksInterface(proposal.organization).stakingTokenTransfer(stakingToken,_beneficiary,potentialAmount,_proposalId));
550+
require(VotingMachineCallbacksInterface(proposal.callbacks).stakingTokenTransfer(stakingToken,_beneficiary,potentialAmount,_proposalId));
558551
proposal.stakers[_beneficiary].amountForBounty = 0;
559552
redeemedAmount = potentialAmount;
560553
emit RedeemDaoBounty(_proposalId,proposal.organization,_beneficiary,redeemedAmount);
@@ -582,10 +575,10 @@ contract GenesisProtocol is IntVoteInterface {
582575

583576
/**
584577
* @dev getBoostedProposalsCount return the number of boosted proposal for an organization
585-
* @param _organization the organization
578+
* @param _organization the organization identifier
586579
* @return uint number of boosted proposals
587580
*/
588-
function getBoostedProposalsCount(address _organization) public view returns(uint) {
581+
function getBoostedProposalsCount(bytes32 _organization) public view returns(uint) {
589582
uint expiredProposals;
590583
if (proposalsExpiredTimes[_organization].count() != 0) {
591584
// solium-disable-next-line security/no-block-members
@@ -598,11 +591,11 @@ contract GenesisProtocol is IntVoteInterface {
598591
* @dev threshold return the organization's score threshold which required by
599592
* a proposal to shift to boosted state.
600593
* This threshold is dynamically set and it depend on the number of boosted proposal.
601-
* @param _organization the organization
594+
* @param _organization the organization identifier
602595
* @param _paramsHash the organization parameters hash
603596
* @return int organization's score threshold.
604597
*/
605-
function threshold(bytes32 _paramsHash,address _organization) public view returns(int) {
598+
function threshold(bytes32 _paramsHash,bytes32 _organization) public view returns(int) {
606599
uint boostedProposals = getBoostedProposalsCount(_organization);
607600
int216 e = 2;
608601

@@ -634,6 +627,7 @@ contract GenesisProtocol is IntVoteInterface {
634627
* _params[11] -_votersGainRepRatioFromLostRep
635628
* _params[12] - _daoBountyConst
636629
* _params[13] - _daoBountyLimit
630+
* @param _voteOnBehalf - authorized to vote on behalf of others.
637631
*/
638632
function setParameters(
639633
uint[14] _params, //use array here due to stack too deep issue.
@@ -654,7 +648,7 @@ contract GenesisProtocol is IntVoteInterface {
654648
require(_params[12] <= (2 * _params[9]),"daoBountyConst <= 2 * stakerFeeRatioForVoters");
655649
require(_params[12] >= _params[9],"daoBountyConst >= stakerFeeRatioForVoters");
656650

657-
bytes32 paramsHash = getParametersHash(_params,_voteOnBehalf);
651+
bytes32 paramsHash = getParametersHash(_params, _voteOnBehalf);
658652

659653
uint[2] memory _daoBountyParams;
660654
_daoBountyParams[0] = _params[12];
@@ -710,7 +704,7 @@ contract GenesisProtocol is IntVoteInterface {
710704
_params[12],
711705
_params[13]
712706
)),
713-
_voteOnBehalf
707+
_voteOnBehalf
714708
));
715709
}
716710

@@ -724,7 +718,7 @@ contract GenesisProtocol is IntVoteInterface {
724718
Proposal storage proposal = proposals[_proposalId];
725719
Parameters memory params = parameters[proposal.paramsHash];
726720
Proposal memory tmpProposal = proposal;
727-
uint totalReputation = GenesisProtocolCallbacksInterface(proposal.organization).getTotalReputationSupply(_proposalId);
721+
uint totalReputation = VotingMachineCallbacksInterface(proposal.callbacks).getTotalReputationSupply(_proposalId);
728722
uint executionBar = totalReputation * params.preBoostedVoteRequiredPercentage/100;
729723
ExecutionState executionState = ExecutionState.None;
730724

@@ -775,8 +769,7 @@ contract GenesisProtocol is IntVoteInterface {
775769
}
776770
emit ExecuteProposal(_proposalId, proposal.organization, proposal.winningVote, totalReputation);
777771
emit GPExecuteProposal(_proposalId, executionState);
778-
GenesisProtocolExecuteInterface(proposal.organization).executeProposal(_proposalId,int(proposal.winningVote));
779-
//(tmpProposal.executable).execute(_proposalId, tmpProposal.organization, int(proposal.winningVote));
772+
ProposalExecuteInterface(proposal.callbacks).executeProposal(_proposalId,int(proposal.winningVote));
780773
}
781774
return (executionState != ExecutionState.None);
782775
}
@@ -850,7 +843,7 @@ contract GenesisProtocol is IntVoteInterface {
850843
Proposal storage proposal = proposals[_proposalId];
851844

852845
// Check voter has enough reputation:
853-
uint reputation = GenesisProtocolCallbacksInterface(proposal.organization).reputationOf(_voter,_proposalId);
846+
uint reputation = VotingMachineCallbacksInterface(proposal.callbacks).reputationOf(_voter,_proposalId);
854847
require(reputation >= _rep,"reputation >= _rep");
855848
uint rep = _rep;
856849
if (rep == 0) {
@@ -891,7 +884,7 @@ contract GenesisProtocol is IntVoteInterface {
891884
if (proposal.state == ProposalState.PreBoosted) {
892885
proposal.preBoostedVotes[_vote] = rep.add(proposal.preBoostedVotes[_vote]);
893886
uint reputationDeposit = (params.votersReputationLossRatio * rep)/100;
894-
GenesisProtocolCallbacksInterface(proposal.organization).burnReputation(reputationDeposit,_voter,_proposalId);
887+
VotingMachineCallbacksInterface(proposal.callbacks).burnReputation(reputationDeposit,_voter,_proposalId);
895888
}
896889
// Event:
897890
emit VoteProposal(_proposalId, proposal.organization, _voter, _vote, rep);

0 commit comments

Comments
 (0)