Skip to content

Commit

Permalink
convert hardhat tasks to cli to avoid error with extractVk
Browse files Browse the repository at this point in the history
  • Loading branch information
yuetloo committed Nov 27, 2023
1 parent 6fbe9be commit 9400e32
Show file tree
Hide file tree
Showing 34 changed files with 1,264 additions and 817 deletions.
4 changes: 2 additions & 2 deletions common/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -16,8 +16,8 @@
"dependencies": {
"@openzeppelin/merkle-tree": "^1.0.5",
"ethers": "^5.7.2",
"maci-crypto": "1.1.1",
"maci-domainobjs": "1.1.1"
"@clrfund/maci-crypto": "^1.1.7",
"@clrfund/maci-domainobjs": "^1.1.7"
},
"repository": {
"type": "git",
Expand Down
6 changes: 5 additions & 1 deletion common/src/keypair.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,9 @@
import { utils, BigNumber } from 'ethers'
import { Keypair as MaciKeypair, PrivKey, PubKey } from 'maci-domainobjs'
import {
Keypair as MaciKeypair,
PrivKey,
PubKey,
} from '@clrfund/maci-domainobjs'

const SNARK_FIELD_SIZE = BigInt(
'21888242871839275222246405745257275088548364400416034343698204186575808495617'
Expand Down
10 changes: 5 additions & 5 deletions common/src/utils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,8 @@ import {
hash5,
hash3,
hash2,
} from 'maci-crypto'
import { PubKey, PCommand, Message } from 'maci-domainobjs'
} from '@clrfund/maci-crypto'
import { PubKey, PCommand, Message } from '@clrfund/maci-domainobjs'
import { Keypair } from './keypair'
import { utils } from 'ethers'
import { Tally } from './tally'
Expand Down Expand Up @@ -99,7 +99,7 @@ export function getRecipientClaimData(
const spentProof: MerkleProof = spentTree.genMerklePath(recipientIndex)

const resultsCommitment = genTallyResultCommitment(
tally.results.tally.map((x) => BigInt(x)),
tally.results.tally.map(x => BigInt(x)),
BigInt(tally.results.salt),
recipientTreeDepth
)
Expand All @@ -112,7 +112,7 @@ export function getRecipientClaimData(
return [
recipientIndex,
spent,
spentProof.pathElements.map((x) => x.map((y) => y.toString())),
spentProof.pathElements.map(x => x.map(y => y.toString())),
spentSalt,
resultsCommitment,
spentVoiceCreditsCommitment,
Expand Down Expand Up @@ -150,7 +150,7 @@ export function genTallyResultCommitment(
for (const result of results) {
tree.insert(result)
}
return hashLeftRight(tree.root, salt).valueOf()
return hashLeftRight(tree.root, salt)
}

export {
Expand Down
63 changes: 63 additions & 0 deletions contracts/cli/addContributors.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
/**
* Add contributors for testing purposes
*
* Sample usage:
*
* HARDHAT_NETWORK=localhost yarn ts-node cli/addContributors.ts <clrfund address>
*
*/

import { program } from 'commander'
import { ethers } from 'hardhat'

program
.description('Add test contributors')
.argument('clrfund', 'The ClrFund contract address')
.parse()

async function main(args: any) {
const [
signer,
,
,
,
,
,
,
,
,
,
,
,
contributor1,
contributor2,
] = await ethers.getSigners()
console.log('Adding contributors by', signer.address)

const clrfundContract = await ethers.getContractAt('ClrFund', args[0], signer)
const userRegistryAddress = await clrfundContract.userRegistry()
console.log('User registry address', userRegistryAddress)

const userRegistry = await ethers.getContractAt(
'SimpleUserRegistry',
userRegistryAddress,
signer
)
const users = [contributor1, contributor2]
let addUserTx
for (const account of users) {
addUserTx = await userRegistry.addUser(account.getAddress())
addUserTx.wait()
}

console.log(`Added ${users.length} contributors`)
}

main(program.args)
.then(() => {
process.exit(0)
})
.catch(err => {
console.error(err)
process.exit(-1)
})
53 changes: 53 additions & 0 deletions contracts/cli/addRecipients.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
/**
* Add recipients for testing purposes
*
* Sample usage:
*
* HARDHAT_NETWORK=localhost yarn ts-node clr/addRecipients.ts <ClrFund address>
*
*/
import { program } from 'commander'
import { ethers } from 'hardhat'

program
.description('Add test recipients')
.argument('clrfund', 'The ClrFund contract address')
.parse()

async function main(args: any) {
const [signer, ...recipients] = await ethers.getSigners()
console.log('Add recipients by', signer.address)

const clrfundContract = await ethers.getContractAt('ClrFund', args[0], signer)
const recipientRegistryAddress = await clrfundContract.recipientRegistry()
console.log('Recipient registry', recipientRegistryAddress)

const recipientRegistry = await ethers.getContractAt(
'SimpleRecipientRegistry',
recipientRegistryAddress,
signer
)

for (let i = 6; i < 10; i++) {
const recipient = recipients[i]
const addRecipientTx = await recipientRegistry.addRecipient(
recipient.address,
JSON.stringify({
name: `recipient ${i}`,
description: `recipient ${i}`,
})
)
addRecipientTx.wait()
}

console.log('Added test recipients')
}

main(program.args)
.then(() => {
process.exit(0)
})
.catch(err => {
console.error(err)
process.exit(-1)
})
73 changes: 73 additions & 0 deletions contracts/cli/claim.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,73 @@
/**
* Claim funds. This script is mainly used by e2e testing
*
* Sample usage:
* HARDHAT_NETWORK=localhost yarn ts-node cli/claim.ts -f fundingRoundAddress -t tally-file
*/

import { getEventArg } from '../utils/contracts'
import { getRecipientClaimData } from '@clrfund/common'
import { JSONFile } from '../utils/JSONFile'
import { ethers } from 'hardhat'
import { program } from 'commander'
import { isPathExist } from '../utils/misc'

program
.description('Claim funnds for test recipients')
.requiredOption(
'-f --funding-round <fundingRoundAddress>',
'The funding round contract address'
)
.requiredOption('-t --tally-file <file>', 'The tally file')
.parse()

async function main(args: any) {
const { fundingRound, tallyFile } = args
const [, , recipient0, recipient1, recipient2] = await ethers.getSigners()

if (!isPathExist(tallyFile)) {
throw new Error(`Path ${tallyFile} does not exist`)
}

const tally = JSONFile.read(tallyFile)

const fundingRoundContract = await ethers.getContractAt(
'FundingRound',
fundingRound
)
const pollAddress = await fundingRoundContract.poll()
console.log('pollAddress', pollAddress)

const poll = await ethers.getContractAt('Poll', pollAddress)
const recipientTreeDepth = (await poll.treeDepths()).voteOptionTreeDepth

// Claim funds
const recipients = [recipient0, recipient1, recipient2]
for (const recipientIndex of [1, 2]) {
const recipientClaimData = getRecipientClaimData(
recipientIndex,
recipientTreeDepth,
tally
)
const fundingRoundAsRecipient = fundingRoundContract.connect(
recipients[recipientIndex]
)
const claimTx = await fundingRoundAsRecipient.claimFunds(
...recipientClaimData
)
const claimedAmount = await getEventArg(
claimTx,
fundingRoundAsRecipient,
'FundsClaimed',
'_amount'
)
console.log(`Recipient ${recipientIndex} claimed ${claimedAmount} tokens.`)
}
}

main(program.opts())
.then(() => process.exit(0))
.catch(error => {
console.error(error)
process.exit(1)
})
109 changes: 109 additions & 0 deletions contracts/cli/contribute.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,109 @@
/**
* Contribute to a funding round. This script is mainly used by e2e testing
* All the input used by the script comes from the state.json file
*
* Sample usage:
* HARDHAT_NETWORK=localhost yarn ts-node cli/contribute.ts <state file>
*/

import { JSONFile } from '../utils/JSONFile'
import { Keypair } from '@clrfund/common'

import { UNIT } from '../utils/constants'
import { getEventArg } from '../utils/contracts'
import { program } from 'commander'
import { ethers } from 'hardhat'
import { isPathExist } from '../utils/misc'

program
.description('Contribute to a funding round')
.argument('state-file', 'The file to store the state information')
.parse()

async function main(args: any) {
const [
,
,
,
,
,
,
,
,
,
,
,
,
contributor1,
contributor2,
] = await ethers.getSigners()

const stateFile = args[0]
if (!isPathExist(stateFile)) {
throw new Error(`File ${stateFile} not found`)
}

const state = JSONFile.read(stateFile)
const fundingRound = await ethers.getContractAt(
'FundingRound',
state.fundingRound
)
const tokenAddress = await fundingRound.nativeToken()
const token = await ethers.getContractAt('AnyOldERC20Token', tokenAddress)
const maciAddress = await fundingRound.maci()
const maci = await ethers.getContractAt('MACI', maciAddress)

const contributionAmount = UNIT.mul(16).div(10)

state.contributors = {}
for (const contributor of [contributor1, contributor2]) {
const contributorAddress = await contributor.getAddress()

// transfer token to contributor first
await token.transfer(contributorAddress, contributionAmount)

const contributorKeypair = new Keypair()
const tokenAsContributor = token.connect(contributor)
await tokenAsContributor.approve(fundingRound.address, contributionAmount)

const fundingRoundAsContributor = fundingRound.connect(contributor)
const contributionTx = await fundingRoundAsContributor.contribute(
contributorKeypair.pubKey.asContractParam(),
contributionAmount
)
const stateIndex = await getEventArg(
contributionTx,
maci,
'SignUp',
'_stateIndex'
)
const voiceCredits = await getEventArg(
contributionTx,
maci,
'SignUp',
'_voiceCreditBalance'
)
console.log('saving states')
state.contributors[contributorAddress] = {
privKey: contributorKeypair.privKey.serialize(),
pubKey: contributorKeypair.pubKey.serialize(),
stateIndex: parseInt(stateIndex),
voiceCredits: voiceCredits.toString(),
}
console.log(
`Contributor ${contributorAddress} registered. State index: ${stateIndex}. Voice credits: ${voiceCredits.toString()}.`
)
}

// Update state file
JSONFile.update(stateFile, state)
}

main(program.args)
.then(() => {
process.exit(0)
})
.catch(err => {
console.error(err)
process.exit(-1)
})
Loading

0 comments on commit 9400e32

Please sign in to comment.