diff --git a/common/package.json b/common/package.json index bd7caa4fb..d7f3da4a5 100644 --- a/common/package.json +++ b/common/package.json @@ -23,8 +23,8 @@ "dependencies": { "@openzeppelin/merkle-tree": "^1.0.5", "ethers": "^6.11.1", - "maci-crypto": "0.0.0-ci.153326b", - "maci-domainobjs": "0.0.0-ci.153326b" + "maci-crypto": "1.2.0", + "maci-domainobjs": "1.2.0" }, "repository": { "type": "git", diff --git a/contracts/contracts/maci/BabyJubJub.sol b/contracts/contracts/maci/BabyJubJub.sol new file mode 100644 index 000000000..7d046b624 --- /dev/null +++ b/contracts/contracts/maci/BabyJubJub.sol @@ -0,0 +1,136 @@ +// @note This code was taken from +// https://github.com/privacy-scaling-explorations/maci/blob/dc18e2f046cf160f846f003c04ec4dfac502f6ae/contracts/contracts/crypto/BabyJubJub.sol +// TODO remove this and use MACI npm package when version greater than 1.2.0 is released + +// SPDX-License-Identifier: MIT +pragma solidity 0.8.10; + +library CurveBabyJubJub { + // Curve parameters + // E: 168700x^2 + y^2 = 1 + 168696x^2y^2 + // A = 168700 + uint256 public constant A = 0x292FC; + // D = 168696 + uint256 public constant D = 0x292F8; + // Prime Q = 21888242871839275222246405745257275088548364400416034343698204186575808495617 + uint256 public constant Q = 0x30644E72E131A029B85045B68181585D2833E84879B9709143E1F593F0000001; + + /** + * @dev Add 2 points on baby jubjub curve + * Formula for adding 2 points on a twisted Edwards curve: + * x3 = (x1y2 + y1x2) / (1 + dx1x2y1y2) + * y3 = (y1y2 - ax1x2) / (1 - dx1x2y1y2) + */ + function pointAdd(uint256 _x1, uint256 _y1, uint256 _x2, uint256 _y2) internal view returns (uint256 x3, uint256 y3) { + if (_x1 == 0 && _y1 == 0) { + return (_x2, _y2); + } + + if (_x2 == 0 && _y1 == 0) { + return (_x1, _y1); + } + + uint256 x1x2 = mulmod(_x1, _x2, Q); + uint256 y1y2 = mulmod(_y1, _y2, Q); + uint256 dx1x2y1y2 = mulmod(D, mulmod(x1x2, y1y2, Q), Q); + uint256 x3Num = addmod(mulmod(_x1, _y2, Q), mulmod(_y1, _x2, Q), Q); + uint256 y3Num = submod(y1y2, mulmod(A, x1x2, Q), Q); + + x3 = mulmod(x3Num, inverse(addmod(1, dx1x2y1y2, Q)), Q); + y3 = mulmod(y3Num, inverse(submod(1, dx1x2y1y2, Q)), Q); + } + + /** + * @dev Double a point on baby jubjub curve + * Doubling can be performed with the same formula as addition + */ + function pointDouble(uint256 _x1, uint256 _y1) internal view returns (uint256 x2, uint256 y2) { + return pointAdd(_x1, _y1, _x1, _y1); + } + + /** + * @dev Multiply a point on baby jubjub curve by a scalar + * Use the double and add algorithm + */ + function pointMul(uint256 _x1, uint256 _y1, uint256 _d) internal view returns (uint256 x2, uint256 y2) { + uint256 remaining = _d; + + uint256 px = _x1; + uint256 py = _y1; + uint256 ax = 0; + uint256 ay = 0; + + while (remaining != 0) { + if ((remaining & 1) != 0) { + // Binary digit is 1 so add + (ax, ay) = pointAdd(ax, ay, px, py); + } + + (px, py) = pointDouble(px, py); + + remaining = remaining / 2; + } + + x2 = ax; + y2 = ay; + } + + /** + * @dev Check if a given point is on the curve + * (168700x^2 + y^2) - (1 + 168696x^2y^2) == 0 + */ + function isOnCurve(uint256 _x, uint256 _y) internal pure returns (bool) { + uint256 xSq = mulmod(_x, _x, Q); + uint256 ySq = mulmod(_y, _y, Q); + uint256 lhs = addmod(mulmod(A, xSq, Q), ySq, Q); + uint256 rhs = addmod(1, mulmod(mulmod(D, xSq, Q), ySq, Q), Q); + return submod(lhs, rhs, Q) == 0; + } + + /** + * @dev Perform modular subtraction + */ + function submod(uint256 _a, uint256 _b, uint256 _mod) internal pure returns (uint256) { + uint256 aNN = _a; + + if (_a <= _b) { + aNN += _mod; + } + + return addmod(aNN - _b, 0, _mod); + } + + /** + * @dev Compute modular inverse of a number + */ + function inverse(uint256 _a) internal view returns (uint256) { + // We can use Euler's theorem instead of the extended Euclidean algorithm + // Since m = Q and Q is prime we have: a^-1 = a^(m - 2) (mod m) + return expmod(_a, Q - 2, Q); + } + + /** + * @dev Helper function to call the bigModExp precompile + */ + function expmod(uint256 _b, uint256 _e, uint256 _m) internal view returns (uint256 o) { + assembly { + let memPtr := mload(0x40) + mstore(memPtr, 0x20) // Length of base _b + mstore(add(memPtr, 0x20), 0x20) // Length of exponent _e + mstore(add(memPtr, 0x40), 0x20) // Length of modulus _m + mstore(add(memPtr, 0x60), _b) // Base _b + mstore(add(memPtr, 0x80), _e) // Exponent _e + mstore(add(memPtr, 0xa0), _m) // Modulus _m + + // The bigModExp precompile is at 0x05 + let success := staticcall(gas(), 0x05, memPtr, 0xc0, memPtr, 0x20) + switch success + case 0 { + revert(0x0, 0x0) + } + default { + o := mload(memPtr) + } + } + } +} diff --git a/contracts/contracts/maci/Poll.sol b/contracts/contracts/maci/Poll.sol new file mode 100644 index 000000000..1306c7698 --- /dev/null +++ b/contracts/contracts/maci/Poll.sol @@ -0,0 +1,286 @@ +// @note This code was taken from maci-contracts v1.2.0 with public key validation from +// https://github.com/privacy-scaling-explorations/maci/blob/dc18e2f046cf160f846f003c04ec4dfac502f6ae/contracts/contracts/Poll.sol +// TODO remove this and use MACI npm package when version greater than 1.2.0 is released + +// SPDX-License-Identifier: MIT +pragma solidity ^0.8.10; + +import { Params } from "maci-contracts/contracts/utilities/Params.sol"; +import { SnarkCommon } from "maci-contracts/contracts/crypto/SnarkCommon.sol"; +import { Ownable } from "@openzeppelin/contracts/access/Ownable.sol"; +import { ERC20 } from "@openzeppelin/contracts/token/ERC20/ERC20.sol"; +import { SafeERC20 } from "@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol"; +import { EmptyBallotRoots } from "maci-contracts/contracts/trees/EmptyBallotRoots.sol"; +import { IPoll } from "maci-contracts/contracts/interfaces/IPoll.sol"; +import { Utilities } from "maci-contracts/contracts/utilities/Utilities.sol"; +import { CurveBabyJubJub } from "./BabyJubJub.sol"; + +/// @title Poll +/// @notice A Poll contract allows voters to submit encrypted messages +/// which can be either votes, key change messages or topup messages. +/// @dev Do not deploy this directly. Use PollFactory.deploy() which performs some +/// checks on the Poll constructor arguments. +contract Poll is Params, Utilities, SnarkCommon, Ownable, EmptyBallotRoots, IPoll { + using SafeERC20 for ERC20; + + /// @notice Whether the Poll has been initialized + bool internal isInit; + + /// @notice The coordinator's public key + PubKey public coordinatorPubKey; + + /// @notice Hash of the coordinator's public key + uint256 public immutable coordinatorPubKeyHash; + + /// @notice the state root of the state merkle tree + uint256 public mergedStateRoot; + + // The timestamp of the block at which the Poll was deployed + uint256 internal immutable deployTime; + + // The duration of the polling period, in seconds + uint256 internal immutable duration; + + /// @notice Whether the MACI contract's stateAq has been merged by this contract + bool public stateAqMerged; + + /// @notice Get the commitment to the state leaves and the ballots. This is + /// hash3(stateRoot, ballotRoot, salt). + /// Its initial value should be + /// hash(maciStateRootSnapshot, emptyBallotRoot, 0) + /// Each successful invocation of processMessages() should use a different + /// salt to update this value, so that an external observer cannot tell in + /// the case that none of the messages are valid. + uint256 public currentSbCommitment; + + /// @notice The number of messages that have been published + uint256 public numMessages; + + /// @notice The number of signups that have been processed + /// before the Poll ended (stateAq merged) + uint256 public numSignups; + + /// @notice Max values for the poll + MaxValues public maxValues; + + /// @notice Depths of the merkle trees + TreeDepths public treeDepths; + + /// @notice The contracts used by the Poll + ExtContracts public extContracts; + + error VotingPeriodOver(); + error VotingPeriodNotOver(); + error PollAlreadyInit(); + error TooManyMessages(); + error InvalidPubKey(); + error StateAqAlreadyMerged(); + error StateAqSubtreesNeedMerge(); + error InvalidBatchLength(); + + event PublishMessage(Message _message, PubKey _encPubKey); + event TopupMessage(Message _message); + event MergeMaciStateAqSubRoots(uint256 _numSrQueueOps); + event MergeMaciStateAq(uint256 _stateRoot, uint256 _numSignups); + event MergeMessageAqSubRoots(uint256 _numSrQueueOps); + event MergeMessageAq(uint256 _messageRoot); + + /// @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 _maxValues The maximum number of messages and vote options + /// @param _treeDepths The depths of the merkle trees + /// @param _coordinatorPubKey The coordinator's public key + /// @param _extContracts The external contracts + constructor( + uint256 _duration, + MaxValues memory _maxValues, + TreeDepths memory _treeDepths, + PubKey memory _coordinatorPubKey, + ExtContracts memory _extContracts + ) payable { + // check that the coordinator public key is valid + if (!CurveBabyJubJub.isOnCurve(_coordinatorPubKey.x, _coordinatorPubKey.y)) { + revert InvalidPubKey(); + } + + // store the pub key as object then calculate the hash + coordinatorPubKey = _coordinatorPubKey; + // we hash it ourselves to ensure we store the correct value + coordinatorPubKeyHash = hashLeftRight(_coordinatorPubKey.x, _coordinatorPubKey.y); + // store the external contracts to interact with + extContracts = _extContracts; + // store duration of the poll + duration = _duration; + // store max values + maxValues = _maxValues; + // store tree depth + treeDepths = _treeDepths; + // Record the current timestamp + deployTime = block.timestamp; + } + + /// @notice A modifier that causes the function to revert if the voting period is + /// not over. + modifier isAfterVotingDeadline() { + uint256 secondsPassed = block.timestamp - deployTime; + if (secondsPassed <= duration) revert VotingPeriodNotOver(); + _; + } + + /// @notice A modifier that causes the function to revert if the voting period is + /// over + modifier isWithinVotingDeadline() { + uint256 secondsPassed = block.timestamp - deployTime; + if (secondsPassed >= duration) revert VotingPeriodOver(); + _; + } + + /// @notice The initialization function. + /// @dev Should be called immediately after Poll creation + /// and messageAq ownership transferred + function init() public { + if (isInit) revert PollAlreadyInit(); + // set to true so it cannot be called again + isInit = true; + + unchecked { + numMessages++; + } + + // init messageAq here by inserting placeholderLeaf + uint256[2] memory dat = [NOTHING_UP_MY_SLEEVE, 0]; + + (Message memory _message, PubKey memory _padKey, uint256 placeholderLeaf) = padAndHashMessage(dat, 1); + extContracts.messageAq.enqueue(placeholderLeaf); + + emit PublishMessage(_message, _padKey); + } + + /// @inheritdoc IPoll + function topup(uint256 stateIndex, uint256 amount) public virtual isWithinVotingDeadline { + // we check that we do not exceed the max number of messages + if (numMessages >= maxValues.maxMessages) revert TooManyMessages(); + + // cannot realistically overflow + unchecked { + numMessages++; + } + + /// @notice topupCredit is a trusted token contract which reverts if the transfer fails + extContracts.topupCredit.transferFrom(msg.sender, address(this), amount); + + uint256[2] memory dat = [stateIndex, amount]; + (Message memory _message, , uint256 messageLeaf) = padAndHashMessage(dat, 2); + + extContracts.messageAq.enqueue(messageLeaf); + + emit TopupMessage(_message); + } + + /// @inheritdoc IPoll + function publishMessage(Message memory _message, PubKey calldata _encPubKey) public virtual isWithinVotingDeadline { + // we check that we do not exceed the max number of messages + if (numMessages >= maxValues.maxMessages) revert TooManyMessages(); + + // validate that the public key is valid + if (!CurveBabyJubJub.isOnCurve(_encPubKey.x, _encPubKey.y)) { + revert InvalidPubKey(); + } + + // cannot realistically overflow + unchecked { + numMessages++; + } + + // we enforce that msgType here is 1 so we don't need checks + // at the circuit level + _message.msgType = 1; + + uint256 messageLeaf = hashMessageAndEncPubKey(_message, _encPubKey); + extContracts.messageAq.enqueue(messageLeaf); + + emit PublishMessage(_message, _encPubKey); + } + + /// @notice submit a message batch + /// @dev Can only be submitted before the voting deadline + /// @param _messages the messages + /// @param _encPubKeys the encrypted public keys + function publishMessageBatch(Message[] calldata _messages, PubKey[] calldata _encPubKeys) external { + if (_messages.length != _encPubKeys.length) { + revert InvalidBatchLength(); + } + + uint256 len = _messages.length; + for (uint256 i = 0; i < len; ) { + // an event will be published by this function already + publishMessage(_messages[i], _encPubKeys[i]); + + unchecked { + i++; + } + } + } + + /// @inheritdoc IPoll + function mergeMaciStateAqSubRoots(uint256 _numSrQueueOps, uint256 _pollId) public onlyOwner isAfterVotingDeadline { + // This function cannot be called after the stateAq was merged + if (stateAqMerged) revert StateAqAlreadyMerged(); + + // merge subroots + extContracts.maci.mergeStateAqSubRoots(_numSrQueueOps, _pollId); + + emit MergeMaciStateAqSubRoots(_numSrQueueOps); + } + + /// @inheritdoc IPoll + function mergeMaciStateAq(uint256 _pollId) public onlyOwner isAfterVotingDeadline { + // This function can only be called once per Poll after the voting + // deadline + if (stateAqMerged) revert StateAqAlreadyMerged(); + + // set merged to true so it cannot be called again + stateAqMerged = true; + + // the subtrees must have been merged first + if (!extContracts.maci.stateAq().subTreesMerged()) revert StateAqSubtreesNeedMerge(); + + mergedStateRoot = extContracts.maci.mergeStateAq(_pollId); + + // Set currentSbCommitment + uint256[3] memory sb; + sb[0] = mergedStateRoot; + sb[1] = emptyBallotRoots[treeDepths.voteOptionTreeDepth - 1]; + sb[2] = uint256(0); + + currentSbCommitment = hash3(sb); + + numSignups = extContracts.maci.numSignUps(); + emit MergeMaciStateAq(mergedStateRoot, numSignups); + } + + /// @inheritdoc IPoll + function mergeMessageAqSubRoots(uint256 _numSrQueueOps) public onlyOwner isAfterVotingDeadline { + extContracts.messageAq.mergeSubRoots(_numSrQueueOps); + emit MergeMessageAqSubRoots(_numSrQueueOps); + } + + /// @inheritdoc IPoll + function mergeMessageAq() public onlyOwner isAfterVotingDeadline { + uint256 root = extContracts.messageAq.merge(treeDepths.messageTreeDepth); + emit MergeMessageAq(root); + } + + /// @inheritdoc IPoll + function getDeployTimeAndDuration() public view returns (uint256 pollDeployTime, uint256 pollDuration) { + pollDeployTime = deployTime; + pollDuration = duration; + } + + /// @inheritdoc IPoll + function numSignUpsAndMessages() public view returns (uint256 numSUps, uint256 numMsgs) { + numSUps = numSignups; + numMsgs = numMessages; + } +} diff --git a/contracts/contracts/maci/PollFactory.sol b/contracts/contracts/maci/PollFactory.sol new file mode 100644 index 000000000..ad91b4305 --- /dev/null +++ b/contracts/contracts/maci/PollFactory.sol @@ -0,0 +1,73 @@ +// @note This code was taken from https://github.com/privacy-scaling-explorations/maci/blob/dc18e2f046cf160f846f003c04ec4dfac502f6ae/contracts/contracts/PollFactory.sol +// TODO remove this and use MACI npm package when version greater than 1.2.0 is released + +// SPDX-License-Identifier: MIT +pragma solidity 0.8.10; + + +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 { TopupCredit } from "maci-contracts/contracts/TopupCredit.sol"; +import { Params } from "maci-contracts/contracts/utilities/Params.sol"; +import { DomainObjs } from "maci-contracts/contracts/utilities/DomainObjs.sol"; +import { Poll } from "./Poll.sol"; +import { IPollFactory } from "maci-contracts/contracts/interfaces/IPollFactory.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 Params, DomainObjs, IPollFactory { + // The number of children each node in the message tree has + uint256 internal constant TREE_ARITY = 5; + + // custom error + error InvalidMaxValues(); + + /// @notice The PollFactory constructor + // solhint-disable-next-line no-empty-blocks + constructor() payable {} + + /// @inheritdoc IPollFactory + function deploy( + uint256 _duration, + MaxValues calldata _maxValues, + TreeDepths calldata _treeDepths, + PubKey calldata _coordinatorPubKey, + address _maci, + TopupCredit _topupCredit, + address _pollOwner + ) public virtual returns (address pollAddr) { + /// @notice Validate _maxValues + /// maxVoteOptions must be less than 2 ** 50 due to circuit limitations; + /// it will be packed as a 50-bit value along with other values as one + /// of the inputs (aka packedVal) + if (_maxValues.maxVoteOptions >= (2 ** 50)) { + revert InvalidMaxValues(); + } + + /// @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, + topupCredit: _topupCredit + }); + + // deploy the poll + Poll poll = new Poll(_duration, _maxValues, _treeDepths, _coordinatorPubKey, extContracts); + + // Make the Poll contract own the messageAq contract, so only it can + // run enqueue/merge + messageAq.transferOwnership(address(poll)); + + // init Poll + poll.init(); + + poll.transferOwnership(_pollOwner); + + pollAddr = address(poll); + } +} diff --git a/contracts/e2e/index.ts b/contracts/e2e/index.ts index 76e21525c..f3ad49b7c 100644 --- a/contracts/e2e/index.ts +++ b/contracts/e2e/index.ts @@ -16,7 +16,11 @@ import { DEFAULT_GET_LOG_BATCH_SIZE, DEFAULT_SR_QUEUE_OPS, } from '../utils/constants' -import { getEventArg } from '../utils/contracts' +import { + getContractAt, + getEventArg, + getQualifiedContractName, +} from '../utils/contracts' import { deployPoseidonLibraries, deployMaciFactory } from '../utils/testutils' import { getIpfsHash } from '../utils/ipfs' import { @@ -33,7 +37,7 @@ import { DEFAULT_CIRCUIT } from '../utils/circuits' import { MaciParameters } from '../utils/maciParameters' import { existsSync, mkdirSync } from 'fs' import path from 'path' -import { FundingRound } from '../typechain-types' +import { FundingRound, Poll } from '../typechain-types' import { JSONFile } from '../utils/JSONFile' import { EContracts } from '../utils/types' import { getTalyFilePath } from '../utils/misc' @@ -270,7 +274,11 @@ describe('End-to-end Tests', function () { pollId = await fundingRound.pollId() const pollAddress = await fundingRound.poll() - pollContract = await ethers.getContractAt(EContracts.Poll, pollAddress) + pollContract = await getContractAt( + EContracts.Poll, + pollAddress, + ethers + ) await mine() }) diff --git a/contracts/package.json b/contracts/package.json index 4498c8aba..9a3941562 100644 --- a/contracts/package.json +++ b/contracts/package.json @@ -18,7 +18,7 @@ "@openzeppelin/contracts": "4.9.0", "@pinata/sdk": "^2.1.0", "dotenv": "^8.2.0", - "maci-contracts": "0.0.0-ci.153326b", + "maci-contracts": "1.2.0", "solidity-rlp": "2.0.8" }, "devDependencies": { @@ -41,7 +41,7 @@ "ipfs-only-hash": "^2.0.1", "maci-circuits": "^1.2.0", "maci-cli": "^1.2.0", - "maci-domainobjs": "0.0.0-ci.153326b", + "maci-domainobjs": "1.2.0", "mocha": "^10.2.0", "solidity-coverage": "^0.8.1", "ts-node": "^10.9.2", diff --git a/contracts/tasks/helpers/ConstructorArguments.ts b/contracts/tasks/helpers/ConstructorArguments.ts index 6f9f3d5b4..1db4beb22 100644 --- a/contracts/tasks/helpers/ConstructorArguments.ts +++ b/contracts/tasks/helpers/ConstructorArguments.ts @@ -12,6 +12,7 @@ import { Poll, Tally, } from '../../typechain-types' +import { getContractAt } from '../../utils/contracts' /** A list of functions to get contract constructor arguments from the contract */ const ConstructorArgumentsGetters: Record< @@ -89,10 +90,11 @@ async function getPollConstructorArguments( address: string, ethers: HardhatEthersHelpers ): Promise> { - const pollContract = (await ethers.getContractAt( + const pollContract = await getContractAt( EContracts.Poll, - address - )) as BaseContract as Poll + address, + ethers + ) const [, duration] = await pollContract.getDeployTimeAndDuration() const [maxValues, treeDepths, coordinatorPubKey, extContracts] = diff --git a/contracts/tasks/runners/claim.ts b/contracts/tasks/runners/claim.ts index e5135aa24..0f27a2e95 100644 --- a/contracts/tasks/runners/claim.ts +++ b/contracts/tasks/runners/claim.ts @@ -5,7 +5,7 @@ * yarn hardhat claim --recipient --network */ -import { getEventArg } from '../../utils/contracts' +import { getContractAt, getEventArg } from '../../utils/contracts' import { getRecipientClaimData } from '@clrfund/common' import { JSONFile } from '../../utils/JSONFile' import { @@ -17,6 +17,7 @@ import { getNumber } from 'ethers' import { task, types } from 'hardhat/config' import { EContracts } from '../../utils/types' import { ContractStorage } from '../helpers/ContractStorage' +import { Poll } from 'maci-contracts/build/typechain-types' task('claim', 'Claim funnds for test recipients') .addOptionalParam('roundAddress', 'Funding round contract address') @@ -64,7 +65,11 @@ task('claim', 'Claim funnds for test recipients') const pollAddress = await fundingRoundContract.poll() console.log('pollAddress', pollAddress) - const poll = await ethers.getContractAt(EContracts.Poll, pollAddress) + const poll = await getContractAt( + EContracts.Poll, + pollAddress, + ethers + ) const treeDepths = await poll.treeDepths() const recipientTreeDepth = getNumber(treeDepths.voteOptionTreeDepth) diff --git a/contracts/tasks/runners/contribute.ts b/contracts/tasks/runners/contribute.ts index 6060c17a1..41cb7d610 100644 --- a/contracts/tasks/runners/contribute.ts +++ b/contracts/tasks/runners/contribute.ts @@ -11,7 +11,7 @@ import { Keypair, createMessage, Message, PubKey } from '@clrfund/common' import { UNIT } from '../../utils/constants' -import { getEventArg } from '../../utils/contracts' +import { getContractAt, getEventArg } from '../../utils/contracts' import type { FundingRound, ERC20, Poll } from '../../typechain-types' import { task } from 'hardhat/config' import { EContracts } from '../../utils/types' @@ -98,9 +98,10 @@ task('contribute', 'Contribute to a funding round').setAction( const pollId = await fundingRound.pollId() const pollAddress = await fundingRound.poll() - const pollContract = await ethers.getContractAt( + const pollContract = await getContractAt( EContracts.Poll, - pollAddress + pollAddress, + ethers ) const rawCoordinatorPubKey = await pollContract.coordinatorPubKey() diff --git a/contracts/tasks/runners/finalize.ts b/contracts/tasks/runners/finalize.ts index e48a6c2b6..74afe85e1 100644 --- a/contracts/tasks/runners/finalize.ts +++ b/contracts/tasks/runners/finalize.ts @@ -17,6 +17,8 @@ import { EContracts } from '../../utils/types' import { ContractStorage } from '../helpers/ContractStorage' import { Subtask } from '../helpers/Subtask' import { getProofDirForRound, getTalyFilePath } from '../../utils/misc' +import { getContractAt } from '../../utils/contracts' +import { Poll } from 'maci-contracts/build/typechain-types' task('finalize', 'Finalize a funding round') .addOptionalParam('clrfund', 'The ClrFund contract address') @@ -47,9 +49,10 @@ task('finalize', 'Finalize a funding round') console.log('Current round', fundingRound.target) const pollAddress = await fundingRound.poll() - const pollContract = await ethers.getContractAt( + const pollContract = await getContractAt( EContracts.Poll, - pollAddress + pollAddress, + ethers ) console.log('Poll', pollAddress) diff --git a/contracts/tasks/runners/publishTallyResults.ts b/contracts/tasks/runners/publishTallyResults.ts index 5651ac353..b9db3404f 100644 --- a/contracts/tasks/runners/publishTallyResults.ts +++ b/contracts/tasks/runners/publishTallyResults.ts @@ -24,10 +24,12 @@ import { FundingRound, Poll } from '../../typechain-types' import { HardhatEthersHelpers } from '@nomicfoundation/hardhat-ethers/types' import { EContracts } from '../../utils/types' import { Subtask } from '../helpers/Subtask' -import { getCurrentFundingRoundContract } from '../../utils/contracts' +import { + getContractAt, + getCurrentFundingRoundContract, +} from '../../utils/contracts' import { getTalyFilePath } from '../../utils/misc' import { ContractStorage } from '../helpers/ContractStorage' -import { PINATA_PINNING_URL } from '../../utils/constants' /** * Publish the tally IPFS hash on chain if it's not already published @@ -92,7 +94,11 @@ async function getRecipientTreeDepth( ethers: HardhatEthersHelpers ): Promise { const pollAddress = await fundingRoundContract.poll() - const pollContract = await ethers.getContractAt(EContracts.Poll, pollAddress) + const pollContract = await getContractAt( + EContracts.Poll, + pollAddress, + ethers + ) const treeDepths = await (pollContract as BaseContract as Poll).treeDepths() const voteOptionTreeDepth = treeDepths.voteOptionTreeDepth return getNumber(voteOptionTreeDepth) diff --git a/contracts/tests/deployer.ts b/contracts/tests/deployer.ts index f21353557..bbe8c027a 100644 --- a/contracts/tests/deployer.ts +++ b/contracts/tests/deployer.ts @@ -6,7 +6,12 @@ import { genRandomSalt } from 'maci-crypto' import { Keypair } from '@clrfund/common' import { TREE_ARITY, ZERO_ADDRESS, UNIT } from '../utils/constants' -import { getGasUsage, getEventArg, deployContract } from '../utils/contracts' +import { + getGasUsage, + getEventArg, + deployContract, + getContractAt, +} from '../utils/contracts' import { deployPoseidonLibraries, deployMaciFactory } from '../utils/testutils' import { MaciParameters } from '../utils/maciParameters' import { HardhatEthersSigner } from '@nomicfoundation/hardhat-ethers/signers' @@ -15,6 +20,7 @@ import { ClrFundDeployer, FundingRoundFactory, MACIFactory, + Poll, } from '../typechain-types' import { EContracts } from '../utils/types' @@ -318,7 +324,11 @@ describe('Clr fund deployer', async () => { 'pollAddr' ) - const poll = await ethers.getContractAt('Poll', pollAddress.poll) + const poll = await getContractAt( + EContracts.Poll, + pollAddress.poll, + ethers + ) const roundCoordinatorPubKey = await poll.coordinatorPubKey() expect(roundCoordinatorPubKey.x).to.equal(coordinatorPubKey.x) expect(roundCoordinatorPubKey.y).to.equal(coordinatorPubKey.y) diff --git a/contracts/tests/round.ts b/contracts/tests/round.ts index c0fa4f813..4e480ff34 100644 --- a/contracts/tests/round.ts +++ b/contracts/tests/round.ts @@ -21,7 +21,7 @@ import { VOICE_CREDIT_FACTOR, ALPHA_PRECISION, } from '../utils/constants' -import { getEventArg, getGasUsage } from '../utils/contracts' +import { getContractAt, getEventArg, getGasUsage } from '../utils/contracts' import { bnSqrt, createMessage, @@ -34,6 +34,7 @@ import { deployTestFundingRound } from '../utils/testutils' // ethStaker test vectors for Quadratic Funding with alpha import smallTallyTestData from './data/testTallySmall.json' import { FundingRound } from '../typechain-types' +import { EContracts } from '../utils/types' const newResultCommitment = hexlify(randomBytes(32)) const perVOSpentVoiceCreditsHash = hexlify(randomBytes(32)) @@ -136,7 +137,12 @@ describe('Funding Round', () => { maciAddress = await fundingRound.maci() maci = await ethers.getContractAt('MACI', maciAddress) const pollAddress = await fundingRound.poll() - poll = await ethers.getContractAt('Poll', pollAddress, deployer) + poll = await getContractAt( + EContracts.Poll, + pollAddress, + ethers, + deployer + ) pollId = await fundingRound.pollId() const treeDepths = await poll.treeDepths() diff --git a/contracts/utils/contracts.ts b/contracts/utils/contracts.ts index 45250e3fb..c72aac709 100644 --- a/contracts/utils/contracts.ts +++ b/contracts/utils/contracts.ts @@ -27,7 +27,7 @@ export async function deployContract( options?: DeployContractOptions & { args?: unknown[]; quiet?: boolean } ): Promise { const args = options?.args || [] - const contractName = String(name).includes('Poseidon') ? ':' + name : name + const contractName = getQualifiedContractName(name) const contract = await ethers.deployContract(contractName, args, options) await contract.waitForDeployment() @@ -116,4 +116,46 @@ export async function getCurrentFundingRoundContract( return fundingRoundContract as BaseContract as FundingRound } + +/** + * Return the fully qualified contract name for Poll and PollFactory + * since there is a local copy and another in the maci-contracts + * otherwise return the name of the contract + * @param name The contract name + * @returns The qualified contract name + */ +export function getQualifiedContractName(name: EContracts): string { + let contractName = String(name) + if (contractName.includes('Poseidon')) { + contractName = `:${name}` + } + if (name === EContracts.PollFactory) { + contractName = 'contracts/maci/PollFactory.sol:PollFactory' + } + if (name === EContracts.Poll) { + contractName = 'contracts/maci/Poll.sol:Poll' + } + return contractName +} + +/** + * Get a contract + * @param name Name of the contract + * @param address The contract address + * @param ethers Hardhat ethers handle + * @param signers The signer + * @returns contract + */ +export async function getContractAt( + name: EContracts, + address: string, + ethers: HardhatEthersHelpers, + signer?: Signer +): Promise { + const contractName = getQualifiedContractName(name) + const contract = await ethers.getContractAt(contractName, address, signer) + + return contract as BaseContract as T +} + export { getEventArg } diff --git a/yarn.lock b/yarn.lock index 10adf18a4..970c4343b 100644 --- a/yarn.lock +++ b/yarn.lock @@ -1912,14 +1912,6 @@ fastfile "0.0.20" ffjavascript "^0.2.48" -"@iden3/binfileutils@0.0.12": - version "0.0.12" - resolved "https://registry.yarnpkg.com/@iden3/binfileutils/-/binfileutils-0.0.12.tgz#3772552f57551814ff606fa68ea1e0ef52795ce3" - integrity sha512-naAmzuDufRIcoNfQ1d99d7hGHufLA3wZSibtr4dMe6ZeiOPV1KwOZWTJ1YVz4HbaWlpDuzVU72dS4ATQS4PXBQ== - dependencies: - fastfile "0.0.20" - ffjavascript "^0.3.0" - "@import-maps/resolve@^1.0.1": version "1.0.1" resolved "https://registry.yarnpkg.com/@import-maps/resolve/-/resolve-1.0.1.tgz#1e9fcadcf23aa0822256a329aabca241879d37c9" @@ -2682,54 +2674,6 @@ "@nodelib/fs.scandir" "2.1.5" fastq "^1.6.0" -"@nomicfoundation/edr-darwin-arm64@0.3.7": - version "0.3.7" - resolved "https://registry.yarnpkg.com/@nomicfoundation/edr-darwin-arm64/-/edr-darwin-arm64-0.3.7.tgz#c204edc79643624dbd431b489b254778817d8244" - integrity sha512-6tK9Lv/lSfyBvpEQ4nsTfgxyDT1y1Uv/x8Wa+aB+E8qGo3ToexQ1BMVjxJk6PChXCDOWxB3B4KhqaZFjdhl3Ow== - -"@nomicfoundation/edr-darwin-x64@0.3.7": - version "0.3.7" - resolved "https://registry.yarnpkg.com/@nomicfoundation/edr-darwin-x64/-/edr-darwin-x64-0.3.7.tgz#c3b394445084270cc5250d6c1869b0574e7ef810" - integrity sha512-1RrQ/1JPwxrYO69e0tglFv5H+ggour5Ii3bb727+yBpBShrxtOTQ7fZyfxA5h62LCN+0Z9wYOPeQ7XFcVurMaQ== - -"@nomicfoundation/edr-linux-arm64-gnu@0.3.7": - version "0.3.7" - resolved "https://registry.yarnpkg.com/@nomicfoundation/edr-linux-arm64-gnu/-/edr-linux-arm64-gnu-0.3.7.tgz#6d65545a44d1323bb7ab08c3306947165d2071de" - integrity sha512-ds/CKlBoVXIihjhflhgPn13EdKWed6r5bgvMs/YwRqT5wldQAQJZWAfA2+nYm0Yi2gMGh1RUpBcfkyl4pq7G+g== - -"@nomicfoundation/edr-linux-arm64-musl@0.3.7": - version "0.3.7" - resolved "https://registry.yarnpkg.com/@nomicfoundation/edr-linux-arm64-musl/-/edr-linux-arm64-musl-0.3.7.tgz#5368534bceac1a8c18b1be6b908caca5d39b0c03" - integrity sha512-e29udiRaPujhLkM3+R6ju7QISrcyOqpcaxb2FsDWBkuD7H8uU9JPZEyyUIpEp5uIY0Jh1eEJPKZKIXQmQAEAuw== - -"@nomicfoundation/edr-linux-x64-gnu@0.3.7": - version "0.3.7" - resolved "https://registry.yarnpkg.com/@nomicfoundation/edr-linux-x64-gnu/-/edr-linux-x64-gnu-0.3.7.tgz#42349bf5941dbb54a5719942924c6e4e8cde348e" - integrity sha512-/xkjmTyv+bbJ4akBCW0qzFKxPOV4AqLOmqurov+s9umHb16oOv72osSa3SdzJED2gHDaKmpMITT4crxbar4Axg== - -"@nomicfoundation/edr-linux-x64-musl@0.3.7": - version "0.3.7" - resolved "https://registry.yarnpkg.com/@nomicfoundation/edr-linux-x64-musl/-/edr-linux-x64-musl-0.3.7.tgz#e6babe11c9a8012f1284e6e48c3551861f2a7cd4" - integrity sha512-QwBP9xlmsbf/ldZDGLcE4QiAb8Zt46E/+WLpxHBATFhGa7MrpJh6Zse+h2VlrT/SYLPbh2cpHgSmoSlqVxWG9g== - -"@nomicfoundation/edr-win32-x64-msvc@0.3.7": - version "0.3.7" - resolved "https://registry.yarnpkg.com/@nomicfoundation/edr-win32-x64-msvc/-/edr-win32-x64-msvc-0.3.7.tgz#1504b98f305f03be153b0220a546985660de9dc6" - integrity sha512-j/80DEnkxrF2ewdbk/gQ2EOPvgF0XSsg8D0o4+6cKhUVAW6XwtWKzIphNL6dyD2YaWEPgIrNvqiJK/aln0ww4Q== - -"@nomicfoundation/edr@^0.3.5": - version "0.3.7" - resolved "https://registry.yarnpkg.com/@nomicfoundation/edr/-/edr-0.3.7.tgz#9c75edf1fcf601617905b2c89acf103f4786d017" - integrity sha512-v2JFWnFKRsnOa6PDUrD+sr8amcdhxnG/YbL7LzmgRGU1odWEyOF4/EwNeUajQr4ZNKVWrYnJ6XjydXtUge5OBQ== - optionalDependencies: - "@nomicfoundation/edr-darwin-arm64" "0.3.7" - "@nomicfoundation/edr-darwin-x64" "0.3.7" - "@nomicfoundation/edr-linux-arm64-gnu" "0.3.7" - "@nomicfoundation/edr-linux-arm64-musl" "0.3.7" - "@nomicfoundation/edr-linux-x64-gnu" "0.3.7" - "@nomicfoundation/edr-linux-x64-musl" "0.3.7" - "@nomicfoundation/edr-win32-x64-msvc" "0.3.7" - "@nomicfoundation/ethereumjs-block@5.0.2": version "5.0.2" resolved "https://registry.yarnpkg.com/@nomicfoundation/ethereumjs-block/-/ethereumjs-block-5.0.2.tgz#13a7968f5964f1697da941281b7f7943b0465d04" @@ -3030,11 +2974,6 @@ resolved "https://registry.yarnpkg.com/@nomicfoundation/hardhat-toolbox/-/hardhat-toolbox-4.0.0.tgz#eb1f619218dd1414fa161dfec92d3e5e53a2f407" integrity sha512-jhcWHp0aHaL0aDYj8IJl80v4SZXWMS1A2XxXa1CA6pBiFfJKuZinCkO6wb+POAt0LIfXB3gA3AgdcOccrcwBwA== -"@nomicfoundation/hardhat-toolbox@^5.0.0": - version "5.0.0" - resolved "https://registry.yarnpkg.com/@nomicfoundation/hardhat-toolbox/-/hardhat-toolbox-5.0.0.tgz#165b47f8a3d2bf668cc5d453ce7f496a1156948d" - integrity sha512-FnUtUC5PsakCbwiVNsqlXVIWG5JIb5CEZoSXbJUsEBun22Bivx2jhF1/q9iQbzuaGpJKFQyOhemPB2+XlEE6pQ== - "@nomicfoundation/hardhat-verify@^2.0.3": version "2.0.3" resolved "https://registry.yarnpkg.com/@nomicfoundation/hardhat-verify/-/hardhat-verify-2.0.3.tgz#173557f8cfa53c8c9da23a326f54d24fe459ae68" @@ -3343,11 +3282,6 @@ resolved "https://registry.yarnpkg.com/@openzeppelin/contracts/-/contracts-4.9.5.tgz#1eed23d4844c861a1835b5d33507c1017fa98de8" integrity sha512-ZK+W5mVhRppff9BE6YdR8CC52C8zAvsVAiWhEtQ5+oNxFE6h1WdeWo+FJSF8KKvtxxVYZ7MTP/5KoVpAU3aSWg== -"@openzeppelin/contracts@^5.0.2": - version "5.0.2" - resolved "https://registry.yarnpkg.com/@openzeppelin/contracts/-/contracts-5.0.2.tgz#b1d03075e49290d06570b2fd42154d76c2a5d210" - integrity sha512-ytPc6eLGcHHnapAZ9S+5qsdomhjo6QBHTDRRBFfTxXIpsicMhVPouPgmUPebZZZGX7vt9USA+Z+0M0dSVtSUEA== - "@openzeppelin/merkle-tree@^1.0.5": version "1.0.5" resolved "https://registry.yarnpkg.com/@openzeppelin/merkle-tree/-/merkle-tree-1.0.5.tgz#4836d377777a7e39f31674f06ec3d6909def7913" @@ -5029,20 +4963,6 @@ dependencies: "@zk-kit/utils" "0.1.0" -"@zk-kit/baby-jubjub@0.2.0": - version "0.2.0" - resolved "https://registry.yarnpkg.com/@zk-kit/baby-jubjub/-/baby-jubjub-0.2.0.tgz#71c5396ddacb97e4e3db677933f74bde3332b236" - integrity sha512-pqiPq621oKpwiIkf1KcVh5MdbFX0V67s9gCmiEkhLMeafZaIXEwVt5qmIu1d2HB4mjXgr4Ys8Jpn2Rw4KXxnFQ== - dependencies: - "@zk-kit/utils" "0.3.0" - -"@zk-kit/baby-jubjub@0.3.0", "@zk-kit/baby-jubjub@^0.3.0": - version "0.3.0" - resolved "https://registry.yarnpkg.com/@zk-kit/baby-jubjub/-/baby-jubjub-0.3.0.tgz#78b8d3226670dd02dc8ced713aec64d6bb2a6e62" - integrity sha512-mA3/M/+4C2vDtc0SpXf/q/nsvwBh+s42ou176sgDzqIBQD/u/N+LaLGorDh+X5AD3dVMHb8rheFpnnrJmjsqdA== - dependencies: - "@zk-kit/utils" "0.6.0" - "@zk-kit/circuits@^0.3.0": version "0.3.0" resolved "https://registry.yarnpkg.com/@zk-kit/circuits/-/circuits-0.3.0.tgz#716d932e9b09f33c71c7ff940a507e519ce0a6f4" @@ -5050,22 +4970,6 @@ dependencies: circomlib "^2.0.5" -"@zk-kit/circuits@^0.4.0": - version "0.4.0" - resolved "https://registry.yarnpkg.com/@zk-kit/circuits/-/circuits-0.4.0.tgz#17a8333e8afe5a4e79260600a2dcefb2bc751a8f" - integrity sha512-Di7mokhwBS3qxVeCfHxGeNIpDg1kTnr1JXmsWiQMZLkRTn3Hugh6Tl07J394rWD0pIWRwPQsinaMVL2sB4F8yQ== - dependencies: - circomlib "^2.0.5" - -"@zk-kit/eddsa-poseidon@^0.11.0": - version "0.11.0" - resolved "https://registry.yarnpkg.com/@zk-kit/eddsa-poseidon/-/eddsa-poseidon-0.11.0.tgz#f648b50a79ce660df75896d8fafa30c0f6eb9a43" - integrity sha512-8XgIVSD+nTnTEjvdrFVvju6lVQ5rxCfkBnf/nCFN/IteiIpYX7LnxrTOV7pIp3RrWL29WuTvNrT8TlBrHRrUFA== - dependencies: - "@zk-kit/baby-jubjub" "0.3.0" - "@zk-kit/utils" "0.8.1" - buffer "6.0.3" - "@zk-kit/eddsa-poseidon@^0.5.1": version "0.5.1" resolved "https://registry.yarnpkg.com/@zk-kit/eddsa-poseidon/-/eddsa-poseidon-0.5.1.tgz#7fef431f441f5385f82e6005cdf83d72d298e8c2" @@ -5082,38 +4986,11 @@ "@zk-kit/baby-jubjub" "0.1.1" "@zk-kit/utils" "0.1.0" -"@zk-kit/poseidon-cipher@^0.3.0": - version "0.3.0" - resolved "https://registry.yarnpkg.com/@zk-kit/poseidon-cipher/-/poseidon-cipher-0.3.0.tgz#e05a5d8a39a2d3a9aadb1b9997c2580713eacfff" - integrity sha512-Byszt7dxssgsR7hog2nf9AMaBKYr8LrgtlU/PPHPEe2OkJwIeQSshoxqquLlZsyfOn2c1ZmTJb4Mo4aHY11pCA== - dependencies: - "@zk-kit/baby-jubjub" "0.2.0" - "@zk-kit/utils" "0.3.0" - "@zk-kit/utils@0.1.0": version "0.1.0" resolved "https://registry.yarnpkg.com/@zk-kit/utils/-/utils-0.1.0.tgz#6c134c22541efc6e634d4a89884c8bfe209b2da1" integrity sha512-MZmuw2w2StB7XOSNg1TW4VwnBJ746UDmdXTvxwDO/U85UZfGfM3zb53gG35qz5sWpQo/DjfoKqaScmh6HUtQpA== -"@zk-kit/utils@0.3.0": - version "0.3.0" - resolved "https://registry.yarnpkg.com/@zk-kit/utils/-/utils-0.3.0.tgz#ca85ab40540ee76b3a09b91df66a55d7f319a71d" - integrity sha512-yVBczOwOSV+evSgdsJ0tpPn3oQpbL7a7fRqANDogleaLLte1IFxKTFLz3WNcgd28Asq2guMGiU6SmiEc61uHAg== - -"@zk-kit/utils@0.6.0": - version "0.6.0" - resolved "https://registry.yarnpkg.com/@zk-kit/utils/-/utils-0.6.0.tgz#30124e98df8e29f7af31e19ce4dc6302f178c0a4" - integrity sha512-sUF1yVjlGmm7/NIN/+d+N8WOcI77bTzgV5+vZmp/S7lXcy4fmO+5TdHERRsDbs8Ep8K33EOC6V+U+JXzmjSe5A== - dependencies: - buffer "^6.0.3" - -"@zk-kit/utils@0.8.1": - version "0.8.1" - resolved "https://registry.yarnpkg.com/@zk-kit/utils/-/utils-0.8.1.tgz#9d358542e6b223dde35f32f3e161d1d3a41b0644" - integrity sha512-m5cvnYo5IBZQCO8H5X0Mw3rGRGEoSqlYXVVF1+4M9IT3olDWcJHLPRqtYGF9zNf+vXV/21srpZ0hX3X2Lzp1TQ== - dependencies: - buffer "^6.0.3" - JSONStream@1.3.2: version "1.3.2" resolved "https://registry.yarnpkg.com/JSONStream/-/JSONStream-1.3.2.tgz#c102371b6ec3a7cf3b847ca00c20bb0fce4c6dea" @@ -7019,7 +6896,7 @@ buffer-from@^1.0.0: resolved "https://registry.yarnpkg.com/buffer-from/-/buffer-from-1.1.2.tgz#2b146a6fd72e80b4f55d255f35ed59a3a9a41bd5" integrity sha512-E+XQCRwSbaaiChtv6k6Dwgc+bx+Bs6vuKJHHl5kox/BaKbhiXzqQOwK4cO22yElGp2OCmjwVhT3HmxgyPGnJfQ== -"buffer-polyfill@npm:buffer@^6.0.3", buffer@6.0.3, buffer@^6.0.1, buffer@^6.0.3: +"buffer-polyfill@npm:buffer@^6.0.3", buffer@^6.0.1, buffer@^6.0.3: name buffer-polyfill version "6.0.3" resolved "https://registry.yarnpkg.com/buffer/-/buffer-6.0.3.tgz#2ace578459cc8fbe2a70aaa8f52ee63b6a74c6c6" @@ -7530,13 +7407,6 @@ circom_runtime@0.1.24: dependencies: ffjavascript "0.2.60" -circom_runtime@0.1.25: - version "0.1.25" - resolved "https://registry.yarnpkg.com/circom_runtime/-/circom_runtime-0.1.25.tgz#62a33b371f4633f30238db7a326c43d988e3a170" - integrity sha512-xBGsBFF5Uv6AKvbpgExYqpHfmfawH2HKe+LyjfKSRevqEV8u63i9KGHVIILsbJNW+0c5bm/66f0PUYQ7qZSkJA== - dependencies: - ffjavascript "0.3.0" - circom_tester@^0.0.19: version "0.0.19" resolved "https://registry.yarnpkg.com/circom_tester/-/circom_tester-0.0.19.tgz#e8bed494d080f8186bd0ac6571755d00ccec83bd" @@ -7561,16 +7431,6 @@ circomkit@^0.0.24: loglevel "^1.8.1" snarkjs "^0.7.0" -circomkit@^0.1.0: - version "0.1.0" - resolved "https://registry.yarnpkg.com/circomkit/-/circomkit-0.1.0.tgz#f44cf86d46b3a3dff5a4958b6450f494d6fa9970" - integrity sha512-Mnc9IuOoaN7FitfURvbg2Q5j62S7/zQl6l18u5dcIhZg3Ot9MZYLiGIotCaF1Gfp/vAUKnvO2lnS3Xc1TdTISA== - dependencies: - chai "^4.3.7" - circom_tester "^0.0.19" - loglevel "^1.8.1" - snarkjs "^0.7.0" - circomlib@^2.0.5: version "2.0.5" resolved "https://registry.yarnpkg.com/circomlib/-/circomlib-2.0.5.tgz#183c703e53ed7d011811842dbeeeb9819f4cc1d6" @@ -10322,19 +10182,6 @@ ethers@^6.11.1: tslib "2.4.0" ws "8.5.0" -ethers@^6.12.0: - version "6.12.1" - resolved "https://registry.yarnpkg.com/ethers/-/ethers-6.12.1.tgz#517ff6d66d4fd5433e38e903051da3e57c87ff37" - integrity sha512-j6wcVoZf06nqEcBbDWkKg8Fp895SS96dSnTCjiXT+8vt2o02raTn4Lo9ERUuIVU5bAjoPYeA+7ytQFexFmLuVw== - dependencies: - "@adraffy/ens-normalize" "1.10.1" - "@noble/curves" "1.2.0" - "@noble/hashes" "1.3.2" - "@types/node" "18.15.13" - aes-js "4.0.0-beta.5" - tslib "2.4.0" - ws "8.5.0" - ethers@^6.9.2: version "6.10.0" resolved "https://registry.yarnpkg.com/ethers/-/ethers-6.10.0.tgz#20f3c63c60d59a993f8090ad423d8a3854b3b1cd" @@ -10861,15 +10708,6 @@ ffjavascript@0.2.63, ffjavascript@^0.2.45, ffjavascript@^0.2.48, ffjavascript@^0 wasmcurves "0.2.2" web-worker "1.2.0" -ffjavascript@0.3.0, ffjavascript@^0.3.0: - version "0.3.0" - resolved "https://registry.yarnpkg.com/ffjavascript/-/ffjavascript-0.3.0.tgz#442cd8fbb1ee4cbb1be9d26fd7b2951a1ea45d6a" - integrity sha512-l7sR5kmU3gRwDy8g0Z2tYBXy5ttmafRPFOqY7S6af5cq51JqJWt5eQ/lSR/rs2wQNbDYaYlQr5O+OSUf/oMLoQ== - dependencies: - wasmbuilder "0.0.16" - wasmcurves "0.2.2" - web-worker "1.2.0" - figures@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/figures/-/figures-2.0.0.tgz#3ab1a2d2a62c8bfb431a0c94cb797a2fce27c962" @@ -12178,55 +12016,6 @@ hardhat@^2.20.1: uuid "^8.3.2" ws "^7.4.6" -hardhat@^2.22.3: - version "2.22.3" - resolved "https://registry.yarnpkg.com/hardhat/-/hardhat-2.22.3.tgz#50605daca6b29862397e446c42ec14c89430bec3" - integrity sha512-k8JV2ECWNchD6ahkg2BR5wKVxY0OiKot7fuxiIpRK0frRqyOljcR2vKwgWSLw6YIeDcNNA4xybj7Og7NSxr2hA== - dependencies: - "@ethersproject/abi" "^5.1.2" - "@metamask/eth-sig-util" "^4.0.0" - "@nomicfoundation/edr" "^0.3.5" - "@nomicfoundation/ethereumjs-common" "4.0.4" - "@nomicfoundation/ethereumjs-tx" "5.0.4" - "@nomicfoundation/ethereumjs-util" "9.0.4" - "@nomicfoundation/solidity-analyzer" "^0.1.0" - "@sentry/node" "^5.18.1" - "@types/bn.js" "^5.1.0" - "@types/lru-cache" "^5.1.0" - adm-zip "^0.4.16" - aggregate-error "^3.0.0" - ansi-escapes "^4.3.0" - boxen "^5.1.2" - chalk "^2.4.2" - chokidar "^3.4.0" - ci-info "^2.0.0" - debug "^4.1.1" - enquirer "^2.3.0" - env-paths "^2.2.0" - ethereum-cryptography "^1.0.3" - 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.0.0-rc.12" - io-ts "1.10.4" - keccak "^3.0.2" - lodash "^4.17.11" - mnemonist "^0.38.0" - mocha "^10.0.0" - p-map "^4.0.0" - raw-body "^2.4.1" - resolve "1.17.0" - semver "^6.3.0" - solc "0.7.3" - source-map-support "^0.5.13" - stacktrace-parser "^0.1.10" - tsort "0.0.1" - undici "^5.14.0" - uuid "^8.3.2" - ws "^7.4.6" - has-ansi@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/has-ansi/-/has-ansi-2.0.0.tgz#34f5049ce1ecdf2b0649af3ef24e45ed35416d91" @@ -15128,19 +14917,6 @@ luxon@^3.1.1, luxon@^3.2.1: resolved "https://registry.yarnpkg.com/luxon/-/luxon-3.4.4.tgz#cf20dc27dc532ba41a169c43fdcc0063601577af" integrity sha512-zobTr7akeGHnv7eBOXcRgMeCP6+uyYsczwmeRCauvpvaAltgNyTbLH/+VaEAPUeWBT+1GuNmz4wC/6jtQzbbVA== -maci-circuits@0.0.0-ci.153326b: - version "0.0.0-ci.153326b" - resolved "https://registry.yarnpkg.com/maci-circuits/-/maci-circuits-0.0.0-ci.153326b.tgz#9958949f675b466c8f0fd7da4d12467012ca1dbb" - integrity sha512-9WYp1465Xelujo4GLpiLqgVdsia2VAl7FEpRMZOJeEJlbl8RUYLBTFlR9X9fBL3sNjoPNFSiswrVoCgmiQEi8A== - dependencies: - "@zk-kit/circuits" "^0.4.0" - circomkit "^0.1.0" - circomlib "^2.0.5" - maci-core "0.0.0-ci.153326b" - maci-crypto "0.0.0-ci.153326b" - maci-domainobjs "0.0.0-ci.153326b" - snarkjs "^0.7.4" - maci-circuits@^1.2.0: version "1.2.0" resolved "https://registry.yarnpkg.com/maci-circuits/-/maci-circuits-1.2.0.tgz#9b1f9c64d48e4dc3c3c7c8ffc4d0f254d60cce3e" @@ -15172,24 +14948,7 @@ maci-cli@^1.2.0: maci-domainobjs "^1.2.0" prompt "^1.3.0" -maci-contracts@0.0.0-ci.153326b: - version "0.0.0-ci.153326b" - resolved "https://registry.yarnpkg.com/maci-contracts/-/maci-contracts-0.0.0-ci.153326b.tgz#4c1d3cc1c5a89cbbe852439a1e81646e8b0dc302" - integrity sha512-DFo8xLR/Ia/CcSFXYjHfMCfaN/GnhNMxVgcRu1EQBY8DzWMs/MBHEYnH/LBpT/r5QscY0kyk45lMdKA24xHsFA== - dependencies: - "@nomicfoundation/hardhat-ethers" "^3.0.5" - "@nomicfoundation/hardhat-toolbox" "^5.0.0" - "@openzeppelin/contracts" "^5.0.2" - circomlibjs "^0.1.7" - ethers "^6.12.0" - hardhat "^2.22.3" - maci-circuits "0.0.0-ci.153326b" - maci-core "0.0.0-ci.153326b" - maci-crypto "0.0.0-ci.153326b" - maci-domainobjs "0.0.0-ci.153326b" - solidity-docgen "^0.6.0-beta.36" - -maci-contracts@^1.2.0: +maci-contracts@1.2.0, maci-contracts@^1.2.0: version "1.2.0" resolved "https://registry.yarnpkg.com/maci-contracts/-/maci-contracts-1.2.0.tgz#a724b3e757d2402442d822c34a5221660ef43b94" integrity sha512-zLYmGzBIBTygw7FiukK9nLNFnDdEWDmizuHruXFjpawCIwH+kzBsGImRy77Rn58SOe9XORdlGZOQckEGvaT4QQ== @@ -15206,14 +14965,6 @@ maci-contracts@^1.2.0: maci-domainobjs "^1.2.0" solidity-docgen "^0.6.0-beta.36" -maci-core@0.0.0-ci.153326b: - version "0.0.0-ci.153326b" - resolved "https://registry.yarnpkg.com/maci-core/-/maci-core-0.0.0-ci.153326b.tgz#08cb39ab66b2e528da319d64e2194c4b1c2fca01" - integrity sha512-lrkPm/gIcHbVO3+tuGnvNdc/Gy5jD0+5biG13RmdIfFiXnND0vD7aX5x45HY4mNK1TUrlS8ZMVHSjY4voeiieg== - dependencies: - maci-crypto "0.0.0-ci.153326b" - maci-domainobjs "0.0.0-ci.153326b" - maci-core@^1.2.0: version "1.2.0" resolved "https://registry.yarnpkg.com/maci-core/-/maci-core-1.2.0.tgz#57ff4b92c457f42a3043fe5b34cfef98a9ac1cf5" @@ -15222,17 +14973,7 @@ maci-core@^1.2.0: maci-crypto "^1.2.0" maci-domainobjs "^1.2.0" -maci-crypto@0.0.0-ci.153326b: - version "0.0.0-ci.153326b" - resolved "https://registry.yarnpkg.com/maci-crypto/-/maci-crypto-0.0.0-ci.153326b.tgz#4d0d2e72dd0aa6dba30d24e2c873729a5706bb8e" - integrity sha512-80QCpFdMts3rgfUn0fSQq0BFsuALOAYRH+MLWWDVTQXu1LtXZ4ikwq4DvD0ZuUDHjf9GgAmsQGQbi/Raa6q0bQ== - dependencies: - "@zk-kit/baby-jubjub" "^0.3.0" - "@zk-kit/eddsa-poseidon" "^0.11.0" - "@zk-kit/poseidon-cipher" "^0.3.0" - ethers "^6.12.0" - -maci-crypto@^1.2.0: +maci-crypto@1.2.0, maci-crypto@^1.2.0: version "1.2.0" resolved "https://registry.yarnpkg.com/maci-crypto/-/maci-crypto-1.2.0.tgz#b894810fa2ab379d93f77a2518f55abfe2f22dbe" integrity sha512-OOQvI+uDR0Q8wji9cbBqfDcwQgjoIIiv5r1pnne4ST15taxgMygep13rsA6UCU/A007rYBa93YAR3vnnBTnmrw== @@ -15242,14 +14983,7 @@ maci-crypto@^1.2.0: "@zk-kit/poseidon-cipher" "^0.2.1" ethers "^6.11.1" -maci-domainobjs@0.0.0-ci.153326b: - version "0.0.0-ci.153326b" - resolved "https://registry.yarnpkg.com/maci-domainobjs/-/maci-domainobjs-0.0.0-ci.153326b.tgz#546649c1b6e29748bc79c77b46081433a8d22876" - integrity sha512-utPsFPC6a6Q8LwtBqTQvzBOsUroprvFoCHy5sTRoRvKsSGLwTibkcYMzmxF5A+tnFJ4n9CKCrr6UF/6Mzc2dlw== - dependencies: - maci-crypto "0.0.0-ci.153326b" - -maci-domainobjs@^1.2.0: +maci-domainobjs@1.2.0, maci-domainobjs@^1.2.0: version "1.2.0" resolved "https://registry.yarnpkg.com/maci-domainobjs/-/maci-domainobjs-1.2.0.tgz#27a6a9e05b3712e54c48dd080dcfc0c1d6035f93" integrity sha512-9ItdA/EVSVqDMOD+Foe+OkDdj/LEfpwSAtXLCxG900TeAZpI486qiAbiJoI5sR8gnoRfSvwnZGJqiB+w0BPgSQ== @@ -18093,16 +17827,6 @@ r1csfile@0.0.47: fastfile "0.0.20" ffjavascript "0.2.60" -r1csfile@0.0.48: - version "0.0.48" - resolved "https://registry.yarnpkg.com/r1csfile/-/r1csfile-0.0.48.tgz#a317fc75407a9da92631666c75bdfc13f0a7835a" - integrity sha512-kHRkKUJNaor31l05f2+RFzvcH5XSa7OfEfd/l4hzjte6NL6fjRkSMfZ4BjySW9wmfdwPOtq3mXurzPvPGEf5Tw== - dependencies: - "@iden3/bigarray" "0.0.2" - "@iden3/binfileutils" "0.0.12" - fastfile "0.0.20" - ffjavascript "0.3.0" - rabin-wasm@~0.0.8: version "0.0.8" resolved "https://registry.yarnpkg.com/rabin-wasm/-/rabin-wasm-0.0.8.tgz#5b61b1d519d0377453435fbca5f82510b3f956cb" @@ -19356,22 +19080,6 @@ snarkjs@^0.7.0, snarkjs@^0.7.3: logplease "^1.2.15" r1csfile "0.0.47" -snarkjs@^0.7.4: - version "0.7.4" - resolved "https://registry.yarnpkg.com/snarkjs/-/snarkjs-0.7.4.tgz#b9ad5813f055ab84d33f1831a6f1f34a71b6cd46" - integrity sha512-x4cOCR4YXSyBlLtfnUUwfbZrw8wFd/Y0lk83eexJzKwZB8ELdpH+10ts8YtDsm2/a3WK7c7p514bbE8NpqxW8w== - dependencies: - "@iden3/binfileutils" "0.0.12" - bfj "^7.0.2" - blake2b-wasm "^2.4.0" - circom_runtime "0.1.25" - ejs "^3.1.6" - fastfile "0.0.20" - ffjavascript "0.3.0" - js-sha3 "^0.8.0" - logplease "^1.2.15" - r1csfile "0.0.48" - solc@0.7.3: version "0.7.3" resolved "https://registry.yarnpkg.com/solc/-/solc-0.7.3.tgz#04646961bd867a744f63d2b4e3c0701ffdc7d78a"