mirror of
https://github.com/status-im/snt-voting.git
synced 2025-02-23 23:58:13 +00:00
proposal manager architectural changes
This commit is contained in:
parent
5643bbc10b
commit
c06ac0492a
@ -16,16 +16,17 @@ contract ProposalManager is Controlled {
|
||||
|
||||
TrustNetwork public trustNet;
|
||||
MiniMeToken public SNT;
|
||||
address public stakeBank;
|
||||
uint256 public tabulationBlockDelay = 10000;
|
||||
|
||||
Proposal[] proposals;
|
||||
|
||||
struct Proposal {
|
||||
address topic;
|
||||
bytes32 topic;
|
||||
|
||||
bytes32 txHash;
|
||||
|
||||
uint value;
|
||||
bytes data;
|
||||
uint stake;
|
||||
address staker;
|
||||
|
||||
uint blockStart;
|
||||
uint voteBlockEnd;
|
||||
@ -33,7 +34,7 @@ contract ProposalManager is Controlled {
|
||||
|
||||
mapping(address => Vote) voteMap;
|
||||
|
||||
mapping(address => bool) tabulated;
|
||||
mapping(address => Tabulations) tabulated;
|
||||
|
||||
mapping(uint8 => uint256) results;
|
||||
|
||||
@ -41,6 +42,11 @@ contract ProposalManager is Controlled {
|
||||
bool executed;
|
||||
}
|
||||
|
||||
struct Tabulations {
|
||||
bool vote;
|
||||
bool veto;
|
||||
}
|
||||
|
||||
enum Vote {
|
||||
Null,
|
||||
Reject,
|
||||
@ -51,19 +57,18 @@ contract ProposalManager is Controlled {
|
||||
function ProposalManager(MiniMeToken _SNT, TrustNetwork _trustNet, address _stakeBank) public {
|
||||
trustNet = _trustNet;
|
||||
SNT = _SNT;
|
||||
stakeBank = _stakeBank;
|
||||
}
|
||||
|
||||
function addProposal(address topic, uint value, bytes data, uint stake) public returns (uint) {
|
||||
require(stake > 1000);
|
||||
require(SNT.transferFrom(msg.sender, stakeBank, stake));
|
||||
function addProposal(bytes32 _topic, bytes32 _txHash, uint _stake) public returns (uint) {
|
||||
require(_stake > 1000);
|
||||
require(SNT.transferFrom(msg.sender, address(this), _stake));
|
||||
uint pos = proposals.length++;
|
||||
Proposal storage p = proposals[pos];
|
||||
|
||||
p.topic = topic;
|
||||
p.value = value;
|
||||
p.data = data;
|
||||
p.stake = stake;
|
||||
p.topic = _topic;
|
||||
p.txHash = _txHash;
|
||||
p.stake = _stake;
|
||||
p.staker = msg.sender;
|
||||
|
||||
p.blockStart = block.number + 1000; //will be replaced by configurations
|
||||
p.voteBlockEnd = p.blockStart + 10000; //dummy value
|
||||
@ -72,20 +77,21 @@ contract ProposalManager is Controlled {
|
||||
return pos;
|
||||
}
|
||||
|
||||
function getProposal(uint id) public constant returns (address topic, uint value, uint stake, bool approved, bool executed) {
|
||||
function getProposal(uint id) public constant returns (bytes32 topic, bytes32 txHash, uint stake, address staker, bool approved, bool executed) {
|
||||
Proposal memory p = proposals[id];
|
||||
return (p.topic, p.value, p.stake, p.approved, p.executed);
|
||||
return (p.topic, p.txHash, p.stake, p.staker, p.approved, p.executed);
|
||||
}
|
||||
|
||||
function getProposalData(uint id) public constant returns(bytes) {
|
||||
return proposals[id].data;
|
||||
function getProposalTxHash(uint id) public constant returns(bytes32) {
|
||||
return proposals[id].txHash;
|
||||
}
|
||||
|
||||
function execute(uint id) public {
|
||||
function execute(uint id, address dest, uint value, bytes data) public {
|
||||
Proposal memory p = proposals[id];
|
||||
require(p.approved == true);
|
||||
require(keccak256(dest, value, data) == p.txHash);
|
||||
proposals[id].executed = true;
|
||||
ProposalExecutor(controller).executeProposal(p.topic, p.value, p.data);
|
||||
ProposalExecutor(controller).executeProposal(dest, value, data);
|
||||
}
|
||||
|
||||
function vote(uint _proposal, Vote _vote) public {
|
||||
@ -101,35 +107,57 @@ contract ProposalManager is Controlled {
|
||||
|
||||
}
|
||||
|
||||
function tabulate(uint _proposal, address _delegator) public {
|
||||
function tabulateVote(uint _proposal, address _delegator) public {
|
||||
Proposal storage proposal = proposals[_proposal];
|
||||
require(block.number > proposal.vetoBlockEnd);
|
||||
|
||||
DelegationProxy voteDelegation;
|
||||
DelegationProxy vetoDelegation;
|
||||
(voteDelegation, vetoDelegation) = trustNet.getTopic(proposal.topic);
|
||||
|
||||
Vote _vote = proposal.voteMap[vetoDelegation.delegationOfAt(_delegator, proposal.vetoBlockEnd)];
|
||||
if (_vote != Vote.Veto) {
|
||||
_vote = proposal.voteMap[voteDelegation.delegationOfAt(_delegator, proposal.voteBlockEnd)];
|
||||
require(block.number > proposal.voteBlockEnd);
|
||||
require(!proposal.tabulated[_delegator].vote);
|
||||
proposal.tabulated[_delegator].vote = true;
|
||||
Vote _vote = proposal.voteMap[_delegator];
|
||||
if(_vote == Vote.Null) {
|
||||
DelegationProxy voteDelegation;
|
||||
DelegationProxy vetoDelegation;
|
||||
(voteDelegation, vetoDelegation) = trustNet.getTopic(proposal.topic);
|
||||
address delegate = voteDelegation.delegationOfAt(_delegator, proposal.vetoBlockEnd);
|
||||
_vote = proposal.voteMap[delegate];
|
||||
}
|
||||
|
||||
if (_vote == Vote.Reject || _vote == Vote.Approve) {
|
||||
proposal.results[uint8(_vote)] += MiniMeToken(SNT).balanceOfAt(_delegator, proposal.voteBlockEnd);
|
||||
} else {
|
||||
proposal.results[uint8(_vote)] += MiniMeToken(SNT).balanceOfAt(_delegator, proposal.vetoBlockEnd);
|
||||
}
|
||||
}
|
||||
|
||||
function tabulateVeto(uint _proposal, address _delegator) public {
|
||||
Proposal storage proposal = proposals[_proposal];
|
||||
require(block.number > proposal.vetoBlockEnd);
|
||||
require(!proposal.tabulated[_delegator].veto);
|
||||
proposal.tabulated[_delegator].veto = true;
|
||||
Vote _vote = proposal.voteMap[_delegator];
|
||||
if (_vote == Vote.Null) {
|
||||
DelegationProxy voteDelegation;
|
||||
DelegationProxy vetoDelegation;
|
||||
(voteDelegation, vetoDelegation) = trustNet.getTopic(proposal.topic);
|
||||
address delegate = vetoDelegation.delegationOfAt(_delegator, proposal.vetoBlockEnd);
|
||||
_vote = proposal.voteMap[delegate];
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
function approve(uint _proposal) public {
|
||||
Proposal storage proposal = proposals[_proposal];
|
||||
uint256 totalTokens = MiniMeToken(SNT).totalSupplyAt(proposal.vetoBlockEnd);
|
||||
uint256 approved = proposal.results[uint8(Vote.Approve)];
|
||||
uint256 veto = proposal.results[uint8(Vote.Veto)];
|
||||
require (approved > veto);
|
||||
if (approved > (totalTokens / 2)) {
|
||||
proposal.approved = true;
|
||||
}
|
||||
}
|
||||
if (_vote == Vote.Veto) {
|
||||
proposal.results[uint8(Vote.Veto)] += MiniMeToken(SNT).balanceOfAt(_delegator, proposal.vetoBlockEnd);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
function approve(uint _proposal) public {
|
||||
Proposal storage proposal = proposals[_proposal];
|
||||
require(proposal.vetoBlockEnd + tabulationBlockDelay > block.number);
|
||||
require(!proposal.approved);
|
||||
uint256 totalTokens = MiniMeToken(SNT).totalSupplyAt(proposal.vetoBlockEnd);
|
||||
uint256 approvals = proposal.results[uint8(Vote.Approve)];
|
||||
uint256 veto = proposal.results[uint8(Vote.Veto)];
|
||||
uint256 approvalQuorum = (totalTokens / 2);
|
||||
uint256 vetoQuorum = (totalTokens / 3);
|
||||
require(veto < vetoQuorum);
|
||||
require(approvals >= approvalQuorum);
|
||||
proposal.approved = true;
|
||||
require(SNT.transferFrom(address(this), proposal.staker, proposal.stake));
|
||||
}
|
||||
}
|
@ -11,7 +11,7 @@ import "./DelegationProxy.sol";
|
||||
* New layers need to be defined under a unique topic address topic, and all fall back to root topic (topic 0x0)
|
||||
*/
|
||||
contract TrustNetwork is Controlled {
|
||||
mapping (address => Topic) topics;
|
||||
mapping (bytes32 => Topic) topics;
|
||||
DelegationProxyFactory delegationFactory;
|
||||
|
||||
struct Topic {
|
||||
@ -24,8 +24,7 @@ contract TrustNetwork is Controlled {
|
||||
topics[0x0] = newTopic(0x0, 0x0);
|
||||
}
|
||||
|
||||
function addTopic(address topicId, address parentTopic) public onlyController {
|
||||
|
||||
function addTopic(bytes32 topicId, bytes32 parentTopic) public onlyController {
|
||||
Topic memory parent = topics[parentTopic];
|
||||
address vote = address(parent.voteProxy);
|
||||
address veto = address(parent.vetoProxy);
|
||||
@ -40,7 +39,7 @@ contract TrustNetwork is Controlled {
|
||||
topics[topicId] = newTopic(vote, veto);
|
||||
}
|
||||
|
||||
function getTopic(address _topicId) public constant returns (DelegationProxy vote, DelegationProxy veto) {
|
||||
function getTopic(bytes32 _topicId) public constant returns (DelegationProxy vote, DelegationProxy veto) {
|
||||
Topic memory topic = topics[_topicId];
|
||||
vote = topic.voteProxy;
|
||||
veto = topic.vetoProxy;
|
||||
|
Loading…
x
Reference in New Issue
Block a user