Skip to content

Commit

Permalink
add autorizedProposerSenders mapping to votingMachines (#16)
Browse files Browse the repository at this point in the history
* add autorizedProposerSender parameter

bump version to 07

* add autorizedProposerSender mapping

* Fix votingmachine.js

* organizationId = hash of proposal msg.sender and organization address
  • Loading branch information
orenyodfat authored Oct 3, 2018
1 parent 732af4d commit 88f3cd2
Show file tree
Hide file tree
Showing 15 changed files with 400 additions and 283 deletions.
26 changes: 14 additions & 12 deletions contracts/VotingMachines/AbsoluteVote.sol
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,8 @@ pragma solidity ^0.4.24;
import "../Reputation.sol";
import "./IntVoteInterface.sol";
import "openzeppelin-solidity/contracts/math/SafeMath.sol";
import "./GenesisProtocolCallbacksInterface.sol";
import "./GenesisProtocolExecuteInterface.sol";
import "./VotingMachineCallbacksInterface.sol";
import "./ProposalExecuteInterface.sol";


contract AbsoluteVote is IntVoteInterface {
Expand All @@ -23,7 +23,8 @@ contract AbsoluteVote is IntVoteInterface {

struct Proposal {
address owner; // the proposal's owner
address organization; // the address of the organization that owns the proposal
bytes32 organization; // the address of the organization that owns the proposal
address callbacks;
uint numOfChoices;
bytes32 paramsHash; // the hash of the parameters of the proposal
uint totalVotes;
Expand All @@ -33,7 +34,7 @@ contract AbsoluteVote is IntVoteInterface {
}

event AVVoteProposal(bytes32 indexed _proposalId, bool _isOwnerVote);
event RefreshReputation(bytes32 indexed _proposalId, address indexed _organization, address indexed _voter,uint _reputation);
event RefreshReputation(bytes32 indexed _proposalId, bytes32 indexed _organization, address indexed _voter,uint _reputation);


mapping(bytes32=>Parameters) public parameters; // A mapping from hashes to parameters
Expand Down Expand Up @@ -63,9 +64,10 @@ contract AbsoluteVote is IntVoteInterface {
* generated by calculating keccak256 of a incremented counter.
* @param _numOfChoices number of voting choices
* @param _paramsHash defined the parameters of the voting machine used for this proposal
* @param _organization address
* @return proposal's id.
*/
function propose(uint _numOfChoices, bytes32 _paramsHash,address)
function propose(uint _numOfChoices, bytes32 _paramsHash, address, address _organization)
external
returns(bytes32)
{
Expand All @@ -79,11 +81,12 @@ contract AbsoluteVote is IntVoteInterface {
Proposal memory proposal;
proposal.numOfChoices = _numOfChoices;
proposal.paramsHash = _paramsHash;
proposal.organization = msg.sender;
proposal.callbacks = msg.sender;
proposal.organization = keccak256(abi.encodePacked(msg.sender,_organization));
proposal.owner = msg.sender;
proposal.open = true;
proposals[proposalId] = proposal;
emit NewProposal(proposalId, msg.sender, _numOfChoices, msg.sender, _paramsHash);
emit NewProposal(proposalId, proposal.organization, _numOfChoices, msg.sender, _paramsHash);
return proposalId;
}

Expand All @@ -95,7 +98,7 @@ contract AbsoluteVote is IntVoteInterface {
if (! parameters[proposals[_proposalId].paramsHash].allowOwner) {
return false;
}
address organization = proposals[_proposalId].organization;
bytes32 organization = proposals[_proposalId].organization;
deleteProposal(_proposalId);
emit CancelProposal(_proposalId, organization);
return true;
Expand Down Expand Up @@ -257,16 +260,15 @@ contract AbsoluteVote is IntVoteInterface {
*/
function _execute(bytes32 _proposalId) internal votable(_proposalId) returns(bool) {
Proposal storage proposal = proposals[_proposalId];
uint totalReputation = GenesisProtocolCallbacksInterface(proposal.organization).getTotalReputationSupply(_proposalId);
uint totalReputation = VotingMachineCallbacksInterface(proposal.callbacks).getTotalReputationSupply(_proposalId);
uint precReq = parameters[proposal.paramsHash].precReq;
// Check if someone crossed the bar:
for (uint cnt = 0; cnt <= proposal.numOfChoices; cnt++) {
if (proposal.votes[cnt] > totalReputation*precReq/100) {
Proposal memory tmpProposal = proposal;
deleteProposal(_proposalId);
emit ExecuteProposal(_proposalId, tmpProposal.organization, cnt, totalReputation);
GenesisProtocolExecuteInterface(tmpProposal.organization).executeProposal(_proposalId,int(cnt));
//(tmpProposal.executable).execute(_proposalId, tmpProposal.organization, int(cnt));
ProposalExecuteInterface(tmpProposal.callbacks).executeProposal(_proposalId,int(cnt));
return true;
}
}
Expand All @@ -287,7 +289,7 @@ contract AbsoluteVote is IntVoteInterface {
// Check valid vote:
require(_vote <= proposal.numOfChoices);
// Check voter has enough reputation:
uint reputation = GenesisProtocolCallbacksInterface(proposal.organization).reputationOf(_voter,_proposalId);
uint reputation = VotingMachineCallbacksInterface(proposal.callbacks).reputationOf(_voter,_proposalId);
require(reputation >= _rep);
uint rep = _rep;
if (rep == 0) {
Expand Down
83 changes: 38 additions & 45 deletions contracts/VotingMachines/GenesisProtocol.sol
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,8 @@ pragma solidity ^0.4.24;

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

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

event Stake(bytes32 indexed _proposalId, address indexed _organization, address indexed _staker,uint _vote,uint _amount);
event Redeem(bytes32 indexed _proposalId, address indexed _organization, address indexed _beneficiary,uint _amount);
event RedeemDaoBounty(bytes32 indexed _proposalId, address indexed _organization, address indexed _beneficiary,uint _amount);
event RedeemReputation(bytes32 indexed _proposalId, address indexed _organization, address indexed _beneficiary,uint _amount);
event Stake(bytes32 indexed _proposalId, bytes32 indexed _organization, address indexed _staker,uint _vote,uint _amount);
event Redeem(bytes32 indexed _proposalId, bytes32 indexed _organization, address indexed _beneficiary,uint _amount);
event RedeemDaoBounty(bytes32 indexed _proposalId, bytes32 indexed _organization, address indexed _beneficiary,uint _amount);
event RedeemReputation(bytes32 indexed _proposalId, bytes32 indexed _organization, address indexed _beneficiary,uint _amount);
event GPExecuteProposal(bytes32 indexed _proposalId, ExecutionState _executionState);

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

// Digest describing the data the user signs according EIP 712.
// Needs to match what is passed to Metamask.
bytes32 public constant DELEGATION_HASH_EIP712 =
keccak256(abi.encodePacked("address GenesisProtocolAddress","bytes32 ProposalId", "uint Vote","uint AmountToStake","uint Nonce"));
// web3.eth.sign prefix
string public constant ETH_SIGN_PREFIX= "\x19Ethereum Signed Message:\n32";

/**
* @dev Constructor
*/
constructor(StandardToken _stakingToken) public
{

//The GEN token (staking token) address is hard coded in the contract by GEN_TOKEN_ADDRESS .
//This will work for a network which already hosted the GEN token on this address (e.g mainnet).
//If such contract address does not exist in the network (e.g ganache) the contract will use the _stakingToken param as the
//staking token address.
if (isContract(address(GEN_TOKEN_ADDRESS))) {
stakingToken = StandardToken(GEN_TOKEN_ADDRESS);
} else {
Expand All @@ -140,9 +143,9 @@ contract GenesisProtocol is IntVoteInterface {
* @param _numOfChoices number of voting choices
* @param _paramsHash parameters hash
* @param _proposer address
* @return proposal's id.
* @param _organization address
*/
function propose(uint _numOfChoices, bytes32 _paramsHash,address _proposer)
function propose(uint _numOfChoices, bytes32 _paramsHash,address _proposer,address _organization)
external
returns(bytes32)
{
Expand All @@ -156,7 +159,9 @@ contract GenesisProtocol is IntVoteInterface {
// Open proposal:
Proposal memory proposal;
proposal.numOfChoices = _numOfChoices;
proposal.organization = msg.sender;
proposal.callbacks = msg.sender;
proposal.organization = keccak256(abi.encodePacked(msg.sender,_organization));

proposal.state = ProposalState.PreBoosted;
// solium-disable-next-line security/no-block-members
proposal.submittedTime = now;
Expand All @@ -165,7 +170,6 @@ contract GenesisProtocol is IntVoteInterface {
proposal.winningVote = NO;
proposal.paramsHash = _paramsHash;
proposals[proposalId] = proposal;
//GenesisProtocolCallbacksInterface(proposal.organization).setProposal(proposalId);
emit NewProposal(proposalId, proposal.organization, _numOfChoices, _proposer, _paramsHash);
return proposalId;
}
Expand Down Expand Up @@ -365,25 +369,12 @@ contract GenesisProtocol is IntVoteInterface {
/**
* @dev getProposalOrganization return the organization for a given proposal
* @param _proposalId the ID of the proposal
* @return uint total reputation supply
* @return bytes32 organization identifier
*/
function getProposalOrganization(bytes32 _proposalId) external view returns(address) {
function getProposalOrganization(bytes32 _proposalId) external view returns(bytes32) {
return (proposals[_proposalId].organization);
}

/**
* @dev scoreThresholdParams return the score threshold params for a given
* organization.
* @param _organization the organization's organization
* @return uint thresholdConstA
* @return uint thresholdConstB
*/
/*function scoreThresholdParams(address _organization) external view returns(uint,uint) {
bytes32 paramsHash = GenesisProtocolCallbacksInterface(_organization).getParametersHash();
Parameters memory params = parameters[paramsHash];
return (params.thresholdConstA,params.thresholdConstB);
}*/

/**
* @dev getStaker return the vote and stake amount for a given proposal and staker
* @param _proposalId the ID of the proposal
Expand Down Expand Up @@ -519,7 +510,7 @@ contract GenesisProtocol is IntVoteInterface {
emit Redeem(_proposalId,proposal.organization,_beneficiary,amount);
}
if (reputation != 0 ) {
GenesisProtocolCallbacksInterface(proposal.organization).mintReputation(reputation,_beneficiary,_proposalId);
VotingMachineCallbacksInterface(proposal.callbacks).mintReputation(reputation,_beneficiary,_proposalId);
emit RedeemReputation(_proposalId,proposal.organization,_beneficiary,reputation);
}
}
Expand Down Expand Up @@ -552,9 +543,11 @@ contract GenesisProtocol is IntVoteInterface {
potentialAmount = beneficiaryLimit;
}
}
if ((potentialAmount != 0)&&(stakingToken.balanceOf(proposal.organization) >= potentialAmount)) {
if ((potentialAmount != 0)&&
(VotingMachineCallbacksInterface(proposal.callbacks).balanceOfStakingToken(stakingToken,_proposalId) >= potentialAmount))
{
proposal.daoBountyRemain = proposal.daoBountyRemain.sub(potentialAmount);
require(GenesisProtocolCallbacksInterface(proposal.organization).stakingTokenTransfer(stakingToken,_beneficiary,potentialAmount,_proposalId));
require(VotingMachineCallbacksInterface(proposal.callbacks).stakingTokenTransfer(stakingToken,_beneficiary,potentialAmount,_proposalId));
proposal.stakers[_beneficiary].amountForBounty = 0;
redeemedAmount = potentialAmount;
emit RedeemDaoBounty(_proposalId,proposal.organization,_beneficiary,redeemedAmount);
Expand Down Expand Up @@ -582,10 +575,10 @@ contract GenesisProtocol is IntVoteInterface {

/**
* @dev getBoostedProposalsCount return the number of boosted proposal for an organization
* @param _organization the organization
* @param _organization the organization identifier
* @return uint number of boosted proposals
*/
function getBoostedProposalsCount(address _organization) public view returns(uint) {
function getBoostedProposalsCount(bytes32 _organization) public view returns(uint) {
uint expiredProposals;
if (proposalsExpiredTimes[_organization].count() != 0) {
// solium-disable-next-line security/no-block-members
Expand All @@ -598,11 +591,11 @@ contract GenesisProtocol is IntVoteInterface {
* @dev threshold return the organization's score threshold which required by
* a proposal to shift to boosted state.
* This threshold is dynamically set and it depend on the number of boosted proposal.
* @param _organization the organization
* @param _organization the organization identifier
* @param _paramsHash the organization parameters hash
* @return int organization's score threshold.
*/
function threshold(bytes32 _paramsHash,address _organization) public view returns(int) {
function threshold(bytes32 _paramsHash,bytes32 _organization) public view returns(int) {
uint boostedProposals = getBoostedProposalsCount(_organization);
int216 e = 2;

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

bytes32 paramsHash = getParametersHash(_params,_voteOnBehalf);
bytes32 paramsHash = getParametersHash(_params, _voteOnBehalf);

uint[2] memory _daoBountyParams;
_daoBountyParams[0] = _params[12];
Expand Down Expand Up @@ -710,7 +704,7 @@ contract GenesisProtocol is IntVoteInterface {
_params[12],
_params[13]
)),
_voteOnBehalf
_voteOnBehalf
));
}

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

Expand Down Expand Up @@ -775,8 +769,7 @@ contract GenesisProtocol is IntVoteInterface {
}
emit ExecuteProposal(_proposalId, proposal.organization, proposal.winningVote, totalReputation);
emit GPExecuteProposal(_proposalId, executionState);
GenesisProtocolExecuteInterface(proposal.organization).executeProposal(_proposalId,int(proposal.winningVote));
//(tmpProposal.executable).execute(_proposalId, tmpProposal.organization, int(proposal.winningVote));
ProposalExecuteInterface(proposal.callbacks).executeProposal(_proposalId,int(proposal.winningVote));
}
return (executionState != ExecutionState.None);
}
Expand Down Expand Up @@ -850,7 +843,7 @@ contract GenesisProtocol is IntVoteInterface {
Proposal storage proposal = proposals[_proposalId];

// Check voter has enough reputation:
uint reputation = GenesisProtocolCallbacksInterface(proposal.organization).reputationOf(_voter,_proposalId);
uint reputation = VotingMachineCallbacksInterface(proposal.callbacks).reputationOf(_voter,_proposalId);
require(reputation >= _rep,"reputation >= _rep");
uint rep = _rep;
if (rep == 0) {
Expand Down Expand Up @@ -891,7 +884,7 @@ contract GenesisProtocol is IntVoteInterface {
if (proposal.state == ProposalState.PreBoosted) {
proposal.preBoostedVotes[_vote] = rep.add(proposal.preBoostedVotes[_vote]);
uint reputationDeposit = (params.votersReputationLossRatio * rep)/100;
GenesisProtocolCallbacksInterface(proposal.organization).burnReputation(reputationDeposit,_voter,_proposalId);
VotingMachineCallbacksInterface(proposal.callbacks).burnReputation(reputationDeposit,_voter,_proposalId);
}
// Event:
emit VoteProposal(_proposalId, proposal.organization, _voter, _vote, rep);
Expand Down
Loading

0 comments on commit 88f3cd2

Please sign in to comment.