mirror of
https://github.com/status-im/visual-identity.git
synced 2025-02-12 20:46:35 +00:00
146 lines
4.4 KiB
Solidity
146 lines
4.4 KiB
Solidity
pragma solidity ^0.4.10;
|
|
|
|
import "./TrustNetwork.sol";
|
|
import "./DelegationProxy.sol";
|
|
import "../token/MiniMeToken.sol";
|
|
import "../common/Controlled.sol";
|
|
|
|
/**
|
|
* @title ProposalManager
|
|
* @author Ricardo Guilherme Schmidt (Status Research & Development GmbH)
|
|
* Store the proposals, votes and results for other smartcontracts
|
|
*/
|
|
contract ProposalManager is Controlled {
|
|
|
|
TrustNetwork public trustNet;
|
|
MiniMeToken public SNT;
|
|
address public stakeBank;
|
|
|
|
Proposal[] proposals;
|
|
|
|
struct Proposal {
|
|
address topic;
|
|
|
|
address destination;
|
|
uint value;
|
|
bytes data;
|
|
uint stake;
|
|
|
|
uint blockStart;
|
|
uint voteBlockEnd;
|
|
uint vetoBlockEnd;
|
|
|
|
VoteTicket[] votes;
|
|
mapping(address => uint) voteIndex;
|
|
|
|
uint tabulationPosition;
|
|
bool tabulated;
|
|
mapping(uint8 => uint) results;
|
|
|
|
bool approved;
|
|
bool executed;
|
|
}
|
|
|
|
|
|
struct VoteTicket {
|
|
address voter;
|
|
Vote vote;
|
|
}
|
|
|
|
enum Vote {
|
|
Reject,
|
|
Approve,
|
|
Veto
|
|
}
|
|
|
|
function ProposalManager(MiniMeToken _SNT, TrustNetwork _trustNet, address _stakeBank) public {
|
|
trustNet = _trustNet;
|
|
SNT = _SNT;
|
|
stakeBank = _stakeBank;
|
|
}
|
|
|
|
function addProposal(address topic, address destination, uint value, bytes data, uint stake) returns (uint) {
|
|
require(stake > 1000);
|
|
require(SNT.transferFrom(msg.sender, stakeBank, stake));
|
|
uint pos = proposals.length++;
|
|
Proposal storage p = proposals[pos];
|
|
|
|
p.topic = topic;
|
|
p.destination = destination;
|
|
p.value = value;
|
|
p.data = data;
|
|
p.stake = stake;
|
|
|
|
p.blockStart = block.number + 1000; //will be replaced by configurations
|
|
p.voteBlockEnd = p.blockStart + 10000; //dummy value
|
|
p.vetoBlockEnd = p.voteBlockEnd + 5000; //dummy value
|
|
|
|
return pos;
|
|
}
|
|
|
|
function getProposal(uint id) public constant returns (address topic, address destination, uint value, uint stake, bool approved, bool executed) {
|
|
Proposal memory p = proposals[id];
|
|
return (p.topic, p.destination, p.value, p.stake, p.approved, p.executed);
|
|
}
|
|
|
|
function getProposalData(uint id) public constant returns(bytes){
|
|
return proposals[id].data;
|
|
}
|
|
|
|
function setExecuted(uint id) public onlyController {
|
|
proposals[id].executed = true;
|
|
}
|
|
|
|
function vote(uint _proposal, Vote _vote) {
|
|
Proposal storage proposal = proposals[_proposal];
|
|
require(block.number >= proposal.blockStart);
|
|
if (_vote == Vote.Veto) {
|
|
require(block.number <= proposal.vetoBlockEnd);
|
|
} else {
|
|
require(block.number <= proposal.voteBlockEnd);
|
|
}
|
|
uint votePos = proposal.voteIndex[msg.sender];
|
|
if (votePos == 0) {
|
|
votePos = proposal.votes.length;
|
|
} else {
|
|
votePos = votePos - 1;
|
|
}
|
|
VoteTicket storage ticket = proposal.votes[votePos];
|
|
assert (ticket.voter == 0x0 || ticket.voter == msg.sender);
|
|
ticket.voter = msg.sender;
|
|
ticket.vote = _vote;
|
|
proposal.voteIndex[msg.sender] = votePos + 1;
|
|
}
|
|
|
|
function tabulate(uint _proposal, uint loopLimit) {
|
|
Proposal storage proposal = proposals[_proposal];
|
|
require(block.number > proposal.vetoBlockEnd);
|
|
require(!proposal.tabulated);
|
|
|
|
uint totalVoted = proposal.votes.length;
|
|
if (loopLimit == 0) {
|
|
loopLimit = totalVoted;
|
|
}
|
|
require (loopLimit <= totalVoted);
|
|
require (loopLimit > proposal.tabulationPosition);
|
|
|
|
DelegationProxy voteDelegation;
|
|
DelegationProxy vetoDelegation;
|
|
(voteDelegation, vetoDelegation) = trustNet.getTopic(proposal.topic);
|
|
|
|
for (uint i = proposal.tabulationPosition; i < loopLimit; i++) {
|
|
VoteTicket memory _vote = proposal.votes[i];
|
|
if (_vote.vote == Vote.Reject || _vote.vote == Vote.Approve) {
|
|
proposal.results[uint8(_vote.vote)] += voteDelegation.influenceOfAt(_vote.voter, SNT, proposal.voteBlockEnd);
|
|
} else {
|
|
proposal.results[uint8(_vote.vote)] += vetoDelegation.influenceOfAt(_vote.voter, SNT, proposal.vetoBlockEnd);
|
|
}
|
|
}
|
|
|
|
proposal.tabulationPosition = i;
|
|
if (proposal.tabulationPosition == totalVoted) {
|
|
proposal.tabulated = true;
|
|
}
|
|
}
|
|
|
|
} |