evm-tokenvote

Unnamed repository; edit this file 'description' to name the repository.
Log | Files | Refs

commit fa01e69dfd66475bb9e142d1b4600176e56c0296
parent cc8bbafddd40fbb3854eadeee36899111160159a
Author: lash <dev@holbrook.no>
Date:   Wed,  3 May 2023 21:38:44 +0100

Ensure voter bootstrap, add remove voter method

Diffstat:
Msolidity/Vote.sol | 71++++++++++++++++++++++++++++++++++++++++++++++++++++++-----------------
1 file changed, 54 insertions(+), 17 deletions(-)

diff --git a/solidity/Vote.sol b/solidity/Vote.sol @@ -18,7 +18,8 @@ contract ERC20Vote { uint256 voteTargetPpm; uint256 scanCursor; address []voters; - bool voterVote; + //bool voterVote; + uint8 voteMode; bool valid; bool active; bool ackScanDone; @@ -35,21 +36,27 @@ contract ERC20Vote { mapping ( uint256 => uint256 ) budget; address newVoter; - //mapping ( address => bytes32 ) newVoterDigest; - Proposal []proposals; - uint256 proposalCursor; + Proposal[] public proposals; + + uint256 public proposalCursor; event ProposalAdded(uint256 indexed _proposalIdx, uint256 indexed _ackBlockDeadline, uint256 indexed voteTargetPpm); - event VoterProposalAdded(uint256 indexed _proposalIdx, uint256 indexed _ackBlockDeadline, uint256 indexed voteTargetPpm, address _voter); + event VoterProposalAdded(uint256 indexed _proposalIdx, uint256 indexed _ackBlockDeadline, uint8 indexed _voteMode, address _voter); event VotesAdded(uint256 indexed _proposalIdx, address indexed _voter, uint256 indexed _total, uint256 _delta); event VotesWithdrawn(uint256 indexed _proposalIdx, address indexed _voter, uint256 indexed _total, uint256 _delta); + event VoteResult(uint256 indexed _proposaldx, bool result); + event ProposalInvalid(uint256 _proposalIdx); - constructor(address _token) { + constructor(address _token, address _secondVoter) { token = _token; + voters.push(msg.sender); + voterState[msg.sender] = block.number; + voters.push(_secondVoter); + voterState[_secondVoter] = block.number; } - // bounded processing of all proposals + // bounded sequential control of all proposals, to avoid gas lockout. // protects the voter population from changing between a vote has been proposed and it has been processed function scanProposal(uint256 _count) public returns (bool) { uint256 i; @@ -73,8 +80,8 @@ contract ERC20Vote { return true; } - // bounded processing of acks for a proposal - // when complete, relevant acks will be committed to the proposal and voting ratification can be possible + // bounded processing of acks for a proposal, to avoid gas lockout. + // when complete, relevant acks will be committed to the proposal and voting ratification can be possible. function scanAck(uint256 _proposalIdx, uint256 _count) public returns (bool) { Proposal storage proposal; uint256 i; @@ -103,6 +110,9 @@ contract ERC20Vote { return true; } + // bounded processing of votes, to avoid gas lockout. + // can only be called after voting deadline. + // adds all cast votes to the tally. function scanVote(uint256 _proposalIdx, uint256 _count) public returns (bool) { Proposal storage proposal; uint256 i; @@ -132,7 +142,7 @@ contract ERC20Vote { return true; } - // finalize proposal and result + // finalize proposal and result. function ratify(uint256 _proposalIdx) public returns (bool) { Proposal storage proposal; uint256 tallyPpm; @@ -141,7 +151,7 @@ contract ERC20Vote { proposal = getActive(_proposalIdx); require(proposal.voteScanDone, "ERR_VOTE_SCAN_MISSING"); - if (proposal.voterVote) { + if (proposal.voteMode > 0) { require(_proposalIdx == proposalCursor, "ERR_PREMATURE_VOTERVOTE"); } @@ -149,13 +159,30 @@ contract ERC20Vote { budgetPpm = budget[_proposalIdx] * 1000000; if (tallyPpm / budgetPpm >= proposal.voteTargetPpm) { - proposal.result = true; + proposal.result = checkRatify(proposal); } proposal.active = false; + emit VoteResult(_proposalIdx, proposal.result); return proposal.result; } - // Common code for propose and proposeVoter + function checkRatify(Proposal storage _proposal) private returns (bool) { + if (_proposal.voteMode == 1) { + if (voterState[newVoter] == 0) { + voters.push(newVoter); + } else { + voterState[newVoter] = block.number; + } + newVoter = address(0); + } + if (_proposal.voteMode < 2) { + return true; + } + voterState[newVoter] = 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff; + return true; + } + + // Common code for propose and proposeVoter. function proposeCore(bytes32 _digest, uint256 _ackBlockDeadline, uint256 _voteBlockDeadline, uint256 _voteTargetPpm) private returns (uint256) { require(_ackBlockDeadline > block.number); require(_voteBlockDeadline > _ackBlockDeadline); @@ -191,7 +218,17 @@ contract ERC20Vote { } // Propose addition of a new voter. - function proposeVoter(address _voter, uint256 _ackBlockDeadline, uint256 _voteBlockDeadline, uint256 _voteTargetPpm) public returns (uint256) { + function proposeAddVoter(address _voter, uint256 _ackBlockDeadline, uint256 _voteBlockDeadline, uint256 _voteTargetPpm) public returns (uint256) { + return proposeVoterCore(_voter, _ackBlockDeadline, _voteBlockDeadline, _voteTargetPpm, 1); + } + + + // Propose removal of an existing voter. + function proposeRemoveVoter(address _voter, uint256 _ackBlockDeadline, uint256 _voteBlockDeadline, uint256 _voteTargetPpm) public returns (uint256) { + return proposeVoterCore(_voter, _ackBlockDeadline, _voteBlockDeadline, _voteTargetPpm, 2); + } + + function proposeVoterCore(address _voter, uint256 _ackBlockDeadline, uint256 _voteBlockDeadline, uint256 _voteTargetPpm, uint8 _voteMode) public returns (uint256) { bytes32 voterDigest; bytes memory voterDigestMaterial; uint256 proposalIdx; @@ -201,11 +238,10 @@ contract ERC20Vote { newVoter = _voter; voterDigestMaterial = abi.encodePacked("bytes", bytes20(_voter)); voterDigest = sha256(voterDigestMaterial); - //newVoterDigest[_voter] = voterDigest; proposalIdx = proposeCore(voterDigest, _ackBlockDeadline, _voteBlockDeadline, _voteTargetPpm); - proposals[proposalIdx].voterVote = true; - emit VoterProposalAdded(proposalIdx, _ackBlockDeadline, _voteTargetPpm, _voter); + proposals[proposalIdx].voteMode = _voteMode; + emit VoterProposalAdded(proposalIdx, _ackBlockDeadline, _voteMode, _voter); return proposalIdx; } @@ -313,6 +349,7 @@ contract ERC20Vote { proposal = proposals[_proposalIdx]; proposal.valid = false; proposal.active = false; + emit ProposalInvalid(_proposalIdx); return 0; } return balance;