diff --git a/contracts/contracts/ClrFund.sol b/contracts/contracts/ClrFund.sol index 45014b3cc..21a0a5bb2 100644 --- a/contracts/contracts/ClrFund.sol +++ b/contracts/contracts/ClrFund.sol @@ -87,17 +87,6 @@ contract ClrFund is OwnableUpgradeable, IPubKey, SnarkCommon, Params { recipientRegistry.setMaxRecipients(maxVoteOptions); } - /** - * @dev Set the Verifying Keys Registry - * @param _vkRegistry Address of the registry - */ - function setVkRegistry(VkRegistry _vkRegistry) - external - onlyOwner - { - maciFactory.setVkRegistry(_vkRegistry); - } - /** * @dev Add matching funds source. * @param _source Address of a funding source. @@ -128,20 +117,6 @@ contract ClrFund is OwnableUpgradeable, IPubKey, SnarkCommon, Params { emit FundingSourceRemoved(_source); } - function setMaciParameters( - uint8 stateTreeDepth, - TreeDepths calldata treeDepths, - MaxValues calldata maxValues, - uint256 messageBatchSize, - VerifyingKey calldata processVk, - VerifyingKey calldata tallyVk - ) - external - onlyCoordinator - { - maciFactory.setMaciParameters(stateTreeDepth, treeDepths, maxValues, messageBatchSize, processVk, tallyVk); - } - function getCurrentRound() public view @@ -167,9 +142,6 @@ contract ClrFund is OwnableUpgradeable, IPubKey, SnarkCommon, Params { requireRecipientRegistry requireUserRegistry { - if (maciFactory.owner() != address(this)) { - revert NotOwnerOfMaciFactory(); - } FundingRound currentRound = getCurrentRound(); if (address(currentRound) != address(0) && !currentRound.isFinalized()) { revert NotFinalized(); diff --git a/contracts/contracts/ClrFundDeployer.sol b/contracts/contracts/ClrFundDeployer.sol index 06dfd31e6..b7d2707a0 100644 --- a/contracts/contracts/ClrFundDeployer.sol +++ b/contracts/contracts/ClrFundDeployer.sol @@ -8,30 +8,24 @@ import {CloneFactory} from './CloneFactory.sol'; import {SignUpGatekeeper} from "@clrfund/maci-contracts/contracts/gatekeepers/SignUpGatekeeper.sol"; import {InitialVoiceCreditProxy} from "@clrfund/maci-contracts/contracts/initialVoiceCreditProxy/InitialVoiceCreditProxy.sol"; -contract ClrFundParams { - struct Templates { - address clrfund; - address pollFactory; - } -} +contract ClrFundDeployer is CloneFactory { -contract ClrFundDeployer is CloneFactory, ClrFundParams { - address public template; mapping (address => bool) public clrfunds; - uint clrId = 0; - ClrFund private clrfund; // funding factory contract - + constructor(address _template) { template = _template; } event NewInstance(address indexed clrfund); event Register(address indexed clrfund, string metadata); - + + // errors + error ClrFundAlreadyRegistered(); + function deployClrFund(MACIFactory _maciFactory) public returns (address) { - clrfund = ClrFund(createClone(template)); + ClrFund clrfund = ClrFund(createClone(template)); clrfund.init(_maciFactory); emit NewInstance(address(clrfund)); @@ -43,15 +37,11 @@ contract ClrFundDeployer is CloneFactory, ClrFundParams { string memory _metadata ) public returns (bool) { - clrfund = ClrFund(_clrFundAddress); - - require(clrfunds[_clrFundAddress] == false, 'ClrFund: metadata already registered'); + if (clrfunds[_clrFundAddress] == true) revert ClrFundAlreadyRegistered(); clrfunds[_clrFundAddress] = true; - clrId = clrId + 1; emit Register(_clrFundAddress, _metadata); return true; } - } diff --git a/contracts/contracts/FundingRound.sol b/contracts/contracts/FundingRound.sol index 33a6c9527..efc98c230 100644 --- a/contracts/contracts/FundingRound.sol +++ b/contracts/contracts/FundingRound.sol @@ -625,22 +625,19 @@ contract FundingRound is Ownable, SignUpGatekeeper, InitialVoiceCreditProxy, Dom revert VoteResultsAlreadyVerified(); } - { - (,,, uint8 voteOptionTreeDepth) = poll.treeDepths(); - bool resultVerified = tally.verifyTallyResult( - _voteOptionIndex, - _tallyResult, - _tallyResultProof, - _tallyResultSalt, - voteOptionTreeDepth, - _spentVoiceCreditsHash, - _perVOSpentVoiceCreditsHash - ); - + (,,, uint8 voteOptionTreeDepth) = poll.treeDepths(); + bool resultVerified = tally.verifyTallyResult( + _voteOptionIndex, + _tallyResult, + _tallyResultProof, + _tallyResultSalt, + voteOptionTreeDepth, + _spentVoiceCreditsHash, + _perVOSpentVoiceCreditsHash + ); - if (!resultVerified) { - revert IncorrectTallyResult(); - } + if (!resultVerified) { + revert IncorrectTallyResult(); } recipient.tallyVerified = true; diff --git a/contracts/contracts/MACIFactory.sol b/contracts/contracts/MACIFactory.sol index 8ffc30c5d..2f5e35983 100644 --- a/contracts/contracts/MACIFactory.sol +++ b/contracts/contracts/MACIFactory.sol @@ -109,7 +109,6 @@ contract MACIFactory is Ownable, Params, SnarkCommon, IPubKey { PubKey calldata coordinatorPubKey ) external - onlyOwner returns (MACI _maci) { if (!vkRegistry.hasProcessVk( diff --git a/contracts/e2e/index.ts b/contracts/e2e/index.ts index 47f549a3b..e6ead998a 100644 --- a/contracts/e2e/index.ts +++ b/contracts/e2e/index.ts @@ -9,7 +9,6 @@ import { genTallyResultCommitment } from '@clrfund/common' import { UNIT } from '../utils/constants' import { getEventArg } from '../utils/contracts' import { - deployVkRegistry, deployMaciFactory, deployContract, mergeMessages, @@ -230,8 +229,6 @@ describe('End-to-end Tests', function () { }) ) - await deployVkRegistry(deployer, maciFactory.address, params) - // Deploy new funding round and MACI const newRoundTx = await fundingRoundFactory.deployNewRound(roundDuration) maciTransactionHash = newRoundTx.hash diff --git a/contracts/tests/deployer.ts b/contracts/tests/deployer.ts index 6715ae596..e86b06356 100644 --- a/contracts/tests/deployer.ts +++ b/contracts/tests/deployer.ts @@ -18,16 +18,7 @@ import { MaciParameters } from '../utils/maci' use(solidity) const roundDuration = 10000 - -async function setMaciParameters( - clrfund: Contract, - signer: Signer, - circuit: string -): Promise { - const clrfundAsSigner = clrfund.connect(signer) - const params = MaciParameters.mock(circuit) - return clrfundAsSigner.setMaciParameters(...params.asContractParam()) -} +const circuit = 'micro' async function setRoundTally( clrfund: Contract, @@ -61,7 +52,6 @@ describe('Clr fund deployer', () => { let factory: Contract let clrFundDeployer: Contract let token: Contract - let maciParameters: MaciParameters const coordinatorPubKey = new Keypair().pubKey.asContractParam() let poseidonContracts: { [name: string]: string } @@ -70,7 +60,8 @@ describe('Clr fund deployer', () => { poseidonContracts = await deployPoseidonLibraries(deployer) } maciFactory = await deployMaciFactory(deployer, poseidonContracts) - maciParameters = await MaciParameters.mock('micro') + const params = MaciParameters.mock(circuit) + await maciFactory.setMaciParameters(...params.asContractParam()) factoryTemplate = await deployContractWithLinkedLibraries( deployer, @@ -104,8 +95,6 @@ describe('Clr fund deployer', () => { factory = await ethers.getContractAt('ClrFund', instanceAddress, deployer) - await maciFactory.transferOwnership(instanceAddress) - const SimpleUserRegistry = await ethers.getContractFactory( 'SimpleUserRegistry', deployer @@ -157,7 +146,7 @@ describe('Clr fund deployer', () => { factory.address, '{name:dead,title:beef}' ) - ).to.be.revertedWith('ClrFund: metadata already registered') + ).to.be.revertedWith('ClrFundAlreadyRegistered') }) it('initializes factory', async () => { @@ -201,13 +190,12 @@ describe('Clr fund deployer', () => { describe('changing recipient registry', () => { it('allows owner to set recipient registry', async () => { await factory.setCoordinator(coordinator.address, coordinatorPubKey) - await setMaciParameters(factory, coordinator, 'micro') await factory.setRecipientRegistry(recipientRegistry.address) expect(await factory.recipientRegistry()).to.equal( recipientRegistry.address ) expect(await recipientRegistry.controller()).to.equal(factory.address) - const params = MaciParameters.mock('micro') + const params = MaciParameters.mock(circuit) expect(await recipientRegistry.maxRecipients()).to.equal( 5 ** params.voteOptionTreeDepth ) @@ -291,35 +279,12 @@ describe('Clr fund deployer', () => { expect(await token.balanceOf(factory.address)).to.equal(contributionAmount) }) - it('sets MACI parameters', async () => { - const newMaciParameters = MaciParameters.mock('micro') - const factoryAsCoordinator = factory.connect(coordinator) - await factory.setCoordinator(coordinator.address, coordinatorPubKey) - - await expect( - factoryAsCoordinator.setMaciParameters( - ...newMaciParameters.asContractParam() - ) - ).to.emit(maciFactory, 'MaciParametersChanged') - const treeDepths = await maciFactory.treeDepths() - expect(treeDepths.voteOptionTreeDepth).to.equal( - newMaciParameters.voteOptionTreeDepth - ) - }) - - it('allows only coordinator to set MACI parameters', async () => { - await expect( - factory.setMaciParameters(...maciParameters.asContractParam()) - ).to.be.revertedWith('NotAuthorized') - }) - describe('deploying funding round', () => { it('deploys funding round', async () => { await factory.setUserRegistry(userRegistry.address) await factory.setRecipientRegistry(recipientRegistry.address) await factory.setToken(token.address) await factory.setCoordinator(coordinator.address, coordinatorPubKey) - await setMaciParameters(factory, coordinator, 'micro') const deployed = factory.deployNewRound(roundDuration) await expect(deployed).to.emit(factory, 'RoundStarted') const deployTx = await deployed @@ -362,7 +327,6 @@ describe('Clr fund deployer', () => { await factory.setRecipientRegistry(recipientRegistry.address) await factory.setToken(token.address) await factory.setCoordinator(coordinator.address, coordinatorPubKey) - await setMaciParameters(factory, coordinator, 'micro') await expect(factory.deployNewRound(roundDuration)).to.be.revertedWith( 'NoUserRegistry' @@ -373,7 +337,6 @@ describe('Clr fund deployer', () => { await factory.setUserRegistry(userRegistry.address) await factory.setToken(token.address) await factory.setCoordinator(coordinator.address, coordinatorPubKey) - await setMaciParameters(factory, coordinator, 'micro') await expect(factory.deployNewRound(roundDuration)).to.be.revertedWith( 'NoRecipientRegistry' @@ -384,7 +347,6 @@ describe('Clr fund deployer', () => { await factory.setUserRegistry(userRegistry.address) await factory.setRecipientRegistry(recipientRegistry.address) await factory.setCoordinator(coordinator.address, coordinatorPubKey) - await setMaciParameters(factory, coordinator, 'micro') await expect(factory.deployNewRound(roundDuration)).to.be.revertedWith( 'NoToken' @@ -405,7 +367,6 @@ describe('Clr fund deployer', () => { await factory.setRecipientRegistry(recipientRegistry.address) await factory.setToken(token.address) await factory.setCoordinator(coordinator.address, coordinatorPubKey) - await setMaciParameters(factory, coordinator, 'micro') await factory.deployNewRound(roundDuration) await expect(factory.deployNewRound(roundDuration)).to.be.revertedWith( @@ -418,7 +379,6 @@ describe('Clr fund deployer', () => { await factory.setRecipientRegistry(recipientRegistry.address) await factory.setToken(token.address) await factory.setCoordinator(coordinator.address, coordinatorPubKey) - await setMaciParameters(factory, coordinator, 'micro') await factory.deployNewRound(roundDuration) await factory.cancelCurrentRound() @@ -433,7 +393,6 @@ describe('Clr fund deployer', () => { await factory.setRecipientRegistry(recipientRegistry.address) await factory.setToken(token.address) await factory.setCoordinator(coordinator.address, coordinatorPubKey) - await setMaciParameters(factory, coordinator, 'micro') const factoryAsContributor = factory.connect(contributor) await expect( @@ -454,7 +413,6 @@ describe('Clr fund deployer', () => { await factory.setRecipientRegistry(recipientRegistry.address) await factory.setToken(token.address) await factory.setCoordinator(coordinator.address, coordinatorPubKey) - await setMaciParameters(factory, coordinator, 'micro') }) it('returns the amount of available matching funding', async () => { @@ -577,7 +535,6 @@ describe('Clr fund deployer', () => { await factory.setRecipientRegistry(recipientRegistry.address) await factory.setToken(token.address) await factory.setCoordinator(coordinator.address, coordinatorPubKey) - await setMaciParameters(factory, coordinator, 'micro') }) it('allows owner to cancel round', async () => { @@ -665,7 +622,6 @@ describe('Clr fund deployer', () => { await factory.setRecipientRegistry(recipientRegistry.address) await factory.setToken(token.address) await factory.setCoordinator(coordinator.address, coordinatorPubKey) - await setMaciParameters(factory, coordinator, 'micro') await factory.deployNewRound(roundDuration) const fundingRoundAddress = await factory.getCurrentRound() const fundingRound = await ethers.getContractAt( diff --git a/contracts/tests/maciFactory.ts b/contracts/tests/maciFactory.ts index 3191a2f06..b43a589bc 100644 --- a/contracts/tests/maciFactory.ts +++ b/contracts/tests/maciFactory.ts @@ -108,22 +108,22 @@ describe('MACI factory', () => { expect(await getGasUsage(deployTx)).lessThan(15094000) }) - it('allows only owner to deploy MACI', async () => { + it('allows anyone to deploy MACI', async () => { const setParamTx = await maciFactory.setMaciParameters( ...maciParameters.asContractParam() ) await setParamTx.wait() const coordinatorMaciFactory = maciFactory.connect(coordinator) - await expect( - coordinatorMaciFactory.deployMaci( - signUpGatekeeper.address, - initialVoiceCreditProxy.address, - topupContract.address, - duration, - coordinator.address, - coordinatorPubKey - ) - ).to.be.revertedWith('Ownable: caller is not the owner') + + const deployTx = await coordinatorMaciFactory.deployMaci( + signUpGatekeeper.address, + initialVoiceCreditProxy.address, + topupContract.address, + duration, + coordinator.address, + coordinatorPubKey + ) + await expect(deployTx).to.emit(maciFactory, 'MaciDeployed') }) it('links with PoseidonT3 correctly', async () => { diff --git a/contracts/utils/deployment.ts b/contracts/utils/deployment.ts index d622c3cf3..8c5ee48d8 100644 --- a/contracts/utils/deployment.ts +++ b/contracts/utils/deployment.ts @@ -11,7 +11,6 @@ import { import { readFileSync } from 'fs' import { MaciParameters } from './maci' -import { CIRCUTIS } from './circuits' const userRegistryNames: Record = { simple: 'SimpleUserRegistry', @@ -126,30 +125,6 @@ export async function deployContract( return await contract.deployed() } -export async function deployVkRegistry( - account: Signer, - owner: string, - params: MaciParameters -): Promise { - const vkRegistry = await deployContract(account, 'VkRegistry') - - const setKeyTx = await vkRegistry.setVerifyingKeys( - params.stateTreeDepth, - params.intStateTreeDepth, - params.messageTreeDepth, - params.voteOptionTreeDepth, - params.messageBatchSize, - params.processVk.asContractParam(), - params.tallyVk.asContractParam() - ) - await setKeyTx.wait() - - const ownerTx = await vkRegistry.transferOwnership(owner) - await ownerTx.wait() - - return vkRegistry -} - export async function deployMaciFactory( account: Signer, poseidonContracts: { [name: string]: string }