diff --git a/contracts/democracy/DefaultDelegation.sol b/contracts/democracy/delegation/DefaultDelegation.sol similarity index 96% rename from contracts/democracy/DefaultDelegation.sol rename to contracts/democracy/delegation/DefaultDelegation.sol index 52f1eb3..4024c9c 100644 --- a/contracts/democracy/DefaultDelegation.sol +++ b/contracts/democracy/delegation/DefaultDelegation.sol @@ -1,7 +1,7 @@ pragma solidity >=0.5.0 <0.6.0; import "./Delegation.sol"; -import "../common/Controlled.sol"; +import "../../common/Controlled.sol"; contract DefaultDelegation is Delegation, Controlled { address public defaultDelegate; diff --git a/contracts/democracy/Delegation.sol b/contracts/democracy/delegation/Delegation.sol similarity index 100% rename from contracts/democracy/Delegation.sol rename to contracts/democracy/delegation/Delegation.sol diff --git a/contracts/democracy/DelegationAbstract.sol b/contracts/democracy/delegation/DelegationAbstract.sol similarity index 98% rename from contracts/democracy/DelegationAbstract.sol rename to contracts/democracy/delegation/DelegationAbstract.sol index be3d6ca..98a9c48 100644 --- a/contracts/democracy/DelegationAbstract.sol +++ b/contracts/democracy/delegation/DelegationAbstract.sol @@ -1,6 +1,6 @@ pragma solidity >=0.5.0 <0.6.0; -import "../deploy/InstanceAbstract.sol"; +import "../../deploy/InstanceAbstract.sol"; import "./Delegation.sol"; /** diff --git a/contracts/democracy/DelegationBase.sol b/contracts/democracy/delegation/DelegationBase.sol similarity index 100% rename from contracts/democracy/DelegationBase.sol rename to contracts/democracy/delegation/DelegationBase.sol diff --git a/contracts/democracy/DelegationFactory.sol b/contracts/democracy/delegation/DelegationFactory.sol similarity index 77% rename from contracts/democracy/DelegationFactory.sol rename to contracts/democracy/delegation/DelegationFactory.sol index 43b629d..53bf4bb 100644 --- a/contracts/democracy/DelegationFactory.sol +++ b/contracts/democracy/delegation/DelegationFactory.sol @@ -1,7 +1,7 @@ pragma solidity >=0.5.0 <0.6.0; -import "../deploy/InstanceFactory.sol"; -import "../deploy/Instance.sol"; +import "../../deploy/InstanceFactory.sol"; +import "../../deploy/Instance.sol"; import "./DelegationAbstract.sol"; /** @@ -22,7 +22,7 @@ contract DelegationFactory is InstanceFactory { external returns (DelegationAbstract instance) { - instance = new Instance(base, prototypes[address(base)].init, msg.data); + instance = DelegationAbstract(new Instance(base, prototypes[address(base)].init, msg.data)); emit InstanceCreated(instance); } diff --git a/contracts/democracy/DelegationInit.sol b/contracts/democracy/delegation/DelegationInit.sol similarity index 100% rename from contracts/democracy/DelegationInit.sol rename to contracts/democracy/delegation/DelegationInit.sol diff --git a/contracts/democracy/proposal/Proposal.sol b/contracts/democracy/proposal/Proposal.sol new file mode 100644 index 0000000..403fe7d --- /dev/null +++ b/contracts/democracy/proposal/Proposal.sol @@ -0,0 +1,35 @@ +pragma solidity >=0.5.0 <0.6.0; + +/** + * @title Proposal + * @author Ricardo Guilherme Schmidt (Status Research & Development GmbH) + * Store votes and tabulate results for Democracy + */ +interface Proposal { + + enum Vote { + Null, + Reject, + Approve + } + + + function voteSigned(bytes32 _signatures) external; + + function voteDirect(Vote _vote) external; + + function tabulateDirect(address _voter) external; + + function tabulateSigned(Vote _vote, uint256 _position, bytes32[] calldata _proof, bytes calldata _signature) external; + + function tabulateDelegated(address _voter) external; + + function precomputeDelegation(address _start, bool _clean) external; + + function finalize() external; + + function clear() external; + + + +} \ No newline at end of file diff --git a/contracts/democracy/proposal/ProposalAbstract.sol b/contracts/democracy/proposal/ProposalAbstract.sol new file mode 100644 index 0000000..6a6adf4 --- /dev/null +++ b/contracts/democracy/proposal/ProposalAbstract.sol @@ -0,0 +1,39 @@ +pragma solidity >=0.5.0 <0.6.0; + +import "../../common/Controlled.sol"; +import "../../deploy/InstanceAbstract.sol"; +import "../../token/MiniMeToken.sol"; +import "../delegation/Delegation.sol"; +import "./Proposal.sol"; + +/** + * @title Proposal + * @author Ricardo Guilherme Schmidt (Status Research & Development GmbH) + * Store votes and tabulate results for Democracy + */ +contract ProposalAbstract is InstanceAbstract, Proposal, Controlled { + + MiniMeToken public token; + Delegation public delegation; + uint256 public tabulationBlockDelay; + + bytes32 topic; + bytes32 txHash; + uint blockStart; + uint voteBlockEnd; + + //votes storage + bytes32[] signatures; + mapping(address => Vote) voteMap; + + //tabulation process + uint256 lastTabulationBlock; + mapping(address => address) delegationOf; + mapping(address => address) tabulated; + mapping(uint8 => uint256) results; + + Vote result; + + + +} \ No newline at end of file diff --git a/contracts/democracy/Proposal.sol b/contracts/democracy/proposal/ProposalBase.sol similarity index 74% rename from contracts/democracy/Proposal.sol rename to contracts/democracy/proposal/ProposalBase.sol index 001648c..76125d7 100644 --- a/contracts/democracy/Proposal.sol +++ b/contracts/democracy/proposal/ProposalBase.sol @@ -1,65 +1,22 @@ pragma solidity >=0.5.0 <0.6.0; -import "../common/Controlled.sol"; -import "../common/MessageSigned.sol"; -import "../common/MerkleProof.sol"; -import "../token/MiniMeToken.sol"; -import "./Delegation.sol"; -import "./TrustNetworkInterface.sol"; +import "../../common/MessageSigned.sol"; +import "../../common/MerkleProof.sol"; +import "./ProposalAbstract.sol"; /** * @title Proposal * @author Ricardo Guilherme Schmidt (Status Research & Development GmbH) * Store votes and tabulate results for Democracy */ -contract Proposal is Controlled, MessageSigned { - MiniMeToken public token; - Delegation public delegation; - uint256 public tabulationBlockDelay; - - bytes32 topic; - bytes32 txHash; - uint blockStart; - uint voteBlockEnd; +contract ProposalBase is ProposalAbstract, MessageSigned { - //votes storage - bytes32[] signatures; - mapping(address => Vote) voteMap; - //tabulation process - uint256 lastTabulationBlock; - mapping(address => address) delegationOf; - mapping(address => address) tabulated; - mapping(uint8 => uint256) results; - - Vote result; - - - enum Vote { - Null, - Reject, - Approve - } - - constructor( - MiniMeToken _token, - Delegation _delegation, - bytes32 _topic, - bytes32 _txHash, - uint256 _tabulationBlockDelay, - uint256 _blockStart, - uint256 _blockEndDelay - ) + constructor() public - { - delegation = _delegation; - token = _token; - tabulationBlockDelay = _tabulationBlockDelay; - topic = _topic; - txHash = _txHash; - blockStart = _blockStart; - voteBlockEnd = blockStart + _blockEndDelay; + blockStart = uint256(-1); + voteBlockEnd = uint256(-1); } function voteSigned(bytes32 _signatures) @@ -169,20 +126,22 @@ contract Proposal is Controlled, MessageSigned { } } - function cacheDelegation(address _delegator, bool _clean) private returns (address) { - address delegate; - if(!_clean) { - delegate = delegationOf[_delegator]; - } - if(delegate == address(0)){ - delegate = delegation.delegatedToAt(_delegator, voteBlockEnd); //get delegate chain tail + function cacheDelegation(address _delegator, bool _clean) private returns (address delegate) { + delegate = _delegator; + if(voteMap[_delegator] == Vote.Null) { + if(!_clean) { + delegate = delegationOf[delegate]; + } + if(delegate == address(0)){ + delegate = delegation.delegatedToAt(_delegator, voteBlockEnd); //get delegate chain tail + } } + require(delegate != address(0), "No delegate vote found"); if(voteMap[delegate] == Vote.Null) { delegate = cacheDelegation(delegate, _clean); } delegationOf[_delegator] = delegate; - return delegate; } diff --git a/contracts/democracy/proposal/ProposalFactory.sol b/contracts/democracy/proposal/ProposalFactory.sol new file mode 100644 index 0000000..b39436a --- /dev/null +++ b/contracts/democracy/proposal/ProposalFactory.sol @@ -0,0 +1,35 @@ +pragma solidity >=0.5.0 <0.6.0; + +import "../../deploy/InstanceFactory.sol"; +import "../../deploy/Instance.sol"; +import "./ProposalAbstract.sol"; + +/** + * @title DelegationFactory + * @author Ricardo Guilherme Schmidt (Status Research & Development GmbH) + * @dev Upgradable delegation proxy factory + */ +contract ProposalFactory is InstanceFactory { + + constructor(InstanceAbstract _base, InstanceAbstract _init, InstanceAbstract _emergency) + InstanceFactory(_base, _init, _emergency) + public + { } + + function createProposal( + MiniMeToken _token, + Delegation _delegation, + bytes32 _topic, + bytes32 _txHash, + uint256 _tabulationBlockDelay, + uint256 _blockStart, + uint256 _blockEndDelay + ) + external + returns (ProposalAbstract instance) + { + instance = ProposalAbstract(new Instance(base, prototypes[address(base)].init, msg.data)); + emit InstanceCreated(instance); + } + +} \ No newline at end of file diff --git a/contracts/democracy/proposal/ProposalInit.sol b/contracts/democracy/proposal/ProposalInit.sol new file mode 100644 index 0000000..ae109d7 --- /dev/null +++ b/contracts/democracy/proposal/ProposalInit.sol @@ -0,0 +1,39 @@ +pragma solidity >=0.5.0 <0.6.0; + +import "./ProposalAbstract.sol"; + +/** + * @title Proposal + * @author Ricardo Guilherme Schmidt (Status Research & Development GmbH) + * Store votes and tabulate results for Democracy + */ +contract ProposalInit is ProposalAbstract { + + constructor() public { + token = MiniMeToken(address(-1)); + } + + function createProposal( + MiniMeToken _token, + Delegation _delegation, + bytes32 _topic, + bytes32 _txHash, + uint256 _tabulationBlockDelay, + uint256 _blockStart, + uint256 _blockEndDelay + ) + external + { + require(address(token) == address(0), "Already initialized"); + delegation = _delegation; + token = _token; + tabulationBlockDelay = _tabulationBlockDelay; + topic = _topic; + txHash = _txHash; + blockStart = _blockStart; + voteBlockEnd = blockStart + _blockEndDelay; + } + + + +} \ No newline at end of file