From 45eb28d698df9e68f0a9538f3cb03d0956ed372d Mon Sep 17 00:00:00 2001 From: 0xmad <0xmad@users.noreply.github.com> Date: Wed, 23 Oct 2024 17:18:39 -0500 Subject: [PATCH] chore(contracts): add struct for add tally results args --- packages/cli/ts/commands/proveOnChain.ts | 18 ++-- packages/contracts/contracts/Tally.sol | 67 +++++++------- packages/contracts/tasks/helpers/Prover.ts | 18 ++-- packages/contracts/tests/Tally.test.ts | 100 ++++++++++----------- 4 files changed, 104 insertions(+), 99 deletions(-) diff --git a/packages/cli/ts/commands/proveOnChain.ts b/packages/cli/ts/commands/proveOnChain.ts index 02b9d2db4..2fde7b89f 100644 --- a/packages/cli/ts/commands/proveOnChain.ts +++ b/packages/cli/ts/commands/proveOnChain.ts @@ -379,17 +379,17 @@ export const proveOnChain = async ({ ); await tallyContract - .addTallyResults( - tallyData.results.tally.map((_, index) => index), + .addTallyResults({ + voteOptionIndices: tallyData.results.tally.map((_, index) => index), tallyResults, tallyResultProofs, - tallyData.totalSpentVoiceCredits.spent, - tallyData.totalSpentVoiceCredits.salt, - tallyData.results.salt, - tallyData.results.commitment, - tallyData.totalSpentVoiceCredits.commitment, - tallyData.perVOSpentVoiceCredits?.commitment ?? 0n, - ) + totalSpent: tallyData.totalSpentVoiceCredits.spent, + totalSpentSalt: tallyData.totalSpentVoiceCredits.salt, + tallyResultSalt: tallyData.results.salt, + newResultsCommitment: tallyData.results.commitment, + spentVoiceCreditsHash: tallyData.totalSpentVoiceCredits.commitment, + perVOSpentVoiceCreditsHash: tallyData.perVOSpentVoiceCredits?.commitment ?? 0n, + }) .then((tx) => tx.wait()); } }; diff --git a/packages/contracts/contracts/Tally.sol b/packages/contracts/contracts/Tally.sol index 3d6743038..5297ad383 100644 --- a/packages/contracts/contracts/Tally.sol +++ b/packages/contracts/contracts/Tally.sol @@ -28,6 +28,28 @@ contract Tally is Ownable, SnarkCommon, CommonUtilities, Hasher, DomainObjs, ITa bool flag; } + /// @notice tally result args + struct AddTallyResultsArgs { + /// @param voteOptionIndices Vote option index. + uint256[] voteOptionIndices; + /// @param tallyResults The results of vote tally for the recipients. + uint256[] tallyResults; + /// @param tallyResultProofs Proofs of correctness of the vote tally results. + uint256[][][] tallyResultProofs; + /// @param totalSpent spent field retrieved in the totalSpentVoiceCredits object + uint256 totalSpent; + /// @param totalSpentSalt spent salt + uint256 totalSpentSalt; + /// @param tallyResultSalt the respective salt in the results object in the tally.json + uint256 tallyResultSalt; + /// @param newResultsCommitment The salted commitment of the vote tally for this batch of leaves plus the vote tally from currentResults + uint256 newResultsCommitment; + /// @param spentVoiceCreditsHash hashLeftRight(number of spent voice credits, spent salt) + uint256 spentVoiceCreditsHash; + /// @param perVOSpentVoiceCreditsHash hashLeftRight(merkle root of the no spent voice credits per vote option, perVOSpentVoiceCredits salt) + uint256 perVOSpentVoiceCreditsHash; + } + /// @notice The commitment to the tally results. Its initial value is 0, but after /// the tally of each batch is proven on-chain via a zk-SNARK, it should be /// updated to: @@ -366,41 +388,24 @@ contract Tally is Ownable, SnarkCommon, CommonUtilities, Hasher, DomainObjs, ITa /** * @notice Add and verify tally results by batch. - * @param _voteOptionIndices Vote option index. - * @param _tallyResults The results of vote tally for the recipients. - * @param _tallyResultProofs Proofs of correctness of the vote tally results. - * @param _totalSpent spent field retrieved in the totalSpentVoiceCredits object - * @param _tallyResultSalt the respective salt in the results object in the tally.json - * @param _newResultsCommitment The salted commitment of the vote tally for this batch of leaves plus the vote tally from currentResults - * @param _spentVoiceCreditsHash hashLeftRight(number of spent voice credits, spent salt) - * @param _perVOSpentVoiceCreditsHash hashLeftRight(merkle root of the no spent voice credits per vote option, perVOSpentVoiceCredits salt) + * @param args add tally result args */ - function addTallyResults( - uint256[] calldata _voteOptionIndices, - uint256[] calldata _tallyResults, - uint256[][][] calldata _tallyResultProofs, - uint256 _totalSpent, - uint256 _totalSpentSalt, - uint256 _tallyResultSalt, - uint256 _newResultsCommitment, - uint256 _spentVoiceCreditsHash, - uint256 _perVOSpentVoiceCreditsHash - ) public virtual onlyOwner { + function addTallyResults(AddTallyResultsArgs calldata args) public virtual onlyOwner { if (!isTallied()) { revert VotesNotTallied(); } (, , , uint8 voteOptionTreeDepth) = poll.treeDepths(); - uint256 voteOptionsLength = _voteOptionIndices.length; + uint256 voteOptionsLength = args.voteOptionIndices.length; for (uint256 i = 0; i < voteOptionsLength; ) { addTallyResult( - _voteOptionIndices[i], - _tallyResults[i], - _tallyResultProofs[i], - _tallyResultSalt, - _spentVoiceCreditsHash, - _perVOSpentVoiceCreditsHash, + args.voteOptionIndices[i], + args.tallyResults[i], + args.tallyResultProofs[i], + args.tallyResultSalt, + args.spentVoiceCreditsHash, + args.perVOSpentVoiceCreditsHash, voteOptionTreeDepth ); @@ -410,17 +415,17 @@ contract Tally is Ownable, SnarkCommon, CommonUtilities, Hasher, DomainObjs, ITa } bool verified = verifySpentVoiceCredits( - _totalSpent, - _totalSpentSalt, - _newResultsCommitment, - _perVOSpentVoiceCreditsHash + args.totalSpent, + args.totalSpentSalt, + args.newResultsCommitment, + args.perVOSpentVoiceCreditsHash ); if (!verified) { revert IncorrectSpentVoiceCredits(); } - totalSpent = _totalSpent; + totalSpent = args.totalSpent; } /** diff --git a/packages/contracts/tasks/helpers/Prover.ts b/packages/contracts/tasks/helpers/Prover.ts index 17cfa6ba6..5ce95a4fb 100644 --- a/packages/contracts/tasks/helpers/Prover.ts +++ b/packages/contracts/tasks/helpers/Prover.ts @@ -317,17 +317,17 @@ export class Prover { ); await this.tallyContract - .addTallyResults( - tallyData.results.tally.map((_, index) => index), + .addTallyResults({ + voteOptionIndices: tallyData.results.tally.map((_, index) => index), tallyResults, tallyResultProofs, - tallyData.totalSpentVoiceCredits.spent, - tallyData.totalSpentVoiceCredits.salt, - tallyData.results.salt, - tallyData.results.commitment, - tallyData.totalSpentVoiceCredits.commitment, - tallyData.perVOSpentVoiceCredits?.commitment ?? 0n, - ) + totalSpent: tallyData.totalSpentVoiceCredits.spent, + totalSpentSalt: tallyData.totalSpentVoiceCredits.salt, + tallyResultSalt: tallyData.results.salt, + newResultsCommitment: tallyData.results.commitment, + spentVoiceCreditsHash: tallyData.totalSpentVoiceCredits.commitment, + perVOSpentVoiceCreditsHash: tallyData.perVOSpentVoiceCredits?.commitment ?? 0n, + }) .then((tx) => tx.wait()); } diff --git a/packages/contracts/tests/Tally.test.ts b/packages/contracts/tests/Tally.test.ts index 2e817b2e3..2a1b0f471 100644 --- a/packages/contracts/tests/Tally.test.ts +++ b/packages/contracts/tests/Tally.test.ts @@ -316,17 +316,17 @@ describe("TallyVotes", () => { ); await expect( - tallyContract.addTallyResults( - tallyData.results.tally.map((_, index) => index), - tallyData.results.tally, + tallyContract.addTallyResults({ + voteOptionIndices: tallyData.results.tally.map((_, index) => index), + tallyResults: tallyData.results.tally, tallyResultProofs, - tallyData.totalSpentVoiceCredits.spent, - tallyData.totalSpentVoiceCredits.salt, - tallyData.results.salt, - tallyData.results.commitment, - tallyData.totalSpentVoiceCredits.commitment, - 0n, - ), + totalSpent: tallyData.totalSpentVoiceCredits.spent, + totalSpentSalt: tallyData.totalSpentVoiceCredits.salt, + tallyResultSalt: tallyData.results.salt, + newResultsCommitment: tallyData.results.commitment, + spentVoiceCreditsHash: tallyData.totalSpentVoiceCredits.commitment, + perVOSpentVoiceCreditsHash: 0n, + }), ).to.be.revertedWithCustomError(tallyContract, "VotesNotTallied"); }); @@ -376,31 +376,31 @@ describe("TallyVotes", () => { const indices = tallyData.results.tally.map((_, index) => index); await expect( - tallyContract.addTallyResults( - indices, - tallyData.results.tally, + tallyContract.addTallyResults({ + voteOptionIndices: indices, + tallyResults: tallyData.results.tally, tallyResultProofs, - 0n, - 0n, - tallyData.results.salt, - 0n, - tallyData.totalSpentVoiceCredits.commitment, - newPerVOSpentVoiceCreditsCommitment, - ), + totalSpent: 0n, + totalSpentSalt: 0n, + tallyResultSalt: tallyData.results.salt, + newResultsCommitment: 0n, + spentVoiceCreditsHash: tallyData.totalSpentVoiceCredits.commitment, + perVOSpentVoiceCreditsHash: newPerVOSpentVoiceCreditsCommitment, + }), ).to.be.revertedWithCustomError(tallyContract, "IncorrectSpentVoiceCredits"); await tallyContract - .addTallyResults( - indices, - tallyData.results.tally, + .addTallyResults({ + voteOptionIndices: indices, + tallyResults: tallyData.results.tally, tallyResultProofs, - tallyData.totalSpentVoiceCredits.spent, - tallyData.totalSpentVoiceCredits.salt, - tallyData.results.salt, - tallyData.results.commitment, - tallyData.totalSpentVoiceCredits.commitment, - newPerVOSpentVoiceCreditsCommitment, - ) + totalSpent: tallyData.totalSpentVoiceCredits.spent, + totalSpentSalt: tallyData.totalSpentVoiceCredits.salt, + tallyResultSalt: tallyData.results.salt, + newResultsCommitment: tallyData.results.commitment, + spentVoiceCreditsHash: tallyData.totalSpentVoiceCredits.commitment, + perVOSpentVoiceCreditsHash: newPerVOSpentVoiceCreditsCommitment, + }) .then((tx) => tx.wait()); const initialResults = await Promise.all(indices.map((index) => tallyContract.tallyResults(index))); @@ -410,17 +410,17 @@ describe("TallyVotes", () => { expect(initialResults.map((result) => result.value)).to.deep.equal(tallyData.results.tally); await tallyContract - .addTallyResults( - indices, - tallyData.results.tally, + .addTallyResults({ + voteOptionIndices: indices, + tallyResults: tallyData.results.tally, tallyResultProofs, - tallyData.totalSpentVoiceCredits.spent, - tallyData.totalSpentVoiceCredits.salt, - tallyData.results.salt, - tallyData.results.commitment, - tallyData.totalSpentVoiceCredits.commitment, - newPerVOSpentVoiceCreditsCommitment, - ) + totalSpent: tallyData.totalSpentVoiceCredits.spent, + totalSpentSalt: tallyData.totalSpentVoiceCredits.salt, + tallyResultSalt: tallyData.results.salt, + newResultsCommitment: tallyData.results.commitment, + spentVoiceCreditsHash: tallyData.totalSpentVoiceCredits.commitment, + perVOSpentVoiceCreditsHash: newPerVOSpentVoiceCreditsCommitment, + }) .then((tx) => tx.wait()); const results = await Promise.all(indices.map((index) => tallyContract.tallyResults(index))); @@ -455,17 +455,17 @@ describe("TallyVotes", () => { ); await expect( - tallyContract.addTallyResults( - tallyData.results.tally.map((_, index) => index), - tallyData.results.tally, + tallyContract.addTallyResults({ + voteOptionIndices: tallyData.results.tally.map((_, index) => index), + tallyResults: tallyData.results.tally, tallyResultProofs, - tallyData.totalSpentVoiceCredits.spent, - tallyData.totalSpentVoiceCredits.salt, - tallyData.results.salt, - tallyData.results.commitment, - tallyData.totalSpentVoiceCredits.commitment, - 0n, - ), + totalSpent: tallyData.totalSpentVoiceCredits.spent, + totalSpentSalt: tallyData.totalSpentVoiceCredits.salt, + tallyResultSalt: tallyData.results.salt, + newResultsCommitment: tallyData.results.commitment, + spentVoiceCreditsHash: tallyData.totalSpentVoiceCredits.commitment, + perVOSpentVoiceCreditsHash: 0n, + }), ).to.be.revertedWithCustomError(tallyContract, "InvalidTallyVotesProof"); }); });