fix delegate flood gas "attack"/"limitation"

This commit is contained in:
Ricardo Guilherme Schmidt 2018-03-11 17:11:46 +07:00
parent bc3ced8f58
commit 9dde851c06

View File

@ -31,24 +31,18 @@ contract ProposalManager is Controlled {
uint voteBlockEnd; uint voteBlockEnd;
uint vetoBlockEnd; uint vetoBlockEnd;
VoteTicket[] votes; mapping(address => Vote) voteMap;
mapping(address => uint) voteIndex;
uint tabulationPosition; mapping(address => bool) tabulated;
bool tabulated;
mapping(uint8 => uint) results; mapping(uint8 => uint256) results;
bool approved; bool approved;
bool executed; bool executed;
} }
struct VoteTicket {
address voter;
Vote vote;
}
enum Vote { enum Vote {
Null,
Reject, Reject,
Approve, Approve,
Veto Veto
@ -88,6 +82,7 @@ contract ProposalManager is Controlled {
} }
function execute(uint id) public { function execute(uint id) public {
//require quorum reached
Proposal memory p = proposals[id]; Proposal memory p = proposals[id];
proposals[id].executed = true; proposals[id].executed = true;
ProposalExecutor(controller).executeProposal(p.topic, p.value, p.data); ProposalExecutor(controller).executeProposal(p.topic, p.value, p.data);
@ -101,47 +96,28 @@ contract ProposalManager is Controlled {
} else { } else {
require(block.number <= proposal.voteBlockEnd); require(block.number <= proposal.voteBlockEnd);
} }
uint votePos = proposal.voteIndex[msg.sender];
if (votePos == 0) { proposal.voteMap[msg.sender] = _vote;
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) public { function tabulate(uint _proposal, address _delegator) public {
Proposal storage proposal = proposals[_proposal]; Proposal storage proposal = proposals[_proposal];
require(block.number > proposal.vetoBlockEnd); 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 voteDelegation;
DelegationProxy vetoDelegation; DelegationProxy vetoDelegation;
(voteDelegation, vetoDelegation) = trustNet.getTopic(proposal.topic); (voteDelegation, vetoDelegation) = trustNet.getTopic(proposal.topic);
for (uint i = proposal.tabulationPosition; i < loopLimit; i++) { Vote _vote = proposal.voteMap[vetoDelegation.delegationOfAt(_delegator, proposal.vetoBlockEnd)];
VoteTicket memory _vote = proposal.votes[i]; if (_vote != Vote.Veto) {
if (_vote.vote == Vote.Reject || _vote.vote == Vote.Approve) { _vote = proposal.voteMap[voteDelegation.delegationOfAt(_delegator, proposal.voteBlockEnd)];
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 (_vote == Vote.Reject || _vote == Vote.Approve) {
if (proposal.tabulationPosition == totalVoted) { proposal.results[uint8(_vote)] += MiniMeToken(SNT).balanceOfAt(_delegator, proposal.voteBlockEnd);
proposal.tabulated = true; } else {
proposal.results[uint8(_vote)] += MiniMeToken(SNT).balanceOfAt(_delegator, proposal.vetoBlockEnd);
} }
} }