refactor constitution, abstract democracy

This commit is contained in:
Ricardo Guilherme Schmidt 2018-03-28 18:33:33 -03:00
parent ed798f4a91
commit 587df6fe40
5 changed files with 133 additions and 8 deletions

View File

@ -0,0 +1,82 @@
pragma solidity ^0.4.21;
import "./DemocracyInterface.sol";
import "./ProposalManager.sol";
contract Democracy is DemocracyInterface {
mapping (bytes32 => Allowance) topicAllowance;
struct Allowance {
mapping(address => bool) anyCall;
mapping(bytes32 => bool) calls;
}
function Democracy(address _baseToken, address _trustNetwork) public {
token = MiniMeTokenInterface(_baseToken);
trustNet = TrustNetworkInterface(_trustNetwork);
proposalManager = new ProposalManager(token, trustNet);
}
function allowTopicSpecific(bytes32 _topic, address _destination, bytes4 _allowedCall, bool allowance)
external
{
require(msg.sender == address(this));
topicAllowance[_topic].calls[keccak256(_destination, _allowedCall)] = allowance;
}
function allowTopicAnyCall(bytes32 _topic, address _destination, bool allowance)
external
{
require(msg.sender == address(this));
topicAllowance[_topic].anyCall[_destination] = allowance;
}
function executeProposal(
uint256 _proposalId,
address _destination,
uint _value,
bytes _data
)
external
returns (bool success)
{
bytes32 topic;
bytes32 txHash;
bool approved;
bool executed;
(topic, txHash, approved, executed) = proposalManager.getProposal(_proposalId);
require(approved);
require(!executed);
require(
txHash == keccak256(
_destination,
_value,
_data
)
);
if(topic != 0x0) { //if not root topic
Allowance storage allowed = topicAllowance[topic];
if(!allowed.anyCall[_destination]){ //if topic not allowed any call to destination
bytes memory data = _data;
bytes4 calling;
assembly {
calling := mload(add(data, 4))
}
delete data;
require(allowed.calls[keccak256(_destination, calling)]); //require call allowance
}
}
// save that this was executed
require(
proposalManager.setExecuted(
_proposalId,
txHash
)
);
//execute the call
return _destination.call.value(_value)(_data);
}
}

View File

@ -0,0 +1,21 @@
pragma solidity ^0.4.17;
import "./DemocracyStorage.sol";
/**
* @title DemocracyInterface
* @author Ricardo Guilherme Schmidt (Status Research & Development GmbH)
*/
contract DemocracyInterface is DemocracyStorage {
function executeProposal(
uint256 _proposalId,
address _destination,
uint _value,
bytes _data
)
external
returns(bool success);
}

View File

@ -0,0 +1,21 @@
pragma solidity ^0.4.17;
import "../deploy/InstanceStorage.sol";
import "../token/MiniMeTokenInterface.sol";
import "./TrustNetworkInterface.sol";
import "./ProposalManagerInterface.sol";
/**
* @title DemocracyStorage
* @author Ricardo Guilherme Schmidt (Status Research & Development GmbH)
* @dev Defines kernel vars that Kernel contract share with Instance.
* Important to avoid overwriting wrong storage pointers is that
* InstanceStorage should be always the first contract at heritance.
*/
contract DemocracyStorage is InstanceStorage {
// protected zone start (InstanceStorage vars)
MiniMeTokenInterface public token;
TrustNetworkInterface public trustNet;
ProposalManagerInterface public proposalManager;
// protected zone end
}

View File

@ -36,9 +36,9 @@ contract ProposalManager is ProposalManagerInterface, Controlled {
return pos;
}
function getProposal(uint id) public constant returns (bytes32 topic, bytes32 txHash, uint stake, address staker, bool approved, bool executed) {
function getProposal(uint id) public constant returns (bytes32 topic, bytes32 txHash, bool approved, bool executed) {
Proposal memory p = proposals[id];
return (p.topic, p.txHash, p.stake, p.staker, p.approved, p.executed);
return (p.topic, p.txHash, p.approved, p.executed);
}
function getProposalTxHash(uint id) public constant returns(bytes32) {
@ -106,10 +106,11 @@ contract ProposalManager is ProposalManagerInterface, Controlled {
require(token.transferFrom(address(this), proposal.staker, proposal.stake));
}
function setExecuted(uint id) public onlyController {
Proposal memory p = proposals[id];
function setExecuted(uint _id, bytes32 _txHash) public onlyController returns(bool){
Proposal memory p = proposals[_id];
require(p.txHash == _txHash);
require(p.approved);
require(!p.executed);
proposals[id].executed = true;
proposals[_id].executed = true;
}
}

View File

@ -49,11 +49,11 @@ contract ProposalManagerInterface {
}
function addProposal(bytes32 _topic, bytes32 _txHash, uint _stake) public returns (uint);
function getProposal(uint id) public constant returns (bytes32 topic, bytes32 txHash, uint stake, address staker, bool approved, bool executed);
function getProposalTxHash(uint id) public constant returns(bytes32);
function getProposal(uint _id) public constant returns (bytes32 topic, bytes32 txHash, bool approved, bool executed);
function getProposalTxHash(uint _id) public constant returns(bytes32);
function vote(uint _proposal, Vote _vote) public;
function tabulateVote(uint _proposal, address _delegator) public;
function tabulateVeto(uint _proposal, address _delegator) public;
function approve(uint _proposal) public;
function setExecuted(uint id) public;
function setExecuted(uint _id, bytes32 _txHash) public returns(bool);
}