From 9420756a83563ebe84dfec6abbdfe6971d598bf0 Mon Sep 17 00:00:00 2001 From: Michael Bucher Date: Fri, 20 May 2022 10:55:34 +0200 Subject: [PATCH] #28: Handle quorum reached but all abstained case --- .../neo/grantshares/GrantSharesGov.java | 3 ++- .../grantshares/ProposalExecutionsTest.java | 24 +++++++++++++++++++ 2 files changed, 26 insertions(+), 1 deletion(-) diff --git a/src/main/java/com/axlabs/neo/grantshares/GrantSharesGov.java b/src/main/java/com/axlabs/neo/grantshares/GrantSharesGov.java index f8ba128..f48fe36 100644 --- a/src/main/java/com/axlabs/neo/grantshares/GrantSharesGov.java +++ b/src/main/java/com/axlabs/neo/grantshares/GrantSharesGov.java @@ -499,7 +499,8 @@ public static Object[] execute(int id) { if (voteCount * 100 / Storage.getInt(getReadOnlyContext(), MEMBERS_COUNT_KEY) < data.quorum) fireErrorAndAbort("Quorum not reached", "execute"); int yesNoCount = votes.approve + votes.reject; - if (votes.approve * 100 / yesNoCount <= data.acceptanceRate) fireErrorAndAbort("Proposal rejected", "execute"); + if (yesNoCount == 0 || (votes.approve * 100 / yesNoCount <= data.acceptanceRate)) + fireErrorAndAbort("Proposal rejected", "execute"); proposal.executed = true; Object[] returnVals = new Object[data.intents.length]; diff --git a/src/test/java/com/axlabs/neo/grantshares/ProposalExecutionsTest.java b/src/test/java/com/axlabs/neo/grantshares/ProposalExecutionsTest.java index b089551..251e324 100644 --- a/src/test/java/com/axlabs/neo/grantshares/ProposalExecutionsTest.java +++ b/src/test/java/com/axlabs/neo/grantshares/ProposalExecutionsTest.java @@ -233,6 +233,30 @@ public void fail_executing_proposal_quorum_reached_but_rejected() throws Throwab assertAborted(tx, "Proposal rejected", neow3j); } + @Test + public void fail_executing_proposal_quorum_reached_but_all_abstained() throws Throwable { + ContractParameter intents = array(array(gov.getScriptHash(), CHANGE_PARAM, + array(MIN_ACCEPTANCE_RATE_KEY, 40), CallFlags.ALL.getValue())); + String offchainUri = "fail_executing_proposal_quorum_reached_but_all_abstained"; + + // 1. Create and endorse proposal, then skip till voting phase. + int id = createAndEndorseProposal(gov, neow3j, bob, alice, intents, offchainUri); + ext.fastForwardOneBlock(PHASE_LENGTH); + + // 2. Vote abstained for all members. + voteForProposal(gov, neow3j, id, 0, alice); + voteForProposal(gov, neow3j, id, 0, charlie); + voteForProposal(gov, neow3j, id, 0, denise); + voteForProposal(gov, neow3j, id, 0, eve); + voteForProposal(gov, neow3j, id, 0, florian); + ext.fastForwardOneBlock(PHASE_LENGTH + PHASE_LENGTH); + + // 3. Call execute + Hash256 tx = gov.execute(id).signers(AccountSigner.calledByEntry(bob)) + .sign().send().getSendRawTransaction().getHash(); + assertAborted(tx, "Proposal rejected", neow3j); + } + @Test public void fail_executing_proposal_quorum_not_reached() throws Throwable { ContractParameter intents = array(array(gov.getScriptHash(), CHANGE_PARAM,