Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Disputable Voting: Support quiet ending #1205

Merged
merged 7 commits into from
Jul 20, 2020

Conversation

facuspagnuolo
Copy link
Contributor

@facuspagnuolo facuspagnuolo commented Jul 14, 2020

Fixes aragon/client#836

Quiet Ending Voting extends the duration of a vote by X amount if the outcome is flipped within Y amount of time before the end of the vote.

This PR proposed the following implementation:

image

Copy link
Contributor

@bingen bingen left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Still reviewing, having hard time to wrap my head around all these periods, haha.

@@ -690,7 +739,7 @@ contract DisputableVoting is DisputableAragonApp, IForwarder {
* @return True if the given voter can participate a certain vote
*/
function _canVote(Vote storage vote_, address _voter) internal view returns (bool) {
return _isVoteOpenForVoting(vote_) && _hasVotingPower(vote_, _voter);
return _isVoteOpenForVoting(vote_) && _hasVotingPower(vote_, _voter) && _voteCaster(vote_, _voter) != _voter;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This means that voters can’t change their cast votes, right? Some discussion rings a bell about this, but I don’t remember it. What was the rationale for this change?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, simply because since multiple extensions are allowed, if we allow voters to change their vote, then they could extend votes indefinitely

function _hasNotVotedYet(Vote storage vote_, address _voter) internal view returns (bool) {
return _voteCaster(vote_, _voter) != _voter;
function _hasCastedVote(Vote storage vote_, address _voter) internal view returns (bool) {
return _voterState(vote_, _voter) != VoterState.Absent;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This changes also means that representatives can’t change votes either, which is consistent with holders not being able.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Exactly, since multiple extensions are allowed, if we allow representatives to change their vote, then they could extend votes indefinitely due to quiet ending

Copy link
Contributor

@bingen bingen left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I left some comments / doubts below, but overall looks good to me. The most important ones about the quietEndingPeriod check and the multiple extensions.

} else if (state == VoterState.Nay) {
vote_.nay = vote_.nay.sub(voterStake);
// Note that votes can be changed only during the overrule window
VoterState previousVoterState = _voterState(vote_, _voter);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It’s actually unrelated to this PR, but I wonder if it would be worth it to check if the new vote is different than the old one.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I tried it but I honestly don't think it looks cleaner. If you see a cleaner way please share!

* @param _quietEndingExtension New quiet ending extension in seconds
*/
function _changeQuietEndingPeriod(uint64 _quietEndingPeriod, uint64 _quietEndingExtension) internal {
require(_quietEndingPeriod <= voteTime, ERROR_INVALID_QUIET_ENDING_PERIOD);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Shouldn’t we enforce that it’s not greater than the overrule window? The diagram in the PR description seems to suggest that.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Not necessarily, look at the diagrams in section (2). It is possible to have a quiet ending period that encapsulates the overrule window.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I see, thanks! And actually, as all those parameters can be zero, this way we can have quiet ending without overrule window.
But now I have another question: why does the quiet ending period need to be <= the quiet ending extension?
Finally, I would personally understand better those diagrams if the “Flipped” arrow was disassociated from the start of the quiet ending extension.

if (voterStake < yeas.add(nays) && _withinQuietEndingPeriod(vote_)) {
bool isAccepted = _isAccepted(yeas, yeas.add(nays), votingPower, supportRequired, minimumAcceptanceQuorum);
if (wasAccepted != isAccepted) {
vote_.quietEndingExtendedSeconds = vote_.quietEndingExtendedSeconds.add(vote_.quietEndingExtension);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why are we adding here? If multiple flips happen (although it’s unlikely), the vote could get very long. Isn’t it enough with one extension?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, but that is the main purpose of quiet ending

* [ vote active ][ vote paused ][ . vote active ]
* ^ ^ ^
* | | |
* vote starts duration start date vote ends
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nice!

@facuspagnuolo facuspagnuolo merged commit d34844a into disputable_voting_app Jul 20, 2020
@facuspagnuolo facuspagnuolo deleted the quiet_ending branch July 20, 2020 20:27
ramilexe pushed a commit to ConsiderItDone/aragon-apps that referenced this pull request Dec 9, 2021
* DisputableVoting: disallow changing votes

* DisputableVoting: split create and vote tests

* DisputableVoting: fix can execute

* DisputableVoting: implement quiet ending

* DisputableVoting: Minor enhancements based on review from @bingen

* DisputableVoting: Add tests for challenged states
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants