From 960248491e14576cd7f889a0a43b9957e8c3621c Mon Sep 17 00:00:00 2001 From: 0xmad <0xmad@users.noreply.github.com> Date: Fri, 16 Aug 2024 14:13:00 -0500 Subject: [PATCH] feat(contracts): add custom maci contracts - [x] Customize Poll and PollFactory - [x] Customize MACI - [x] Add tests --- packages/contracts/.solcover.js | 20 ++ .../contracts/interfaces/IOwnable.sol | 28 +++ .../contracts/contracts/interfaces/IPoll.sol | 13 ++ packages/contracts/contracts/maci/MACI.sol | 56 ++++++ packages/contracts/contracts/maci/Poll.sol | 35 ++++ .../contracts/contracts/maci/PollFactory.sol | 34 ++++ packages/contracts/contracts/mocks/Mocker.sol | 16 ++ packages/contracts/package.json | 5 +- packages/contracts/scripts/compileSol.ts | 3 + packages/contracts/tests/Poll.test.ts | 100 ++++++++++ packages/contracts/tests/constants.ts | 20 ++ packages/contracts/tests/utils.ts | 127 ++++++++++++ pnpm-lock.yaml | 183 ++++++++---------- 13 files changed, 533 insertions(+), 107 deletions(-) create mode 100644 packages/contracts/.solcover.js create mode 100644 packages/contracts/contracts/interfaces/IOwnable.sol create mode 100644 packages/contracts/contracts/interfaces/IPoll.sol create mode 100644 packages/contracts/contracts/maci/MACI.sol create mode 100644 packages/contracts/contracts/maci/Poll.sol create mode 100644 packages/contracts/contracts/maci/PollFactory.sol create mode 100644 packages/contracts/contracts/mocks/Mocker.sol create mode 100644 packages/contracts/tests/Poll.test.ts create mode 100644 packages/contracts/tests/constants.ts create mode 100644 packages/contracts/tests/utils.ts diff --git a/packages/contracts/.solcover.js b/packages/contracts/.solcover.js new file mode 100644 index 00000000..2885b4d1 --- /dev/null +++ b/packages/contracts/.solcover.js @@ -0,0 +1,20 @@ +const { buildPoseidonT3, buildPoseidonT4, buildPoseidonT5, buildPoseidonT6 } = require("maci-contracts"); +const fs = require("fs"); +const path = require("path"); + +const PATHS = [ + path.resolve(__dirname, "..", "artifacts"), + path.resolve(__dirname, "..", "cache"), + path.resolve(__dirname, "..", "typechain-types"), +]; + +module.exports = { + onPreCompile: async () => { + await Promise.all( + PATHS.map((filepath) => fs.existsSync(filepath) && fs.promises.rm(filepath, { recursive: true })), + ); + }, + onCompileComplete: async () => { + await Promise.all([buildPoseidonT3(), buildPoseidonT4(), buildPoseidonT5(), buildPoseidonT6()]); + }, +}; diff --git a/packages/contracts/contracts/interfaces/IOwnable.sol b/packages/contracts/contracts/interfaces/IOwnable.sol new file mode 100644 index 00000000..1898f29c --- /dev/null +++ b/packages/contracts/contracts/interfaces/IOwnable.sol @@ -0,0 +1,28 @@ +// SPDX-License-Identifier: MIT +pragma solidity ^0.8.20; + +import { IPoll as IPollBase } from "maci-contracts/contracts/interfaces/IPoll.sol"; + +/// @title IOwnable +/// @notice Ownable interface +interface IOwnable { + /** + * @dev Transfers ownership of the contract to a new account (`newOwner`). + * Can only be called by the current owner. + */ + function transferOwnership(address newOwner) external; + + /** + * @dev Leaves the contract without owner. It will not be possible to call + * `onlyOwner` functions. Can only be called by the current owner. + * + * NOTE: Renouncing ownership will leave the contract without an owner, + * thereby disabling any functionality that is only available to the owner. + */ + function renounceOwnership() external; + + /** + * @dev Returns the address of the current owner. + */ + function owner() external view returns (address); +} diff --git a/packages/contracts/contracts/interfaces/IPoll.sol b/packages/contracts/contracts/interfaces/IPoll.sol new file mode 100644 index 00000000..8a894a2e --- /dev/null +++ b/packages/contracts/contracts/interfaces/IPoll.sol @@ -0,0 +1,13 @@ +// SPDX-License-Identifier: MIT +pragma solidity ^0.8.20; + +import { IPoll as IPollBase } from "maci-contracts/contracts/interfaces/IPoll.sol"; + +import { IOwnable } from "./IOwnable.sol"; + +/// @title IPollBase +/// @notice Poll interface +interface IPoll is IPollBase, IOwnable { + /// @notice The initialization function. + function init() external; +} diff --git a/packages/contracts/contracts/maci/MACI.sol b/packages/contracts/contracts/maci/MACI.sol new file mode 100644 index 00000000..7c5a91d0 --- /dev/null +++ b/packages/contracts/contracts/maci/MACI.sol @@ -0,0 +1,56 @@ +// SPDX-License-Identifier: MIT +pragma solidity ^0.8.20; + +import { Ownable } from "@openzeppelin/contracts/access/Ownable.sol"; +import { MACI as BaseMACI } from "maci-contracts/contracts/MACI.sol"; +import { IPollFactory } from "maci-contracts/contracts/interfaces/IPollFactory.sol"; +import { IMessageProcessorFactory } from "maci-contracts/contracts/interfaces/IMPFactory.sol"; +import { ITallyFactory } from "maci-contracts/contracts/interfaces/ITallyFactory.sol"; +import { InitialVoiceCreditProxy } from "maci-contracts/contracts/initialVoiceCreditProxy/InitialVoiceCreditProxy.sol"; +import { SignUpGatekeeper } from "maci-contracts/contracts/gatekeepers/SignUpGatekeeper.sol"; + +import { IPoll } from "../interfaces/IPoll.sol"; + +/// @title MACI - Minimum Anti-Collusion Infrastructure +/// @notice A contract which allows users to sign up, and deploy new polls +contract MACI is Ownable, BaseMACI { + /// @notice Create a new instance of the MACI contract. + /// @param pollFactory The PollFactory contract + /// @param messageProcessorFactory The MessageProcessorFactory contract + /// @param tallyFactory The TallyFactory contract + /// @param signUpGatekeeper The SignUpGatekeeper contract + /// @param initialVoiceCreditProxy The InitialVoiceCreditProxy contract + /// @param stateTreeDepth The depth of the state tree + /// @param emptyBallotRoots The roots of the empty ballot trees + constructor( + IPollFactory pollFactory, + IMessageProcessorFactory messageProcessorFactory, + ITallyFactory tallyFactory, + SignUpGatekeeper signUpGatekeeper, + InitialVoiceCreditProxy initialVoiceCreditProxy, + uint8 stateTreeDepth, + uint256[5] memory emptyBallotRoots + ) + payable + Ownable(msg.sender) + BaseMACI( + pollFactory, + messageProcessorFactory, + tallyFactory, + signUpGatekeeper, + initialVoiceCreditProxy, + stateTreeDepth, + emptyBallotRoots + ) + {} + + /// @notice Initialize the poll by given poll id and transfer poll ownership to the caller. + /// @param pollId The poll id + function initPoll(uint256 pollId) public onlyOwner { + PollContracts memory pollAddresses = polls[pollId]; + IPoll poll = IPoll(pollAddresses.poll); + + poll.init(); + poll.transferOwnership(msg.sender); + } +} diff --git a/packages/contracts/contracts/maci/Poll.sol b/packages/contracts/contracts/maci/Poll.sol new file mode 100644 index 00000000..dc6fd8e8 --- /dev/null +++ b/packages/contracts/contracts/maci/Poll.sol @@ -0,0 +1,35 @@ +// SPDX-License-Identifier: MIT +pragma solidity ^0.8.20; + +import { Ownable } from "@openzeppelin/contracts/access/Ownable.sol"; +import { Poll as BasePoll } from "maci-contracts/contracts/Poll.sol"; + +/// @title Poll +/// @notice A Poll contract allows voters to submit encrypted messages +/// which can be either votes or key change messages. +/// @dev Do not deploy this directly. Use PollFactory.deploy() which performs some +/// checks on the Poll constructor arguments. +contract Poll is Ownable, BasePoll { + /// @notice Each MACI instance can have multiple Polls. + /// When a Poll is deployed, its voting period starts immediately. + /// @param duration The duration of the voting period, in seconds + /// @param treeDepths The depths of the merkle trees + /// @param coordinatorPubKey The coordinator's public key + /// @param extContracts The external contracts + constructor( + uint256 duration, + TreeDepths memory treeDepths, + PubKey memory coordinatorPubKey, + ExtContracts memory extContracts, + uint256 emptyBallotRoot + ) + payable + Ownable(address(extContracts.maci)) + BasePoll(duration, treeDepths, coordinatorPubKey, extContracts, emptyBallotRoot) + {} + + /// @notice The initialization function. + function init() public override onlyOwner { + super.init(); + } +} diff --git a/packages/contracts/contracts/maci/PollFactory.sol b/packages/contracts/contracts/maci/PollFactory.sol new file mode 100644 index 00000000..4e26de39 --- /dev/null +++ b/packages/contracts/contracts/maci/PollFactory.sol @@ -0,0 +1,34 @@ +// SPDX-License-Identifier: MIT +pragma solidity ^0.8.20; + +import { PollFactory as BasePollFactory } from "maci-contracts/contracts/PollFactory.sol"; +import { IMACI } from "maci-contracts/contracts/interfaces/IMACI.sol"; +import { AccQueue } from "maci-contracts/contracts/trees/AccQueue.sol"; +import { AccQueueQuinaryMaci } from "maci-contracts/contracts/trees/AccQueueQuinaryMaci.sol"; +import { Poll } from "./Poll.sol"; + +/// @title PollFactory +/// @notice A factory contract which deploys Poll contracts. It allows the MACI contract +/// size to stay within the limit set by EIP-170. +contract PollFactory is BasePollFactory { + /// @inheritdoc BasePollFactory + function deploy( + uint256 duration, + TreeDepths calldata treeDepths, + PubKey calldata coordinatorPubKey, + address maci, + uint256 emptyBallotRoot + ) public virtual override returns (address pollAddr) { + /// @notice deploy a new AccQueue contract to store messages + AccQueue messageAq = new AccQueueQuinaryMaci(treeDepths.messageTreeSubDepth); + + /// @notice the smart contracts that a Poll would interact with + ExtContracts memory extContracts = ExtContracts({ maci: IMACI(maci), messageAq: messageAq }); + + Poll poll = new Poll(duration, treeDepths, coordinatorPubKey, extContracts, emptyBallotRoot); + + messageAq.transferOwnership(address(poll)); + + pollAddr = address(poll); + } +} diff --git a/packages/contracts/contracts/mocks/Mocker.sol b/packages/contracts/contracts/mocks/Mocker.sol new file mode 100644 index 00000000..a94260f2 --- /dev/null +++ b/packages/contracts/contracts/mocks/Mocker.sol @@ -0,0 +1,16 @@ +// SPDX-License-Identifier: MIT +pragma solidity ^0.8.20; + +import "maci-contracts/contracts/crypto/Hasher.sol"; +import "maci-contracts/contracts/crypto/MockVerifier.sol"; +import "maci-contracts/contracts/gatekeepers/FreeForAllSignUpGatekeeper.sol"; +import "maci-contracts/contracts/initialVoiceCreditProxy/ConstantInitialVoiceCreditProxy.sol"; +import "maci-contracts/contracts/VkRegistry.sol"; +import "maci-contracts/contracts/TallyFactory.sol"; +import "maci-contracts/contracts/MessageProcessorFactory.sol"; + +/// @title Mocker +/// @notice import all MACI protocol related contract for tests +contract Mocker { + +} diff --git a/packages/contracts/package.json b/packages/contracts/package.json index 6be55659..96d6b8f2 100644 --- a/packages/contracts/package.json +++ b/packages/contracts/package.json @@ -31,6 +31,7 @@ "postbuild": "cp -r ./artifacts ./build", "types": "tsc -p tsconfig.json --noEmit", "docs": "hardhat docgen", + "coverage": "BLOCK_GAS_LIMIT=1599511627775 hardhat coverage", "test": "hardhat test --network hardhat" }, "dependencies": { @@ -40,7 +41,9 @@ "ethers": "^6.13.2", "hardhat": "^2.22.8", "lowdb": "^1.0.0", - "maci-contracts": "^2.1.0", + "maci-contracts": "0.0.0-ci.b8d42a3", + "maci-core": "^2.0.0", + "maci-domainobjs": "^2.0.0", "solidity-docgen": "^0.6.0-beta.36" }, "devDependencies": { diff --git a/packages/contracts/scripts/compileSol.ts b/packages/contracts/scripts/compileSol.ts index c7a827a7..30156314 100644 --- a/packages/contracts/scripts/compileSol.ts +++ b/packages/contracts/scripts/compileSol.ts @@ -1,4 +1,5 @@ import hre from "hardhat"; +import { buildPoseidonT3, buildPoseidonT4, buildPoseidonT5, buildPoseidonT6 } from "maci-contracts"; import fs from "fs"; import path from "path"; @@ -13,6 +14,8 @@ async function main(): Promise { await Promise.all(PATHS.map((filepath) => fs.existsSync(filepath) && fs.promises.rm(filepath, { recursive: true }))); await hre.run("compile"); + + await Promise.all([buildPoseidonT3(), buildPoseidonT4(), buildPoseidonT5(), buildPoseidonT6()]); } main(); diff --git a/packages/contracts/tests/Poll.test.ts b/packages/contracts/tests/Poll.test.ts new file mode 100644 index 00000000..9efd580d --- /dev/null +++ b/packages/contracts/tests/Poll.test.ts @@ -0,0 +1,100 @@ +import { expect } from "chai"; +import { Signer } from "ethers"; +import { Verifier, VkRegistry, EMode, getSigners } from "maci-contracts"; +import { MaciState } from "maci-core"; +import { Keypair, Message, PubKey } from "maci-domainobjs"; + +import { MACI, Poll__factory as PollFactory, Poll as PollContract } from "../typechain-types"; + +import { + NOTHING_UP_MY_SLEEVE, + STATE_TREE_DEPTH, + duration, + initialVoiceCreditBalance, + messageBatchSize, + treeDepths, +} from "./constants"; +import { deployTestContracts } from "./utils"; + +describe("Poll", () => { + let maciContract: MACI; + let pollId: bigint; + let pollContract: PollContract; + let verifierContract: Verifier; + let vkRegistryContract: VkRegistry; + let owner: Signer; + let user: Signer; + let deployTime: number; + const coordinator = new Keypair(); + + const maciState = new MaciState(STATE_TREE_DEPTH); + + describe("deployment", () => { + before(async () => { + [owner, user] = await getSigners(); + + const contracts = await deployTestContracts({ + initialVoiceCreditBalance, + stateTreeDepth: STATE_TREE_DEPTH, + signer: owner, + }); + maciContract = contracts.maciContract; + verifierContract = contracts.mockVerifierContract as Verifier; + vkRegistryContract = contracts.vkRegistryContract; + + // deploy on chain poll + const tx = await maciContract.deployPoll( + duration, + treeDepths, + coordinator.pubKey.asContractParam(), + verifierContract, + vkRegistryContract, + EMode.QV, + ); + const receipt = await tx.wait(); + + const block = await owner.provider!.getBlock(receipt!.blockHash); + deployTime = block!.timestamp; + + expect(receipt?.status).to.eq(1); + + pollId = (await maciContract.nextPollId()) - 1n; + + const pollContracts = await maciContract.getPoll(pollId); + pollContract = PollFactory.connect(pollContracts.poll, owner); + + // deploy local poll + const p = maciState.deployPoll(BigInt(deployTime + duration), treeDepths, messageBatchSize, coordinator); + expect(p.toString()).to.eq(pollId.toString()); + // publish the NOTHING_UP_MY_SLEEVE message + const messageData = [NOTHING_UP_MY_SLEEVE]; + for (let i = 1; i < 10; i += 1) { + messageData.push(BigInt(0)); + } + const message = new Message(messageData); + const padKey = new PubKey([ + BigInt("10457101036533406547632367118273992217979173478358440826365724437999023779287"), + BigInt("19824078218392094440610104313265183977899662750282163392862422243483260492317"), + ]); + maciState.polls.get(pollId)?.publishMessage(message, padKey); + }); + + it("should fail if unauthorized user tries to init the poll", async () => { + await expect(maciContract.initPoll(pollId)).not.to.be.revertedWithCustomError(pollContract, "PollAlreadyInit"); + await expect(maciContract.connect(user).initPoll(pollId)).to.be.revertedWithCustomError( + pollContract, + "OwnableUnauthorizedAccount", + ); + await expect(pollContract.init()).to.be.revertedWithCustomError(pollContract, "PollAlreadyInit"); + }); + + it("should not be possible to init the Poll contract twice", async () => { + await expect(maciContract.initPoll(pollId)).not.to.be.revertedWithCustomError(pollContract, "PollAlreadyInit"); + await expect(maciContract.initPoll(pollId)).to.be.revertedWithCustomError( + pollContract, + "OwnableUnauthorizedAccount", + ); + await expect(pollContract.init()).to.be.revertedWithCustomError(pollContract, "PollAlreadyInit"); + }); + }); +}); diff --git a/packages/contracts/tests/constants.ts b/packages/contracts/tests/constants.ts new file mode 100644 index 00000000..d24d2aa1 --- /dev/null +++ b/packages/contracts/tests/constants.ts @@ -0,0 +1,20 @@ +import { TreeDepths, STATE_TREE_ARITY, MESSAGE_TREE_ARITY } from "maci-core"; + +export const duration = 2_000; + +export const STATE_TREE_DEPTH = 10; +export const MESSAGE_TREE_DEPTH = 2; +export const MESSAGE_TREE_SUBDEPTH = 1; +export const messageBatchSize = MESSAGE_TREE_ARITY ** MESSAGE_TREE_SUBDEPTH; +export const NOTHING_UP_MY_SLEEVE = 8370432830353022751713833565135785980866757267633941821328460903436894336785n; + +export const initialVoiceCreditBalance = 100; + +export const treeDepths: TreeDepths = { + intStateTreeDepth: 1, + messageTreeDepth: MESSAGE_TREE_DEPTH, + messageTreeSubDepth: MESSAGE_TREE_SUBDEPTH, + voteOptionTreeDepth: 2, +}; + +export const tallyBatchSize = STATE_TREE_ARITY ** treeDepths.intStateTreeDepth; diff --git a/packages/contracts/tests/utils.ts b/packages/contracts/tests/utils.ts new file mode 100644 index 00000000..b786cd6a --- /dev/null +++ b/packages/contracts/tests/utils.ts @@ -0,0 +1,127 @@ +import { ethers } from "hardhat"; +import { + deployConstantInitialVoiceCreditProxy, + deployFreeForAllSignUpGatekeeper, + deployMaci, + deployMockVerifier, + deployPoseidonContracts, + deployVkRegistry, + type ConstantInitialVoiceCreditProxy, + type FreeForAllGatekeeper, + type MockVerifier, + type VkRegistry, +} from "maci-contracts"; + +import type { ContractFactory, Signer } from "ethers"; + +import { type MACI } from "../typechain-types"; + +/** + * An interface that represents argument for deployment test contracts + */ +export interface IDeployedTestContractsArgs { + initialVoiceCreditBalance: number; + stateTreeDepth: number; + signer?: Signer; + quiet?: boolean; + gatekeeper?: FreeForAllGatekeeper; +} + +/** + * An interface holding all of the smart contracts part of MACI. + */ +export interface IDeployedTestContracts { + mockVerifierContract: MockVerifier; + gatekeeperContract: FreeForAllGatekeeper; + constantInitialVoiceCreditProxyContract: ConstantInitialVoiceCreditProxy; + maciContract: MACI; + vkRegistryContract: VkRegistry; +} + +/** + * Deploy a set of smart contracts that can be used for testing. + * @param initialVoiceCreditBalance - the initial voice credit balance for each user + * @param stateTreeDepth - the depth of the state tree + * @param signer - the signer to use + * @param quiet - whether to suppress console output + * @param gatekeeper - the gatekeeper contract to use + * @returns the deployed contracts + */ +export const deployTestContracts = async ({ + initialVoiceCreditBalance, + stateTreeDepth, + signer, + quiet = true, + gatekeeper, +}: IDeployedTestContractsArgs): Promise => { + const mockVerifierContract = await deployMockVerifier(signer, true); + + let gatekeeperContract = gatekeeper; + if (!gatekeeperContract) { + gatekeeperContract = await deployFreeForAllSignUpGatekeeper(signer, true); + } + + const constantInitialVoiceCreditProxyContract = await deployConstantInitialVoiceCreditProxy( + initialVoiceCreditBalance, + signer, + true, + ); + + // VkRegistry + const vkRegistryContract = await deployVkRegistry(signer, true); + const [gatekeeperContractAddress, constantInitialVoiceCreditProxyContractAddress] = await Promise.all([ + gatekeeperContract.getAddress(), + constantInitialVoiceCreditProxyContract.getAddress(), + ]); + + const { PoseidonT3Contract, PoseidonT4Contract, PoseidonT5Contract, PoseidonT6Contract } = + await deployPoseidonContracts(signer, {}, quiet); + + const poseidonAddresses = await Promise.all([ + PoseidonT3Contract.getAddress(), + PoseidonT4Contract.getAddress(), + PoseidonT5Contract.getAddress(), + PoseidonT6Contract.getAddress(), + ]).then(([poseidonT3, poseidonT4, poseidonT5, poseidonT6]) => ({ + poseidonT3, + poseidonT4, + poseidonT5, + poseidonT6, + })); + + const factories = await Promise.all( + [ + "contracts/maci/MACI.sol:MACI", + "contracts/maci/PollFactory.sol:PollFactory", + "MessageProcessorFactory", + "TallyFactory", + ].map((factory) => + ethers.getContractFactory(factory, { + libraries: { + "maci-contracts/contracts/crypto/PoseidonT3.sol:PoseidonT3": PoseidonT3Contract, + "maci-contracts/contracts/crypto/PoseidonT4.sol:PoseidonT4": PoseidonT4Contract, + "maci-contracts/contracts/crypto/PoseidonT5.sol:PoseidonT5": PoseidonT5Contract, + "maci-contracts/contracts/crypto/PoseidonT6.sol:PoseidonT6": PoseidonT6Contract, + }, + }), + ), + ); + + const { maciContract } = await deployMaci({ + signUpTokenGatekeeperContractAddress: gatekeeperContractAddress, + initialVoiceCreditBalanceAddress: constantInitialVoiceCreditProxyContractAddress, + signer, + stateTreeDepth, + poseidonAddresses, + factories: factories as [ContractFactory, ContractFactory, ContractFactory, ContractFactory], + quiet, + }); + + return { + mockVerifierContract, + gatekeeperContract, + constantInitialVoiceCreditProxyContract, + maciContract: maciContract as MACI, + vkRegistryContract, + }; +}; diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index bd9d4fba..df0b6159 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -102,8 +102,14 @@ importers: specifier: ^1.0.0 version: 1.0.0 maci-contracts: - specifier: ^2.1.0 - version: 2.1.0(flxhpragqyg57es62n2ruk56xe) + specifier: 0.0.0-ci.b8d42a3 + version: 0.0.0-ci.b8d42a3(flxhpragqyg57es62n2ruk56xe) + maci-core: + specifier: ^2.0.0 + version: 2.0.0(bufferutil@4.0.8)(utf-8-validate@5.0.10) + maci-domainobjs: + specifier: ^2.0.0 + version: 2.0.0(bufferutil@4.0.8)(utf-8-validate@5.0.10) solidity-docgen: specifier: ^0.6.0-beta.36 version: 0.6.0-beta.36(hardhat@2.22.8(bufferutil@4.0.8)(ts-node@10.9.2(@types/node@22.2.0)(typescript@5.5.4))(typescript@5.5.4)(utf-8-validate@5.0.10)) @@ -9166,6 +9172,9 @@ packages: resolution: {integrity: sha512-h5bgJWpxJNswbU7qCrV0tIKQCaS3blPDrqKWx+QxzuzL1zGUzij9XCWLrSLsJPu5t+eWA/ycetzYAO5IOMcWAQ==} hasBin: true + maci-circuits@0.0.0-ci.b8d42a3: + resolution: {integrity: sha512-uXZp/m2bYk1ac8MJu1aiexW1G/eqRUHciJv4+sQsjeBCDdnStEMS/rj9KNzZQPbENESiq04vGn2l+jxowFaU3Q==} + maci-circuits@2.1.0: resolution: {integrity: sha512-nYk8OM8NigLPhod+hPRK2sNpfoKjsOakBflsYqOKTA6N/fWHsMsfQUS83Qg6v7y5s1m5Nr/cATj+eWea2esd2Q==} @@ -9173,16 +9182,29 @@ packages: resolution: {integrity: sha512-nrbzEqwtRAoGtW1L34blmyEtXMRJsrZ0ovV2GY++yEZFiaYLLdPGzbDcrxBHMoViIrIjo/nNQn9CxqwzSI5+tw==} hasBin: true + maci-contracts@0.0.0-ci.b8d42a3: + resolution: {integrity: sha512-fnREAdMK92olVulMkxN+XDZlxUqFfszxS81GYOVbYYiGUYsmE2sHHSun2k/2Rqo3r2HtSNHdaQmm7AvYE5/+Eg==} + hasBin: true + maci-contracts@2.1.0: resolution: {integrity: sha512-OwYSYPEmcyXlyrd9LauMsJwbXKftYcdWdcGvcl4o0W8EqlC1ujrav/nWLXDbl6EiHB7QL/mhhlNIP/RQSCstDQ==} hasBin: true + maci-core@0.0.0-ci.b8d42a3: + resolution: {integrity: sha512-fAzIXuwMDWOfFESGxWwg/07j8KyXfEtdzY97C+RIOk5QgPPHCtTm/9HgpqKVLVrX75BHbauB2IEMbrgb/76PgQ==} + maci-core@2.0.0: resolution: {integrity: sha512-FI7L3QB5E2mNaHQNrjnfHjNGnpZMvmHN1ZBlHgRHgz1xu02c/uR4FrO8A9cudWoGJzefA/y+nEb4irdirfTFJA==} + maci-crypto@0.0.0-ci.b8d42a3: + resolution: {integrity: sha512-KnGpZKtg0qlpdgDExN43c8jeVL1I7KltBlC9CRFUb/cgewvEiZhKL0QxXUROBDDURFLqS/Tph7fHEPzPu3VTKA==} + maci-crypto@2.0.0: resolution: {integrity: sha512-bkgOoDA1ABG49MXDzzsQPsFVEijAkLk8ocJKGyeNQS7YpNhC3YEVVz/SE4g0td+N4xJhD3PbXsyHeaTM3ApIjw==} + maci-domainobjs@0.0.0-ci.b8d42a3: + resolution: {integrity: sha512-25yhHi+obvEkiW7JBnbTGPScORCep8AYJkXpQ72LyU/v+YI1U0zzVcJvoy3wcam9DfV+dh2kL27F+KDXMv8uwQ==} + maci-domainobjs@2.0.0: resolution: {integrity: sha512-FmQdIC1omsWR/98wt8WvEJj0SDfnVTl9/2FMDp3N4WwUy1lzmmlVjUGKSFKj2+dj2Rx26DmBWsmKhbTIQeoPOQ==} @@ -15998,15 +16020,6 @@ snapshots: transitivePeerDependencies: - supports-color - '@nomicfoundation/hardhat-ethers@3.0.6(ethers@6.13.2(bufferutil@4.0.8)(utf-8-validate@5.0.10))(hardhat@2.22.7(bufferutil@4.0.8)(ts-node@10.9.2(@types/node@22.2.0)(typescript@5.5.4))(typescript@5.5.4)(utf-8-validate@5.0.10))': - dependencies: - debug: 4.3.6(supports-color@8.1.1) - ethers: 6.13.2(bufferutil@4.0.8)(utf-8-validate@5.0.10) - hardhat: 2.22.7(bufferutil@4.0.8)(ts-node@10.9.2(@types/node@22.2.0)(typescript@5.5.4))(typescript@5.5.4)(utf-8-validate@5.0.10) - lodash.isequal: 4.5.0 - transitivePeerDependencies: - - supports-color - '@nomicfoundation/hardhat-ethers@3.0.6(ethers@6.13.2(bufferutil@4.0.8)(utf-8-validate@5.0.10))(hardhat@2.22.8(bufferutil@4.0.8)(ts-node@10.9.2(@types/node@22.2.0)(typescript@5.5.4))(typescript@5.5.4)(utf-8-validate@5.0.10))': dependencies: debug: 4.3.6(supports-color@8.1.1) @@ -16114,27 +16127,6 @@ snapshots: typechain: 8.3.2(typescript@5.5.4) typescript: 5.5.4 - '@nomicfoundation/hardhat-toolbox@5.0.0(wjsanafrhl4y3mcgsypw7riji4)': - dependencies: - '@nomicfoundation/hardhat-chai-matchers': 2.0.7(@nomicfoundation/hardhat-ethers@3.0.6(ethers@6.13.2(bufferutil@4.0.8)(utf-8-validate@5.0.10))(hardhat@2.22.8(bufferutil@4.0.8)(ts-node@10.9.2(@types/node@22.2.0)(typescript@5.5.4))(typescript@5.5.4)(utf-8-validate@5.0.10)))(chai@4.5.0)(ethers@6.13.2(bufferutil@4.0.8)(utf-8-validate@5.0.10))(hardhat@2.22.8(bufferutil@4.0.8)(ts-node@10.9.2(@types/node@22.2.0)(typescript@5.5.4))(typescript@5.5.4)(utf-8-validate@5.0.10)) - '@nomicfoundation/hardhat-ethers': 3.0.6(ethers@6.13.2(bufferutil@4.0.8)(utf-8-validate@5.0.10))(hardhat@2.22.7(bufferutil@4.0.8)(ts-node@10.9.2(@types/node@22.2.0)(typescript@5.5.4))(typescript@5.5.4)(utf-8-validate@5.0.10)) - '@nomicfoundation/hardhat-ignition-ethers': 0.15.5(@nomicfoundation/hardhat-ethers@3.0.6(ethers@6.13.2(bufferutil@4.0.8)(utf-8-validate@5.0.10))(hardhat@2.22.8(bufferutil@4.0.8)(ts-node@10.9.2(@types/node@22.2.0)(typescript@5.5.4))(typescript@5.5.4)(utf-8-validate@5.0.10)))(@nomicfoundation/hardhat-ignition@0.15.5(@nomicfoundation/hardhat-verify@2.0.9(hardhat@2.22.8(bufferutil@4.0.8)(ts-node@10.9.2(@types/node@22.2.0)(typescript@5.5.4))(typescript@5.5.4)(utf-8-validate@5.0.10)))(bufferutil@4.0.8)(hardhat@2.22.8(bufferutil@4.0.8)(ts-node@10.9.2(@types/node@22.2.0)(typescript@5.5.4))(typescript@5.5.4)(utf-8-validate@5.0.10))(utf-8-validate@5.0.10))(@nomicfoundation/ignition-core@0.15.5(bufferutil@4.0.8)(utf-8-validate@5.0.10))(ethers@6.13.2(bufferutil@4.0.8)(utf-8-validate@5.0.10))(hardhat@2.22.8(bufferutil@4.0.8)(ts-node@10.9.2(@types/node@22.2.0)(typescript@5.5.4))(typescript@5.5.4)(utf-8-validate@5.0.10)) - '@nomicfoundation/hardhat-network-helpers': 1.0.11(hardhat@2.22.8(bufferutil@4.0.8)(ts-node@10.9.2(@types/node@22.2.0)(typescript@5.5.4))(typescript@5.5.4)(utf-8-validate@5.0.10)) - '@nomicfoundation/hardhat-verify': 2.0.9(hardhat@2.22.8(bufferutil@4.0.8)(ts-node@10.9.2(@types/node@22.2.0)(typescript@5.5.4))(typescript@5.5.4)(utf-8-validate@5.0.10)) - '@typechain/ethers-v6': 0.5.1(ethers@6.13.2(bufferutil@4.0.8)(utf-8-validate@5.0.10))(typechain@8.3.2(typescript@5.5.4))(typescript@5.5.4) - '@typechain/hardhat': 9.1.0(@typechain/ethers-v6@0.5.1(ethers@6.13.2(bufferutil@4.0.8)(utf-8-validate@5.0.10))(typechain@8.3.2(typescript@5.5.4))(typescript@5.5.4))(ethers@6.13.2(bufferutil@4.0.8)(utf-8-validate@5.0.10))(hardhat@2.22.8(bufferutil@4.0.8)(ts-node@10.9.2(@types/node@22.2.0)(typescript@5.5.4))(typescript@5.5.4)(utf-8-validate@5.0.10))(typechain@8.3.2(typescript@5.5.4)) - '@types/chai': 4.3.17 - '@types/mocha': 10.0.7 - '@types/node': 22.2.0 - chai: 4.5.0 - ethers: 6.13.2(bufferutil@4.0.8)(utf-8-validate@5.0.10) - hardhat: 2.22.7(bufferutil@4.0.8)(ts-node@10.9.2(@types/node@22.2.0)(typescript@5.5.4))(typescript@5.5.4)(utf-8-validate@5.0.10) - hardhat-gas-reporter: 1.0.10(bufferutil@4.0.8)(hardhat@2.22.8(bufferutil@4.0.8)(ts-node@10.9.2(@types/node@22.2.0)(typescript@5.5.4))(typescript@5.5.4)(utf-8-validate@5.0.10))(utf-8-validate@5.0.10) - solidity-coverage: 0.8.12(hardhat@2.22.8(bufferutil@4.0.8)(ts-node@10.9.2(@types/node@22.2.0)(typescript@5.5.4))(typescript@5.5.4)(utf-8-validate@5.0.10)) - ts-node: 10.9.2(@types/node@22.2.0)(typescript@5.5.4) - typechain: 8.3.2(typescript@5.5.4) - typescript: 5.5.4 - '@nomicfoundation/hardhat-verify@2.0.9(hardhat@2.22.7(bufferutil@4.0.8)(ts-node@10.9.2(@types/node@20.14.14)(typescript@5.5.4))(typescript@5.5.4)(utf-8-validate@5.0.10))': dependencies: '@ethersproject/abi': 5.7.0 @@ -23189,60 +23181,6 @@ snapshots: - supports-color - utf-8-validate - hardhat@2.22.7(bufferutil@4.0.8)(ts-node@10.9.2(@types/node@22.2.0)(typescript@5.5.4))(typescript@5.5.4)(utf-8-validate@5.0.10): - dependencies: - '@ethersproject/abi': 5.7.0 - '@metamask/eth-sig-util': 4.0.1 - '@nomicfoundation/edr': 0.5.2 - '@nomicfoundation/ethereumjs-common': 4.0.4 - '@nomicfoundation/ethereumjs-tx': 5.0.4 - '@nomicfoundation/ethereumjs-util': 9.0.4 - '@nomicfoundation/solidity-analyzer': 0.1.2 - '@sentry/node': 5.30.0 - '@types/bn.js': 5.1.5 - '@types/lru-cache': 5.1.1 - adm-zip: 0.4.16 - aggregate-error: 3.1.0 - ansi-escapes: 4.3.2 - boxen: 5.1.2 - chalk: 2.4.2 - chokidar: 3.6.0 - ci-info: 2.0.0 - debug: 4.3.6(supports-color@8.1.1) - enquirer: 2.4.1 - env-paths: 2.2.1 - ethereum-cryptography: 1.2.0 - ethereumjs-abi: 0.6.8 - find-up: 2.1.0 - fp-ts: 1.19.3 - fs-extra: 7.0.1 - glob: 7.2.0 - immutable: 4.3.7 - io-ts: 1.10.4 - keccak: 3.0.4 - lodash: 4.17.21 - mnemonist: 0.38.5 - mocha: 10.7.0 - p-map: 4.0.0 - raw-body: 2.5.2 - resolve: 1.17.0 - semver: 6.3.1 - solc: 0.8.26(debug@4.3.6) - source-map-support: 0.5.21 - stacktrace-parser: 0.1.10 - tsort: 0.0.1 - undici: 5.28.4 - uuid: 8.3.2 - ws: 7.5.10(bufferutil@4.0.8)(utf-8-validate@5.0.10) - optionalDependencies: - ts-node: 10.9.2(@types/node@22.2.0)(typescript@5.5.4) - typescript: 5.5.4 - transitivePeerDependencies: - - bufferutil - - c-kzg - - supports-color - - utf-8-validate - hardhat@2.22.8(bufferutil@4.0.8)(ts-node@10.9.2(@types/node@22.2.0)(typescript@5.5.4))(typescript@5.5.4)(utf-8-validate@5.0.10): dependencies: '@ethersproject/abi': 5.7.0 @@ -25226,6 +25164,20 @@ snapshots: lz-string@1.5.0: {} + maci-circuits@0.0.0-ci.b8d42a3(@types/snarkjs@0.7.8)(bufferutil@4.0.8)(utf-8-validate@5.0.10): + dependencies: + '@zk-kit/circuits': 0.4.0 + circomkit: 0.2.1(@types/snarkjs@0.7.8)(snarkjs@0.7.4) + circomlib: 2.0.5 + maci-core: 0.0.0-ci.b8d42a3(bufferutil@4.0.8)(utf-8-validate@5.0.10) + maci-crypto: 0.0.0-ci.b8d42a3(bufferutil@4.0.8)(utf-8-validate@5.0.10) + maci-domainobjs: 0.0.0-ci.b8d42a3(bufferutil@4.0.8)(utf-8-validate@5.0.10) + snarkjs: 0.7.4 + transitivePeerDependencies: + - '@types/snarkjs' + - bufferutil + - utf-8-validate + maci-circuits@2.1.0(@types/snarkjs@0.7.8)(bufferutil@4.0.8)(utf-8-validate@5.0.10): dependencies: '@zk-kit/circuits': 0.4.0 @@ -25277,20 +25229,20 @@ snapshots: - typescript - utf-8-validate - maci-contracts@2.1.0(7htv7pg2ka7ncyn53uwoaz3m6q): + maci-contracts@0.0.0-ci.b8d42a3(flxhpragqyg57es62n2ruk56xe): dependencies: - '@nomicfoundation/hardhat-ethers': 3.0.6(ethers@6.13.2(bufferutil@4.0.8)(utf-8-validate@5.0.10))(hardhat@2.22.7(bufferutil@4.0.8)(ts-node@10.9.2(@types/node@20.14.14)(typescript@5.5.4))(typescript@5.5.4)(utf-8-validate@5.0.10)) - '@nomicfoundation/hardhat-toolbox': 5.0.0(qc2x6fg2hvcwib2hi3ibxymkay) + '@nomicfoundation/hardhat-ethers': 3.0.6(ethers@6.13.2(bufferutil@4.0.8)(utf-8-validate@5.0.10))(hardhat@2.22.8(bufferutil@4.0.8)(ts-node@10.9.2(@types/node@22.2.0)(typescript@5.5.4))(typescript@5.5.4)(utf-8-validate@5.0.10)) + '@nomicfoundation/hardhat-toolbox': 5.0.0(croq2hzbpfcsi44fcj2jwym2jy) '@openzeppelin/contracts': 5.0.2 circomlibjs: 0.1.7(bufferutil@4.0.8)(utf-8-validate@5.0.10) ethers: 6.13.2(bufferutil@4.0.8)(utf-8-validate@5.0.10) - hardhat: 2.22.7(bufferutil@4.0.8)(ts-node@10.9.2(@types/node@20.14.14)(typescript@5.5.4))(typescript@5.5.4)(utf-8-validate@5.0.10) + hardhat: 2.22.8(bufferutil@4.0.8)(ts-node@10.9.2(@types/node@22.2.0)(typescript@5.5.4))(typescript@5.5.4)(utf-8-validate@5.0.10) lowdb: 1.0.0 - maci-circuits: 2.1.0(@types/snarkjs@0.7.8)(bufferutil@4.0.8)(utf-8-validate@5.0.10) - maci-core: 2.0.0(bufferutil@4.0.8)(utf-8-validate@5.0.10) - maci-crypto: 2.0.0(bufferutil@4.0.8)(utf-8-validate@5.0.10) - maci-domainobjs: 2.0.0(bufferutil@4.0.8)(utf-8-validate@5.0.10) - solidity-docgen: 0.6.0-beta.36(hardhat@2.22.7(bufferutil@4.0.8)(ts-node@10.9.2(@types/node@20.14.14)(typescript@5.5.4))(typescript@5.5.4)(utf-8-validate@5.0.10)) + maci-circuits: 0.0.0-ci.b8d42a3(@types/snarkjs@0.7.8)(bufferutil@4.0.8)(utf-8-validate@5.0.10) + maci-core: 0.0.0-ci.b8d42a3(bufferutil@4.0.8)(utf-8-validate@5.0.10) + maci-crypto: 0.0.0-ci.b8d42a3(bufferutil@4.0.8)(utf-8-validate@5.0.10) + maci-domainobjs: 0.0.0-ci.b8d42a3(bufferutil@4.0.8)(utf-8-validate@5.0.10) + solidity-docgen: 0.6.0-beta.36(hardhat@2.22.8(bufferutil@4.0.8)(ts-node@10.9.2(@types/node@22.2.0)(typescript@5.5.4))(typescript@5.5.4)(utf-8-validate@5.0.10)) uuid: 10.0.0 transitivePeerDependencies: - '@nomicfoundation/hardhat-chai-matchers' @@ -25314,20 +25266,20 @@ snapshots: - typescript - utf-8-validate - maci-contracts@2.1.0(flxhpragqyg57es62n2ruk56xe): + maci-contracts@2.1.0(7htv7pg2ka7ncyn53uwoaz3m6q): dependencies: - '@nomicfoundation/hardhat-ethers': 3.0.6(ethers@6.13.2(bufferutil@4.0.8)(utf-8-validate@5.0.10))(hardhat@2.22.7(bufferutil@4.0.8)(ts-node@10.9.2(@types/node@22.2.0)(typescript@5.5.4))(typescript@5.5.4)(utf-8-validate@5.0.10)) - '@nomicfoundation/hardhat-toolbox': 5.0.0(wjsanafrhl4y3mcgsypw7riji4) + '@nomicfoundation/hardhat-ethers': 3.0.6(ethers@6.13.2(bufferutil@4.0.8)(utf-8-validate@5.0.10))(hardhat@2.22.7(bufferutil@4.0.8)(ts-node@10.9.2(@types/node@20.14.14)(typescript@5.5.4))(typescript@5.5.4)(utf-8-validate@5.0.10)) + '@nomicfoundation/hardhat-toolbox': 5.0.0(qc2x6fg2hvcwib2hi3ibxymkay) '@openzeppelin/contracts': 5.0.2 circomlibjs: 0.1.7(bufferutil@4.0.8)(utf-8-validate@5.0.10) ethers: 6.13.2(bufferutil@4.0.8)(utf-8-validate@5.0.10) - hardhat: 2.22.7(bufferutil@4.0.8)(ts-node@10.9.2(@types/node@22.2.0)(typescript@5.5.4))(typescript@5.5.4)(utf-8-validate@5.0.10) + hardhat: 2.22.7(bufferutil@4.0.8)(ts-node@10.9.2(@types/node@20.14.14)(typescript@5.5.4))(typescript@5.5.4)(utf-8-validate@5.0.10) lowdb: 1.0.0 maci-circuits: 2.1.0(@types/snarkjs@0.7.8)(bufferutil@4.0.8)(utf-8-validate@5.0.10) maci-core: 2.0.0(bufferutil@4.0.8)(utf-8-validate@5.0.10) maci-crypto: 2.0.0(bufferutil@4.0.8)(utf-8-validate@5.0.10) maci-domainobjs: 2.0.0(bufferutil@4.0.8)(utf-8-validate@5.0.10) - solidity-docgen: 0.6.0-beta.36(hardhat@2.22.7(bufferutil@4.0.8)(ts-node@10.9.2(@types/node@22.2.0)(typescript@5.5.4))(typescript@5.5.4)(utf-8-validate@5.0.10)) + solidity-docgen: 0.6.0-beta.36(hardhat@2.22.7(bufferutil@4.0.8)(ts-node@10.9.2(@types/node@20.14.14)(typescript@5.5.4))(typescript@5.5.4)(utf-8-validate@5.0.10)) uuid: 10.0.0 transitivePeerDependencies: - '@nomicfoundation/hardhat-chai-matchers' @@ -25351,6 +25303,14 @@ snapshots: - typescript - utf-8-validate + maci-core@0.0.0-ci.b8d42a3(bufferutil@4.0.8)(utf-8-validate@5.0.10): + dependencies: + maci-crypto: 0.0.0-ci.b8d42a3(bufferutil@4.0.8)(utf-8-validate@5.0.10) + maci-domainobjs: 0.0.0-ci.b8d42a3(bufferutil@4.0.8)(utf-8-validate@5.0.10) + transitivePeerDependencies: + - bufferutil + - utf-8-validate + maci-core@2.0.0(bufferutil@4.0.8)(utf-8-validate@5.0.10): dependencies: maci-crypto: 2.0.0(bufferutil@4.0.8)(utf-8-validate@5.0.10) @@ -25359,6 +25319,16 @@ snapshots: - bufferutil - utf-8-validate + maci-crypto@0.0.0-ci.b8d42a3(bufferutil@4.0.8)(utf-8-validate@5.0.10): + dependencies: + '@zk-kit/baby-jubjub': 1.0.1 + '@zk-kit/eddsa-poseidon': 1.0.2 + '@zk-kit/poseidon-cipher': 0.3.1 + ethers: 6.13.2(bufferutil@4.0.8)(utf-8-validate@5.0.10) + transitivePeerDependencies: + - bufferutil + - utf-8-validate + maci-crypto@2.0.0(bufferutil@4.0.8)(utf-8-validate@5.0.10): dependencies: '@zk-kit/baby-jubjub': 1.0.1 @@ -25369,6 +25339,13 @@ snapshots: - bufferutil - utf-8-validate + maci-domainobjs@0.0.0-ci.b8d42a3(bufferutil@4.0.8)(utf-8-validate@5.0.10): + dependencies: + maci-crypto: 0.0.0-ci.b8d42a3(bufferutil@4.0.8)(utf-8-validate@5.0.10) + transitivePeerDependencies: + - bufferutil + - utf-8-validate + maci-domainobjs@2.0.0(bufferutil@4.0.8)(utf-8-validate@5.0.10): dependencies: maci-crypto: 2.0.0(bufferutil@4.0.8)(utf-8-validate@5.0.10) @@ -28343,12 +28320,6 @@ snapshots: hardhat: 2.22.7(bufferutil@4.0.8)(ts-node@10.9.2(@types/node@20.14.14)(typescript@5.5.4))(typescript@5.5.4)(utf-8-validate@5.0.10) solidity-ast: 0.4.56 - solidity-docgen@0.6.0-beta.36(hardhat@2.22.7(bufferutil@4.0.8)(ts-node@10.9.2(@types/node@22.2.0)(typescript@5.5.4))(typescript@5.5.4)(utf-8-validate@5.0.10)): - dependencies: - handlebars: 4.7.8 - hardhat: 2.22.7(bufferutil@4.0.8)(ts-node@10.9.2(@types/node@22.2.0)(typescript@5.5.4))(typescript@5.5.4)(utf-8-validate@5.0.10) - solidity-ast: 0.4.56 - solidity-docgen@0.6.0-beta.36(hardhat@2.22.8(bufferutil@4.0.8)(ts-node@10.9.2(@types/node@22.2.0)(typescript@5.5.4))(typescript@5.5.4)(utf-8-validate@5.0.10)): dependencies: handlebars: 4.7.8