From 7d31cd8bc6d6bd20ab1b8237fd236cc48235c439 Mon Sep 17 00:00:00 2001 From: yuetloo Date: Wed, 24 Apr 2024 13:38:35 -0400 Subject: [PATCH 01/57] remove brightid sponsorship as sponsorship is done in the BrightID app now --- vue-app/src/locales/cn.json | 7 +-- vue-app/src/locales/en.json | 7 +-- vue-app/src/locales/es.json | 7 +-- vue-app/src/views/Verify.vue | 104 +---------------------------------- 4 files changed, 5 insertions(+), 120 deletions(-) diff --git a/vue-app/src/locales/cn.json b/vue-app/src/locales/cn.json index dbc945f34..63d63539e 100644 --- a/vue-app/src/locales/cn.json +++ b/vue-app/src/locales/cn.json @@ -803,15 +803,10 @@ "p7": "为了防止受贿和欺诈,您需要将您的钱包地址添加到智能合约注册表中。完成后,您就可以参加筹款活动了!", "btn": " 成为捐赠者", "next": "下一步", - "previous": "前一步", "copy_link": "复制", "verification_status": "您的钱包地址没有连接到 BrightID 的户口。 这可能需要几分钟的时间,稍等候后点击按钮再试。", "getting_proof": "正在获取验证证明...", - "not_authorized": "您没有权限注册", - "skip_sponsorship": "跳过", - "get_sponsored_header": "赞助", - "get_sponsored_text": "您需要一个赞助令牌才能为 BrightID 认证。这有助于支持 BrightID 作为去中心化平台。您只需这样做一次, 就可以应用任何 BrightID APPS。检查 BrightID 移动应用程序,看看您是否受到赞助。如果没有,请点击按钮提交赞助请求。如果您已受到赞助,您可跳过这一步。", - "get_sponsored_cta": "赞助" + "not_authorized": "您没有权限注册" }, "verifyLanding": { "h1": "证明您只使用一个帐户", diff --git a/vue-app/src/locales/en.json b/vue-app/src/locales/en.json index 3811acfbc..8462655d5 100644 --- a/vue-app/src/locales/en.json +++ b/vue-app/src/locales/en.json @@ -803,15 +803,10 @@ "p7": "To protect the round from bribery and fraud, you need to add your wallet address to a smart contract registry. Once you’re done, you can join the funding round!", "btn": " Become a contributor", "next": "Next", - "previous": "Previous", "copy_link": "Copy Link", "verification_status": "Your wallet address is not linked with BrightID. It may take a few minutes to verify the connection, please wait and click the button later to check the status.", "getting_proof": "Retrieving the verification proof...", - "not_authorized": "You are not authorized to register", - "skip_sponsorship": "Skip", - "get_sponsored_header": "Get sponsored", - "get_sponsored_text": "You need a sponsorship token to connect your wallet address with BrightID. This helps support BrightID as a decentralized platform. You’ll only ever need to do this once and it covers you for any other app that works with BrightID. Check the BrightID mobile app to see if you're sponsored. Get sponsored by submitting a sponsorship transaction or skip to the next step.", - "get_sponsored_cta": "Get Sponsored" + "not_authorized": "You are not authorized to register" }, "verifyLanding": { "h1": "Prove you’re only using one account", diff --git a/vue-app/src/locales/es.json b/vue-app/src/locales/es.json index ae103f13e..d76cba03a 100644 --- a/vue-app/src/locales/es.json +++ b/vue-app/src/locales/es.json @@ -803,15 +803,10 @@ "p7": "Para proteger la ronda de sobornos y fraudes, debes agregar la dirección de tu billetera a un registro de contrato inteligente. ¡Una vez que hayas terminado, puedes unirte a la ronda de financiamiento!", "btn": "Conviértete en colaborador", "next": "Siguiente", - "previous": "Anterior", "copy_link": "Copiar Enlace", "verification_status": "Tu dirección de billetera no está vinculada con BrightID. Puede tomar unos minutos verificar la conexión, por favor espera y haz clic en el botón más tarde para verificar el estado.", "getting_proof": "Recuperando la prueba de verificación...", - "not_authorized": "No está autorizado/a para registrarse", - "skip_sponsorship": "Saltar", - "get_sponsored_header": "Obtén un patrocinio", - "get_sponsored_text": "Necesitas un token de patrocinio para conectar tu dirección de billetera con BrightID. Esto ayuda a apoyar a BrightID como una plataforma descentralizada. Solo necesitarás hacer esto una vez y te cubrirá para cualquier otra aplicación que funcione con BrightID. Verifica en la aplicación móvil de BrightID si estás patrocinado. Obtén patrocinio al enviar una transacción de patrocinio o salta al siguiente paso.", - "get_sponsored_cta": "Obtener Patrocinio" + "not_authorized": "No está autorizado/a para registrarse" }, "verifyLanding": { "h1": "Demuestra que solo usas una cuenta", diff --git a/vue-app/src/views/Verify.vue b/vue-app/src/views/Verify.vue index c3ea80179..de2c99b65 100644 --- a/vue-app/src/views/Verify.vue +++ b/vue-app/src/views/Verify.vue @@ -56,30 +56,6 @@
-
-

{{ $t('verify.get_sponsored_header') }}

-

- {{ $t('verify.get_sponsored_text') }} -

-
-
-
- - -
-
{{ sponsorTxError }}
-
-
-

{{ $t('verify.h2_1') }}

@@ -88,16 +64,8 @@

{{ $t('verify.click_next') }}

- -
- +

{{ $t('verify.p4') }} @@ -124,14 +92,6 @@

- @@ -195,9 +155,7 @@ interface VerificationStep { function getVerificationSteps(): Array { switch (userRegistryType) { case UserRegistryType.BRIGHT_ID: - return brightIdSponsorUrl - ? [{ page: 'connect' }, { page: 'registration' }] - : [{ page: 'sponsorship' }, { page: 'connect' }, { page: 'registration' }] + return [{ page: 'connect' }, { page: 'registration' }] default: return [{ page: 'registration' }] } @@ -224,11 +182,7 @@ const registrationTxError = ref('') const notAuthorized = ref(false) const loadingTx = ref(false) const gettingProof = ref(false) -const isSponsoring = ref(!brightIdSponsorUrl) const showVerificationStatus = ref(false) -const autoSponsorError = ref('') -const sponsorTxError = ref('') -const selfSponsorTxHash = ref('') const brightId = computed(() => currentUser.value?.brightId) @@ -237,9 +191,6 @@ const currentStep = computed(() => { if (!brightId.value) { return 0 } - if (isSponsoring.value) { - return stepNumbers['sponsorship'] - } if (!brightId.value.isVerified) { return stepNumbers['connect'] } @@ -255,19 +206,6 @@ const currentPage = computed(() => { return steps[currentStep.value].page }) -// if the sponsor url is not defined, we are doing self sponsorship, show the button -// to allow users to go back to that page -const showBackToSponsorshipButton = !brightIdSponsorUrl - -function backToSponsorship() { - isSponsoring.value = true - showVerificationStatus.value = false -} - -function skipSponsorship() { - isSponsoring.value = false -} - async function checkVerificationStatus() { showVerificationStatus.value = false await userStore.loadBrightID() @@ -295,24 +233,8 @@ onMounted(async () => { // mounted if (isBrightIdRequired && currentUser.value && !brightId.value?.isVerified) { const walletAddress = currentUser.value.walletAddress - // send sponsorship request if automatic sponsoring is enabled - if (brightIdSponsorUrl) { - try { - const res = await sponsorUser(walletAddress) - if (!res.hash) { - autoSponsorError.value = res.error ? res.error : JSON.stringify(res) - return - } - } catch (err) { - const errorMessage = (err as Error).message - autoSponsorError.value = - 'Unable to sponsor user. Make sure the brightId node is setup correctly.' + errorMessage - return - } - } // Present app link and QR code - appLink.value = getBrightIdUniversalLink(walletAddress) const qrcodeLink = getBrightIdLink(walletAddress) QRCode.toDataURL(qrcodeLink, (error, url: string) => { @@ -329,26 +251,6 @@ watch(currentUser, () => { } }) -async function selfSponsorAndWait() { - if (!userRegistryAddress.value) { - sponsorTxError.value = 'Missing the user registry address' - return - } - - const signer = await userStore.getSigner() - loadingTx.value = true - sponsorTxError.value = '' - - try { - await waitForTransaction(selfSponsor(userRegistryAddress.value, signer), hash => (selfSponsorTxHash.value = hash)) - isSponsoring.value = false - } catch (error) { - sponsorTxError.value = (error as Error).message - } finally { - loadingTx.value = false - } -} - async function register() { const signer = await userStore.getSigner() @@ -418,8 +320,6 @@ function isStepUnlocked(step: number): boolean { const stepName = steps[step].page switch (stepName) { - case 'sponsorship': - return !isSponsoring.value case 'connect': return !!currentUser.value?.brightId?.isVerified case 'registration': From 45fe06d61d63bdbaa66d81e3e940bf102192957d Mon Sep 17 00:00:00 2001 From: yuetloo Date: Wed, 24 Apr 2024 15:07:59 -0400 Subject: [PATCH 02/57] remove brightid sponsorship logic --- contracts/deploy-config-example.json | 8 +- .../tasks/subtasks/user/03-brightidSponsor.ts | 62 ------ .../subtasks/user/04-brightidUserRegistry.ts | 14 +- vue-app/.env.example | 9 - vue-app/src/api/bright-id.ts | 177 +----------------- vue-app/src/api/core.ts | 4 +- vue-app/src/lambda/sponsor.mts | 137 -------------- vue-app/src/views/Verify.vue | 6 +- 8 files changed, 11 insertions(+), 406 deletions(-) delete mode 100644 contracts/tasks/subtasks/user/03-brightidSponsor.ts delete mode 100644 vue-app/src/lambda/sponsor.mts diff --git a/contracts/deploy-config-example.json b/contracts/deploy-config-example.json index 77032cfed..4fbcc8441 100644 --- a/contracts/deploy-config-example.json +++ b/contracts/deploy-config-example.json @@ -16,11 +16,6 @@ "OptimisticRecipientRegistry": { "challengePeriodSeconds": 9007199254740990, "deposit": "0.001" - }, - "BrightIdUserRegistry": { - "deploy": false, - "context": "clrfund-arbitrum-goerli", - "verifier": "0xdbf0b2ee9887fe11934789644096028ed3febe9c" } }, "arbitrum-sepolia": { @@ -43,8 +38,7 @@ }, "BrightIdUserRegistry": { "context": "clrfund-arbitrum-goerli", - "verifier": "0xdbf0b2ee9887fe11934789644096028ed3febe9c", - "sponsor": "0xC7c81634Dac2de4E7f2Ba407B638ff003ce4534C" + "verifier": "0xdbf0b2ee9887fe11934789644096028ed3febe9c" } } } diff --git a/contracts/tasks/subtasks/user/03-brightidSponsor.ts b/contracts/tasks/subtasks/user/03-brightidSponsor.ts deleted file mode 100644 index 9482a449e..000000000 --- a/contracts/tasks/subtasks/user/03-brightidSponsor.ts +++ /dev/null @@ -1,62 +0,0 @@ -/** - * Deploy an instance of the BrightID sponsor contract - * - */ -import { ContractStorage } from '../../helpers/ContractStorage' -import { Subtask } from '../../helpers/Subtask' -import { EContracts } from '../../../utils/types' - -const subtask = Subtask.getInstance() -const storage = ContractStorage.getInstance() - -/** - * Deploy step registration and task itself - */ -subtask - .addTask('user:deploy-brightid-sponsor', 'Deploy BrightID sponsor contract') - .setAction(async (_, hre) => { - subtask.setHre(hre) - const deployer = await subtask.getDeployer() - - const userRegistryName = subtask.getConfigField( - EContracts.ClrFund, - 'userRegistry' - ) - - if (userRegistryName !== EContracts.BrightIdUserRegistry) { - return - } - - let brightidSponsorContractAddress = subtask.tryGetConfigField( - EContracts.BrightIdUserRegistry, - 'sponsor' - ) - - if (brightidSponsorContractAddress) { - console.log( - `Skip BrightIdSponsor deployment, use ${brightidSponsorContractAddress}` - ) - return - } - - brightidSponsorContractAddress = storage.getAddress( - EContracts.BrightIdSponsor, - hre.network.name - ) - - if (brightidSponsorContractAddress) { - return - } - - const BrightIdSponsorContract = await subtask.deployContract( - EContracts.BrightIdSponsor, - { signer: deployer } - ) - - await storage.register({ - id: EContracts.BrightIdSponsor, - contract: BrightIdSponsorContract, - args: [], - network: hre.network.name, - }) - }) diff --git a/contracts/tasks/subtasks/user/04-brightidUserRegistry.ts b/contracts/tasks/subtasks/user/04-brightidUserRegistry.ts index 6db98dc2c..73f1ce259 100644 --- a/contracts/tasks/subtasks/user/04-brightidUserRegistry.ts +++ b/contracts/tasks/subtasks/user/04-brightidUserRegistry.ts @@ -10,6 +10,10 @@ import { EContracts } from '../../../utils/types' const subtask = Subtask.getInstance() const storage = ContractStorage.getInstance() +// @TODO remove this on the next major release when the sponsor contract is removed +// Hardcode with a dummy address for now +const BRIGHTID_SPONSOR = '0xC7c81634Dac2de4E7f2Ba407B638ff003ce4534C' + /** * Deploy step registration and task itself */ @@ -58,15 +62,7 @@ subtask 'verifier' ) - let sponsor = subtask.tryGetConfigField( - EContracts.BrightIdUserRegistry, - 'sponsor' - ) - if (!sponsor) { - sponsor = storage.mustGetAddress(EContracts.BrightIdSponsor, network) - } - - const args = [encodeBytes32String(context), verifier, sponsor] + const args = [encodeBytes32String(context), verifier, BRIGHTID_SPONSOR] const brightidUserRegistryContract = await subtask.deployContract( EContracts.BrightIdUserRegistry, { signer: deployer, args } diff --git a/vue-app/.env.example b/vue-app/.env.example index b7a9357e4..d0a44456f 100644 --- a/vue-app/.env.example +++ b/vue-app/.env.example @@ -28,20 +28,11 @@ VITE_USER_REGISTRY_TYPE=simple VITE_BRIGHTID_CONTEXT=clrfund-goerli -# These are for interacting with the BrightID api. When the SPONSOR_API_URL and one of the -# SPONSOR_KEY is set, a sponsor request will be sent to the BrightID node when the QR code -# to link users wallet address to BrightID is displayed. SPONSOR_KEY is used to sign the -# sponsor request. The SPONSOR_KEY_FOR_NETLIFY will trigger the netlify serverless function -# to send the sponsor request. The SPONSOR_KEY alone will send the request directly from -# the web app without using the netlify function. # VITE_BRIGHTID_NODE_URL is the BrightID node used to query BrightID status. It needs to # match the BRIGHTID_VERIFIER_ADDR defined in the contract .env file. This address is used # to verify the signature returned from the BrightID verification status for user registration. # The BRIGHTID_VERIFIER_ADDR value is the ethSigningAddress from the node url, # e.g. https://brightid.clr.fund -#VITE_BRIGHTID_SPONSOR_KEY_FOR_NETLIFY= -#VITE_BRIGHTID_SPONSOR_KEY= -#VITE_BRIGHTID_SPONSOR_API_URL=https://brightid.clr.fund/brightid/v6/operations # BrightId node one url, default to clrfund node at https://brightid.clr.fund/brightid/v6 #VITE_BRIGHTID_NODE_URL=https://app.brightid.org/node/v6 diff --git a/vue-app/src/api/bright-id.ts b/vue-app/src/api/bright-id.ts index 0aba9a8ad..10330c6fe 100644 --- a/vue-app/src/api/bright-id.ts +++ b/vue-app/src/api/bright-id.ts @@ -2,7 +2,7 @@ import { Contract, encodeBytes32String, toUtf8Bytes, decodeBase64, encodeBase64 import type { TransactionResponse, Signer } from 'ethers' import { BrightIdUserRegistry } from './abi' -import { brightIdSponsorKey, brightIdNodeUrl } from './core' +import { brightIdNodeUrl } from './core' import nacl from 'tweetnacl' const BRIGHTID_APP_URL = 'https://app.brightid.org' @@ -44,55 +44,6 @@ export interface Verification { app: string } -export interface Sponsorship { - timestamp: number - app: string - appHasAuthorized: boolean - spendRequested: boolean -} - -type AppData = { - id: string - name: string - context?: string - verification: string - verifications?: string[] - verificationsUrl: string - logo?: string - url?: string - assignedSponsorships?: number - unusedSponsorships?: number - testing?: boolean - idAsHex?: boolean - usingBlindSig?: boolean - verificationExpirationLength?: number - sponsorPublicKey?: string - nodeUrl?: string - soulbound: boolean - callbackUrl?: string -} - -type SponsorOperation = { - name: string - app: string - appUserId: string - timestamp: number - v: number - sig?: string -} - -type SponsorData = { - hash?: string - error?: string -} - -export async function selfSponsor(registryAddress: string, signer: Signer): Promise { - const registry = new Contract(registryAddress, BrightIdUserRegistry, signer) - const userAddress = await signer.getAddress() - const transaction = await registry.sponsor(userAddress) - return transaction -} - // This link is for generating QR code export function getBrightIdLink(userAddress: string): string { const deepLink = `brightid://link-verification/${CONTEXT}/${userAddress}` @@ -166,129 +117,3 @@ export async function getBrightId(contextId: string): Promise { } return brightId } - -/** - * Get the unused sponsorship amount - * @param context - the context to retrieve unused sponsorships for - * - * @returns Returns the number of sponsorships available to the specified `context` - */ -async function unusedSponsorships(context: string): Promise { - const endpoint = `${NODE_URL}/apps/${context}` - const response = await fetch(endpoint) - const json = await response.json() - - if (json['errorMessage']) { - throw new Error(JSON.stringify(json)) - } - - const data = json['data'] as AppData - return data.unusedSponsorships || 0 -} - -/** - * Call the BrightID sponsor operation endpoint to put a sponsorship request for the user - * @param userAddress user wallet address - * @returns sponsporship result or error - */ -export async function brightIdSponsor(userAddress: string): Promise { - const endpoint = `${NODE_URL}/operations` - - if (!brightIdSponsorKey) { - return { error: 'BrightId sponsor key not set' } - } - - const sponsorships = await unusedSponsorships(CONTEXT) - if (typeof sponsorships === 'number' && sponsorships < 1) { - return { error: 'BrightID sponsorships not available' } - } - - if (typeof sponsorships !== 'number') { - return { error: 'Invalid BrightID sponsorship' } - } - - const timestamp = Date.now() - - // these fields must be in alphabetical because - // BrightID nodes use 'fast-json-stable-stringify' that sorts fields - const op: SponsorOperation = { - app: CONTEXT, - appUserId: userAddress, - name: 'Sponsor', - timestamp, - v: 6, - } - - const message = JSON.stringify(op) - const arrayedMessage = toUtf8Bytes(message) - const arrayedKey = decodeBase64(brightIdSponsorKey) - const signature = nacl.sign.detached(arrayedMessage, arrayedKey) - op.sig = encodeBase64(signature) - - const res = await fetch(endpoint, { - method: 'POST', - headers: { - 'Content-Type': 'application/json', - }, - body: JSON.stringify(op), - }) - const json = await res.json() - - if (json['error']) { - if (canIgnoreError(json.errorNum)) { - // sponsorship already sent recently, ignore this error - return { hash: '0x0' } - } - return { error: json['errorMessage'] } - } else { - return json['data'] - } -} - -/** - * Call the netlify function to invoke the BrightId sponsor api - * @param userAddress user wallet address - * @returns sponsorship data or error - */ -async function netlifySponsor(userAddress: string): Promise { - const res = await fetch('/.netlify/functions/sponsor', { - method: 'POST', - headers: { - 'Content-Type': 'application/json', - }, - body: JSON.stringify({ userAddress }), - }) - - const json = await res.json() - if (res.status === 200) { - return json - } - - if (res.status === 400 && canIgnoreError(json.errorNum)) { - return { hash: '0x0' } - } - - // return the error - return json -} - -/** - * Sponsor a BrightID user using the sponsorship api - * @param userAddress user wallet address - * @returns sponsporship result or error - */ -export async function sponsorUser(userAddress: string): Promise { - if (brightIdSponsorKey) { - return brightIdSponsor(userAddress) - } - - try { - return await netlifySponsor(userAddress) - } catch (err) { - if (err instanceof Error) { - return { error: (err as Error).message } - } else { - return { error: 'Unknown sponsorhip error' } - } - } -} diff --git a/vue-app/src/api/core.ts b/vue-app/src/api/core.ts index 5caa704c6..f120af12f 100644 --- a/vue-app/src/api/core.ts +++ b/vue-app/src/api/core.ts @@ -72,10 +72,8 @@ export const maxDecimals = Number(import.meta.env.VUE_APP_MAX_DECIMAL || 1) // the number of records per batch in the `pending submissions` export file export const exportBatchSize = Number(import.meta.env.VITE_EXPORT_BATCH_SIZE) || 60 -// BrightId sponsorhip stuff, set these parameters to automatically sponsor user using the brightId URL -export const brightIdSponsorKey = import.meta.env.VITE_BRIGHTID_SPONSOR_KEY +// BrightId url for querying user verification export const brightIdNodeUrl = import.meta.env.VITE_BRIGHTID_NODE_URL || 'https://brightid.clr.fund/brightid/v6' -export const brightIdSponsorUrl = import.meta.env.VITE_BRIGHTID_SPONSOR_API_URL // wait for data to sync with the subgraph export const MAX_WAIT_DEPTH = Number(import.meta.env.VITE_MAX_WAIT_DEPTH) || 15 diff --git a/vue-app/src/lambda/sponsor.mts b/vue-app/src/lambda/sponsor.mts deleted file mode 100644 index 5d460e17a..000000000 --- a/vue-app/src/lambda/sponsor.mts +++ /dev/null @@ -1,137 +0,0 @@ -import { decodeBase64, encodeBase64, toUtf8Bytes } from 'ethers' -import nacl from 'tweetnacl' -import type { Handler } from '@netlify/functions' - -const NODE_URL = process.env.VITE_BRIGHTID_NODE_URL || 'https://app.brightid.org/node/v6' - -// these fields must be in alphabetical because -// BrightID nodes use 'fast-json-stable-stringify' that sorts fields -type BrightIDMessage = { - app: string - appUserId: string - name: string - sig?: string - timestamp: number - v: number -} - -/** - * Returns an error object - * @param errorMessage error message - * @returns error object - */ -function makeError(errorMessage: string, errorNum: number) { - const body = JSON.stringify({ error: errorMessage, errorNum }) - return { statusCode: 400, body } -} - -/** - * Returns the result with statusCode and body - * @param result the result - * @returns result object - */ -function makeResult(result: any) { - const body = JSON.stringify(result) - return { statusCode: 200, body } -} - -/** - * Get the unused sponsorship amount - * @param context - the context to retrieve unused sponsorships for - * - * @returns the number of sponsorships available to the specified `context` - */ -async function unusedSponsorships(context: string) { - const endpoint = `${NODE_URL}/apps/${context}` - const response = await fetch(endpoint) - const json = await response.json() - - if (json['errorMessage']) { - throw new Error(JSON.stringify(json)) - } - - const data = json['data'] - return data.unusedSponsorships || 0 -} - -async function handleSponsorRequest(userAddress: string) { - const endpoint = process.env.VITE_BRIGHTID_SPONSOR_API_URL - if (!endpoint) { - throw new Error('Environment variable VITE_BRIGHTID_SPONSOR_API_URL not set') - } - - const brightIdSponsorKey = process.env.VITE_BRIGHTID_SPONSOR_KEY_FOR_NETLIFY - if (!brightIdSponsorKey) { - throw new Error('Environment variable VITE_BRIGHTID_SPONSOR_KEY_FOR_NETLIFY not set') - } - - const CONTEXT = process.env.VITE_BRIGHTID_CONTEXT - if (!CONTEXT) { - throw new Error('Environment variable VITE_BRIGHTID_CONTEXT not set') - } - - const sponsorships = await unusedSponsorships(CONTEXT) - if (typeof sponsorships === 'number' && sponsorships < 1) { - throw new Error('BrightID sponsorships not available') - } - if (typeof sponsorships !== 'number') { - throw new Error('Invalid BrightID sponsorship') - } - - const timestamp = Date.now() - - const op: BrightIDMessage = { - app: CONTEXT, - appUserId: userAddress, - name: 'Sponsor', - timestamp, - v: 6, - } - - const message = JSON.stringify(op) - const arrayedMessage = toUtf8Bytes(message) - const arrayedKey = decodeBase64(brightIdSponsorKey) - const signature = nacl.sign.detached(arrayedMessage, arrayedKey) - op.sig = encodeBase64(signature) - - const res = await fetch(endpoint, { - method: 'POST', - headers: { - 'Content-Type': 'application/json', - }, - body: JSON.stringify(op), - }) - const json = await res.json() - - if (json.error) { - return makeError(json.errorMessage, json.errorNum) - } - - if (json.data) { - return makeResult({ hash: json.data.hash }) - } - - return makeError('Unexpected result from the BrightID sponsorship API.', 500) -} - -/** - * Submit a sponsorship request using the BrightID api - * @param event contains user address to sponsor - * @returns sponsor data or error - */ -export const handler: Handler = async event => { - if (!event.body) { - return makeError('Missing request body', 400) - } - - try { - const jsonBody = JSON.parse(event.body) - if (!jsonBody.userAddress) { - return makeError('Missing userAddress in request body: ' + event.body, 400) - } - - return await handleSponsorRequest(jsonBody.userAddress) - } catch (err) { - return makeError(err.message, 500) - } -} diff --git a/vue-app/src/views/Verify.vue b/vue-app/src/views/Verify.vue index de2c99b65..9fa25f2f6 100644 --- a/vue-app/src/views/Verify.vue +++ b/vue-app/src/views/Verify.vue @@ -136,7 +136,7 @@ import { ref, computed, onMounted, watch } from 'vue' import ProgressBar from '@/components/ProgressBar.vue' import QRCode from 'qrcode' -import { getBrightIdLink, getBrightIdUniversalLink, registerUser, selfSponsor, sponsorUser } from '@/api/bright-id' +import { getBrightIdLink, getBrightIdUniversalLink, registerUser } from '@/api/bright-id' import { getProofSnapshot, getProofMerkle, registerUserSnapshot, registerUserMerkle } from '@/api/user' import Transaction from '@/components/Transaction.vue' import Loader from '@/components/Loader.vue' @@ -145,11 +145,11 @@ import { waitForTransaction } from '@/utils/contracts' import { useAppStore, useUserStore } from '@/stores' import { storeToRefs } from 'pinia' import { useRouter } from 'vue-router' -import { UserRegistryType, isBrightIdRequired, brightIdSponsorUrl, userRegistryType } from '@/api/core' +import { UserRegistryType, isBrightIdRequired, userRegistryType } from '@/api/core' import { assert } from '@/utils/assert' interface VerificationStep { - page: 'connect' | 'registration' | 'sponsorship' + page: 'connect' | 'registration' } function getVerificationSteps(): Array { From c638d80e3582615829c2c2e407929f93f634a252 Mon Sep 17 00:00:00 2001 From: yuetloo Date: Wed, 24 Apr 2024 15:09:47 -0400 Subject: [PATCH 03/57] fix missing duration error --- contracts/sh/deployLocal.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/contracts/sh/deployLocal.sh b/contracts/sh/deployLocal.sh index d0c1aac73..0c48ffe01 100755 --- a/contracts/sh/deployLocal.sh +++ b/contracts/sh/deployLocal.sh @@ -26,4 +26,4 @@ export COORDINATOR_MACISK=$(echo "${MACI_KEYPAIR}" | grep -o "macisk.*$") yarn hardhat new-clrfund --network ${NETWORK} # deploy a new funding round -yarn hardhat new-round --network ${NETWORK} +yarn hardhat new-round --network ${NETWORK} --round-duration 3600 From 9dafeb63d58b9541e2a6e70aff15719da299cebe Mon Sep 17 00:00:00 2001 From: yuetloo Date: Wed, 24 Apr 2024 19:10:37 -0400 Subject: [PATCH 04/57] remove goerli and add sepolia --- vue-app/src/utils/chains.ts | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/vue-app/src/utils/chains.ts b/vue-app/src/utils/chains.ts index b84942d8b..acab4ecfe 100644 --- a/vue-app/src/utils/chains.ts +++ b/vue-app/src/utils/chains.ts @@ -1,6 +1,6 @@ export enum ChainId { MAINNET = 1, - GOERLI = 5, + SEPOLIA = 11155111, HARDHAT = 31337, ARBITRUM_ONE = 42161, ARBITRUM_RINKEBY = 421611, @@ -36,12 +36,12 @@ export const CHAIN_INFO: ChainInfo = { explorerLogo: 'etherscan.svg', explorerLabel: 'Etherscan', }, - [ChainId.GOERLI]: { - label: 'Goerli', + [ChainId.SEPOLIA]: { + label: 'Sepolia', currency: 'ETH', logo: 'eth.svg', isLayer2: false, - explorer: 'https://goerli.etherscan.io', + explorer: 'https://sepolia.etherscan.io', explorerLogo: 'etherscan.svg', explorerLabel: 'Etherscan', }, From 7b097b04608520c91a00766c82ccb181f13ee397 Mon Sep 17 00:00:00 2001 From: yuetloo Date: Wed, 24 Apr 2024 19:30:06 -0400 Subject: [PATCH 05/57] remove BrightId sponsorship instructions --- docs/brightid.md | 39 ++++++++++----------------------------- docs/deployment.md | 9 --------- 2 files changed, 10 insertions(+), 38 deletions(-) diff --git a/docs/brightid.md b/docs/brightid.md index efd01636d..0b03aa3e3 100644 --- a/docs/brightid.md +++ b/docs/brightid.md @@ -18,13 +18,13 @@ USER_REGISTRY_TYPE=brightid Available envs: -| Network/Env | Context | Sponsor Contract | -| ----------- | ------- | ---------------- | -| arbitrum | clrfund-arbitrum |0x669A55Dd17a2f9F4dacC37C7eeB5Ed3e13f474f9| -| arbitrum rinkeby | clrfund-arbitrum-rinkeby | 0xC7c81634Dac2de4E7f2Ba407B638ff003ce4534C | -| arbitrum sepolia | clrfund-arbitrum-goerli | 0xF1ef516dEa7e6Dd334996726D58029Ee9bAD081D | -| goerli | clrfund-goerli | 0xF045234A776C87060DEEc5689056455A24a59c08 | -| xdai | clrfund-gnosischain |0x669A55Dd17a2f9F4dacC37C7eeB5Ed3e13f474f9| +| Network/Env | Context | +| ----------- | ------- | +| arbitrum | clrfund-arbitrum | +| arbitrum rinkeby | clrfund-arbitrum-rinkeby | +| arbitrum sepolia | clrfund-arbitrum-goerli | +| goerli | clrfund-goerli | +| xdai | clrfund-gnosischain | ```.sh # /vue-app/.env @@ -35,7 +35,6 @@ BRIGHTID_CONTEXT={CONTEXT} ``` Note: the BrightID context is specific to the BrightID network - it's independent from the Ethereum network you choose to run the app on. It refers to the BrightID app context where you want to burn sponsorship tokens. -The `Sponsor Contract` is the contract set up in the BrightID node to track the sponsorship event. The BrightID context can be found here: https://apps.brightid.org/#nodes @@ -55,27 +54,9 @@ BRIGHTID_VERIFIER_ADDR=0xdbf0b2ee9887fe11934789644096028ed3febe9c By default, the clrfund app will connect to the BrightId node run by clrfund, https://brightid.clr.fund. -**#4 configure the BrightID sponsorship page** -By default, the clrfund app will sponsor the BrightId users using the smart contract event logging method. The `Sponsor` contract is listed in the step #2 above. - -Alternatively, you can configure the clrfund app to use the BrightId sponsorship api to submit the sponsorship request directly by setting the following environment variables. Only one of VITE_BRIGHTID_SPONSOR_KEY_FOR_NETLIFY or VITE_BRIGHTID_SPONSOR_KEY needs to be set. If VITE_BRIGHTID_SPONSOR_KEY_FOR_NETLIFY is set, the clrfund app must be deployed to the netlify platform as it will use the netlify serverless function. The netlify option is used if you want to protect the BrightId sponsor key. - -The BrightId sponsor key can be generated using the random Nacl keypair at [https://tweetnacl.js.org/#/sign](https://tweetnacl.js.org/#/sign). Give the public key part to the BrightId folks to setup the context and put the private key part in VITE_BRIGHTID_SPONSOR_KEY or VITE_BRIGHTID_SPONSOR_KEY_FOR_NETLIFY. - -```.sh -# /vue-app/.env -VITE_BRIGHTID_SPONSOR_API_URL=https://brightid.clr.fund/brightid/v6/operations -VITE_BRIGHTID_SPONSOR_KEY_FOR_NETLIFY= -VITE_BRIGHTID_SPONSOR_KEY= -``` - -**#5 netlify function setup** -See the [deployment guide](./deploymnet.md) for special setup to use the sponsor netlify function. - ## Troubleshooting linking failure -### Sponsorship timeout -1. check for sponsorship status https://app.brightid.org/node/v6/sponsorships/WALLET_ADDRESS -2. check for sponsorship status from clrfund's brightid node: +### General linking error +1. check for sponsorship status from clrfund's brightid node: - https://brightid.clr.fund/brightid/v6/sponsorships/WALLET_ADDRESS 3. check the clrfund's brightid node docker logs - look for sponsorship event listening error @@ -86,7 +67,7 @@ See the [deployment guide](./deploymnet.md) for special setup to use the sponsor - for clrfund-arbitrum context: https://brightid.clr.fund/brightid/v6/apps/clrfund-arbitrum ### Signature is not valid 1. Check that the verifier address is correct, it is the `ethSigningAddress` from https://brightid.clr.fund -2. You can update the verifier address using `sponsorContract.setSettings()` +2. You can update the verifier address using `BrightIdUserRegistryContract.setSettings()` ## Resources diff --git a/docs/deployment.md b/docs/deployment.md index 4ddb0ccc1..56ffb6368 100644 --- a/docs/deployment.md +++ b/docs/deployment.md @@ -24,13 +24,6 @@ Note: select the `hex address (ONLY)` option to identify users and the `meet` ve Once the app is registered, you will get an appId which will be set to `BRIGHTID_CONTEXT` when deploying the contracts in later steps. -### Setup BrightID sponsorship keys - -1. Generate sponsorship signing keys here: https://tweetnacl.js.org/#/sign -2. Provide the public key to BrightID support through their discord channel: https://discord.gg/QW7ThZ5K4V -3. Save the private key for setting up the clrfund user interface in environment variable: `VITE_BRIGHTID_SPONSOR_KEY` - - ## Deploy Contracts Goto the `contracts` folder. @@ -161,8 +154,6 @@ VITE_SUBGRAPH_URL= VITE_CLRFUND_ADDRESS= VITE_USER_REGISTRY_TYPE= VITE_BRIGHTID_CONTEXT= -VITE_BRIGHTID_SPONSOR_KEY= -VITE_BRIGHTID_SPONSOR_API_URL=https://brightid.clr.fund/brightid/v6/operations VITE_RECIPIENT_REGISTRY_TYPE= # see google-sheets.md for instruction on how to set these From f04320de3eae26345c3d38144d58de9e855d4a25 Mon Sep 17 00:00:00 2001 From: yuetloo Date: Wed, 24 Apr 2024 19:37:47 -0400 Subject: [PATCH 06/57] update numbering --- docs/brightid.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/docs/brightid.md b/docs/brightid.md index 0b03aa3e3..5c84d799e 100644 --- a/docs/brightid.md +++ b/docs/brightid.md @@ -58,12 +58,12 @@ By default, the clrfund app will connect to the BrightId node run by clrfund, ht ### General linking error 1. check for sponsorship status from clrfund's brightid node: - https://brightid.clr.fund/brightid/v6/sponsorships/WALLET_ADDRESS -3. check the clrfund's brightid node docker logs +2. check the clrfund's brightid node docker logs - look for sponsorship event listening error ```.sh docker logs --since 1440m brightid-node-docker-db-1 ``` -4. check for sponsorship token balance +3. check for sponsorship token balance - for clrfund-arbitrum context: https://brightid.clr.fund/brightid/v6/apps/clrfund-arbitrum ### Signature is not valid 1. Check that the verifier address is correct, it is the `ethSigningAddress` from https://brightid.clr.fund From 6a845566f060115dd949114592dc94b05fc4a711 Mon Sep 17 00:00:00 2001 From: yuetloo Date: Wed, 24 Apr 2024 19:39:30 -0400 Subject: [PATCH 07/57] remove special netlify lambda settings --- docs/deployment.md | 4 ---- vue-app/.env.example | 3 --- 2 files changed, 7 deletions(-) diff --git a/docs/deployment.md b/docs/deployment.md index 56ffb6368..284076f84 100644 --- a/docs/deployment.md +++ b/docs/deployment.md @@ -168,10 +168,6 @@ VITE_GOOGLE_SPREADSHEET_ID= See [How to set netlify function directory](https://docs.netlify.com/functions/optional-configuration/?fn-language=ts) -2. Set environment variable: `AWS_LAMBDA_JS_RUNTIME=nodejs18.x` - -This environment variable is needed for the `sponsor.js` function. If not set, it will throw error `fetch not found`. - #### Deploy on IPFS diff --git a/vue-app/.env.example b/vue-app/.env.example index d0a44456f..be1b3b535 100644 --- a/vue-app/.env.example +++ b/vue-app/.env.example @@ -66,9 +66,6 @@ GOOGLE_SHEET_NAME= # the number of record to export in a pending submissions JSON file. Default 60. VITE_EXPORT_BATCH_SIZE= -# This is only used for netlify function, sponsor.js, to avoid getting the 'fetch not found' error -AWS_LAMBDA_JS_RUNTIME=nodejs18.x - # walletconnect project id VITE_WALLET_CONNECT_PROJECT_ID=walletconnect_project_id From d5bf85984dccbf4c7451078d85dc39b0b58ffaae Mon Sep 17 00:00:00 2001 From: yuetloo Date: Wed, 24 Apr 2024 22:47:34 -0400 Subject: [PATCH 08/57] do not show verify page if using semaphore user registry --- vue-app/src/api/core.ts | 7 ++++++- vue-app/src/components/CallToActionCard.vue | 4 ++-- vue-app/src/components/Cart.vue | 6 ++---- 3 files changed, 10 insertions(+), 7 deletions(-) diff --git a/vue-app/src/api/core.ts b/vue-app/src/api/core.ts index 5caa704c6..6d79b2785 100644 --- a/vue-app/src/api/core.ts +++ b/vue-app/src/api/core.ts @@ -45,6 +45,7 @@ export enum UserRegistryType { SIMPLE = 'simple', SNAPSHOT = 'snapshot', MERKLE = 'merkle', + SEMAPHORE = 'semaphore', } if (!Object.values(UserRegistryType).includes(userRegistryType as UserRegistryType)) { @@ -92,7 +93,11 @@ export const showComplianceRequirement = /^yes$/i.test(import.meta.env.VITE_SHOW export const isBrightIdRequired = userRegistryType === 'brightid' export const isOptimisticRecipientRegistry = recipientRegistryType === 'optimistic' -export const isUserRegistrationRequired = userRegistryType !== UserRegistryType.SIMPLE +export const isUserRegistrationRequired = [ + UserRegistryType.BRIGHT_ID, + UserRegistryType.MERKLE, + UserRegistryType.SNAPSHOT, +].includes(userRegistryType) // Try to get the next scheduled start date const nextStartDate = import.meta.env.VITE_NEXT_ROUND_START_DATE diff --git a/vue-app/src/components/CallToActionCard.vue b/vue-app/src/components/CallToActionCard.vue index 7d094a1a6..2d29121d7 100644 --- a/vue-app/src/components/CallToActionCard.vue +++ b/vue-app/src/components/CallToActionCard.vue @@ -55,7 +55,7 @@ import { computed } from 'vue' import BrightIdWidget from '@/components/BrightIdWidget.vue' import Links from '@/components/Links.vue' -import { userRegistryType, UserRegistryType, isBrightIdRequired } from '@/api/core' +import { isUserRegistrationRequired, isBrightIdRequired } from '@/api/core' import { useAppStore, useUserStore } from '@/stores' import { storeToRefs } from 'pinia' @@ -69,7 +69,7 @@ const hasStartedVerification = computed( ) const showUserVerification = computed(() => { return ( - userRegistryType !== UserRegistryType.SIMPLE && + isUserRegistrationRequired && currentRound.value && currentUser.value?.isRegistered !== undefined && !currentUser.value.isRegistered diff --git a/vue-app/src/components/Cart.vue b/vue-app/src/components/Cart.vue index cb10c454a..605a766fc 100644 --- a/vue-app/src/components/Cart.vue +++ b/vue-app/src/components/Cart.vue @@ -237,7 +237,7 @@ import CartItems from '@/components/CartItems.vue' import Links from '@/components/Links.vue' import TimeLeft from '@/components/TimeLeft.vue' import { MAX_CONTRIBUTION_AMOUNT, MAX_CART_SIZE, type CartItem, isContributionAmountValid } from '@/api/contributions' -import { userRegistryType, UserRegistryType, operator } from '@/api/core' +import { userRegistryType, UserRegistryType, operator, isUserRegistrationRequired } from '@/api/core' import { RoundStatus } from '@/api/round' import { formatAmount as _formatAmount } from '@/utils/amounts' import FundsNeededWarning from '@/components/FundsNeededWarning.vue' @@ -477,9 +477,7 @@ const isBrightIdRequired = computed( () => userRegistryType === UserRegistryType.BRIGHT_ID && !currentUser.value?.isRegistered, ) -const isRegistrationRequired = computed( - () => userRegistryType !== UserRegistryType.SIMPLE && !currentUser.value?.isRegistered, -) +const isRegistrationRequired = computed(() => isUserRegistrationRequired && !currentUser.value?.isRegistered) const errorMessage = computed(() => { if (isMessageLimitReached.value) return t('dynamic.cart.error.reached_contribution_limit') From e4d8d20cf841d958d2b0279d02ae74c06f085326 Mon Sep 17 00:00:00 2001 From: yuetloo Date: Wed, 24 Apr 2024 22:57:04 -0400 Subject: [PATCH 09/57] add sepolia and remove goerli --- contracts/hardhat.config.ts | 7 ++----- vue-app/src/utils/chains.ts | 8 ++++---- 2 files changed, 6 insertions(+), 9 deletions(-) diff --git a/contracts/hardhat.config.ts b/contracts/hardhat.config.ts index e9fcb6931..470029275 100644 --- a/contracts/hardhat.config.ts +++ b/contracts/hardhat.config.ts @@ -39,7 +39,7 @@ export default { url: 'http://127.0.0.1:8555', gasLimit: GAS_LIMIT, } as any, - goerli: { + sepolia: { url: process.env.JSONRPC_HTTP_URL || 'http://127.0.0.1:8545', accounts, }, @@ -67,10 +67,6 @@ export default { url: process.env.JSONRPC_HTTP_URL || 'https://sepolia.optimism.io', accounts, }, - sepolia: { - url: process.env.JSONRPC_HTTP_URL || 'http://127.0.0.1:8545', - accounts, - }, 'mantle-testnet': { url: process.env.JSONRPC_HTTP_URL || 'https://rpc.testnet.mantle.xyz', accounts, @@ -89,6 +85,7 @@ export default { process.env.OPTIMISMSCAN_API_KEY || 'YOUR_OPTIMISMSCAN_API_KEY', 'optimism-sepolia': process.env.OPTIMISMSCAN_API_KEY || 'YOUR_OPTIMISMSCAN_API_KEY', + sepolia: process.env.ETHERSCAN_API_KEY || 'YOUR_ETHERSCAN_API_KEY', }, customChains: [ { diff --git a/vue-app/src/utils/chains.ts b/vue-app/src/utils/chains.ts index b84942d8b..acab4ecfe 100644 --- a/vue-app/src/utils/chains.ts +++ b/vue-app/src/utils/chains.ts @@ -1,6 +1,6 @@ export enum ChainId { MAINNET = 1, - GOERLI = 5, + SEPOLIA = 11155111, HARDHAT = 31337, ARBITRUM_ONE = 42161, ARBITRUM_RINKEBY = 421611, @@ -36,12 +36,12 @@ export const CHAIN_INFO: ChainInfo = { explorerLogo: 'etherscan.svg', explorerLabel: 'Etherscan', }, - [ChainId.GOERLI]: { - label: 'Goerli', + [ChainId.SEPOLIA]: { + label: 'Sepolia', currency: 'ETH', logo: 'eth.svg', isLayer2: false, - explorer: 'https://goerli.etherscan.io', + explorer: 'https://sepolia.etherscan.io', explorerLogo: 'etherscan.svg', explorerLabel: 'Etherscan', }, From 5102e77acd377c82ba7d73bbc1ae0f4f0aba21ec Mon Sep 17 00:00:00 2001 From: yuetloo Date: Wed, 24 Apr 2024 23:17:38 -0400 Subject: [PATCH 10/57] handle user not registered case for semaphore user registry --- vue-app/src/components/Cart.vue | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/vue-app/src/components/Cart.vue b/vue-app/src/components/Cart.vue index 605a766fc..1e0301d38 100644 --- a/vue-app/src/components/Cart.vue +++ b/vue-app/src/components/Cart.vue @@ -484,9 +484,9 @@ const errorMessage = computed(() => { if (!currentUser.value) return t('dynamic.cart.error.connect_wallet') if (isBrightIdRequired.value) return t('dynamic.cart.error.need_to_setup_brightid') if (!currentUser.value.isRegistered) { - return userRegistryType === UserRegistryType.SIMPLE - ? t('dynamic.cart.error.user_not_registered', { operator }) - : t('dynamic.cart.error.need_to_register') + return isUserRegistrationRequired + ? t('dynamic.cart.error.need_to_register') + : t('dynamic.cart.error.user_not_registered', { operator }) } if (!isFormValid()) return t('dynamic.cart.error.invalid_contribution_amount') if (cart.value.length > MAX_CART_SIZE) From 08dc551507cc95fc57f38a03433f399822794f90 Mon Sep 17 00:00:00 2001 From: yuetloo Date: Wed, 24 Apr 2024 23:21:05 -0400 Subject: [PATCH 11/57] add semaphore user registry --- vue-app/.env.example | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/vue-app/.env.example b/vue-app/.env.example index b7a9357e4..26689edf3 100644 --- a/vue-app/.env.example +++ b/vue-app/.env.example @@ -21,7 +21,7 @@ VITE_SUBGRAPH_URL=http://localhost:8000/subgraphs/name/clrfund/clrfund VITE_CLRFUND_ADDRESS=0x0DCd1Bf9A1b36cE34237eEaFef220932846BCD82 -# Supported values: simple, brightid, snapshot, merkle +# Supported values: simple, brightid, snapshot, merkle, semaphore VITE_USER_REGISTRY_TYPE=simple # clr.fund (prod) or CLRFundTest (testing) # Learn more about BrightID and context in /docs/brightid.md From ef12b74f3cb36a9b4da9f7fcfd0fc055232e0342 Mon Sep 17 00:00:00 2001 From: yuetloo Date: Mon, 6 May 2024 14:25:06 -0400 Subject: [PATCH 12/57] use maci 0.0.0-ci.153326b: do not allow invalid pub key --- common/package.json | 4 +- contracts/package.json | 4 +- yarn.lock | 294 ++++++++++++++++++++++++++++++++++++++++- 3 files changed, 297 insertions(+), 5 deletions(-) diff --git a/common/package.json b/common/package.json index ee496d949..bd7caa4fb 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": "^1.2.0", - "maci-domainobjs": "^1.2.0" + "maci-crypto": "0.0.0-ci.153326b", + "maci-domainobjs": "0.0.0-ci.153326b" }, "repository": { "type": "git", diff --git a/contracts/package.json b/contracts/package.json index 94bb91a88..4498c8aba 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": "^1.2.0", + "maci-contracts": "0.0.0-ci.153326b", "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": "^1.2.0", + "maci-domainobjs": "0.0.0-ci.153326b", "mocha": "^10.2.0", "solidity-coverage": "^0.8.1", "ts-node": "^10.9.2", diff --git a/yarn.lock b/yarn.lock index 86e13a1f9..10adf18a4 100644 --- a/yarn.lock +++ b/yarn.lock @@ -1912,6 +1912,14 @@ 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" @@ -2674,6 +2682,54 @@ "@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" @@ -2974,6 +3030,11 @@ 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" @@ -3282,6 +3343,11 @@ 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" @@ -4963,6 +5029,20 @@ 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" @@ -4970,6 +5050,22 @@ 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" @@ -4986,11 +5082,38 @@ "@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" @@ -6896,7 +7019,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.1, buffer@^6.0.3: +"buffer-polyfill@npm:buffer@^6.0.3", 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" @@ -7407,6 +7530,13 @@ 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" @@ -7431,6 +7561,16 @@ 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" @@ -10182,6 +10322,19 @@ 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" @@ -10708,6 +10861,15 @@ 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" @@ -12016,6 +12178,55 @@ 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" @@ -14917,6 +15128,19 @@ 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" @@ -14948,6 +15172,23 @@ 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: version "1.2.0" resolved "https://registry.yarnpkg.com/maci-contracts/-/maci-contracts-1.2.0.tgz#a724b3e757d2402442d822c34a5221660ef43b94" @@ -14965,6 +15206,14 @@ 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" @@ -14973,6 +15222,16 @@ 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: version "1.2.0" resolved "https://registry.yarnpkg.com/maci-crypto/-/maci-crypto-1.2.0.tgz#b894810fa2ab379d93f77a2518f55abfe2f22dbe" @@ -14983,6 +15242,13 @@ 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: version "1.2.0" resolved "https://registry.yarnpkg.com/maci-domainobjs/-/maci-domainobjs-1.2.0.tgz#27a6a9e05b3712e54c48dd080dcfc0c1d6035f93" @@ -17827,6 +18093,16 @@ 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" @@ -19080,6 +19356,22 @@ 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" From 3969baca810a1e84643a40d3a4efc4a950a2526a Mon Sep 17 00:00:00 2001 From: yuetloo Date: Thu, 9 May 2024 10:52:11 -0400 Subject: [PATCH 13/57] verify validity of public key using babyjubjub function --- common/package.json | 4 +- contracts/contracts/maci/BabyJubJub.sol | 136 ++++++++ contracts/contracts/maci/Poll.sol | 286 +++++++++++++++++ contracts/contracts/maci/PollFactory.sol | 73 +++++ contracts/e2e/index.ts | 14 +- contracts/package.json | 4 +- .../tasks/helpers/ConstructorArguments.ts | 8 +- contracts/tasks/runners/claim.ts | 9 +- contracts/tasks/runners/contribute.ts | 7 +- contracts/tasks/runners/finalize.ts | 7 +- .../tasks/runners/publishTallyResults.ts | 12 +- contracts/tests/deployer.ts | 14 +- contracts/tests/round.ts | 10 +- contracts/utils/contracts.ts | 44 ++- yarn.lock | 300 +----------------- 15 files changed, 607 insertions(+), 321 deletions(-) create mode 100644 contracts/contracts/maci/BabyJubJub.sol create mode 100644 contracts/contracts/maci/Poll.sol create mode 100644 contracts/contracts/maci/PollFactory.sol 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" From bcdd62cb96b926355d6b4453420c9257485f9eda Mon Sep 17 00:00:00 2001 From: yuetloo Date: Thu, 9 May 2024 12:50:57 -0400 Subject: [PATCH 14/57] use qualified contract name --- contracts/tasks/helpers/Subtask.ts | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/contracts/tasks/helpers/Subtask.ts b/contracts/tasks/helpers/Subtask.ts index 089cf06d6..06eed8015 100644 --- a/contracts/tasks/helpers/Subtask.ts +++ b/contracts/tasks/helpers/Subtask.ts @@ -18,7 +18,7 @@ import type { HardhatRuntimeEnvironment, } from 'hardhat/types' -import { deployContract } from '../../utils/contracts' +import { deployContract, getQualifiedContractName } from '../../utils/contracts' import { EContracts } from '../../utils/types' import { ContractStorage } from './ContractStorage' import { @@ -527,7 +527,8 @@ export class Subtask { const contractAddress = address || this.storage.mustGetAddress(name, this.hre.network.name) - const { abi } = await this.hre.artifacts.readArtifact(name.toString()) + const qualifiedName = getQualifiedContractName(name) + const { abi } = await this.hre.artifacts.readArtifact(qualifiedName) return new BaseContract(contractAddress, abi, deployer) as T } From 4e3d72ae9bc79325d5d3d7d95ec9b2b951fbe346 Mon Sep 17 00:00:00 2001 From: GitHub Actions Bot <> Date: Thu, 9 May 2024 16:56:42 +0000 Subject: [PATCH 15/57] v5.2.0 --- contracts/package.json | 2 +- subgraph/package.json | 2 +- vue-app/package.json | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/contracts/package.json b/contracts/package.json index 94bb91a88..90e5f730c 100644 --- a/contracts/package.json +++ b/contracts/package.json @@ -1,6 +1,6 @@ { "name": "@clrfund/contracts", - "version": "5.1.1", + "version": "5.2.0", "license": "GPL-3.0", "scripts": { "hardhat": "hardhat", diff --git a/subgraph/package.json b/subgraph/package.json index e764fefc9..8efc48965 100644 --- a/subgraph/package.json +++ b/subgraph/package.json @@ -1,6 +1,6 @@ { "name": "@clrfund/subgraph", - "version": "5.1.1", + "version": "5.2.0", "repository": "https://github.com/clrfund/monorepo/subgraph", "keywords": [ "clr.fund", diff --git a/vue-app/package.json b/vue-app/package.json index 1c7267fbd..48e8b4efc 100644 --- a/vue-app/package.json +++ b/vue-app/package.json @@ -1,6 +1,6 @@ { "name": "@clrfund/vue-app", - "version": "5.1.1", + "version": "5.2.0", "private": true, "license": "GPL-3.0", "type": "module", From 2ff9b0b1de19393a1c21887056f95e9441414724 Mon Sep 17 00:00:00 2001 From: yuetloo Date: Thu, 9 May 2024 13:21:00 -0400 Subject: [PATCH 16/57] use qualified name for Poll --- contracts/tasks/runners/exportRound.ts | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/contracts/tasks/runners/exportRound.ts b/contracts/tasks/runners/exportRound.ts index fa3e332b1..27be1e51b 100644 --- a/contracts/tasks/runners/exportRound.ts +++ b/contracts/tasks/runners/exportRound.ts @@ -14,12 +14,14 @@ import { task, types } from 'hardhat/config' import { Contract, formatUnits, getNumber } from 'ethers' import { Ipfs } from '../../utils/ipfs' -import { Project, Round, RoundFileContent } from '../../utils/types' +import { EContracts, Project, Round, RoundFileContent } from '../../utils/types' import { RecipientRegistryLogProcessor } from '../../utils/RecipientRegistryLogProcessor' import { getRecipientAddressAbi, MaciV0Abi } from '../../utils/abi' import { JSONFile } from '../../utils/JSONFile' import path from 'path' import fs from 'fs' +import { getContractAt } from '../../utils/contracts' +import { Poll } from '../../typechain-types' type RoundListEntry = { network: string @@ -216,7 +218,11 @@ async function getRoundInfo( try { if (pollAddress) { - const pollContract = await ethers.getContractAt('Poll', pollAddress) + const pollContract = await getContractAt( + EContracts.Poll, + pollAddress, + ethers + ) const [roundStartTime, roundDuration] = await pollContract.getDeployTimeAndDuration() startTime = getNumber(roundStartTime) From e78fc12adb2bf1a768272fcc1fc63c2a011444bd Mon Sep 17 00:00:00 2001 From: yuetloo Date: Thu, 9 May 2024 13:24:30 -0400 Subject: [PATCH 17/57] make script maci-pubkey available --- contracts/tasks/index.ts | 1 + 1 file changed, 1 insertion(+) diff --git a/contracts/tasks/index.ts b/contracts/tasks/index.ts index 59f1c9699..b25d56890 100644 --- a/contracts/tasks/index.ts +++ b/contracts/tasks/index.ts @@ -28,3 +28,4 @@ import './runners/genProofs' import './runners/proveOnChain' import './runners/publishTallyResults' import './runners/resetTally' +import './runners/maciPubkey' From 6bbd012dd4c6082a5ee8c778ca680285b69992cd Mon Sep 17 00:00:00 2001 From: yuetloo Date: Fri, 10 May 2024 11:09:44 -0400 Subject: [PATCH 18/57] validate key using the serialize function --- common/src/keypair.ts | 41 +++++++++++++++++++---------------------- 1 file changed, 19 insertions(+), 22 deletions(-) diff --git a/common/src/keypair.ts b/common/src/keypair.ts index 8e02ab52f..649ef4b9f 100644 --- a/common/src/keypair.ts +++ b/common/src/keypair.ts @@ -1,37 +1,34 @@ import { keccak256, isBytesLike, concat, toBeArray } from 'ethers' import { Keypair as MaciKeypair, PrivKey, PubKey } from 'maci-domainobjs' -const SNARK_FIELD_SIZE = BigInt( - '21888242871839275222246405745257275088548364400416034343698204186575808495617' -) - /** - * Returns a BabyJub-compatible value. This function is modified from - * the MACI's genRandomBabyJubValue(). Instead of returning random value - * for the private key, it derives the private key from the users - * signature hash + * Derives the MACI private key from the users signature hash * @param hash - user's signature hash + * @return The MACI private key */ function genPrivKey(hash: string): PrivKey { - // Prevent modulo bias - //const lim = BigInt('0x10000000000000000000000000000000000000000000000000000000000000000') - //const min = (lim - SNARK_FIELD_SIZE) % SNARK_FIELD_SIZE - const min = BigInt( - '6350874878119819312338956282401532410528162663560392320966563075034087161851' - ) - if (!isBytesLike(hash)) { - throw new Error(`Hash must be a hex string: ${hash}`) + throw new Error(`genPrivKey() error. Hash must be a hex string: ${hash}`) } - let hashBN = BigInt(hash) - // don't think we'll enter the for loop below, but, just in case - for (let counter = 1; hashBN < min; counter++) { - const data = concat([toBeArray(hashBN), toBeArray(counter)]) - hashBN = BigInt(keccak256(data)) + let rawPrivKey = BigInt(hash) + let pubKey: PubKey | null = null + + for (let counter = 1; pubKey === null; counter++) { + try { + const privKey = new PrivKey(rawPrivKey) + const keypair = new Keypair(privKey) + + // this will throw 'Invalid public key' if key is not on the Baby Jubjub elliptic curve + keypair.pubKey.serialize() + + pubKey = keypair.pubKey + } catch { + const data = concat([toBeArray(rawPrivKey), toBeArray(counter)]) + rawPrivKey = BigInt(keccak256(data)) + } } - const rawPrivKey = hashBN % SNARK_FIELD_SIZE return new PrivKey(rawPrivKey) } From 0ff9b2b7cd212e004867ab1b82448fd4b621aaff Mon Sep 17 00:00:00 2001 From: yuetloo Date: Mon, 13 May 2024 12:31:48 -0400 Subject: [PATCH 19/57] add test for common package --- common/src/__tests__/keypair.spec.ts | 20 ++++++++++++++++++++ 1 file changed, 20 insertions(+) create mode 100644 common/src/__tests__/keypair.spec.ts diff --git a/common/src/__tests__/keypair.spec.ts b/common/src/__tests__/keypair.spec.ts new file mode 100644 index 000000000..47f1cba72 --- /dev/null +++ b/common/src/__tests__/keypair.spec.ts @@ -0,0 +1,20 @@ +import { expect } from 'chai' +import { Keypair, PubKey } from '../keypair' +import { Wallet, sha256, randomBytes } from 'ethers' + +describe.only('keypair', function () { + for (let i = 0; i < 10; i++) { + it(`should generate key ${i} from seed successfully`, function () { + const wallet = Wallet.createRandom() + const signature = wallet.signMessageSync(randomBytes(32).toString()) + const seed = sha256(signature) + const keypair = Keypair.createFromSeed(seed) + expect(keypair.pubKey.serialize()).to.match(/^macipk./) + }) + } + + it('should throw if pubKey is invalid', () => { + const pubKey = new PubKey([1n, 1n]) + expect(() => pubKey.serialize()).to.throw('Invalid public key') + }) +}) From b031c8edde8e2ff5b57698e9f45291160cce91be Mon Sep 17 00:00:00 2001 From: yuetloo Date: Mon, 13 May 2024 12:32:50 -0400 Subject: [PATCH 20/57] add test common to pre push script --- .husky/pre-push | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.husky/pre-push b/.husky/pre-push index c0bc1da1c..c0d892312 100755 --- a/.husky/pre-push +++ b/.husky/pre-push @@ -11,4 +11,4 @@ export VITE_RECIPIENT_REGISTRY_TYPE=simple export VITE_USER_REGISTRY_TYPE=simple export VITE_WALLET_CONNECT_PROJECT_ID=1 -yarn test:format && yarn test:web && yarn test:lint-i18n +yarn test:format && yarn test:common && yarn test:web && yarn test:lint-i18n From 2f980e27122ca016b7a98e0b61bdb5e7e44277bd Mon Sep 17 00:00:00 2001 From: yuetloo Date: Mon, 13 May 2024 12:55:49 -0400 Subject: [PATCH 21/57] add test:common script --- package.json | 1 + 1 file changed, 1 insertion(+) diff --git a/package.json b/package.json index 072d15e02..0ae9648b6 100644 --- a/package.json +++ b/package.json @@ -42,6 +42,7 @@ "test:contracts": "yarn workspace @clrfund/contracts run test", "test:e2e": "yarn workspace @clrfund/contracts run e2e", "test:web": "yarn workspace @clrfund/vue-app run test", + "test:common": "yarn workspace @clrfund/common run test", "test:format": "yarn prettier --check", "test:lint-i18n": "echo yarn workspace @clrfund/vue-app run test:lint-i18n --ci", "deploy:subgraph": "yarn workspace @clrfund/subgraph run deploy", From 37247636510834661947c4c7b9581a6d5a01b8bb Mon Sep 17 00:00:00 2001 From: yuetloo Date: Mon, 13 May 2024 12:56:02 -0400 Subject: [PATCH 22/57] fix contract verification error --- contracts/tasks/helpers/ConstructorArguments.ts | 5 +++-- contracts/utils/contracts.ts | 8 +++----- 2 files changed, 6 insertions(+), 7 deletions(-) diff --git a/contracts/tasks/helpers/ConstructorArguments.ts b/contracts/tasks/helpers/ConstructorArguments.ts index 1db4beb22..751a8bbc4 100644 --- a/contracts/tasks/helpers/ConstructorArguments.ts +++ b/contracts/tasks/helpers/ConstructorArguments.ts @@ -12,7 +12,7 @@ import { Poll, Tally, } from '../../typechain-types' -import { getContractAt } from '../../utils/contracts' +import { getContractAt, getQualifiedContractName } from '../../utils/contracts' /** A list of functions to get contract constructor arguments from the contract */ const ConstructorArgumentsGetters: Record< @@ -312,7 +312,8 @@ export class ConstructorArguments { address: string, ethers: HardhatEthersHelpers ): Promise> { - const contractArtifact = this.hre.artifacts.readArtifactSync(name) + const qualifiedName = getQualifiedContractName(name) + const contractArtifact = this.hre.artifacts.readArtifactSync(qualifiedName) const contractInterface = new Interface(contractArtifact.abi) if (contractInterface.deploy.inputs.length === 0) { // no argument diff --git a/contracts/utils/contracts.ts b/contracts/utils/contracts.ts index c72aac709..77a2bc72d 100644 --- a/contracts/utils/contracts.ts +++ b/contracts/utils/contracts.ts @@ -124,15 +124,13 @@ export async function getCurrentFundingRoundContract( * @param name The contract name * @returns The qualified contract name */ -export function getQualifiedContractName(name: EContracts): string { +export function getQualifiedContractName(name: EContracts | string): string { let contractName = String(name) if (contractName.includes('Poseidon')) { contractName = `:${name}` - } - if (name === EContracts.PollFactory) { + } else if (name === EContracts.PollFactory) { contractName = 'contracts/maci/PollFactory.sol:PollFactory' - } - if (name === EContracts.Poll) { + } else if (name === EContracts.Poll) { contractName = 'contracts/maci/Poll.sol:Poll' } return contractName From d8cd50ca00108896cfe5746291a56509b91b05a8 Mon Sep 17 00:00:00 2001 From: yuetloo Date: Thu, 16 May 2024 06:04:03 -0400 Subject: [PATCH 23/57] use MACI v1.2.1 --- common/package.json | 4 +- common/src/__tests__/keypair.spec.ts | 7 +- common/src/keypair.ts | 5 +- contracts/contracts/AnyOldERC20Token.sol | 2 +- contracts/contracts/CloneFactory.sol | 2 +- contracts/contracts/ClrFund.sol | 2 +- contracts/contracts/ClrFundDeployer.sol | 4 +- contracts/contracts/ExternalContacts.sol | 3 +- contracts/contracts/FundingRound.sol | 12 +- contracts/contracts/FundingRoundFactory.sol | 2 +- contracts/contracts/MACICommon.sol | 2 +- contracts/contracts/MACIFactory.sol | 24 +- contracts/contracts/OwnableUpgradeable.sol | 2 +- contracts/contracts/TopupToken.sol | 4 +- contracts/contracts/interfaces/IClrFund.sol | 2 +- .../contracts/interfaces/IFundingRound.sol | 2 +- .../interfaces/IFundingRoundFactory.sol | 2 +- .../contracts/interfaces/IMACIFactory.sol | 2 +- contracts/contracts/maci/BabyJubJub.sol | 136 ----- contracts/contracts/maci/Poll.sol | 286 ---------- contracts/contracts/maci/PollFactory.sol | 73 --- .../BaseRecipientRegistry.sol | 2 +- .../recipientRegistry/IKlerosGTCR.sol | 2 +- .../recipientRegistry/IRecipientRegistry.sol | 2 +- .../recipientRegistry/KlerosGTCRAdapter.sol | 2 +- .../recipientRegistry/KlerosGTCRMock.sol | 4 +- .../OptimisticRecipientRegistry.sol | 4 +- .../PermissionedRecipientRegistry.sol | 4 +- .../SimpleRecipientRegistry.sol | 4 +- .../userRegistry/BrightIdSponsor.sol | 2 +- .../userRegistry/BrightIdUserRegistry.sol | 4 +- .../contracts/userRegistry/IUserRegistry.sol | 2 +- .../userRegistry/MerkleUserRegistry.sol | 4 +- .../userRegistry/SemaphoreUserRegistry.sol | 4 +- .../userRegistry/SimpleUserRegistry.sol | 4 +- .../userRegistry/SnapshotUserRegistry.sol | 4 +- .../MerklePatriciaProofVerifier.sol | 2 +- .../utils/cryptography/MerkleProof.sol | 2 +- .../utils/cryptography/StateProofVerifier.sol | 2 +- contracts/hardhat.config.ts | 7 +- contracts/package.json | 18 +- contracts/tasks/runners/genProofs.ts | 2 +- .../subtasks/clrfund/03-setVkRegsitry.ts | 7 +- .../subtasks/coordinator/01-coordinator.ts | 23 +- .../tasks/subtasks/round/02-deploy-round.ts | 6 +- contracts/utils/contracts.ts | 7 +- contracts/utils/maci.ts | 6 +- subgraph/abis/MACI.json | 62 +- subgraph/abis/Poll.json | 34 +- subgraph/generated/ClrFund/MACI.ts | 59 +- subgraph/generated/templates/MACI/MACI.ts | 59 +- yarn.lock | 539 +++++++++--------- 52 files changed, 473 insertions(+), 988 deletions(-) delete mode 100644 contracts/contracts/maci/BabyJubJub.sol delete mode 100644 contracts/contracts/maci/Poll.sol delete mode 100644 contracts/contracts/maci/PollFactory.sol diff --git a/common/package.json b/common/package.json index d7f3da4a5..713437020 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": "1.2.0", - "maci-domainobjs": "1.2.0" + "maci-crypto": "1.2.1", + "maci-domainobjs": "1.2.1" }, "repository": { "type": "git", diff --git a/common/src/__tests__/keypair.spec.ts b/common/src/__tests__/keypair.spec.ts index 47f1cba72..7dbc6e195 100644 --- a/common/src/__tests__/keypair.spec.ts +++ b/common/src/__tests__/keypair.spec.ts @@ -2,7 +2,7 @@ import { expect } from 'chai' import { Keypair, PubKey } from '../keypair' import { Wallet, sha256, randomBytes } from 'ethers' -describe.only('keypair', function () { +describe('keypair', function () { for (let i = 0; i < 10; i++) { it(`should generate key ${i} from seed successfully`, function () { const wallet = Wallet.createRandom() @@ -14,7 +14,8 @@ describe.only('keypair', function () { } it('should throw if pubKey is invalid', () => { - const pubKey = new PubKey([1n, 1n]) - expect(() => pubKey.serialize()).to.throw('Invalid public key') + expect(() => { + new PubKey([1n, 1n]) + }).to.throw('PubKey not on curve') }) }) diff --git a/common/src/keypair.ts b/common/src/keypair.ts index 649ef4b9f..c6c9ea165 100644 --- a/common/src/keypair.ts +++ b/common/src/keypair.ts @@ -17,11 +17,8 @@ function genPrivKey(hash: string): PrivKey { for (let counter = 1; pubKey === null; counter++) { try { const privKey = new PrivKey(rawPrivKey) - const keypair = new Keypair(privKey) - // this will throw 'Invalid public key' if key is not on the Baby Jubjub elliptic curve - keypair.pubKey.serialize() - + const keypair = new Keypair(privKey) pubKey = keypair.pubKey } catch { const data = concat([toBeArray(rawPrivKey), toBeArray(counter)]) diff --git a/contracts/contracts/AnyOldERC20Token.sol b/contracts/contracts/AnyOldERC20Token.sol index 3d88c9508..be5ba8656 100644 --- a/contracts/contracts/AnyOldERC20Token.sol +++ b/contracts/contracts/AnyOldERC20Token.sol @@ -1,6 +1,6 @@ // SPDX-License-Identifier: GPL-3.0 -pragma solidity ^0.8.10; +pragma solidity 0.8.20; import '@openzeppelin/contracts/token/ERC20/ERC20.sol'; diff --git a/contracts/contracts/CloneFactory.sol b/contracts/contracts/CloneFactory.sol index 99247f723..fcdf5d9b6 100644 --- a/contracts/contracts/CloneFactory.sol +++ b/contracts/contracts/CloneFactory.sol @@ -21,7 +21,7 @@ TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ -pragma solidity 0.8.10; +pragma solidity 0.8.20; contract CloneFactory { // implementation of eip-1167 - see https://eips.ethereum.org/EIPS/eip-1167 function createClone(address target) internal returns (address result) { diff --git a/contracts/contracts/ClrFund.sol b/contracts/contracts/ClrFund.sol index c9ad77389..4f5ad30bc 100644 --- a/contracts/contracts/ClrFund.sol +++ b/contracts/contracts/ClrFund.sol @@ -1,6 +1,6 @@ // SPDX-License-Identifier: GPL-3.0 -pragma solidity 0.8.10; +pragma solidity 0.8.20; import '@openzeppelin/contracts/token/ERC20/ERC20.sol'; import '@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol'; diff --git a/contracts/contracts/ClrFundDeployer.sol b/contracts/contracts/ClrFundDeployer.sol index 2487723ff..4f2b279d5 100644 --- a/contracts/contracts/ClrFundDeployer.sol +++ b/contracts/contracts/ClrFundDeployer.sol @@ -1,6 +1,6 @@ // SPDX-License-Identifier: GPL-3.0 -pragma solidity 0.8.10; +pragma solidity 0.8.20; import {MACIFactory} from './MACIFactory.sol'; import {ClrFund} from './ClrFund.sol'; @@ -9,7 +9,7 @@ import {SignUpGatekeeper} from "maci-contracts/contracts/gatekeepers/SignUpGatek import {InitialVoiceCreditProxy} from "maci-contracts/contracts/initialVoiceCreditProxy/InitialVoiceCreditProxy.sol"; import {Ownable} from '@openzeppelin/contracts/access/Ownable.sol'; -contract ClrFundDeployer is CloneFactory, Ownable { +contract ClrFundDeployer is CloneFactory, Ownable(msg.sender) { address public clrfundTemplate; address public maciFactory; address public roundFactory; diff --git a/contracts/contracts/ExternalContacts.sol b/contracts/contracts/ExternalContacts.sol index 51706fb5f..d2f1d989e 100644 --- a/contracts/contracts/ExternalContacts.sol +++ b/contracts/contracts/ExternalContacts.sol @@ -1,6 +1,6 @@ // SPDX-License-Identifier: GPL-3.0 -pragma solidity ^0.8.10; +pragma solidity 0.8.20; /* * These imports are just for hardhat to find the contracts for deployment @@ -9,5 +9,4 @@ pragma solidity ^0.8.10; import {Poll} from 'maci-contracts/contracts/Poll.sol'; import {PollFactory} from 'maci-contracts/contracts/PollFactory.sol'; import {TallyFactory} from 'maci-contracts/contracts/TallyFactory.sol'; -import {SubsidyFactory} from 'maci-contracts/contracts/SubsidyFactory.sol'; import {MessageProcessorFactory} from 'maci-contracts/contracts/MessageProcessorFactory.sol'; diff --git a/contracts/contracts/FundingRound.sol b/contracts/contracts/FundingRound.sol index 38bb4f1ee..9f8fe143b 100644 --- a/contracts/contracts/FundingRound.sol +++ b/contracts/contracts/FundingRound.sol @@ -1,6 +1,6 @@ // SPDX-License-Identifier: GPL-3.0 -pragma solidity 0.8.10; +pragma solidity 0.8.20; import '@openzeppelin/contracts/access/Ownable.sol'; import '@openzeppelin/contracts/token/ERC20/ERC20.sol'; @@ -15,7 +15,7 @@ import {SignUpGatekeeper} from 'maci-contracts/contracts/gatekeepers/SignUpGatek import {InitialVoiceCreditProxy} from 'maci-contracts/contracts/initialVoiceCreditProxy/InitialVoiceCreditProxy.sol'; import {CommonUtilities} from 'maci-contracts/contracts/utilities/CommonUtilities.sol'; import {SnarkCommon} from 'maci-contracts/contracts/crypto/SnarkCommon.sol'; -import {ITallySubsidyFactory} from 'maci-contracts/contracts/interfaces/ITallySubsidyFactory.sol'; +import {ITallyFactory} from 'maci-contracts/contracts/interfaces/ITallyFactory.sol'; import {IMessageProcessorFactory} from 'maci-contracts/contracts/interfaces/IMPFactory.sol'; import {IClrFund} from './interfaces/IClrFund.sol'; import {IMACIFactory} from './interfaces/IMACIFactory.sol'; @@ -25,7 +25,7 @@ import './userRegistry/IUserRegistry.sol'; import './recipientRegistry/IRecipientRegistry.sol'; contract FundingRound is - Ownable, + Ownable(msg.sender), SignUpGatekeeper, InitialVoiceCreditProxy, DomainObjs, @@ -221,10 +221,10 @@ contract FundingRound is address vkRegistry = address(tally.vkRegistry()); IMessageProcessorFactory messageProcessorFactory = maci.messageProcessorFactory(); - ITallySubsidyFactory tallyFactory = maci.tallyFactory(); + ITallyFactory tallyFactory = maci.tallyFactory(); - address mp = messageProcessorFactory.deploy(verifier, vkRegistry, address(poll), coordinator); - address newTally = tallyFactory.deploy(verifier, vkRegistry, address(poll), mp, coordinator); + address mp = messageProcessorFactory.deploy(verifier, vkRegistry, address(poll), coordinator, Mode.QV); + address newTally = tallyFactory.deploy(verifier, vkRegistry, address(poll), mp, coordinator, Mode.QV); _setTally(newTally); } diff --git a/contracts/contracts/FundingRoundFactory.sol b/contracts/contracts/FundingRoundFactory.sol index 9a35c1077..06d0453e5 100644 --- a/contracts/contracts/FundingRoundFactory.sol +++ b/contracts/contracts/FundingRoundFactory.sol @@ -1,6 +1,6 @@ // SPDX-License-Identifier: GPL-3.0 -pragma solidity ^0.8.10; +pragma solidity 0.8.20; import {FundingRound} from './FundingRound.sol'; import {IClrFund} from './interfaces/IClrFund.sol'; diff --git a/contracts/contracts/MACICommon.sol b/contracts/contracts/MACICommon.sol index 3a73b4110..05762874e 100644 --- a/contracts/contracts/MACICommon.sol +++ b/contracts/contracts/MACICommon.sol @@ -1,6 +1,6 @@ // SPDX-License-Identifier: GPL-3.0 -pragma solidity ^0.8.10; +pragma solidity 0.8.20; /** * @dev a contract that holds common MACI structures diff --git a/contracts/contracts/MACIFactory.sol b/contracts/contracts/MACIFactory.sol index 1fb0b800b..2bccc4655 100644 --- a/contracts/contracts/MACIFactory.sol +++ b/contracts/contracts/MACIFactory.sol @@ -1,10 +1,10 @@ // SPDX-License-Identifier: GPL-3.0 -pragma solidity ^0.8.10; +pragma solidity 0.8.20; import {MACI} from 'maci-contracts/contracts/MACI.sol'; import {IPollFactory} from 'maci-contracts/contracts/interfaces/IPollFactory.sol'; -import {ITallySubsidyFactory} from 'maci-contracts/contracts/interfaces/ITallySubsidyFactory.sol'; +import {ITallyFactory} from 'maci-contracts/contracts/interfaces/ITallyFactory.sol'; import {IMessageProcessorFactory} from 'maci-contracts/contracts/interfaces/IMPFactory.sol'; import {SignUpGatekeeper} from 'maci-contracts/contracts/gatekeepers/SignUpGatekeeper.sol'; import {InitialVoiceCreditProxy} from 'maci-contracts/contracts/initialVoiceCreditProxy/InitialVoiceCreditProxy.sol'; @@ -17,7 +17,7 @@ import {Params} from 'maci-contracts/contracts/utilities/Params.sol'; import {DomainObjs} from 'maci-contracts/contracts/utilities/DomainObjs.sol'; import {MACICommon} from './MACICommon.sol'; -contract MACIFactory is Ownable, Params, SnarkCommon, DomainObjs, MACICommon { +contract MACIFactory is Ownable(msg.sender), Params, SnarkCommon, DomainObjs, MACICommon { // Verifying Key Registry containing circuit parameters VkRegistry public vkRegistry; @@ -135,7 +135,8 @@ contract MACIFactory is Ownable, Params, SnarkCommon, DomainObjs, MACICommon { _stateTreeDepth, _treeDepths.messageTreeDepth, _treeDepths.voteOptionTreeDepth, - messageBatchSize) + messageBatchSize, + Mode.QV) ) { revert ProcessVkNotSet(); } @@ -143,7 +144,8 @@ contract MACIFactory is Ownable, Params, SnarkCommon, DomainObjs, MACICommon { if (!vkRegistry.hasTallyVk( _stateTreeDepth, _treeDepths.intStateTreeDepth, - _treeDepths.voteOptionTreeDepth) + _treeDepths.voteOptionTreeDepth, + Mode.QV) ) { revert TallyVkNotSet(); } @@ -175,7 +177,8 @@ contract MACIFactory is Ownable, Params, SnarkCommon, DomainObjs, MACICommon { stateTreeDepth, treeDepths.messageTreeDepth, treeDepths.voteOptionTreeDepth, - messageBatchSize) + messageBatchSize, + Mode.QV) ) { revert ProcessVkNotSet(); } @@ -183,7 +186,8 @@ contract MACIFactory is Ownable, Params, SnarkCommon, DomainObjs, MACICommon { if (!vkRegistry.hasTallyVk( stateTreeDepth, treeDepths.intStateTreeDepth, - treeDepths.voteOptionTreeDepth) + treeDepths.voteOptionTreeDepth, + Mode.QV) ) { revert TallyVkNotSet(); } @@ -191,8 +195,7 @@ contract MACIFactory is Ownable, Params, SnarkCommon, DomainObjs, MACICommon { _maci = new MACI( IPollFactory(factories.pollFactory), IMessageProcessorFactory(factories.messageProcessorFactory), - ITallySubsidyFactory(factories.tallyFactory), - ITallySubsidyFactory(factories.subsidyFactory), + ITallyFactory(factories.tallyFactory), signUpGatekeeper, initialVoiceCreditProxy, TopupCredit(topupCredit), @@ -205,8 +208,7 @@ contract MACIFactory is Ownable, Params, SnarkCommon, DomainObjs, MACICommon { coordinatorPubKey, address(verifier), address(vkRegistry), - // pass false to not deploy the subsidy contract - false + Mode.QV ); // transfer ownership to coordinator to run the tally scripts diff --git a/contracts/contracts/OwnableUpgradeable.sol b/contracts/contracts/OwnableUpgradeable.sol index 3826e125a..152178fe4 100644 --- a/contracts/contracts/OwnableUpgradeable.sol +++ b/contracts/contracts/OwnableUpgradeable.sol @@ -1,6 +1,6 @@ // SPDX-License-Identifier: MIT -pragma solidity ^0.8.10; +pragma solidity 0.8.20; // NOTE: had to copy contracts over since OZ uses a higher pragma than we do in the one's they maintain. diff --git a/contracts/contracts/TopupToken.sol b/contracts/contracts/TopupToken.sol index c70068ae7..8cafce9e1 100644 --- a/contracts/contracts/TopupToken.sol +++ b/contracts/contracts/TopupToken.sol @@ -1,6 +1,6 @@ // SPDX-License-Identifier: GPL-3.0 -pragma solidity ^0.8.10; +pragma solidity 0.8.20; import {ERC20} from '@openzeppelin/contracts/token/ERC20/ERC20.sol'; import {Ownable} from "@openzeppelin/contracts/access/Ownable.sol"; @@ -9,7 +9,7 @@ import {Ownable} from "@openzeppelin/contracts/access/Ownable.sol"; * TopupToken is used by MACI Poll contract to validate the topup credits of a user * In clrfund, this is only used as gateway to pass the topup amount to the Poll contract */ -contract TopupToken is ERC20, Ownable { +contract TopupToken is ERC20, Ownable(msg.sender) { constructor() ERC20("TopupCredit", "TopupCredit") {} function airdrop(uint256 amount) public onlyOwner { diff --git a/contracts/contracts/interfaces/IClrFund.sol b/contracts/contracts/interfaces/IClrFund.sol index 5da1b8b45..2f77f992d 100644 --- a/contracts/contracts/interfaces/IClrFund.sol +++ b/contracts/contracts/interfaces/IClrFund.sol @@ -1,6 +1,6 @@ // SPDX-License-Identifier: GPL-3.0 -pragma solidity 0.8.10; +pragma solidity 0.8.20; import {ERC20} from '@openzeppelin/contracts/token/ERC20/ERC20.sol'; import {IUserRegistry} from '../userRegistry/IUserRegistry.sol'; diff --git a/contracts/contracts/interfaces/IFundingRound.sol b/contracts/contracts/interfaces/IFundingRound.sol index 026f40c0a..65daf3ea6 100644 --- a/contracts/contracts/interfaces/IFundingRound.sol +++ b/contracts/contracts/interfaces/IFundingRound.sol @@ -1,6 +1,6 @@ // SPDX-License-Identifier: GPL-3.0 -pragma solidity ^0.8.10; +pragma solidity 0.8.20; import {ERC20} from '@openzeppelin/contracts/token/ERC20/ERC20.sol'; diff --git a/contracts/contracts/interfaces/IFundingRoundFactory.sol b/contracts/contracts/interfaces/IFundingRoundFactory.sol index 9ca5806f1..45ec956fa 100644 --- a/contracts/contracts/interfaces/IFundingRoundFactory.sol +++ b/contracts/contracts/interfaces/IFundingRoundFactory.sol @@ -1,6 +1,6 @@ // SPDX-License-Identifier: GPL-3.0 -pragma solidity ^0.8.10; +pragma solidity 0.8.20; import {ERC20} from '@openzeppelin/contracts/token/ERC20/ERC20.sol'; diff --git a/contracts/contracts/interfaces/IMACIFactory.sol b/contracts/contracts/interfaces/IMACIFactory.sol index d5d0bf3b2..eacfd7df2 100644 --- a/contracts/contracts/interfaces/IMACIFactory.sol +++ b/contracts/contracts/interfaces/IMACIFactory.sol @@ -1,6 +1,6 @@ // SPDX-License-Identifier: GPL-3.0 -pragma solidity ^0.8.10; +pragma solidity 0.8.20; import {IVkRegistry} from 'maci-contracts/contracts/interfaces/IVkRegistry.sol'; import {IVerifier} from 'maci-contracts/contracts/interfaces/IVerifier.sol'; diff --git a/contracts/contracts/maci/BabyJubJub.sol b/contracts/contracts/maci/BabyJubJub.sol deleted file mode 100644 index 7d046b624..000000000 --- a/contracts/contracts/maci/BabyJubJub.sol +++ /dev/null @@ -1,136 +0,0 @@ -// @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 deleted file mode 100644 index 1306c7698..000000000 --- a/contracts/contracts/maci/Poll.sol +++ /dev/null @@ -1,286 +0,0 @@ -// @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 deleted file mode 100644 index ad91b4305..000000000 --- a/contracts/contracts/maci/PollFactory.sol +++ /dev/null @@ -1,73 +0,0 @@ -// @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/contracts/recipientRegistry/BaseRecipientRegistry.sol b/contracts/contracts/recipientRegistry/BaseRecipientRegistry.sol index 8215fce92..d8c656d21 100644 --- a/contracts/contracts/recipientRegistry/BaseRecipientRegistry.sol +++ b/contracts/contracts/recipientRegistry/BaseRecipientRegistry.sol @@ -1,6 +1,6 @@ // SPDX-License-Identifier: GPL-3.0 -pragma solidity ^0.8.10; +pragma solidity 0.8.20; import './IRecipientRegistry.sol'; diff --git a/contracts/contracts/recipientRegistry/IKlerosGTCR.sol b/contracts/contracts/recipientRegistry/IKlerosGTCR.sol index 6eda6f7cb..2326e70ba 100644 --- a/contracts/contracts/recipientRegistry/IKlerosGTCR.sol +++ b/contracts/contracts/recipientRegistry/IKlerosGTCR.sol @@ -1,6 +1,6 @@ // SPDX-License-Identifier: GPL-3.0 -pragma solidity ^0.8.10; +pragma solidity 0.8.20; /** * @dev Interface for Kleros Generalized TCR. diff --git a/contracts/contracts/recipientRegistry/IRecipientRegistry.sol b/contracts/contracts/recipientRegistry/IRecipientRegistry.sol index 3f139948e..82fc0c4a9 100644 --- a/contracts/contracts/recipientRegistry/IRecipientRegistry.sol +++ b/contracts/contracts/recipientRegistry/IRecipientRegistry.sol @@ -1,6 +1,6 @@ // SPDX-License-Identifier: GPL-3.0 -pragma solidity ^0.8.10; +pragma solidity 0.8.20; /** * @dev Interface of the recipient registry. diff --git a/contracts/contracts/recipientRegistry/KlerosGTCRAdapter.sol b/contracts/contracts/recipientRegistry/KlerosGTCRAdapter.sol index 2bf70bd6d..621e6dd45 100644 --- a/contracts/contracts/recipientRegistry/KlerosGTCRAdapter.sol +++ b/contracts/contracts/recipientRegistry/KlerosGTCRAdapter.sol @@ -1,6 +1,6 @@ // SPDX-License-Identifier: GPL-3.0 -pragma solidity ^0.8.10; +pragma solidity 0.8.20; import 'solidity-rlp/contracts/RLPReader.sol'; diff --git a/contracts/contracts/recipientRegistry/KlerosGTCRMock.sol b/contracts/contracts/recipientRegistry/KlerosGTCRMock.sol index abbc9bd16..e1988cd4e 100644 --- a/contracts/contracts/recipientRegistry/KlerosGTCRMock.sol +++ b/contracts/contracts/recipientRegistry/KlerosGTCRMock.sol @@ -1,6 +1,6 @@ // SPDX-License-Identifier: MIT -pragma solidity ^0.8.10; +pragma solidity 0.8.20; import '@openzeppelin/contracts/access/Ownable.sol'; @@ -9,7 +9,7 @@ import '@openzeppelin/contracts/access/Ownable.sol'; * This contract is a curated registry for any types of items. Just like a TCR contract it features the request-challenge protocol and appeal fees crowdfunding. * Adapted from https://github.com/kleros/tcr/blob/v2.0.0/contracts/GeneralizedTCR.sol */ -contract KlerosGTCRMock is Ownable { +contract KlerosGTCRMock is Ownable(msg.sender) { enum Status { Absent, // The item is not in the registry. diff --git a/contracts/contracts/recipientRegistry/OptimisticRecipientRegistry.sol b/contracts/contracts/recipientRegistry/OptimisticRecipientRegistry.sol index 8bc331dbb..57ac016f5 100644 --- a/contracts/contracts/recipientRegistry/OptimisticRecipientRegistry.sol +++ b/contracts/contracts/recipientRegistry/OptimisticRecipientRegistry.sol @@ -1,6 +1,6 @@ // SPDX-License-Identifier: GPL-3.0 -pragma solidity ^0.8.10; +pragma solidity 0.8.20; import '@openzeppelin/contracts/access/Ownable.sol'; @@ -9,7 +9,7 @@ import './BaseRecipientRegistry.sol'; /** * @dev Recipient registry with optimistic execution of registrations and removals. */ -contract OptimisticRecipientRegistry is Ownable, BaseRecipientRegistry { +contract OptimisticRecipientRegistry is Ownable(msg.sender), BaseRecipientRegistry { // Enums enum RequestType { diff --git a/contracts/contracts/recipientRegistry/PermissionedRecipientRegistry.sol b/contracts/contracts/recipientRegistry/PermissionedRecipientRegistry.sol index 3833f3f77..fe8e16829 100644 --- a/contracts/contracts/recipientRegistry/PermissionedRecipientRegistry.sol +++ b/contracts/contracts/recipientRegistry/PermissionedRecipientRegistry.sol @@ -1,6 +1,6 @@ // SPDX-License-Identifier: GPL-3.0 -pragma solidity ^0.8.10; +pragma solidity 0.8.20; import '@openzeppelin/contracts/access/Ownable.sol'; @@ -9,7 +9,7 @@ import './BaseRecipientRegistry.sol'; /** * @dev Recipient registry with permissioned execution of registrations and removals. */ -contract PermissionedRecipientRegistry is Ownable, BaseRecipientRegistry { +contract PermissionedRecipientRegistry is Ownable(msg.sender), BaseRecipientRegistry { // Enums enum RequestType { diff --git a/contracts/contracts/recipientRegistry/SimpleRecipientRegistry.sol b/contracts/contracts/recipientRegistry/SimpleRecipientRegistry.sol index bd273cea1..11c2b2014 100644 --- a/contracts/contracts/recipientRegistry/SimpleRecipientRegistry.sol +++ b/contracts/contracts/recipientRegistry/SimpleRecipientRegistry.sol @@ -1,6 +1,6 @@ // SPDX-License-Identifier: GPL-3.0 -pragma solidity ^0.8.10; +pragma solidity 0.8.20; import '@openzeppelin/contracts/access/Ownable.sol'; @@ -9,7 +9,7 @@ import './BaseRecipientRegistry.sol'; /** * @dev A simple recipient registry managed by a trusted entity. */ -contract SimpleRecipientRegistry is Ownable, BaseRecipientRegistry { +contract SimpleRecipientRegistry is Ownable(msg.sender), BaseRecipientRegistry { // Events event RecipientAdded( diff --git a/contracts/contracts/userRegistry/BrightIdSponsor.sol b/contracts/contracts/userRegistry/BrightIdSponsor.sol index 302a80b13..d27487d2a 100644 --- a/contracts/contracts/userRegistry/BrightIdSponsor.sol +++ b/contracts/contracts/userRegistry/BrightIdSponsor.sol @@ -1,6 +1,6 @@ // SPDX-License-Identifier: GPL-3.0 -pragma solidity ^0.8.10; +pragma solidity 0.8.20; contract BrightIdSponsor { event Sponsor(address indexed addr); diff --git a/contracts/contracts/userRegistry/BrightIdUserRegistry.sol b/contracts/contracts/userRegistry/BrightIdUserRegistry.sol index 09557af3a..49033f0bc 100644 --- a/contracts/contracts/userRegistry/BrightIdUserRegistry.sol +++ b/contracts/contracts/userRegistry/BrightIdUserRegistry.sol @@ -1,12 +1,12 @@ // SPDX-License-Identifier: GPL-3.0 -pragma solidity ^0.8.10; +pragma solidity 0.8.20; import './IUserRegistry.sol'; import './BrightIdSponsor.sol'; import '@openzeppelin/contracts/access/Ownable.sol'; -contract BrightIdUserRegistry is Ownable, IUserRegistry { +contract BrightIdUserRegistry is Ownable(msg.sender), IUserRegistry { string private constant ERROR_NEWER_VERIFICATION = 'NEWER VERIFICATION REGISTERED BEFORE'; string private constant ERROR_NOT_AUTHORIZED = 'NOT AUTHORIZED'; string private constant ERROR_INVALID_VERIFIER = 'INVALID VERIFIER'; diff --git a/contracts/contracts/userRegistry/IUserRegistry.sol b/contracts/contracts/userRegistry/IUserRegistry.sol index cce90ae42..2bd12bddf 100644 --- a/contracts/contracts/userRegistry/IUserRegistry.sol +++ b/contracts/contracts/userRegistry/IUserRegistry.sol @@ -1,6 +1,6 @@ // SPDX-License-Identifier: GPL-3.0 -pragma solidity ^0.8.10; +pragma solidity 0.8.20; /** * @dev Interface of the registry of verified users. diff --git a/contracts/contracts/userRegistry/MerkleUserRegistry.sol b/contracts/contracts/userRegistry/MerkleUserRegistry.sol index e6ff85c0f..0c6c39303 100644 --- a/contracts/contracts/userRegistry/MerkleUserRegistry.sol +++ b/contracts/contracts/userRegistry/MerkleUserRegistry.sol @@ -1,6 +1,6 @@ // SPDX-License-Identifier: GPL-3.0 -pragma solidity ^0.8.10; +pragma solidity 0.8.20; import '@openzeppelin/contracts/access/Ownable.sol'; @@ -13,7 +13,7 @@ import {MerkleProof} from '../utils/cryptography/MerkleProof.sol'; * a successful verification against the merkle root set by * the funding round coordinator. */ -contract MerkleUserRegistry is Ownable, IUserRegistry { +contract MerkleUserRegistry is Ownable(msg.sender), IUserRegistry { // verified users grouped by merkleRoot // merkleRoot -> user -> status diff --git a/contracts/contracts/userRegistry/SemaphoreUserRegistry.sol b/contracts/contracts/userRegistry/SemaphoreUserRegistry.sol index a141e422e..9be159b9b 100644 --- a/contracts/contracts/userRegistry/SemaphoreUserRegistry.sol +++ b/contracts/contracts/userRegistry/SemaphoreUserRegistry.sol @@ -1,6 +1,6 @@ // SPDX-License-Identifier: GPL-3.0 -pragma solidity ^0.8.10; +pragma solidity 0.8.20; import '@openzeppelin/contracts/access/Ownable.sol'; @@ -9,7 +9,7 @@ import './IUserRegistry.sol'; /** * @dev A simple semaphore user registry managed by a trusted entity. */ -contract SemaphoreUserRegistry is Ownable, IUserRegistry { +contract SemaphoreUserRegistry is Ownable(msg.sender), IUserRegistry { mapping(address => bool) private users; mapping(uint256 => bool) private semaphoreIds; diff --git a/contracts/contracts/userRegistry/SimpleUserRegistry.sol b/contracts/contracts/userRegistry/SimpleUserRegistry.sol index 4f4a7ff00..21fcaa38a 100644 --- a/contracts/contracts/userRegistry/SimpleUserRegistry.sol +++ b/contracts/contracts/userRegistry/SimpleUserRegistry.sol @@ -1,6 +1,6 @@ // SPDX-License-Identifier: GPL-3.0 -pragma solidity ^0.8.10; +pragma solidity 0.8.20; import '@openzeppelin/contracts/access/Ownable.sol'; @@ -9,7 +9,7 @@ import './IUserRegistry.sol'; /** * @dev A simple user registry managed by a trusted entity. */ -contract SimpleUserRegistry is Ownable, IUserRegistry { +contract SimpleUserRegistry is Ownable(msg.sender), IUserRegistry { mapping(address => bool) private users; diff --git a/contracts/contracts/userRegistry/SnapshotUserRegistry.sol b/contracts/contracts/userRegistry/SnapshotUserRegistry.sol index 754bf869c..3d7ecdd18 100644 --- a/contracts/contracts/userRegistry/SnapshotUserRegistry.sol +++ b/contracts/contracts/userRegistry/SnapshotUserRegistry.sol @@ -1,6 +1,6 @@ // SPDX-License-Identifier: GPL-3.0 -pragma solidity ^0.8.10; +pragma solidity 0.8.20; import '@openzeppelin/contracts/access/Ownable.sol'; @@ -14,7 +14,7 @@ import {StateProofVerifier} from '../utils/cryptography/StateProofVerifier.sol'; * @dev A user registry that verifies users based on ownership of a token * at a specific block snapshot */ -contract SnapshotUserRegistry is Ownable, IUserRegistry { +contract SnapshotUserRegistry is Ownable(msg.sender), IUserRegistry { using RLPReader for RLPReader.RLPItem; using RLPReader for bytes; diff --git a/contracts/contracts/utils/cryptography/MerklePatriciaProofVerifier.sol b/contracts/contracts/utils/cryptography/MerklePatriciaProofVerifier.sol index b0a6df1d3..a24404e9e 100644 --- a/contracts/contracts/utils/cryptography/MerklePatriciaProofVerifier.sol +++ b/contracts/contracts/utils/cryptography/MerklePatriciaProofVerifier.sol @@ -4,7 +4,7 @@ * Modified from https://github.com/lidofinance/curve-merkle-oracle/blob/main/contracts/MerklePatriciaProofVerifier.sol * git commit hash 1033b3e84142317ffd8f366b52e489d5eb49c73f */ -pragma solidity ^0.8.10; +pragma solidity 0.8.20; import {RLPReader} from 'solidity-rlp/contracts/RLPReader.sol'; diff --git a/contracts/contracts/utils/cryptography/MerkleProof.sol b/contracts/contracts/utils/cryptography/MerkleProof.sol index 08c4a87ed..dd2c0aa99 100644 --- a/contracts/contracts/utils/cryptography/MerkleProof.sol +++ b/contracts/contracts/utils/cryptography/MerkleProof.sol @@ -1,7 +1,7 @@ // SPDX-License-Identifier: MIT // Modified from OpenZeppelin Contracts (last updated v4.9.2) (utils/cryptography/MerkleProof.sol) -pragma solidity ^0.8.10; +pragma solidity 0.8.20; /** * @dev These functions deal with verification of Merkle Tree proofs. diff --git a/contracts/contracts/utils/cryptography/StateProofVerifier.sol b/contracts/contracts/utils/cryptography/StateProofVerifier.sol index 407ccd0bc..9425345b1 100644 --- a/contracts/contracts/utils/cryptography/StateProofVerifier.sol +++ b/contracts/contracts/utils/cryptography/StateProofVerifier.sol @@ -1,6 +1,6 @@ // SPDX-License-Identifier: MIT -pragma solidity ^0.8.10; +pragma solidity 0.8.20; import {RLPReader} from 'solidity-rlp/contracts/RLPReader.sol'; import {MerklePatriciaProofVerifier} from './MerklePatriciaProofVerifier.sol'; diff --git a/contracts/hardhat.config.ts b/contracts/hardhat.config.ts index 470029275..7837be09c 100644 --- a/contracts/hardhat.config.ts +++ b/contracts/hardhat.config.ts @@ -119,7 +119,7 @@ export default { disambiguatePaths: false, }, solidity: { - version: '0.8.10', + version: '0.8.20', settings: { optimizer: { enabled: true, @@ -128,7 +128,6 @@ export default { }, overrides: { 'contracts/FundingRoundFactory.sol': { - version: '0.8.10', settings: { optimizer: { enabled: true, @@ -137,7 +136,6 @@ export default { }, }, 'contracts/FundingRound.sol': { - version: '0.8.10', settings: { optimizer: { enabled: true, @@ -146,7 +144,6 @@ export default { }, }, 'contracts/recipientRegistry/OptimisticRecipientRegistry.sol': { - version: '0.8.10', settings: { optimizer: { enabled: true, @@ -155,7 +152,6 @@ export default { }, }, 'contracts/userRegistry/SimpleUserRegistry.sol': { - version: '0.8.10', settings: { optimizer: { enabled: true, @@ -164,7 +160,6 @@ export default { }, }, 'contracts/userRegistry/BrightIdUserRegistry.sol': { - version: '0.8.10', settings: { optimizer: { enabled: true, diff --git a/contracts/package.json b/contracts/package.json index 9a3941562..2f70d0f24 100644 --- a/contracts/package.json +++ b/contracts/package.json @@ -15,18 +15,18 @@ "clean": "rm -rf cache && rm -rf build" }, "dependencies": { - "@openzeppelin/contracts": "4.9.0", + "@openzeppelin/contracts": "5.0.2", "@pinata/sdk": "^2.1.0", "dotenv": "^8.2.0", - "maci-contracts": "1.2.0", + "maci-contracts": "1.2.1", "solidity-rlp": "2.0.8" }, "devDependencies": { "@clrfund/common": "^0.0.1", "@clrfund/waffle-mock-contract": "^0.0.4", "@kleros/gtcr-encoder": "^1.4.0", - "@nomicfoundation/hardhat-chai-matchers": "^2.0.3", - "@nomicfoundation/hardhat-ethers": "^3.0.5", + "@nomicfoundation/hardhat-chai-matchers": "^2.0.6", + "@nomicfoundation/hardhat-ethers": "^3.0.6", "@nomicfoundation/hardhat-network-helpers": "^1.0.10", "@nomicfoundation/hardhat-toolbox": "^4.0.0", "@nomicfoundation/hardhat-verify": "^2.0.3", @@ -34,14 +34,16 @@ "@typechain/ethers-v6": "^0.5.1", "@typechain/hardhat": "^9.1.0", "@types/mocha": "^10.0.6", - "ethers": "^6.11.1", + "chai": "4", + "ethers": "^6.12.1", "hardhat": "^2.19.4", "hardhat-contract-sizer": "^2.10.0", "hardhat-gas-reporter": "^1.0.8", "ipfs-only-hash": "^2.0.1", - "maci-circuits": "^1.2.0", - "maci-cli": "^1.2.0", - "maci-domainobjs": "1.2.0", + "lowdb": "1.0.0", + "maci-circuits": "1.2.1", + "maci-cli": "1.2.1", + "maci-domainobjs": "1.2.1", "mocha": "^10.2.0", "solidity-coverage": "^0.8.1", "ts-node": "^10.9.2", diff --git a/contracts/tasks/runners/genProofs.ts b/contracts/tasks/runners/genProofs.ts index ed3061edb..708573980 100644 --- a/contracts/tasks/runners/genProofs.ts +++ b/contracts/tasks/runners/genProofs.ts @@ -187,7 +187,7 @@ task('gen-proofs', 'Generate MACI proofs offchain') quiet, outputPath: maciStateFile, pollId, - maciContractAddress: maciAddress, + maciAddress, coordinatorPrivateKey: coordinatorMacisk, ethereumProvider: providerUrl, transactionHash: maciTxHash, diff --git a/contracts/tasks/subtasks/clrfund/03-setVkRegsitry.ts b/contracts/tasks/subtasks/clrfund/03-setVkRegsitry.ts index a3fefb412..fcbe9b1bb 100644 --- a/contracts/tasks/subtasks/clrfund/03-setVkRegsitry.ts +++ b/contracts/tasks/subtasks/clrfund/03-setVkRegsitry.ts @@ -3,6 +3,7 @@ import { setVerifyingKeys } from '../../../utils/contracts' import { MaciParameters } from '../../../utils/maciParameters' import { Subtask } from '../../helpers/Subtask' import { EContracts, ISubtaskParams } from '../../helpers/types' +import { EMode } from 'maci-contracts' const subtask = Subtask.getInstance() @@ -39,13 +40,15 @@ subtask stateTreeDepth, messageTreeDepth, voteOptionTreeDepth, - messageBatchSize + messageBatchSize, + EMode.QV ) const hasTallyVk = await vkRegistryContract.hasTallyVk( stateTreeDepth, intStateTreeDepth, - voteOptionTreeDepth + voteOptionTreeDepth, + EMode.QV ) if (incremental) { diff --git a/contracts/tasks/subtasks/coordinator/01-coordinator.ts b/contracts/tasks/subtasks/coordinator/01-coordinator.ts index 3b2f0b767..10685b5a7 100644 --- a/contracts/tasks/subtasks/coordinator/01-coordinator.ts +++ b/contracts/tasks/subtasks/coordinator/01-coordinator.ts @@ -44,19 +44,30 @@ subtask clrfundContract.coordinatorPubKey(), ]) - const currentPubKey = new PubKey([coordinatorPubKey.x, coordinatorPubKey.y]) + // if the coordinator has not been set in the clrfund contract + // use allowInvalid option to prevent it from throwing in new PubKey() + const allowInvalid = true + const currentPubKey = new PubKey( + [coordinatorPubKey.x, coordinatorPubKey.y], + allowInvalid + ) const newPrivKey = PrivKey.deserialize(coordinatorMacisk) const newKeypair = new Keypair(newPrivKey) const normalizedCurrentCoordinator = getAddress(currentCoordinator) const normalizedNewCoordinator = getAddress(coordinatorAddress) - console.log('Current coordinator', normalizedCurrentCoordinator) - console.log(' New coordinator', normalizedNewCoordinator) + console.log('Current coordinator:', normalizedCurrentCoordinator) + console.log(' New coordinator:', normalizedNewCoordinator) - const serializedCurrentPubKey = currentPubKey.serialize() + let serializedCurrentPubKey = 'Not set' + try { + serializedCurrentPubKey = currentPubKey.serialize() + } catch { + // if the public key was not set, serialize will throw. + } const serializedNewPubKey = newKeypair.pubKey.serialize() - console.log('Current MACI key', serializedCurrentPubKey) - console.log(' New MACI key', serializedNewPubKey) + console.log('Current MACI key:', serializedCurrentPubKey) + console.log(' New MACI key:', serializedNewPubKey) console.log() if ( diff --git a/contracts/tasks/subtasks/round/02-deploy-round.ts b/contracts/tasks/subtasks/round/02-deploy-round.ts index 812bf75b7..707216d2c 100644 --- a/contracts/tasks/subtasks/round/02-deploy-round.ts +++ b/contracts/tasks/subtasks/round/02-deploy-round.ts @@ -15,6 +15,7 @@ import { } from '../../../typechain-types' import { ContractTransactionResponse } from 'ethers' import { ISubtaskParams } from '../../helpers/types' +import { EMode } from 'maci-contracts' const subtask = Subtask.getInstance() const storage = ContractStorage.getInstance() @@ -69,7 +70,6 @@ async function registerMaci( maciContract.pollFactory(), maciContract.messageProcessorFactory(), maciContract.tallyFactory(), - maciContract.subsidyFactory(), maciContract.signUpGatekeeper(), maciContract.initialVoiceCreditProxy(), maciContract.topupCredit(), @@ -180,7 +180,7 @@ async function registerTallyAndMessageProcessor( tallyContract.vkRegistry(), ]) - let args = [verifier, vkRegistry, poll, mp] + let args = [verifier, vkRegistry, poll, mp, EMode.QV] await storage.register({ id: EContracts.Tally, contract: tallyContract, @@ -189,7 +189,7 @@ async function registerTallyAndMessageProcessor( tx, }) - args = [verifier, vkRegistry, poll] + args = [verifier, vkRegistry, poll, EMode.QV] await storage.register({ id: EContracts.MessageProcessor, contract: messageProcessorContract, diff --git a/contracts/utils/contracts.ts b/contracts/utils/contracts.ts index 77a2bc72d..3c26cf5d8 100644 --- a/contracts/utils/contracts.ts +++ b/contracts/utils/contracts.ts @@ -12,7 +12,7 @@ import { } from '@nomicfoundation/hardhat-ethers/types' import { VkRegistry, FundingRound } from '../typechain-types' import { MaciParameters } from './maciParameters' -import { IVerifyingKeyStruct } from 'maci-contracts' +import { EMode, IVerifyingKeyStruct } from 'maci-contracts' /** * Deploy a contract @@ -54,6 +54,7 @@ export async function setVerifyingKeys( params.treeDepths.messageTreeDepth, params.treeDepths.voteOptionTreeDepth, messageBatchSize, + EMode.QV, params.processVk.asContractParam() as IVerifyingKeyStruct, params.tallyVk.asContractParam() as IVerifyingKeyStruct ) @@ -128,10 +129,6 @@ export function getQualifiedContractName(name: EContracts | string): string { let contractName = String(name) if (contractName.includes('Poseidon')) { contractName = `:${name}` - } else if (name === EContracts.PollFactory) { - contractName = 'contracts/maci/PollFactory.sol:PollFactory' - } else if (name === EContracts.Poll) { - contractName = 'contracts/maci/Poll.sol:Poll' } return contractName } diff --git a/contracts/utils/maci.ts b/contracts/utils/maci.ts index bb3e3bb0b..caa8467ba 100644 --- a/contracts/utils/maci.ts +++ b/contracts/utils/maci.ts @@ -23,7 +23,7 @@ import { verify, } from 'maci-cli' -import { getTalyFilePath, isPathExist } from './misc' +import { isPathExist } from './misc' import { getCircuitFiles } from './circuits' import { FundingRound } from '../typechain-types' @@ -303,7 +303,7 @@ export async function mergeMaciSubtrees({ await mergeMessages({ pollId, - maciContractAddress: maciAddress, + maciAddress, numQueueOps, signer, quiet, @@ -311,7 +311,7 @@ export async function mergeMaciSubtrees({ await mergeSignups({ pollId, - maciContractAddress: maciAddress, + maciAddress, numQueueOps, signer, quiet, diff --git a/subgraph/abis/MACI.json b/subgraph/abis/MACI.json index 4a09120f9..ba7b1c96a 100644 --- a/subgraph/abis/MACI.json +++ b/subgraph/abis/MACI.json @@ -12,15 +12,10 @@ "type": "address" }, { - "internalType": "contract ITallySubsidyFactory", + "internalType": "contract ITallyFactory", "name": "_tallyFactory", "type": "address" }, - { - "internalType": "contract ITallySubsidyFactory", - "name": "_subsidyFactory", - "type": "address" - }, { "internalType": "contract SignUpGatekeeper", "name": "_signUpGatekeeper", @@ -63,7 +58,29 @@ }, { "inputs": [], - "name": "MaciPubKeyLargerThanSnarkFieldSize", + "name": "InvalidPubKey", + "type": "error" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "owner", + "type": "address" + } + ], + "name": "OwnableInvalidOwner", + "type": "error" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "account", + "type": "address" + } + ], + "name": "OwnableUnauthorizedAccount", "type": "error" }, { @@ -140,11 +157,6 @@ "internalType": "address", "name": "tally", "type": "address" - }, - { - "internalType": "address", - "name": "subsidy", - "type": "address" } ], "indexed": false, @@ -287,9 +299,9 @@ "type": "address" }, { - "internalType": "bool", - "name": "useSubsidy", - "type": "bool" + "internalType": "enum DomainObjs.Mode", + "name": "_mode", + "type": "uint8" } ], "name": "deployPoll", @@ -310,11 +322,6 @@ "internalType": "address", "name": "tally", "type": "address" - }, - { - "internalType": "address", - "name": "subsidy", - "type": "address" } ], "internalType": "struct MACI.PollContracts", @@ -845,19 +852,6 @@ "stateMutability": "view", "type": "function" }, - { - "inputs": [], - "name": "subsidyFactory", - "outputs": [ - { - "internalType": "contract ITallySubsidyFactory", - "name": "", - "type": "address" - } - ], - "stateMutability": "view", - "type": "function" - }, { "inputs": [], "name": "subtreesMerged", @@ -876,7 +870,7 @@ "name": "tallyFactory", "outputs": [ { - "internalType": "contract ITallySubsidyFactory", + "internalType": "contract ITallyFactory", "name": "", "type": "address" } diff --git a/subgraph/abis/Poll.json b/subgraph/abis/Poll.json index 671177ba2..e31d07163 100644 --- a/subgraph/abis/Poll.json +++ b/subgraph/abis/Poll.json @@ -105,7 +105,29 @@ }, { "inputs": [], - "name": "MaciPubKeyLargerThanSnarkFieldSize", + "name": "InvalidPubKey", + "type": "error" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "owner", + "type": "address" + } + ], + "name": "OwnableInvalidOwner", + "type": "error" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "account", + "type": "address" + } + ], + "name": "OwnableUnauthorizedAccount", "type": "error" }, { @@ -142,13 +164,13 @@ "anonymous": false, "inputs": [ { - "indexed": false, + "indexed": true, "internalType": "uint256", "name": "_stateRoot", "type": "uint256" }, { - "indexed": false, + "indexed": true, "internalType": "uint256", "name": "_numSignups", "type": "uint256" @@ -161,7 +183,7 @@ "anonymous": false, "inputs": [ { - "indexed": false, + "indexed": true, "internalType": "uint256", "name": "_numSrQueueOps", "type": "uint256" @@ -174,7 +196,7 @@ "anonymous": false, "inputs": [ { - "indexed": false, + "indexed": true, "internalType": "uint256", "name": "_messageRoot", "type": "uint256" @@ -187,7 +209,7 @@ "anonymous": false, "inputs": [ { - "indexed": false, + "indexed": true, "internalType": "uint256", "name": "_numSrQueueOps", "type": "uint256" diff --git a/subgraph/generated/ClrFund/MACI.ts b/subgraph/generated/ClrFund/MACI.ts index b1b8238e1..a770b955e 100644 --- a/subgraph/generated/ClrFund/MACI.ts +++ b/subgraph/generated/ClrFund/MACI.ts @@ -54,10 +54,6 @@ export class DeployPollPollAddrStruct extends ethereum.Tuple { get tally(): Address { return this[2].toAddress(); } - - get subsidy(): Address { - return this[3].toAddress(); - } } export class OwnershipTransferred extends ethereum.Event { @@ -128,10 +124,6 @@ export class MACI__deployPollResultPollAddrStruct extends ethereum.Tuple { get tally(): Address { return this[2].toAddress(); } - - get subsidy(): Address { - return this[3].toAddress(); - } } export class MACI__deployPollInput_treeDepthsStruct extends ethereum.Tuple { @@ -298,18 +290,18 @@ export class MACI extends ethereum.SmartContract { _coordinatorPubKey: MACI__deployPollInput_coordinatorPubKeyStruct, _verifier: Address, _vkRegistry: Address, - useSubsidy: boolean, + _mode: i32, ): MACI__deployPollResultPollAddrStruct { let result = super.call( "deployPoll", - "deployPoll(uint256,(uint8,uint8,uint8,uint8),(uint256,uint256),address,address,bool):((address,address,address,address))", + "deployPoll(uint256,(uint8,uint8,uint8,uint8),(uint256,uint256),address,address,uint8):((address,address,address))", [ ethereum.Value.fromUnsignedBigInt(_duration), ethereum.Value.fromTuple(_treeDepths), ethereum.Value.fromTuple(_coordinatorPubKey), ethereum.Value.fromAddress(_verifier), ethereum.Value.fromAddress(_vkRegistry), - ethereum.Value.fromBoolean(useSubsidy), + ethereum.Value.fromUnsignedBigInt(BigInt.fromI32(_mode)), ], ); @@ -324,18 +316,18 @@ export class MACI extends ethereum.SmartContract { _coordinatorPubKey: MACI__deployPollInput_coordinatorPubKeyStruct, _verifier: Address, _vkRegistry: Address, - useSubsidy: boolean, + _mode: i32, ): ethereum.CallResult { let result = super.tryCall( "deployPoll", - "deployPoll(uint256,(uint8,uint8,uint8,uint8),(uint256,uint256),address,address,bool):((address,address,address,address))", + "deployPoll(uint256,(uint8,uint8,uint8,uint8),(uint256,uint256),address,address,uint8):((address,address,address))", [ ethereum.Value.fromUnsignedBigInt(_duration), ethereum.Value.fromTuple(_treeDepths), ethereum.Value.fromTuple(_coordinatorPubKey), ethereum.Value.fromAddress(_verifier), ethereum.Value.fromAddress(_vkRegistry), - ethereum.Value.fromBoolean(useSubsidy), + ethereum.Value.fromUnsignedBigInt(BigInt.fromI32(_mode)), ], ); if (result.reverted) { @@ -831,25 +823,6 @@ export class MACI extends ethereum.SmartContract { return ethereum.CallResult.fromValue(value[0].toI32()); } - subsidyFactory(): Address { - let result = super.call("subsidyFactory", "subsidyFactory():(address)", []); - - return result[0].toAddress(); - } - - try_subsidyFactory(): ethereum.CallResult
{ - let result = super.tryCall( - "subsidyFactory", - "subsidyFactory():(address)", - [], - ); - if (result.reverted) { - return new ethereum.CallResult(); - } - let value = result.value; - return ethereum.CallResult.fromValue(value[0].toAddress()); - } - subtreesMerged(): boolean { let result = super.call("subtreesMerged", "subtreesMerged():(bool)", []); @@ -925,24 +898,20 @@ export class ConstructorCall__Inputs { return this._call.inputValues[2].value.toAddress(); } - get _subsidyFactory(): Address { - return this._call.inputValues[3].value.toAddress(); - } - get _signUpGatekeeper(): Address { - return this._call.inputValues[4].value.toAddress(); + return this._call.inputValues[3].value.toAddress(); } get _initialVoiceCreditProxy(): Address { - return this._call.inputValues[5].value.toAddress(); + return this._call.inputValues[4].value.toAddress(); } get _topupCredit(): Address { - return this._call.inputValues[6].value.toAddress(); + return this._call.inputValues[5].value.toAddress(); } get _stateTreeDepth(): i32 { - return this._call.inputValues[7].value.toI32(); + return this._call.inputValues[6].value.toI32(); } } @@ -995,8 +964,8 @@ export class DeployPollCall__Inputs { return this._call.inputValues[4].value.toAddress(); } - get useSubsidy(): boolean { - return this._call.inputValues[5].value.toBoolean(); + get _mode(): i32 { + return this._call.inputValues[5].value.toI32(); } } @@ -1054,10 +1023,6 @@ export class DeployPollCallPollAddrStruct extends ethereum.Tuple { get tally(): Address { return this[2].toAddress(); } - - get subsidy(): Address { - return this[3].toAddress(); - } } export class MergeStateAqCall extends ethereum.Call { diff --git a/subgraph/generated/templates/MACI/MACI.ts b/subgraph/generated/templates/MACI/MACI.ts index b1b8238e1..a770b955e 100644 --- a/subgraph/generated/templates/MACI/MACI.ts +++ b/subgraph/generated/templates/MACI/MACI.ts @@ -54,10 +54,6 @@ export class DeployPollPollAddrStruct extends ethereum.Tuple { get tally(): Address { return this[2].toAddress(); } - - get subsidy(): Address { - return this[3].toAddress(); - } } export class OwnershipTransferred extends ethereum.Event { @@ -128,10 +124,6 @@ export class MACI__deployPollResultPollAddrStruct extends ethereum.Tuple { get tally(): Address { return this[2].toAddress(); } - - get subsidy(): Address { - return this[3].toAddress(); - } } export class MACI__deployPollInput_treeDepthsStruct extends ethereum.Tuple { @@ -298,18 +290,18 @@ export class MACI extends ethereum.SmartContract { _coordinatorPubKey: MACI__deployPollInput_coordinatorPubKeyStruct, _verifier: Address, _vkRegistry: Address, - useSubsidy: boolean, + _mode: i32, ): MACI__deployPollResultPollAddrStruct { let result = super.call( "deployPoll", - "deployPoll(uint256,(uint8,uint8,uint8,uint8),(uint256,uint256),address,address,bool):((address,address,address,address))", + "deployPoll(uint256,(uint8,uint8,uint8,uint8),(uint256,uint256),address,address,uint8):((address,address,address))", [ ethereum.Value.fromUnsignedBigInt(_duration), ethereum.Value.fromTuple(_treeDepths), ethereum.Value.fromTuple(_coordinatorPubKey), ethereum.Value.fromAddress(_verifier), ethereum.Value.fromAddress(_vkRegistry), - ethereum.Value.fromBoolean(useSubsidy), + ethereum.Value.fromUnsignedBigInt(BigInt.fromI32(_mode)), ], ); @@ -324,18 +316,18 @@ export class MACI extends ethereum.SmartContract { _coordinatorPubKey: MACI__deployPollInput_coordinatorPubKeyStruct, _verifier: Address, _vkRegistry: Address, - useSubsidy: boolean, + _mode: i32, ): ethereum.CallResult { let result = super.tryCall( "deployPoll", - "deployPoll(uint256,(uint8,uint8,uint8,uint8),(uint256,uint256),address,address,bool):((address,address,address,address))", + "deployPoll(uint256,(uint8,uint8,uint8,uint8),(uint256,uint256),address,address,uint8):((address,address,address))", [ ethereum.Value.fromUnsignedBigInt(_duration), ethereum.Value.fromTuple(_treeDepths), ethereum.Value.fromTuple(_coordinatorPubKey), ethereum.Value.fromAddress(_verifier), ethereum.Value.fromAddress(_vkRegistry), - ethereum.Value.fromBoolean(useSubsidy), + ethereum.Value.fromUnsignedBigInt(BigInt.fromI32(_mode)), ], ); if (result.reverted) { @@ -831,25 +823,6 @@ export class MACI extends ethereum.SmartContract { return ethereum.CallResult.fromValue(value[0].toI32()); } - subsidyFactory(): Address { - let result = super.call("subsidyFactory", "subsidyFactory():(address)", []); - - return result[0].toAddress(); - } - - try_subsidyFactory(): ethereum.CallResult
{ - let result = super.tryCall( - "subsidyFactory", - "subsidyFactory():(address)", - [], - ); - if (result.reverted) { - return new ethereum.CallResult(); - } - let value = result.value; - return ethereum.CallResult.fromValue(value[0].toAddress()); - } - subtreesMerged(): boolean { let result = super.call("subtreesMerged", "subtreesMerged():(bool)", []); @@ -925,24 +898,20 @@ export class ConstructorCall__Inputs { return this._call.inputValues[2].value.toAddress(); } - get _subsidyFactory(): Address { - return this._call.inputValues[3].value.toAddress(); - } - get _signUpGatekeeper(): Address { - return this._call.inputValues[4].value.toAddress(); + return this._call.inputValues[3].value.toAddress(); } get _initialVoiceCreditProxy(): Address { - return this._call.inputValues[5].value.toAddress(); + return this._call.inputValues[4].value.toAddress(); } get _topupCredit(): Address { - return this._call.inputValues[6].value.toAddress(); + return this._call.inputValues[5].value.toAddress(); } get _stateTreeDepth(): i32 { - return this._call.inputValues[7].value.toI32(); + return this._call.inputValues[6].value.toI32(); } } @@ -995,8 +964,8 @@ export class DeployPollCall__Inputs { return this._call.inputValues[4].value.toAddress(); } - get useSubsidy(): boolean { - return this._call.inputValues[5].value.toBoolean(); + get _mode(): i32 { + return this._call.inputValues[5].value.toI32(); } } @@ -1054,10 +1023,6 @@ export class DeployPollCallPollAddrStruct extends ethereum.Tuple { get tally(): Address { return this[2].toAddress(); } - - get subsidy(): Address { - return this[3].toAddress(); - } } export class MergeStateAqCall extends ethereum.Call { diff --git a/yarn.lock b/yarn.lock index 970c4343b..025a4e9ea 100644 --- a/yarn.lock +++ b/yarn.lock @@ -631,10 +631,10 @@ resolved "https://registry.yarnpkg.com/@colors/colors/-/colors-1.6.0.tgz#ec6cd237440700bc23ca23087f513c75508958b0" integrity sha512-Ir+AOibqzrIsL6ajt3Rz3LskB7OiMVHqltZmspbW/TJuTVuyOMirVqAkjfY6JISiLHgyNqicAC8AyHHGzNd/dA== -"@commander-js/extra-typings@^12.0.0": - version "12.0.0" - resolved "https://registry.yarnpkg.com/@commander-js/extra-typings/-/extra-typings-12.0.0.tgz#a3ef893e75dcf08bb1e51fc7e9fe8ed2d9246bf4" - integrity sha512-7zGCwtRKOJ978LCuEZbQ9ZmLdrRkNNASphEO5i9MZb6HfOk7KfsA3f4oXqYDhko4tNrU3GmZTlHqQ/nRlYtYSw== +"@commander-js/extra-typings@^12.0.1": + version "12.0.1" + resolved "https://registry.yarnpkg.com/@commander-js/extra-typings/-/extra-typings-12.0.1.tgz#4a74a9ccf1d19ef24e71df59359c6d90a605a469" + integrity sha512-OvkMobb1eMqOCuJdbuSin/KJkkZr7n24/UNV+Lcz/0Dhepf3r2p9PaGwpRpAWej7A+gQnny4h8mGhpFl4giKkg== "@cspotcode/source-map-support@^0.8.0": version "0.8.1" @@ -1912,6 +1912,14 @@ 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" @@ -2674,6 +2682,54 @@ "@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.7": + 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" @@ -2687,18 +2743,6 @@ ethereum-cryptography "0.1.3" ethers "^5.7.1" -"@nomicfoundation/ethereumjs-block@5.0.4": - version "5.0.4" - resolved "https://registry.yarnpkg.com/@nomicfoundation/ethereumjs-block/-/ethereumjs-block-5.0.4.tgz#ff2acb98a86b9290e35e315a6abfb9aebb9cf39e" - integrity sha512-AcyacJ9eX/uPEvqsPiB+WO1ymE+kyH48qGGiGV+YTojdtas8itUTW5dehDSOXEEItWGbbzEJ4PRqnQZlWaPvDw== - dependencies: - "@nomicfoundation/ethereumjs-common" "4.0.4" - "@nomicfoundation/ethereumjs-rlp" "5.0.4" - "@nomicfoundation/ethereumjs-trie" "6.0.4" - "@nomicfoundation/ethereumjs-tx" "5.0.4" - "@nomicfoundation/ethereumjs-util" "9.0.4" - ethereum-cryptography "0.1.3" - "@nomicfoundation/ethereumjs-blockchain@7.0.2": version "7.0.2" resolved "https://registry.yarnpkg.com/@nomicfoundation/ethereumjs-blockchain/-/ethereumjs-blockchain-7.0.2.tgz#45323b673b3d2fab6b5008535340d1b8fea7d446" @@ -2718,22 +2762,6 @@ lru-cache "^5.1.1" memory-level "^1.0.0" -"@nomicfoundation/ethereumjs-blockchain@7.0.4": - version "7.0.4" - resolved "https://registry.yarnpkg.com/@nomicfoundation/ethereumjs-blockchain/-/ethereumjs-blockchain-7.0.4.tgz#b77511b389290b186c8d999e70f4b15c27ef44ea" - integrity sha512-jYsd/kwzbmpnxx86tXsYV8wZ5xGvFL+7/P0c6OlzpClHsbFzeF41KrYA9scON8Rg6bZu3ZTv6JOAgj3t7USUfg== - dependencies: - "@nomicfoundation/ethereumjs-block" "5.0.4" - "@nomicfoundation/ethereumjs-common" "4.0.4" - "@nomicfoundation/ethereumjs-ethash" "3.0.4" - "@nomicfoundation/ethereumjs-rlp" "5.0.4" - "@nomicfoundation/ethereumjs-trie" "6.0.4" - "@nomicfoundation/ethereumjs-tx" "5.0.4" - "@nomicfoundation/ethereumjs-util" "9.0.4" - debug "^4.3.3" - ethereum-cryptography "0.1.3" - lru-cache "^10.0.0" - "@nomicfoundation/ethereumjs-common@4.0.2": version "4.0.2" resolved "https://registry.yarnpkg.com/@nomicfoundation/ethereumjs-common/-/ethereumjs-common-4.0.2.tgz#a15d1651ca36757588fdaf2a7d381a150662a3c3" @@ -2761,17 +2789,6 @@ bigint-crypto-utils "^3.0.23" ethereum-cryptography "0.1.3" -"@nomicfoundation/ethereumjs-ethash@3.0.4": - version "3.0.4" - resolved "https://registry.yarnpkg.com/@nomicfoundation/ethereumjs-ethash/-/ethereumjs-ethash-3.0.4.tgz#06cb2502b3012fb6c11cffd44af08aecf71310da" - integrity sha512-xvIrwIMl9sSaiYKRem68+O7vYdj7Q2XWv5P7JXiIkn83918QzWHvqbswTRsH7+r6X1UEvdsURRnZbvZszEjAaQ== - dependencies: - "@nomicfoundation/ethereumjs-block" "5.0.4" - "@nomicfoundation/ethereumjs-rlp" "5.0.4" - "@nomicfoundation/ethereumjs-util" "9.0.4" - bigint-crypto-utils "^3.2.2" - ethereum-cryptography "0.1.3" - "@nomicfoundation/ethereumjs-evm@2.0.2": version "2.0.2" resolved "https://registry.yarnpkg.com/@nomicfoundation/ethereumjs-evm/-/ethereumjs-evm-2.0.2.tgz#4c2f4b84c056047102a4fa41c127454e3f0cfcf6" @@ -2786,20 +2803,6 @@ mcl-wasm "^0.7.1" rustbn.js "~0.2.0" -"@nomicfoundation/ethereumjs-evm@2.0.4": - version "2.0.4" - resolved "https://registry.yarnpkg.com/@nomicfoundation/ethereumjs-evm/-/ethereumjs-evm-2.0.4.tgz#c9c761767283ac53946185474362230b169f8f63" - integrity sha512-lTyZZi1KpeMHzaO6cSVisR2tjiTTedjo7PcmhI/+GNFo9BmyY6QYzGeSti0sFttmjbEMioHgXxl5yrLNRg6+1w== - dependencies: - "@nomicfoundation/ethereumjs-common" "4.0.4" - "@nomicfoundation/ethereumjs-statemanager" "2.0.4" - "@nomicfoundation/ethereumjs-tx" "5.0.4" - "@nomicfoundation/ethereumjs-util" "9.0.4" - "@types/debug" "^4.1.9" - debug "^4.3.3" - ethereum-cryptography "0.1.3" - rustbn-wasm "^0.2.0" - "@nomicfoundation/ethereumjs-rlp@5.0.2": version "5.0.2" resolved "https://registry.yarnpkg.com/@nomicfoundation/ethereumjs-rlp/-/ethereumjs-rlp-5.0.2.tgz#4fee8dc58a53ac6ae87fb1fca7c15dc06c6b5dea" @@ -2822,20 +2825,6 @@ ethers "^5.7.1" js-sdsl "^4.1.4" -"@nomicfoundation/ethereumjs-statemanager@2.0.4": - version "2.0.4" - resolved "https://registry.yarnpkg.com/@nomicfoundation/ethereumjs-statemanager/-/ethereumjs-statemanager-2.0.4.tgz#bf14415e1f31b5ea8b98a0c027c547d0555059b6" - integrity sha512-HPDjeFrxw6llEi+BzqXkZ+KkvFnTOPczuHBtk21hRlDiuKuZz32dPzlhpRsDBGV1b5JTmRDUVqCS1lp3Gghw4Q== - dependencies: - "@nomicfoundation/ethereumjs-common" "4.0.4" - "@nomicfoundation/ethereumjs-rlp" "5.0.4" - "@nomicfoundation/ethereumjs-trie" "6.0.4" - "@nomicfoundation/ethereumjs-util" "9.0.4" - debug "^4.3.3" - ethereum-cryptography "0.1.3" - js-sdsl "^4.1.4" - lru-cache "^10.0.0" - "@nomicfoundation/ethereumjs-trie@6.0.2": version "6.0.2" resolved "https://registry.yarnpkg.com/@nomicfoundation/ethereumjs-trie/-/ethereumjs-trie-6.0.2.tgz#9a6dbd28482dca1bc162d12b3733acab8cd12835" @@ -2847,18 +2836,6 @@ ethereum-cryptography "0.1.3" readable-stream "^3.6.0" -"@nomicfoundation/ethereumjs-trie@6.0.4": - version "6.0.4" - resolved "https://registry.yarnpkg.com/@nomicfoundation/ethereumjs-trie/-/ethereumjs-trie-6.0.4.tgz#688a3f76646c209365ee6d959c3d7330ede5e609" - integrity sha512-3nSwQiFMvr2VFe/aZUyinuohYvtytUqZCUCvIWcPJ/BwJH6oQdZRB42aNFBJ/8nAh2s3OcroWpBLskzW01mFKA== - dependencies: - "@nomicfoundation/ethereumjs-rlp" "5.0.4" - "@nomicfoundation/ethereumjs-util" "9.0.4" - "@types/readable-stream" "^2.3.13" - ethereum-cryptography "0.1.3" - lru-cache "^10.0.0" - readable-stream "^3.6.0" - "@nomicfoundation/ethereumjs-tx@5.0.2": version "5.0.2" resolved "https://registry.yarnpkg.com/@nomicfoundation/ethereumjs-tx/-/ethereumjs-tx-5.0.2.tgz#117813b69c0fdc14dd0446698a64be6df71d7e56" @@ -2898,16 +2875,6 @@ "@nomicfoundation/ethereumjs-rlp" "5.0.4" ethereum-cryptography "0.1.3" -"@nomicfoundation/ethereumjs-verkle@0.0.2": - version "0.0.2" - resolved "https://registry.yarnpkg.com/@nomicfoundation/ethereumjs-verkle/-/ethereumjs-verkle-0.0.2.tgz#7686689edec775b2efea5a71548f417c18f7dea4" - integrity sha512-bjnfZElpYGK/XuuVRmLS3yDvr+cDs85D9oonZ0YUa5A3lgFgokWMp76zXrxX2jVQ0BfHaw12y860n1+iOi6yFQ== - dependencies: - "@nomicfoundation/ethereumjs-rlp" "5.0.4" - "@nomicfoundation/ethereumjs-util" "9.0.4" - lru-cache "^10.0.0" - rust-verkle-wasm "^0.0.1" - "@nomicfoundation/ethereumjs-vm@7.0.2": version "7.0.2" resolved "https://registry.yarnpkg.com/@nomicfoundation/ethereumjs-vm/-/ethereumjs-vm-7.0.2.tgz#3b0852cb3584df0e18c182d0672a3596c9ca95e6" @@ -2927,27 +2894,10 @@ mcl-wasm "^0.7.1" rustbn.js "~0.2.0" -"@nomicfoundation/ethereumjs-vm@7.0.4": - version "7.0.4" - resolved "https://registry.yarnpkg.com/@nomicfoundation/ethereumjs-vm/-/ethereumjs-vm-7.0.4.tgz#e5a6eec4877dc62dda93003c6d7afd1fe4b9625b" - integrity sha512-gsA4IhmtWHI4BofKy3kio9W+dqZQs5Ji5mLjLYxHCkat+JQBUt5szjRKra2F9nGDJ2XcI/wWb0YWUFNgln4zRQ== - dependencies: - "@nomicfoundation/ethereumjs-block" "5.0.4" - "@nomicfoundation/ethereumjs-blockchain" "7.0.4" - "@nomicfoundation/ethereumjs-common" "4.0.4" - "@nomicfoundation/ethereumjs-evm" "2.0.4" - "@nomicfoundation/ethereumjs-rlp" "5.0.4" - "@nomicfoundation/ethereumjs-statemanager" "2.0.4" - "@nomicfoundation/ethereumjs-trie" "6.0.4" - "@nomicfoundation/ethereumjs-tx" "5.0.4" - "@nomicfoundation/ethereumjs-util" "9.0.4" - debug "^4.3.3" - ethereum-cryptography "0.1.3" - -"@nomicfoundation/hardhat-chai-matchers@^2.0.3": - version "2.0.3" - resolved "https://registry.yarnpkg.com/@nomicfoundation/hardhat-chai-matchers/-/hardhat-chai-matchers-2.0.3.tgz#f4c074d39b74bd283c99e2c2bf143e3cef51ae18" - integrity sha512-A40s7EAK4Acr8UP1Yudgi9GGD9Cca/K3LHt3DzmRIje14lBfHtg9atGQ7qK56vdPcTwKmeaGn30FzxMUfPGEMw== +"@nomicfoundation/hardhat-chai-matchers@^2.0.6": + version "2.0.6" + resolved "https://registry.yarnpkg.com/@nomicfoundation/hardhat-chai-matchers/-/hardhat-chai-matchers-2.0.6.tgz#ef88be3bd666adf29c06ac7882e96c8dbaaa32ba" + integrity sha512-Te1Uyo9oJcTCF0Jy9dztaLpshmlpjLf2yPtWXlXuLjMt3RRSmJLm/+rKVTW6gfadAEs12U/it6D0ZRnnRGiICQ== dependencies: "@types/chai-as-promised" "^7.1.3" chai-as-promised "^7.1.1" @@ -2962,6 +2912,14 @@ debug "^4.1.1" lodash.isequal "^4.5.0" +"@nomicfoundation/hardhat-ethers@^3.0.6": + version "3.0.6" + resolved "https://registry.yarnpkg.com/@nomicfoundation/hardhat-ethers/-/hardhat-ethers-3.0.6.tgz#e8ba7f9719de360c03501b85dae4999bb3a7e1c5" + integrity sha512-/xzkFQAaHQhmIAYOQmvHBPwL+NkwLzT9gRZBsgWUYeV+E6pzXsBQsHfRYbAZ3XEYare+T7S+5Tg/1KDJgepSkA== + dependencies: + debug "^4.1.1" + lodash.isequal "^4.5.0" + "@nomicfoundation/hardhat-network-helpers@^1.0.10": version "1.0.10" resolved "https://registry.yarnpkg.com/@nomicfoundation/hardhat-network-helpers/-/hardhat-network-helpers-1.0.10.tgz#c61042ceb104fdd6c10017859fdef6529c1d6585" @@ -2974,6 +2932,11 @@ 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" @@ -3272,15 +3235,10 @@ resolved "https://registry.yarnpkg.com/@opentelemetry/api/-/api-1.6.0.tgz#de2c6823203d6f319511898bb5de7e70f5267e19" integrity sha512-OWlrQAnWn9577PhVgqjUvMr1pg57Bc4jv0iL4w0PRuOSRvq67rvHW9Ie/dZVMvCzhSCB+UxhcY/PmCmFj33Q+g== -"@openzeppelin/contracts@4.9.0": - version "4.9.0" - resolved "https://registry.yarnpkg.com/@openzeppelin/contracts/-/contracts-4.9.0.tgz#683f33b6598970051bc5f0806fd8660da9e018dd" - integrity sha512-DUP74AFGKlic2sQb/CmgrN2aUPMFGxRrmCTUxLHsiU2RzwWqVuMPZBxiAyvlff6Pea77uylAX6B5x9W6evEbhA== - -"@openzeppelin/contracts@^4.8.0": - version "4.9.5" - 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", "@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" @@ -3544,7 +3502,7 @@ resolved "https://registry.yarnpkg.com/@rushstack/eslint-patch/-/eslint-patch-1.6.1.tgz#9ab8f811930d7af3e3d549183a50884f9eb83f36" integrity sha512-UY+FGM/2jjMkzQLn8pxcHGMaVLh9aEitG3zY2CiY7XHdLiz3bZOwa6oDxNqEMv7zZkV+cj5DOdz0cQ1BP5Hjgw== -"@scure/base@^1.1.1", "@scure/base@~1.1.0": +"@scure/base@~1.1.0": version "1.1.5" resolved "https://registry.yarnpkg.com/@scure/base/-/base-1.1.5.tgz#1d85d17269fe97694b9c592552dd9e5e33552157" integrity sha512-Brj9FiG2W1MRQSTB212YVPRrcbjkv48FoZi/u4l/zds/ieRrqsh7aUf6CLwkAq61oKXr/ZlTzlY66gLIj3TFTQ== @@ -3964,13 +3922,6 @@ dependencies: "@types/node" "*" -"@types/debug@^4.1.9": - version "4.1.12" - resolved "https://registry.yarnpkg.com/@types/debug/-/debug-4.1.12.tgz#a155f21690871953410df4b6b6f53187f0500917" - integrity sha512-vIChWdVG3LG1SMxEvI/AK+FWJthlrqlTu7fbrlywTkkaONwk/UAGaULXRlf8vkzFBLVm0zkMdCquhL5aOjhXPQ== - dependencies: - "@types/ms" "*" - "@types/estree@^1.0.0": version "1.0.5" resolved "https://registry.yarnpkg.com/@types/estree/-/estree-1.0.5.tgz#a6ce3e556e00fd9895dd872dd172ad0d4bd687f4" @@ -4091,11 +4042,6 @@ resolved "https://registry.yarnpkg.com/@types/mocha/-/mocha-10.0.6.tgz#818551d39113081048bdddbef96701b4e8bb9d1b" integrity sha512-dJvrYWxP/UcXm36Qn36fxhUKu8A/xMRXVT2cliFF1Z7UA9liG5Psj3ezNSZw+5puH2czDXRLcXQxf8JbJt0ejg== -"@types/ms@*": - version "0.7.34" - resolved "https://registry.yarnpkg.com/@types/ms/-/ms-0.7.34.tgz#10964ba0dee6ac4cd462e2795b6bebd407303433" - integrity sha512-nG96G3Wp6acyAgJqGasjODb+acrI7KltPiRxzHPXnP3NgI28bpQDRv53olbqGXbfcgF5aiiHmO3xpwEpS5Ld9g== - "@types/node@*", "@types/node@>=13.7.0": version "20.11.2" resolved "https://registry.yarnpkg.com/@types/node/-/node-20.11.2.tgz#39cea3fe02fbbc2f80ed283e94e1d24f2d3856fb" @@ -4956,40 +4902,62 @@ resolved "https://registry.yarnpkg.com/@yarnpkg/lockfile/-/lockfile-1.1.0.tgz#e77a97fbd345b76d83245edcd17d393b1b41fb31" integrity sha512-GpSwvyXOcOOlV70vbnzjj4fW5xW/FdUF6nQEt1ENy7m4ZCczi1+/buVUPAqmGfqznsORNFzUMjctTIp8a9tuCQ== -"@zk-kit/baby-jubjub@0.1.1", "@zk-kit/baby-jubjub@^0.1.1": - version "0.1.1" - resolved "https://registry.yarnpkg.com/@zk-kit/baby-jubjub/-/baby-jubjub-0.1.1.tgz#8da922d1c0138ca8668c6ba1134ec04f51b24804" - integrity sha512-eWpUSpKKpllGZXE6mdS1IVuegRjY2Yu+3Qccyfg0+gMI8+p0ruioMM/MCK3tg2lRIUJTVd+16UghVcK0145yWg== +"@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.1.0" + "@zk-kit/utils" "0.3.0" -"@zk-kit/circuits@^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/circuits/-/circuits-0.3.0.tgz#716d932e9b09f33c71c7ff940a507e519ce0a6f4" - integrity sha512-v46KHC3sBRXUJbYi8d5PTAm3zCdBeArvWw3de+A2LcW/C9beYqBo8QJ/h6NWKZWOgpwqvCHzJa5HvyG6x3lIZQ== + 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.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.5.1": - version "0.5.1" - resolved "https://registry.yarnpkg.com/@zk-kit/eddsa-poseidon/-/eddsa-poseidon-0.5.1.tgz#7fef431f441f5385f82e6005cdf83d72d298e8c2" - integrity sha512-sPyoyjwg9EZ+tHLGxOG+FDj9XJK1knVjm27nTMV4ZSiQIf0427QWnLhOk7b6zMvFmEpBWTG9gneJ5pr3jzJ4zg== +"@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.1.1" - "@zk-kit/utils" "0.1.0" + "@zk-kit/baby-jubjub" "0.3.0" + "@zk-kit/utils" "0.8.1" + buffer "6.0.3" -"@zk-kit/poseidon-cipher@^0.2.1": - version "0.2.1" - resolved "https://registry.yarnpkg.com/@zk-kit/poseidon-cipher/-/poseidon-cipher-0.2.1.tgz#74cd80144b6755eff8e92643c4ef3f828f5822c5" - integrity sha512-/k7lUzYPuzFmdjBCvl8yTE4aDCnqxoVC46Txa9Z0i7rb+ilXHp2EEwfig/G7moTukSiOB3hywF3im/QGs3cYHg== +"@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.1.1" - "@zk-kit/utils" "0.1.0" + "@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" @@ -6464,7 +6432,7 @@ bfj@^7.0.2: jsonpath "^1.1.1" tryer "^1.0.1" -bigint-crypto-utils@^3.0.23, bigint-crypto-utils@^3.2.2: +bigint-crypto-utils@^3.0.23: version "3.3.0" resolved "https://registry.yarnpkg.com/bigint-crypto-utils/-/bigint-crypto-utils-3.3.0.tgz#72ad00ae91062cf07f2b1def9594006c279c1d77" integrity sha512-jOTSb+drvEDxEq6OuUybOAv/xxoh3cuYRUIPyu8sSHQNKM303UQ2R1DAo45o1AkcIXw6fzbaFI1+xGGdaXs2lg== @@ -6896,7 +6864,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.1, buffer@^6.0.3: +"buffer-polyfill@npm:buffer@^6.0.3", 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" @@ -7180,7 +7148,7 @@ chai-as-promised@^7.1.1: dependencies: check-error "^1.0.2" -chai@^4.2.0, chai@^4.3.6, chai@^4.3.7: +chai@4, chai@^4.2.0, chai@^4.3.6, chai@^4.3.7: version "4.4.1" resolved "https://registry.yarnpkg.com/chai/-/chai-4.4.1.tgz#3603fa6eba35425b0f2ac91a009fe924106e50d1" integrity sha512-13sOfMv2+DWduEU+/xbun3LScLoqN17nBeTLUsmDfKdoiC1fr0n9PU4guu4AhRcOVFk/sW8LyZWHuhWtQZiF+g== @@ -7407,6 +7375,13 @@ 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" @@ -7421,10 +7396,10 @@ circom_tester@^0.0.19: tmp-promise "^3.0.3" util "^0.12.4" -circomkit@^0.0.24: - version "0.0.24" - resolved "https://registry.yarnpkg.com/circomkit/-/circomkit-0.0.24.tgz#11db0ba17da9f5bd3e58bc87d5b39bb8375e3bf8" - integrity sha512-lw5Kj6zAWS8NYZjlDCGEDeA1e0/Vpa6t6W3GT0AxfhswUoqK0Nu3sz5hu8ZQ+Efh0Ss3eLoD0y+9sOkySEwgEA== +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" @@ -10182,6 +10157,19 @@ ethers@^6.11.1: tslib "2.4.0" ws "8.5.0" +ethers@^6.12.0, ethers@^6.12.1: + 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" @@ -10708,6 +10696,15 @@ 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" @@ -11960,24 +11957,17 @@ hardhat@^2.19.4: uuid "^8.3.2" ws "^7.4.6" -hardhat@^2.20.1: - version "2.20.1" - resolved "https://registry.yarnpkg.com/hardhat/-/hardhat-2.20.1.tgz#3ad8f2b003a96c9ce80a55fec3575580ff2ddcd4" - integrity sha512-q75xDQiQtCZcTMBwjTovrXEU5ECr49baxr4/OBkIu/ULTPzlB20yk1dRWNmD2IFbAeAeXggaWvQAdpiScaHtPw== +hardhat@^2.22.3: + version "2.22.4" + resolved "https://registry.yarnpkg.com/hardhat/-/hardhat-2.22.4.tgz#766227b6cefca5dbf4fd15ab5b5a68138fa13baf" + integrity sha512-09qcXJFBHQUaraJkYNr7XlmwjOj27xBB0SL2rYS024hTj9tPMbp26AFjlf5quBMO9SR4AJFg+4qWahcYcvXBuQ== dependencies: "@ethersproject/abi" "^5.1.2" "@metamask/eth-sig-util" "^4.0.0" - "@nomicfoundation/ethereumjs-block" "5.0.4" - "@nomicfoundation/ethereumjs-blockchain" "7.0.4" + "@nomicfoundation/edr" "^0.3.7" "@nomicfoundation/ethereumjs-common" "4.0.4" - "@nomicfoundation/ethereumjs-evm" "2.0.4" - "@nomicfoundation/ethereumjs-rlp" "5.0.4" - "@nomicfoundation/ethereumjs-statemanager" "2.0.4" - "@nomicfoundation/ethereumjs-trie" "6.0.4" "@nomicfoundation/ethereumjs-tx" "5.0.4" "@nomicfoundation/ethereumjs-util" "9.0.4" - "@nomicfoundation/ethereumjs-verkle" "0.0.2" - "@nomicfoundation/ethereumjs-vm" "7.0.4" "@nomicfoundation/solidity-analyzer" "^0.1.0" "@sentry/node" "^5.18.1" "@types/bn.js" "^5.1.0" @@ -13328,6 +13318,11 @@ is-potential-custom-element-name@^1.0.1: resolved "https://registry.yarnpkg.com/is-potential-custom-element-name/-/is-potential-custom-element-name-1.0.1.tgz#171ed6f19e3ac554394edf78caa05784a45bebb5" integrity sha512-bCYeRA2rVibKZd+s2625gGnGF/t7DSqDs4dP7CrLA1m7jKWz6pps0LpYLJN8Q64HtmPKJ1hrN3nzPNKFEKOUiQ== +is-promise@^2.1.0: + version "2.2.2" + resolved "https://registry.yarnpkg.com/is-promise/-/is-promise-2.2.2.tgz#39ab959ccbf9a774cf079f7b40c7a26f763135f1" + integrity sha512-+lP4/6lKUBfQjZ2pdxThZvLUAafmZb8OAxFb8XXtiQmS35INgr85hdOGoEs124ez1FCnZJt6jau/T+alh58QFQ== + is-promise@^4.0.0: version "4.0.0" resolved "https://registry.yarnpkg.com/is-promise/-/is-promise-4.0.0.tgz#42ff9f84206c1991d26debf520dd5c01042dd2f3" @@ -14714,16 +14709,16 @@ lodash.upperfirst@^4.3.1: resolved "https://registry.yarnpkg.com/lodash.upperfirst/-/lodash.upperfirst-4.3.1.tgz#1365edf431480481ef0d1c68957a5ed99d49f7ce" integrity sha512-sReKOYJIJf74dhJONhU4e0/shzi1trVbSWDOhKYE5XV2O+H7Sb2Dihwuc7xWxVl+DgFPyTqIN3zMfT9cq5iWDg== +lodash@4, lodash@4.17.21, lodash@^4.17.11, lodash@^4.17.12, lodash@^4.17.14, lodash@^4.17.15, lodash@^4.17.20, lodash@^4.17.21, lodash@^4.17.4, lodash@~4.17.0: + version "4.17.21" + resolved "https://registry.yarnpkg.com/lodash/-/lodash-4.17.21.tgz#679591c564c3bffaae8454cf0b3df370c3d6911c" + integrity sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg== + lodash@4.17.20: version "4.17.20" resolved "https://registry.yarnpkg.com/lodash/-/lodash-4.17.20.tgz#b44a9b6297bcb698f1c51a3545a2b3b368d59c52" integrity sha512-PlhdFcillOINfeV7Ni6oF1TAEayyZBoZ8bcshTHqOYJYlrqzRK5hagpagky5o4HfCzzd1TRkXPMFq6cKk9rGmA== -lodash@4.17.21, lodash@^4.17.11, lodash@^4.17.12, lodash@^4.17.14, lodash@^4.17.15, lodash@^4.17.20, lodash@^4.17.21, lodash@^4.17.4, lodash@~4.17.0: - version "4.17.21" - resolved "https://registry.yarnpkg.com/lodash/-/lodash-4.17.21.tgz#679591c564c3bffaae8454cf0b3df370c3d6911c" - integrity sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg== - log-process-errors@^8.0.0: version "8.0.0" resolved "https://registry.yarnpkg.com/log-process-errors/-/log-process-errors-8.0.0.tgz#f88a9556e4914037ad97ceee24b148dc1b566dfd" @@ -14837,6 +14832,17 @@ loupe@^2.3.6: dependencies: get-func-name "^2.0.1" +lowdb@1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/lowdb/-/lowdb-1.0.0.tgz#5243be6b22786ccce30e50c9a33eac36b20c8064" + integrity sha512-2+x8esE/Wb9SQ1F9IHaYWfsC9FIecLOPrK4g17FGEayjUWH172H6nwicRovGvSE2CPZouc2MCIqCI7h9d+GftQ== + dependencies: + graceful-fs "^4.1.3" + is-promise "^2.1.0" + lodash "4" + pify "^3.0.0" + steno "^0.4.1" + lower-case-first@^2.0.2: version "2.0.2" resolved "https://registry.yarnpkg.com/lower-case-first/-/lower-case-first-2.0.2.tgz#64c2324a2250bf7c37c5901e76a5b5309301160b" @@ -14873,11 +14879,6 @@ lru-cache@5.1.1, lru-cache@^5.1.1: dependencies: yallist "^3.0.2" -lru-cache@^10.0.0: - version "10.2.0" - resolved "https://registry.yarnpkg.com/lru-cache/-/lru-cache-10.2.0.tgz#0bd445ca57363465900f4d1f9bd8db343a4d95c3" - integrity sha512-2bIM8x+VAf6JT4bKAljS1qUWgMsqZRPGJS6FSahIMPVvctcNhyVp7AJu7quxOW9jwkryBReKZY5tY5JYv2n/7Q== - lru-cache@^10.0.2, "lru-cache@^9.1.1 || ^10.0.0": version "10.1.0" resolved "https://registry.yarnpkg.com/lru-cache/-/lru-cache-10.1.0.tgz#2098d41c2dc56500e6c88584aa656c84de7d0484" @@ -14917,78 +14918,78 @@ 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@^1.2.0: - version "1.2.0" - resolved "https://registry.yarnpkg.com/maci-circuits/-/maci-circuits-1.2.0.tgz#9b1f9c64d48e4dc3c3c7c8ffc4d0f254d60cce3e" - integrity sha512-51VMv7prUfRuko+PWDJOhwl9dLP82lAW2WHA39x+SFn1tkGAF3K3gw5TcIu7P6DQcwDblmbufn4OlrMc6jQXZg== +maci-circuits@1.2.1, maci-circuits@^1.2.1: + version "1.2.1" + resolved "https://registry.yarnpkg.com/maci-circuits/-/maci-circuits-1.2.1.tgz#8012ac317736c7324af492eaf6e25e34b8e44519" + integrity sha512-Rch7UFOlrt9ENT8E8QQuAH7vNRVaMFcsk6Eg3C/BRQqKwb+f2A+PSb8qFEGGrqj51DaVEVZWL5KDPDbFpW5DoQ== dependencies: - "@zk-kit/circuits" "^0.3.0" - circomkit "^0.0.24" + "@zk-kit/circuits" "^0.4.0" + circomkit "^0.1.0" circomlib "^2.0.5" - maci-core "^1.2.0" - maci-crypto "^1.2.0" - maci-domainobjs "^1.2.0" - snarkjs "^0.7.3" + maci-core "^1.2.1" + maci-crypto "^1.2.1" + maci-domainobjs "^1.2.1" + snarkjs "^0.7.4" -maci-cli@^1.2.0: - version "1.2.0" - resolved "https://registry.yarnpkg.com/maci-cli/-/maci-cli-1.2.0.tgz#caf8756d7e8dbfef61af6c7ac14068dfbc7d5db4" - integrity sha512-l3HYHvcafD6Z9ctPOBsYfZ5H/hdiS4rh0X3vEeLlncnsfKRPIpAej+2RHzsTooBH3ZvAp2f6wh+m2C9fRiU/7A== +maci-cli@1.2.1: + version "1.2.1" + resolved "https://registry.yarnpkg.com/maci-cli/-/maci-cli-1.2.1.tgz#0a23092163c24d215ddb392b98834f1d526e8340" + integrity sha512-48XZzRKONc4NGVJB1dnqL0Jou+f0WdMkwn7uP5PUhXBTbUY9lySZuHzWFUtWJ9ooW8s1acYgjAhpbmkHZatL4Q== dependencies: - "@commander-js/extra-typings" "^12.0.0" - "@nomicfoundation/hardhat-toolbox" "^4.0.0" + "@commander-js/extra-typings" "^12.0.1" + "@nomicfoundation/hardhat-toolbox" "^5.0.0" commander "^12.0.0" dotenv "^16.4.5" - ethers "^6.11.1" - hardhat "^2.20.1" - maci-circuits "^1.2.0" - maci-contracts "^1.2.0" - maci-core "^1.2.0" - maci-crypto "^1.2.0" - maci-domainobjs "^1.2.0" + ethers "^6.12.0" + hardhat "^2.22.3" + maci-circuits "^1.2.1" + maci-contracts "^1.2.1" + maci-core "^1.2.1" + maci-crypto "^1.2.1" + maci-domainobjs "^1.2.1" prompt "^1.3.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== +maci-contracts@1.2.1, maci-contracts@^1.2.1: + version "1.2.1" + resolved "https://registry.yarnpkg.com/maci-contracts/-/maci-contracts-1.2.1.tgz#ac9f44dc895573d8fe026f19a21edb255fe822ea" + integrity sha512-/B5P82nZgKpSBvxZ3xUoF1mTPDZRMviCWG0ItF93TLnxPTJSMBqFrqJy3mXOHS7sK2/7M5E4NXC1TQ/oFVUATg== dependencies: "@nomicfoundation/hardhat-ethers" "^3.0.5" - "@nomicfoundation/hardhat-toolbox" "^4.0.0" - "@openzeppelin/contracts" "^4.8.0" + "@nomicfoundation/hardhat-toolbox" "^5.0.0" + "@openzeppelin/contracts" "^5.0.2" circomlibjs "^0.1.7" - ethers "^6.11.1" - hardhat "^2.20.1" - maci-circuits "^1.2.0" - maci-core "^1.2.0" - maci-crypto "^1.2.0" - maci-domainobjs "^1.2.0" + ethers "^6.12.0" + hardhat "^2.22.3" + maci-circuits "^1.2.1" + maci-core "^1.2.1" + maci-crypto "^1.2.1" + maci-domainobjs "^1.2.1" solidity-docgen "^0.6.0-beta.36" -maci-core@^1.2.0: - version "1.2.0" - resolved "https://registry.yarnpkg.com/maci-core/-/maci-core-1.2.0.tgz#57ff4b92c457f42a3043fe5b34cfef98a9ac1cf5" - integrity sha512-odqIpafdQmSN0VlvaPESyPQybVcQzxxg9Zvh/DEUSiPMNHBJfHd0ke+CIUVdBN0z2pLaN9VlAFyMDf/CYEuivw== +maci-core@^1.2.1: + version "1.2.1" + resolved "https://registry.yarnpkg.com/maci-core/-/maci-core-1.2.1.tgz#546f5a4ea0df0e1525df0ccfb3c54c4bb569c81f" + integrity sha512-8AXzvgcmQFdq5oQCvVZClK7FmTVLzPMDNgKAkc8waTtxLJIhP7Of3SMxfX5zu9Gay1ZGc9YMbC4NVdvdJTsC7g== dependencies: - maci-crypto "^1.2.0" - maci-domainobjs "^1.2.0" + maci-crypto "^1.2.1" + maci-domainobjs "^1.2.1" -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== +maci-crypto@1.2.1, maci-crypto@^1.2.1: + version "1.2.1" + resolved "https://registry.yarnpkg.com/maci-crypto/-/maci-crypto-1.2.1.tgz#46999c233f43556960a50bec60c5437443dcd108" + integrity sha512-NERlCuBXYBsTSrE4GMozEgP9x8cL0Wk5ng9XZ/aBp4ib2HAJWyJC78gslRpwhjNNiRFw7TsYH0fcHqHjQ7YCKg== dependencies: - "@zk-kit/baby-jubjub" "^0.1.1" - "@zk-kit/eddsa-poseidon" "^0.5.1" - "@zk-kit/poseidon-cipher" "^0.2.1" - ethers "^6.11.1" + "@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-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== +maci-domainobjs@1.2.1, maci-domainobjs@^1.2.1: + version "1.2.1" + resolved "https://registry.yarnpkg.com/maci-domainobjs/-/maci-domainobjs-1.2.1.tgz#7bb0ecc6131ed11aba1e73ad6112d7ad6ad807ac" + integrity sha512-oA/Qgigvr8UAvlBx+avNnN2QYd7tREW/SjMiNtHrhnn64cHCqrnuWGSylGYFec0CUaYHQ5RGho1tvHdce1xBLA== dependencies: - maci-crypto "^1.2.0" + maci-crypto "^1.2.1" macos-release@^3.1.0: version "3.2.0" @@ -17173,6 +17174,11 @@ pify@^2.3.0: resolved "https://registry.yarnpkg.com/pify/-/pify-2.3.0.tgz#ed141a6ac043a849ea588498e7dca8b15330e90c" integrity sha512-udgsAY+fTnvv7kI7aaxbqwWNb0AHiB0qBO89PZKPkoTmGOgdbrHDKD+0B2X4uTfJ/FT1R09r9gTsjUjNJotuog== +pify@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/pify/-/pify-3.0.0.tgz#e5a4acd2c101fdf3d9a4d07f0dbc4db49dd28176" + integrity sha512-C3FsVNH1udSEX48gGX1xfvwTWfsYWj5U+8/uK15BGzIGrKoUpghX8hWZwa/OFnakBiiVNmBvemTJR5mcy7iPcg== + pify@^4.0.1: version "4.0.1" resolved "https://registry.yarnpkg.com/pify/-/pify-4.0.1.tgz#4b2cd25c50d598735c50292224fd8c6df41e3231" @@ -17827,6 +17833,16 @@ 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" @@ -18491,18 +18507,6 @@ run-parallel@^1.1.4, run-parallel@^1.1.9: dependencies: queue-microtask "^1.2.2" -rust-verkle-wasm@^0.0.1: - version "0.0.1" - resolved "https://registry.yarnpkg.com/rust-verkle-wasm/-/rust-verkle-wasm-0.0.1.tgz#fd8396a7060d8ee8ea10da50ab6e862948095a74" - integrity sha512-BN6fiTsxcd2dCECz/cHtGTt9cdLJR925nh7iAuRcj8ymKw7OOaPmCneQZ7JePOJ/ia27TjEL91VdOi88Yf+mcA== - -rustbn-wasm@^0.2.0: - version "0.2.0" - resolved "https://registry.yarnpkg.com/rustbn-wasm/-/rustbn-wasm-0.2.0.tgz#0407521fb55ae69eeb4968d01885d63efd1c4ff9" - integrity sha512-FThvYFNTqrEKGqXuseeg0zR7yROh/6U1617mCHF68OVqrN1tNKRN7Tdwy4WayPVsCmmK+eMxtIZX1qL6JxTkMg== - dependencies: - "@scure/base" "^1.1.1" - rustbn.js@~0.2.0: version "0.2.0" resolved "https://registry.yarnpkg.com/rustbn.js/-/rustbn.js-0.2.0.tgz#8082cb886e707155fd1cb6f23bd591ab8d55d0ca" @@ -19064,7 +19068,7 @@ snarkjs@0.5.0: logplease "^1.2.15" r1csfile "0.0.41" -snarkjs@^0.7.0, snarkjs@^0.7.3: +snarkjs@^0.7.0: version "0.7.3" resolved "https://registry.yarnpkg.com/snarkjs/-/snarkjs-0.7.3.tgz#7f703d05b810235255f2d0a70d8a9b8b3ea916e5" integrity sha512-cDLpWqdqEJSCQNc+cXYX1XTKdUZBtYEisuOsgmXf/HUsN5WmGN+FO7HfCS+cMQT1Nzbm1a9gAEpKH6KRtDtS1Q== @@ -19080,6 +19084,22 @@ 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" @@ -19400,6 +19420,13 @@ stdin-discarder@^0.1.0: dependencies: bl "^5.0.0" +steno@^0.4.1: + version "0.4.4" + resolved "https://registry.yarnpkg.com/steno/-/steno-0.4.4.tgz#071105bdfc286e6615c0403c27e9d7b5dcb855cb" + integrity sha512-EEHMVYHNXFHfGtgjNITnka0aHhiAlo93F7z2/Pwd+g0teG9CnM3JIINM7hVVB5/rhw9voufD7Wukwgtw2uqh6w== + dependencies: + graceful-fs "^4.1.3" + stream-browserify@^3.0.0: version "3.0.0" resolved "https://registry.yarnpkg.com/stream-browserify/-/stream-browserify-3.0.0.tgz#22b0a2850cdf6503e73085da1fc7b7d0c2122f2f" From bb48206d91b09bb2f0db4723c3c1169faaa26311 Mon Sep 17 00:00:00 2001 From: yuetloo Date: Thu, 16 May 2024 07:35:21 -0400 Subject: [PATCH 24/57] use hardhat ^v2.22.3 to fix Invalid Chai property: revertedWith --- contracts/package.json | 2 +- contracts/tests/maciFactory.ts | 5 +- contracts/tests/recipientRegistry.ts | 12 +- contracts/tests/round.ts | 14 +- contracts/tests/userRegistry.ts | 14 +- contracts/tests/userRegistryMerkle.ts | 5 +- contracts/tests/userRegistrySemaphore.ts | 12 +- contracts/utils/testutils.ts | 5 +- yarn.lock | 351 +---------------------- 9 files changed, 53 insertions(+), 367 deletions(-) diff --git a/contracts/package.json b/contracts/package.json index 2f70d0f24..c4b870f22 100644 --- a/contracts/package.json +++ b/contracts/package.json @@ -36,7 +36,7 @@ "@types/mocha": "^10.0.6", "chai": "4", "ethers": "^6.12.1", - "hardhat": "^2.19.4", + "hardhat": "^2.22.3", "hardhat-contract-sizer": "^2.10.0", "hardhat-gas-reporter": "^1.0.8", "ipfs-only-hash": "^2.0.1", diff --git a/contracts/tests/maciFactory.ts b/contracts/tests/maciFactory.ts index 3f23d58ad..fcaf8d483 100644 --- a/contracts/tests/maciFactory.ts +++ b/contracts/tests/maciFactory.ts @@ -89,7 +89,10 @@ describe('MACI factory', () => { coordinatorMaciFactory.setMaciParameters( ...maciParameters.asContractParam() ) - ).to.be.revertedWith('Ownable: caller is not the owner') + ).to.be.revertedWithCustomError( + coordinatorMaciFactory, + 'OwnableUnauthorizedAccount' + ) }) it('deploys MACI', async () => { diff --git a/contracts/tests/recipientRegistry.ts b/contracts/tests/recipientRegistry.ts index ea5932993..1e0124376 100644 --- a/contracts/tests/recipientRegistry.ts +++ b/contracts/tests/recipientRegistry.ts @@ -154,7 +154,10 @@ describe('Simple Recipient Registry', async () => { const registryAsRecipient = registry.connect(recipient) as Contract await expect( registryAsRecipient.addRecipient(recipientAddress, metadata) - ).to.be.revertedWith('Ownable: caller is not the owner') + ).to.be.revertedWithCustomError( + registryAsRecipient, + 'OwnableUnauthorizedAccount' + ) }) it('should not accept zero-address as recipient address', async () => { @@ -218,7 +221,10 @@ describe('Simple Recipient Registry', async () => { const registryAsRecipient = registry.connect(recipient) as Contract await expect( registryAsRecipient.removeRecipient(recipientId) - ).to.be.revertedWith('Ownable: caller is not the owner') + ).to.be.revertedWithCustomError( + registryAsRecipient, + 'OwnableUnauthorizedAccount' + ) }) it('reverts if recipient is not in registry', async () => { @@ -762,7 +768,7 @@ describe('Optimistic recipient registry', () => { recipientId, requester.address ) - ).to.be.revertedWith('Ownable: caller is not the owner') + ).to.be.revertedWithCustomError(registry, 'OwnableUnauthorizedAccount') }) it('should not allow to challenge resolved request', async () => { diff --git a/contracts/tests/round.ts b/contracts/tests/round.ts index 4e480ff34..887e9224a 100644 --- a/contracts/tests/round.ts +++ b/contracts/tests/round.ts @@ -249,7 +249,7 @@ describe('Funding Round', () => { it('requires approval', async () => { await expect( fundingRoundAsContributor.contribute(userPubKey, contributionAmount) - ).to.be.revertedWith('ERC20: insufficient allowance') + ).to.be.revertedWithCustomError(token, 'ERC20InsufficientAllowance') }) it('rejects contributions from unverified users', async () => { @@ -750,7 +750,10 @@ describe('Funding Round', () => { newResultCommitment, perVOSpentVoiceCreditsHash ) - ).to.be.revertedWith('Ownable: caller is not the owner') + ).to.be.revertedWithCustomError( + fundingRoundAsCoordinator, + 'OwnableUnauthorizedAccount' + ) }) }) @@ -811,8 +814,11 @@ describe('Funding Round', () => { const fundingRoundAsCoordinator = fundingRound.connect( coordinator ) as Contract - await expect(fundingRoundAsCoordinator.cancel()).to.be.revertedWith( - 'Ownable: caller is not the owner' + await expect( + fundingRoundAsCoordinator.cancel() + ).to.be.revertedWithCustomError( + fundingRoundAsCoordinator, + 'OwnableUnauthorizedAccount' ) }) }) diff --git a/contracts/tests/userRegistry.ts b/contracts/tests/userRegistry.ts index 63d05e76f..7d0c9e7bc 100644 --- a/contracts/tests/userRegistry.ts +++ b/contracts/tests/userRegistry.ts @@ -44,8 +44,11 @@ describe('Simple User Registry', () => { it('allows only owner to add users', async () => { const registryAsUser = registry.connect(user) as Contract - await expect(registryAsUser.addUser(user.address)).to.be.revertedWith( - 'Ownable: caller is not the owner' + await expect( + registryAsUser.addUser(user.address) + ).to.be.revertedWithCustomError( + registryAsUser, + 'OwnableUnauthorizedAccount' ) }) @@ -66,8 +69,11 @@ describe('Simple User Registry', () => { it('allows only owner to remove users', async () => { await registry.addUser(user.address) const registryAsUser = registry.connect(user) as Contract - await expect(registryAsUser.removeUser(user.address)).to.be.revertedWith( - 'Ownable: caller is not the owner' + await expect( + registryAsUser.removeUser(user.address) + ).to.be.revertedWithCustomError( + registryAsUser, + 'OwnableUnauthorizedAccount' ) }) }) diff --git a/contracts/tests/userRegistryMerkle.ts b/contracts/tests/userRegistryMerkle.ts index 87c021a55..8761e33dc 100644 --- a/contracts/tests/userRegistryMerkle.ts +++ b/contracts/tests/userRegistryMerkle.ts @@ -39,7 +39,10 @@ describe('Merkle User Registry', () => { const registryAsUser = registry.connect(signers[user1.address]) as Contract await expect( registryAsUser.setMerkleRoot(randomBytes(32), 'non owner') - ).to.be.revertedWith('Ownable: caller is not the owner') + ).to.be.revertedWithCustomError( + registryAsUser, + 'OwnableUnauthorizedAccount' + ) }) describe('registration', () => { diff --git a/contracts/tests/userRegistrySemaphore.ts b/contracts/tests/userRegistrySemaphore.ts index 95a71c4ef..af500261f 100644 --- a/contracts/tests/userRegistrySemaphore.ts +++ b/contracts/tests/userRegistrySemaphore.ts @@ -66,7 +66,10 @@ describe('Semaphore User Registry', () => { const registryAsUser = registry.connect(user) as Contract await expect( registryAsUser.addUser(user.address, semaphoreId) - ).to.be.revertedWith('Ownable: caller is not the owner') + ).to.be.revertedWithCustomError( + registryAsUser, + 'OwnableUnauthorizedAccount' + ) }) it('allows owner to remove user', async () => { @@ -88,8 +91,11 @@ describe('Semaphore User Registry', () => { const semaphoreId = 1 await registry.addUser(user.address, semaphoreId) const registryAsUser = registry.connect(user) as Contract - await expect(registryAsUser.removeUser(user.address)).to.be.revertedWith( - 'Ownable: caller is not the owner' + await expect( + registryAsUser.removeUser(user.address) + ).to.be.revertedWithCustomError( + registryAsUser, + 'OwnableUnauthorizedAccount' ) }) diff --git a/contracts/utils/testutils.ts b/contracts/utils/testutils.ts index e5ace7da7..e423421fd 100644 --- a/contracts/utils/testutils.ts +++ b/contracts/utils/testutils.ts @@ -9,6 +9,7 @@ import { EContracts } from './types' import { Libraries } from 'hardhat/types' import { MACIFactory, VkRegistry } from '../typechain-types' import { ZERO_ADDRESS } from './constants' +import { EMode } from 'maci-contracts' /** * Deploy a mock contract with the given contract name @@ -236,7 +237,6 @@ export async function deployTestFundingRound( factories.pollFactory, factories.messageProcessorFactory, factories.tallyFactory, - factories.subsidyFactory, fundingRound.target, fundingRound.target, topupToken.target, @@ -254,8 +254,7 @@ export async function deployTestFundingRound( coordinatorPubKey.asContractParam(), mockVerifier.target, vkRegistry.target, - // pass false to not deploy the subsidy contract - false + EMode.QV ) const pollAddr = await getEventArg( deployPollTx, diff --git a/yarn.lock b/yarn.lock index 025a4e9ea..3b91a1800 100644 --- a/yarn.lock +++ b/yarn.lock @@ -578,42 +578,6 @@ resolved "https://registry.yarnpkg.com/@bugsnag/safe-json-stringify/-/safe-json-stringify-6.0.0.tgz#22abdcd83e008c369902976730c34c150148a758" integrity sha512-htzFO1Zc57S8kgdRK9mLcPVTW1BY2ijfH7Dk2CeZmspTWKdKqSo1iwmqrq2WtRjFlo8aRZYgLX0wFrDXF/9DLA== -"@chainsafe/as-sha256@^0.3.1": - version "0.3.1" - resolved "https://registry.yarnpkg.com/@chainsafe/as-sha256/-/as-sha256-0.3.1.tgz#3639df0e1435cab03f4d9870cc3ac079e57a6fc9" - integrity sha512-hldFFYuf49ed7DAakWVXSJODuq3pzJEguD8tQ7h+sGkM18vja+OFoJI9krnGmgzyuZC2ETX0NOIcCTy31v2Mtg== - -"@chainsafe/persistent-merkle-tree@^0.4.2": - version "0.4.2" - resolved "https://registry.yarnpkg.com/@chainsafe/persistent-merkle-tree/-/persistent-merkle-tree-0.4.2.tgz#4c9ee80cc57cd3be7208d98c40014ad38f36f7ff" - integrity sha512-lLO3ihKPngXLTus/L7WHKaw9PnNJWizlOF1H9NNzHP6Xvh82vzg9F2bzkXhYIFshMZ2gTCEz8tq6STe7r5NDfQ== - dependencies: - "@chainsafe/as-sha256" "^0.3.1" - -"@chainsafe/persistent-merkle-tree@^0.5.0": - version "0.5.0" - resolved "https://registry.yarnpkg.com/@chainsafe/persistent-merkle-tree/-/persistent-merkle-tree-0.5.0.tgz#2b4a62c9489a5739dedd197250d8d2f5427e9f63" - integrity sha512-l0V1b5clxA3iwQLXP40zYjyZYospQLZXzBVIhhr9kDg/1qHZfzzHw0jj4VPBijfYCArZDlPkRi1wZaV2POKeuw== - dependencies: - "@chainsafe/as-sha256" "^0.3.1" - -"@chainsafe/ssz@^0.10.0": - version "0.10.2" - resolved "https://registry.yarnpkg.com/@chainsafe/ssz/-/ssz-0.10.2.tgz#c782929e1bb25fec66ba72e75934b31fd087579e" - integrity sha512-/NL3Lh8K+0q7A3LsiFq09YXS9fPE+ead2rr7vM2QK8PLzrNsw3uqrif9bpRX5UxgeRjM+vYi+boCM3+GM4ovXg== - dependencies: - "@chainsafe/as-sha256" "^0.3.1" - "@chainsafe/persistent-merkle-tree" "^0.5.0" - -"@chainsafe/ssz@^0.9.2": - version "0.9.4" - resolved "https://registry.yarnpkg.com/@chainsafe/ssz/-/ssz-0.9.4.tgz#696a8db46d6975b600f8309ad3a12f7c0e310497" - integrity sha512-77Qtg2N1ayqs4Bg/wvnWfg5Bta7iy7IRh8XqXh7oNMeP2HBbBwx8m6yTpA8p0EHItWPEBkgZd5S5/LSlp3GXuQ== - dependencies: - "@chainsafe/as-sha256" "^0.3.1" - "@chainsafe/persistent-merkle-tree" "^0.4.2" - case "^1.6.3" - "@clrfund/waffle-mock-contract@^0.0.4": version "0.0.4" resolved "https://registry.yarnpkg.com/@clrfund/waffle-mock-contract/-/waffle-mock-contract-0.0.4.tgz#97bb6b20df60a77b8a501e45fb4f049bdaebbea0" @@ -1157,7 +1121,7 @@ dependencies: "@ethersproject/logger" "^5.7.0" -"@ethersproject/providers@5.7.2", "@ethersproject/providers@^5.7.1", "@ethersproject/providers@^5.7.2": +"@ethersproject/providers@5.7.2": version "5.7.2" resolved "https://registry.yarnpkg.com/@ethersproject/providers/-/providers-5.7.2.tgz#f8b1a4f275d7ce58cf0a2eec222269a08beb18cb" integrity sha512-g34EWZ1WWAVgr4aptGlVBF8mhl3VWjv+8hoAnzStu8Ah22VHBsuGzP17eb6xDVRzw895G4W7vvx60lFFur/1Rg== @@ -2730,46 +2694,6 @@ "@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" - integrity sha512-hSe6CuHI4SsSiWWjHDIzWhSiAVpzMUcDRpWYzN0T9l8/Rz7xNn3elwVOJ/tAyS0LqL6vitUD78Uk7lQDXZun7Q== - dependencies: - "@nomicfoundation/ethereumjs-common" "4.0.2" - "@nomicfoundation/ethereumjs-rlp" "5.0.2" - "@nomicfoundation/ethereumjs-trie" "6.0.2" - "@nomicfoundation/ethereumjs-tx" "5.0.2" - "@nomicfoundation/ethereumjs-util" "9.0.2" - ethereum-cryptography "0.1.3" - ethers "^5.7.1" - -"@nomicfoundation/ethereumjs-blockchain@7.0.2": - version "7.0.2" - resolved "https://registry.yarnpkg.com/@nomicfoundation/ethereumjs-blockchain/-/ethereumjs-blockchain-7.0.2.tgz#45323b673b3d2fab6b5008535340d1b8fea7d446" - integrity sha512-8UUsSXJs+MFfIIAKdh3cG16iNmWzWC/91P40sazNvrqhhdR/RtGDlFk2iFTGbBAZPs2+klZVzhRX8m2wvuvz3w== - dependencies: - "@nomicfoundation/ethereumjs-block" "5.0.2" - "@nomicfoundation/ethereumjs-common" "4.0.2" - "@nomicfoundation/ethereumjs-ethash" "3.0.2" - "@nomicfoundation/ethereumjs-rlp" "5.0.2" - "@nomicfoundation/ethereumjs-trie" "6.0.2" - "@nomicfoundation/ethereumjs-tx" "5.0.2" - "@nomicfoundation/ethereumjs-util" "9.0.2" - abstract-level "^1.0.3" - debug "^4.3.3" - ethereum-cryptography "0.1.3" - level "^8.0.0" - lru-cache "^5.1.1" - memory-level "^1.0.0" - -"@nomicfoundation/ethereumjs-common@4.0.2": - version "4.0.2" - resolved "https://registry.yarnpkg.com/@nomicfoundation/ethereumjs-common/-/ethereumjs-common-4.0.2.tgz#a15d1651ca36757588fdaf2a7d381a150662a3c3" - integrity sha512-I2WGP3HMGsOoycSdOTSqIaES0ughQTueOsddJ36aYVpI3SN8YSusgRFLwzDJwRFVIYDKx/iJz0sQ5kBHVgdDwg== - dependencies: - "@nomicfoundation/ethereumjs-util" "9.0.2" - crc-32 "^1.2.0" - "@nomicfoundation/ethereumjs-common@4.0.4": version "4.0.4" resolved "https://registry.yarnpkg.com/@nomicfoundation/ethereumjs-common/-/ethereumjs-common-4.0.4.tgz#9901f513af2d4802da87c66d6f255b510bef5acb" @@ -2777,77 +2701,11 @@ dependencies: "@nomicfoundation/ethereumjs-util" "9.0.4" -"@nomicfoundation/ethereumjs-ethash@3.0.2": - version "3.0.2" - resolved "https://registry.yarnpkg.com/@nomicfoundation/ethereumjs-ethash/-/ethereumjs-ethash-3.0.2.tgz#da77147f806401ee996bfddfa6487500118addca" - integrity sha512-8PfoOQCcIcO9Pylq0Buijuq/O73tmMVURK0OqdjhwqcGHYC2PwhbajDh7GZ55ekB0Px197ajK3PQhpKoiI/UPg== - dependencies: - "@nomicfoundation/ethereumjs-block" "5.0.2" - "@nomicfoundation/ethereumjs-rlp" "5.0.2" - "@nomicfoundation/ethereumjs-util" "9.0.2" - abstract-level "^1.0.3" - bigint-crypto-utils "^3.0.23" - ethereum-cryptography "0.1.3" - -"@nomicfoundation/ethereumjs-evm@2.0.2": - version "2.0.2" - resolved "https://registry.yarnpkg.com/@nomicfoundation/ethereumjs-evm/-/ethereumjs-evm-2.0.2.tgz#4c2f4b84c056047102a4fa41c127454e3f0cfcf6" - integrity sha512-rBLcUaUfANJxyOx9HIdMX6uXGin6lANCulIm/pjMgRqfiCRMZie3WKYxTSd8ZE/d+qT+zTedBF4+VHTdTSePmQ== - dependencies: - "@ethersproject/providers" "^5.7.1" - "@nomicfoundation/ethereumjs-common" "4.0.2" - "@nomicfoundation/ethereumjs-tx" "5.0.2" - "@nomicfoundation/ethereumjs-util" "9.0.2" - debug "^4.3.3" - ethereum-cryptography "0.1.3" - mcl-wasm "^0.7.1" - rustbn.js "~0.2.0" - -"@nomicfoundation/ethereumjs-rlp@5.0.2": - version "5.0.2" - resolved "https://registry.yarnpkg.com/@nomicfoundation/ethereumjs-rlp/-/ethereumjs-rlp-5.0.2.tgz#4fee8dc58a53ac6ae87fb1fca7c15dc06c6b5dea" - integrity sha512-QwmemBc+MMsHJ1P1QvPl8R8p2aPvvVcKBbvHnQOKBpBztEo0omN0eaob6FeZS/e3y9NSe+mfu3nNFBHszqkjTA== - "@nomicfoundation/ethereumjs-rlp@5.0.4": version "5.0.4" resolved "https://registry.yarnpkg.com/@nomicfoundation/ethereumjs-rlp/-/ethereumjs-rlp-5.0.4.tgz#66c95256fc3c909f6fb18f6a586475fc9762fa30" integrity sha512-8H1S3s8F6QueOc/X92SdrA4RDenpiAEqMg5vJH99kcQaCy/a3Q6fgseo75mgWlbanGJXSlAPtnCeG9jvfTYXlw== -"@nomicfoundation/ethereumjs-statemanager@2.0.2": - version "2.0.2" - resolved "https://registry.yarnpkg.com/@nomicfoundation/ethereumjs-statemanager/-/ethereumjs-statemanager-2.0.2.tgz#3ba4253b29b1211cafe4f9265fee5a0d780976e0" - integrity sha512-dlKy5dIXLuDubx8Z74sipciZnJTRSV/uHG48RSijhgm1V7eXYFC567xgKtsKiVZB1ViTP9iFL4B6Je0xD6X2OA== - dependencies: - "@nomicfoundation/ethereumjs-common" "4.0.2" - "@nomicfoundation/ethereumjs-rlp" "5.0.2" - debug "^4.3.3" - ethereum-cryptography "0.1.3" - ethers "^5.7.1" - js-sdsl "^4.1.4" - -"@nomicfoundation/ethereumjs-trie@6.0.2": - version "6.0.2" - resolved "https://registry.yarnpkg.com/@nomicfoundation/ethereumjs-trie/-/ethereumjs-trie-6.0.2.tgz#9a6dbd28482dca1bc162d12b3733acab8cd12835" - integrity sha512-yw8vg9hBeLYk4YNg5MrSJ5H55TLOv2FSWUTROtDtTMMmDGROsAu+0tBjiNGTnKRi400M6cEzoFfa89Fc5k8NTQ== - dependencies: - "@nomicfoundation/ethereumjs-rlp" "5.0.2" - "@nomicfoundation/ethereumjs-util" "9.0.2" - "@types/readable-stream" "^2.3.13" - ethereum-cryptography "0.1.3" - readable-stream "^3.6.0" - -"@nomicfoundation/ethereumjs-tx@5.0.2": - version "5.0.2" - resolved "https://registry.yarnpkg.com/@nomicfoundation/ethereumjs-tx/-/ethereumjs-tx-5.0.2.tgz#117813b69c0fdc14dd0446698a64be6df71d7e56" - integrity sha512-T+l4/MmTp7VhJeNloMkM+lPU3YMUaXdcXgTGCf8+ZFvV9NYZTRLFekRwlG6/JMmVfIfbrW+dRRJ9A6H5Q/Z64g== - dependencies: - "@chainsafe/ssz" "^0.9.2" - "@ethersproject/providers" "^5.7.2" - "@nomicfoundation/ethereumjs-common" "4.0.2" - "@nomicfoundation/ethereumjs-rlp" "5.0.2" - "@nomicfoundation/ethereumjs-util" "9.0.2" - ethereum-cryptography "0.1.3" - "@nomicfoundation/ethereumjs-tx@5.0.4": version "5.0.4" resolved "https://registry.yarnpkg.com/@nomicfoundation/ethereumjs-tx/-/ethereumjs-tx-5.0.4.tgz#b0ceb58c98cc34367d40a30d255d6315b2f456da" @@ -2858,15 +2716,6 @@ "@nomicfoundation/ethereumjs-util" "9.0.4" ethereum-cryptography "0.1.3" -"@nomicfoundation/ethereumjs-util@9.0.2": - version "9.0.2" - resolved "https://registry.yarnpkg.com/@nomicfoundation/ethereumjs-util/-/ethereumjs-util-9.0.2.tgz#16bdc1bb36f333b8a3559bbb4b17dac805ce904d" - integrity sha512-4Wu9D3LykbSBWZo8nJCnzVIYGvGCuyiYLIJa9XXNVt1q1jUzHdB+sJvx95VGCpPkCT+IbLecW6yfzy3E1bQrwQ== - dependencies: - "@chainsafe/ssz" "^0.10.0" - "@nomicfoundation/ethereumjs-rlp" "5.0.2" - ethereum-cryptography "0.1.3" - "@nomicfoundation/ethereumjs-util@9.0.4": version "9.0.4" resolved "https://registry.yarnpkg.com/@nomicfoundation/ethereumjs-util/-/ethereumjs-util-9.0.4.tgz#84c5274e82018b154244c877b76bc049a4ed7b38" @@ -2875,25 +2724,6 @@ "@nomicfoundation/ethereumjs-rlp" "5.0.4" ethereum-cryptography "0.1.3" -"@nomicfoundation/ethereumjs-vm@7.0.2": - version "7.0.2" - resolved "https://registry.yarnpkg.com/@nomicfoundation/ethereumjs-vm/-/ethereumjs-vm-7.0.2.tgz#3b0852cb3584df0e18c182d0672a3596c9ca95e6" - integrity sha512-Bj3KZT64j54Tcwr7Qm/0jkeZXJMfdcAtRBedou+Hx0dPOSIgqaIr0vvLwP65TpHbak2DmAq+KJbW2KNtIoFwvA== - dependencies: - "@nomicfoundation/ethereumjs-block" "5.0.2" - "@nomicfoundation/ethereumjs-blockchain" "7.0.2" - "@nomicfoundation/ethereumjs-common" "4.0.2" - "@nomicfoundation/ethereumjs-evm" "2.0.2" - "@nomicfoundation/ethereumjs-rlp" "5.0.2" - "@nomicfoundation/ethereumjs-statemanager" "2.0.2" - "@nomicfoundation/ethereumjs-trie" "6.0.2" - "@nomicfoundation/ethereumjs-tx" "5.0.2" - "@nomicfoundation/ethereumjs-util" "9.0.2" - debug "^4.3.3" - ethereum-cryptography "0.1.3" - mcl-wasm "^0.7.1" - rustbn.js "~0.2.0" - "@nomicfoundation/hardhat-chai-matchers@^2.0.6": version "2.0.6" resolved "https://registry.yarnpkg.com/@nomicfoundation/hardhat-chai-matchers/-/hardhat-chai-matchers-2.0.6.tgz#ef88be3bd666adf29c06ac7882e96c8dbaaa32ba" @@ -4103,14 +3933,6 @@ resolved "https://registry.yarnpkg.com/@types/qs/-/qs-6.9.11.tgz#208d8a30bc507bd82e03ada29e4732ea46a6bbda" integrity sha512-oGk0gmhnEJK4Yyk+oI7EfXsLayXatCWPHary1MtcmbAifkobT9cM9yutG/hZKIseOU0MqbIwQ/u2nn/Gb+ltuQ== -"@types/readable-stream@^2.3.13": - version "2.3.15" - resolved "https://registry.yarnpkg.com/@types/readable-stream/-/readable-stream-2.3.15.tgz#3d79c9ceb1b6a57d5f6e6976f489b9b5384321ae" - integrity sha512-oM5JSKQCcICF1wvGgmecmHldZ48OZamtMxcGGVICOJA8o8cahXC1zEVAif8iwoc5j8etxFaRFnf095+CDsuoFQ== - dependencies: - "@types/node" "*" - safe-buffer "~5.1.1" - "@types/resolve@^0.0.8": version "0.0.8" resolved "https://registry.yarnpkg.com/@types/resolve/-/resolve-0.0.8.tgz#f26074d238e02659e323ce1a13d041eee280e194" @@ -4997,19 +4819,6 @@ abort-controller@^3.0.0: dependencies: event-target-shim "^5.0.0" -abstract-level@^1.0.0, abstract-level@^1.0.2, abstract-level@^1.0.3: - version "1.0.3" - resolved "https://registry.yarnpkg.com/abstract-level/-/abstract-level-1.0.3.tgz#78a67d3d84da55ee15201486ab44c09560070741" - integrity sha512-t6jv+xHy+VYwc4xqZMn2Pa9DjcdzvzZmQGRjTFc8spIbRGHgBrEKbPq+rYXc7CCo0lxgYvSgKVg9qZAhpVQSjA== - dependencies: - buffer "^6.0.3" - catering "^2.1.0" - is-buffer "^2.0.5" - level-supports "^4.0.0" - level-transcoder "^1.0.1" - module-error "^1.0.1" - queue-microtask "^1.2.3" - abstract-leveldown@3.0.0: version "3.0.0" resolved "https://registry.yarnpkg.com/abstract-leveldown/-/abstract-leveldown-3.0.0.tgz#5cb89f958a44f526779d740d1440e743e0c30a57" @@ -6432,11 +6241,6 @@ bfj@^7.0.2: jsonpath "^1.1.1" tryer "^1.0.1" -bigint-crypto-utils@^3.0.23: - version "3.3.0" - resolved "https://registry.yarnpkg.com/bigint-crypto-utils/-/bigint-crypto-utils-3.3.0.tgz#72ad00ae91062cf07f2b1def9594006c279c1d77" - integrity sha512-jOTSb+drvEDxEq6OuUybOAv/xxoh3cuYRUIPyu8sSHQNKM303UQ2R1DAo45o1AkcIXw6fzbaFI1+xGGdaXs2lg== - bignumber.js@^9.0.0: version "9.1.2" resolved "https://registry.yarnpkg.com/bignumber.js/-/bignumber.js-9.1.2.tgz#b7c4242259c008903b13707983b5f4bbd31eda0c" @@ -6702,16 +6506,6 @@ brorand@^1.0.1, brorand@^1.1.0: resolved "https://registry.yarnpkg.com/brorand/-/brorand-1.1.0.tgz#12c25efe40a45e3c323eb8675a0a0ce57b22371f" integrity sha512-cKV8tMCEpQs4hK/ik71d6LrPOnpkpGBR0wzxqr68g2m/LB2GxVYQroAjMJZRVM1Y4BCjCKc3vAamxSzOY2RP+w== -browser-level@^1.0.1: - version "1.0.1" - resolved "https://registry.yarnpkg.com/browser-level/-/browser-level-1.0.1.tgz#36e8c3183d0fe1c405239792faaab5f315871011" - integrity sha512-XECYKJ+Dbzw0lbydyQuJzwNXtOpbMSq737qxJN11sIRTErOMShvDpbzTlgju7orJKvx4epULolZAuJGLzCmWRQ== - dependencies: - abstract-level "^1.0.2" - catering "^2.1.1" - module-error "^1.0.2" - run-parallel-limit "^1.1.0" - browser-readablestream-to-it@^1.0.0, browser-readablestream-to-it@^1.0.1, browser-readablestream-to-it@^1.0.3: version "1.0.3" resolved "https://registry.yarnpkg.com/browser-readablestream-to-it/-/browser-readablestream-to-it-1.0.3.tgz#ac3e406c7ee6cdf0a502dd55db33bab97f7fba76" @@ -7114,21 +6908,11 @@ cardinal@^2.1.1: ansicolors "~0.3.2" redeyed "~2.1.0" -case@^1.6.3: - version "1.6.3" - resolved "https://registry.yarnpkg.com/case/-/case-1.6.3.tgz#0a4386e3e9825351ca2e6216c60467ff5f1ea1c9" - integrity sha512-mzDSXIPaFwVDvZAHqZ9VlbyF4yyXRuX6IvB06WvPYkqJVO24kX1PPhv9bfpKNFZyxYFmmgo03HUiD8iklmJYRQ== - caseless@^0.12.0, caseless@~0.12.0: version "0.12.0" resolved "https://registry.yarnpkg.com/caseless/-/caseless-0.12.0.tgz#1b681c21ff84033c826543090689420d187151dc" integrity sha512-4tYFyifaFfGacoiObjJegolkwSU4xQNGbVgUiNYVUxbQ2x2lUsFvY4hVgVzGiIe6WLOPqycWXA40l+PWsxthUw== -catering@^2.1.0, catering@^2.1.1: - version "2.1.1" - resolved "https://registry.yarnpkg.com/catering/-/catering-2.1.1.tgz#66acba06ed5ee28d5286133982a927de9a04b510" - integrity sha512-K7Qy8O9p76sL3/3m7/zLKbRkyOlSZAgzEaLhyj2mXS8PsCud2Eo4hAb8aLtZqHh0QGqLcb9dlJSu6lHRVENm1w== - cbor@^8.1.0: version "8.1.0" resolved "https://registry.yarnpkg.com/cbor/-/cbor-8.1.0.tgz#cfc56437e770b73417a2ecbfc9caf6b771af60d5" @@ -7443,17 +7227,6 @@ class-utils@^0.3.5: isobject "^3.0.0" static-extend "^0.1.1" -classic-level@^1.2.0: - version "1.3.0" - resolved "https://registry.yarnpkg.com/classic-level/-/classic-level-1.3.0.tgz#5e36680e01dc6b271775c093f2150844c5edd5c8" - integrity sha512-iwFAJQYtqRTRM0F6L8h4JCt00ZSGdOyqh7yVrhhjrOpFhmBjNlRUey64MCiyo6UmQHMJ+No3c81nujPv+n9yrg== - dependencies: - abstract-level "^1.0.2" - catering "^2.1.0" - module-error "^1.0.1" - napi-macros "^2.2.2" - node-gyp-build "^4.3.0" - clean-deep@3.4.0: version "3.4.0" resolved "https://registry.yarnpkg.com/clean-deep/-/clean-deep-3.4.0.tgz#c465c4de1003ae13a1a859e6c69366ab96069f75" @@ -8442,7 +8215,7 @@ debug@3.2.6: dependencies: ms "^2.1.1" -debug@4, debug@4.3.4, debug@^4.0.0, debug@^4.0.1, debug@^4.1.0, debug@^4.1.1, debug@^4.3.1, debug@^4.3.2, debug@^4.3.3, debug@^4.3.4: +debug@4, debug@4.3.4, debug@^4.0.0, debug@^4.0.1, debug@^4.1.0, debug@^4.1.1, debug@^4.3.1, debug@^4.3.2, debug@^4.3.4: version "4.3.4" resolved "https://registry.yarnpkg.com/debug/-/debug-4.3.4.tgz#1319f6579357f2338d3337d2cdd4914bb5dcc865" integrity sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ== @@ -10108,7 +9881,7 @@ ethereumjs-wallet@0.6.5: utf8 "^3.0.0" uuid "^3.3.2" -ethers@^5.0.3, ethers@^5.5.1, ethers@^5.7.1, ethers@^5.7.2: +ethers@^5.0.3, ethers@^5.5.1, ethers@^5.7.2: version "5.7.2" resolved "https://registry.yarnpkg.com/ethers/-/ethers-5.7.2.tgz#3a7deeabbb8c030d4126b24f84e525466145872e" integrity sha512-wswUsmWo1aOK8rR7DIKiWSw9DbLWe6x98Jrn8wcTflTVvaXhAMaB5zGAXy0GYQEQp9iO1iSHWVyARQm11zUtyg== @@ -11903,60 +11676,6 @@ hardhat-gas-reporter@^1.0.8: eth-gas-reporter "^0.2.25" sha1 "^1.1.1" -hardhat@^2.19.4: - version "2.19.4" - resolved "https://registry.yarnpkg.com/hardhat/-/hardhat-2.19.4.tgz#5112c30295d8be2e18e55d847373c50483ed1902" - integrity sha512-fTQJpqSt3Xo9Mn/WrdblNGAfcANM6XC3tAEi6YogB4s02DmTf93A8QsGb8uR0KR8TFcpcS8lgiW4ugAIYpnbrQ== - dependencies: - "@ethersproject/abi" "^5.1.2" - "@metamask/eth-sig-util" "^4.0.0" - "@nomicfoundation/ethereumjs-block" "5.0.2" - "@nomicfoundation/ethereumjs-blockchain" "7.0.2" - "@nomicfoundation/ethereumjs-common" "4.0.2" - "@nomicfoundation/ethereumjs-evm" "2.0.2" - "@nomicfoundation/ethereumjs-rlp" "5.0.2" - "@nomicfoundation/ethereumjs-statemanager" "2.0.2" - "@nomicfoundation/ethereumjs-trie" "6.0.2" - "@nomicfoundation/ethereumjs-tx" "5.0.2" - "@nomicfoundation/ethereumjs-util" "9.0.2" - "@nomicfoundation/ethereumjs-vm" "7.0.2" - "@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" - 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" - hardhat@^2.22.3: version "2.22.4" resolved "https://registry.yarnpkg.com/hardhat/-/hardhat-2.22.4.tgz#766227b6cefca5dbf4fd15ab5b5a68138fa13baf" @@ -13019,11 +12738,6 @@ is-buffer@^1.1.5: resolved "https://registry.yarnpkg.com/is-buffer/-/is-buffer-1.1.6.tgz#efaa2ea9daa0d7ab2ea13a97b2b8ad51fefbe8be" integrity sha512-NcdALwpXkTm5Zvvbk7owOUSvVvBKDgKP5/ewfXEznmQFfs4ZRmanOeKBTjRVjka3QFoN6XJ+9F3USqfHqTaU5w== -is-buffer@^2.0.5: - version "2.0.5" - resolved "https://registry.yarnpkg.com/is-buffer/-/is-buffer-2.0.5.tgz#ebc252e400d22ff8d77fa09888821a24a658c191" - integrity sha512-i2R6zNFDwgEHJyQUtJEk0XFi1i0dPFn/oqjK3/vPCcDeJvW5NQ83V8QbicfF1SupOaB0h8ntgBC2YiE7dfyctQ== - is-builtin-module@^3.1.0: version "3.2.1" resolved "https://registry.yarnpkg.com/is-builtin-module/-/is-builtin-module-3.2.1.tgz#f03271717d8654cfcaf07ab0463faa3571581169" @@ -13690,11 +13404,6 @@ jose@^4.11.4: resolved "https://registry.yarnpkg.com/jose/-/jose-4.15.4.tgz#02a9a763803e3872cf55f29ecef0dfdcc218cc03" integrity sha512-W+oqK4H+r5sITxfxpSU+MMdr/YSWGvgZMQDIsNoBDGGy4i7GBPTtvFKibQzW06n3U3TqHjhvBJsirShsEJ6eeQ== -js-sdsl@^4.1.4: - version "4.4.2" - resolved "https://registry.yarnpkg.com/js-sdsl/-/js-sdsl-4.4.2.tgz#2e3c031b1f47d3aca8b775532e3ebb0818e7f847" - integrity sha512-dwXFwByc/ajSV6m5bcKAPwe4yDDF6D614pxmIi5odytzxRlwqF6nwoiCek80Ixc7Cvma5awClxrzFtxCQvcM8w== - js-sha3@0.8.0, js-sha3@^0.8.0: version "0.8.0" resolved "https://registry.yarnpkg.com/js-sha3/-/js-sha3-0.8.0.tgz#b9b7a5da73afad7dedd0f8c463954cbde6818840" @@ -14279,11 +13988,6 @@ level-sublevel@6.6.4: typewiselite "~1.0.0" xtend "~4.0.0" -level-supports@^4.0.0: - version "4.0.1" - resolved "https://registry.yarnpkg.com/level-supports/-/level-supports-4.0.1.tgz#431546f9d81f10ff0fea0e74533a0e875c08c66a" - integrity sha512-PbXpve8rKeNcZ9C1mUicC9auIYFyGpkV9/i6g76tLgANwWhtG2v7I4xNBUlkn3lE2/dZF3Pi0ygYGtLc4RXXdA== - level-supports@~1.0.0: version "1.0.1" resolved "https://registry.yarnpkg.com/level-supports/-/level-supports-1.0.1.tgz#2f530a596834c7301622521988e2c36bb77d122d" @@ -14291,14 +13995,6 @@ level-supports@~1.0.0: dependencies: xtend "^4.0.2" -level-transcoder@^1.0.1: - version "1.0.1" - resolved "https://registry.yarnpkg.com/level-transcoder/-/level-transcoder-1.0.1.tgz#f8cef5990c4f1283d4c86d949e73631b0bc8ba9c" - integrity sha512-t7bFwFtsQeD8cl8NIoQ2iwxA0CL/9IFw7/9gAjOonH0PWTTiRfY7Hq+Ejbsxh86tXobDQ6IOiddjNYIfOBs06w== - dependencies: - buffer "^6.0.3" - module-error "^1.0.1" - level-ws@0.0.0: version "0.0.0" resolved "https://registry.yarnpkg.com/level-ws/-/level-ws-0.0.0.tgz#372e512177924a00424b0b43aef2bb42496d228b" @@ -14326,14 +14022,6 @@ level@^5.0.1: leveldown "^5.0.0" opencollective-postinstall "^2.0.0" -level@^8.0.0: - version "8.0.0" - resolved "https://registry.yarnpkg.com/level/-/level-8.0.0.tgz#41b4c515dabe28212a3e881b61c161ffead14394" - integrity sha512-ypf0jjAk2BWI33yzEaaotpq7fkOPALKAgDBxggO6Q9HGX2MRXn0wbP1Jn/tJv1gtL867+YOjOB49WaUF3UoJNQ== - dependencies: - browser-level "^1.0.1" - classic-level "^1.2.0" - leveldown@^5.0.0: version "5.6.0" resolved "https://registry.yarnpkg.com/leveldown/-/leveldown-5.6.0.tgz#16ba937bb2991c6094e13ac5a6898ee66d3eee98" @@ -15106,11 +14794,6 @@ maxstache@^1.0.0: resolved "https://registry.yarnpkg.com/maxstache/-/maxstache-1.0.7.tgz#2231d5180ba783d5ecfc31c45fedac7ae4276984" integrity sha512-53ZBxHrZM+W//5AcRVewiLpDunHnucfdzZUGz54Fnvo4tE+J3p8EL66kBrs2UhBXvYKTWckWYYWBqJqoTcenqg== -mcl-wasm@^0.7.1: - version "0.7.9" - resolved "https://registry.yarnpkg.com/mcl-wasm/-/mcl-wasm-0.7.9.tgz#c1588ce90042a8700c3b60e40efb339fc07ab87f" - integrity sha512-iJIUcQWA88IJB/5L15GnJVnSQJmf/YaxxV6zRavv83HILHaJQb6y0iFyDMdDO0gN8X37tdxmAOrH/P8B6RB8sQ== - md5-hex@^3.0.1: version "3.0.1" resolved "https://registry.yarnpkg.com/md5-hex/-/md5-hex-3.0.1.tgz#be3741b510591434b2784d79e556eefc2c9a8e5c" @@ -15176,15 +14859,6 @@ memoize-one@^6.0.0: resolved "https://registry.yarnpkg.com/memoize-one/-/memoize-one-6.0.0.tgz#b2591b871ed82948aee4727dc6abceeeac8c1045" integrity sha512-rkpe71W0N0c0Xz6QD0eJETuWAJGnJ9afsl1srmwPrI+yBCkge5EycXXbYRyvL29zZVUWQCY7InPRCv3GDXuZNw== -memory-level@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/memory-level/-/memory-level-1.0.0.tgz#7323c3fd368f9af2f71c3cd76ba403a17ac41692" - integrity sha512-UXzwewuWeHBz5krr7EvehKcmLFNoXxGcvuYhC41tRnkrTbJohtS7kVn9akmgirtRygg+f7Yjsfi8Uu5SGSQ4Og== - dependencies: - abstract-level "^1.0.0" - functional-red-black-tree "^1.0.1" - module-error "^1.0.1" - memorystream@^0.3.1: version "0.3.1" resolved "https://registry.yarnpkg.com/memorystream/-/memorystream-0.3.1.tgz#86d7090b30ce455d63fbae12dda51a47ddcaf9b2" @@ -15605,11 +15279,6 @@ module-definition@^5.0.1: ast-module-types "^5.0.0" node-source-walk "^6.0.1" -module-error@^1.0.1, module-error@^1.0.2: - version "1.0.2" - resolved "https://registry.yarnpkg.com/module-error/-/module-error-1.0.2.tgz#8d1a48897ca883f47a45816d4fb3e3c6ba404d86" - integrity sha512-0yuvsqSCv8LbaOKhnsQ/T5JhyFlCYLPXK3U2sgV10zoKQwzs/MyfuQUOZQ1V/6OCOJsK/TRgNVrPuPDqtdMFtA== - moize@^6.1.0, moize@^6.1.3: version "6.1.6" resolved "https://registry.yarnpkg.com/moize/-/moize-6.1.6.tgz#ac2e723e74b951875fe2c0c3433405c2b098c3e6" @@ -15857,11 +15526,6 @@ napi-build-utils@^1.0.1: resolved "https://registry.yarnpkg.com/napi-build-utils/-/napi-build-utils-1.0.2.tgz#b1fddc0b2c46e380a0b7a76f984dd47c41a13806" integrity sha512-ONmRUqK7zj7DWX0D9ADe03wbwOBZxNAfF20PlGfCWQcD3+/MakShIHrMqx9YwPTfxDdF1zLeL+RGZiR9kGMLdg== -napi-macros@^2.2.2: - version "2.2.2" - resolved "https://registry.yarnpkg.com/napi-macros/-/napi-macros-2.2.2.tgz#817fef20c3e0e40a963fbf7b37d1600bd0201044" - integrity sha512-hmEVtAGYzVQpCKdbQea4skABsdXW4RUh5t5mJ2zzqowJS2OyXZTU1KhDVFhx+NlWZ4ap9mqR9TcDO3LTTttd+g== - napi-macros@~2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/napi-macros/-/napi-macros-2.0.0.tgz#2b6bae421e7b96eb687aa6c77a7858640670001b" @@ -17783,7 +17447,7 @@ querystringify@^2.1.1: resolved "https://registry.yarnpkg.com/querystringify/-/querystringify-2.2.0.tgz#3345941b4153cb9d082d8eee4cda2016a9aef7f6" integrity sha512-FIqgj2EUvTa7R50u0rGsyTftzjYmv/a3hO345bZNrqabNqjtgiDMgmo4mkUjd+nzU5oF3dClKqFIPUKybUyqoQ== -queue-microtask@^1.2.2, queue-microtask@^1.2.3: +queue-microtask@^1.2.2: version "1.2.3" resolved "https://registry.yarnpkg.com/queue-microtask/-/queue-microtask-1.2.3.tgz#4929228bbc724dfac43e0efb058caf7b6cfb6243" integrity sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A== @@ -18493,13 +18157,6 @@ run-async@^2.2.0, run-async@^2.4.0: resolved "https://registry.yarnpkg.com/run-async/-/run-async-2.4.1.tgz#8440eccf99ea3e70bd409d49aab88e10c189a455" integrity sha512-tvVnVv01b8c1RrA6Ep7JkStj85Guv/YrMcwqYQnwjsAS2cTmmPGBBjAjpCW7RrSodNSoE2/qg9O4bceNvUuDgQ== -run-parallel-limit@^1.1.0: - version "1.1.0" - resolved "https://registry.yarnpkg.com/run-parallel-limit/-/run-parallel-limit-1.1.0.tgz#be80e936f5768623a38a963262d6bef8ff11e7ba" - integrity sha512-jJA7irRNM91jaKc3Hcl1npHsFLOXOoTkPCUL1JEa1R82O2miplXXRaGdjW/KM/98YQWDhJLiSs793CnXfblJUw== - dependencies: - queue-microtask "^1.2.2" - run-parallel@^1.1.4, run-parallel@^1.1.9: version "1.2.0" resolved "https://registry.yarnpkg.com/run-parallel/-/run-parallel-1.2.0.tgz#66d1368da7bdf921eb9d95bd1a9229e7f21a43ee" From 4194fea493104ff61b20cfe9301ef1dccf95d9ed Mon Sep 17 00:00:00 2001 From: yuetloo Date: Thu, 16 May 2024 09:27:48 -0400 Subject: [PATCH 25/57] use MACI v1.2.2 --- common/package.json | 4 +-- contracts/package.json | 8 ++--- yarn.lock | 81 +++++++++++++++++++++--------------------- 3 files changed, 47 insertions(+), 46 deletions(-) diff --git a/common/package.json b/common/package.json index 713437020..fe0e1c90e 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": "1.2.1", - "maci-domainobjs": "1.2.1" + "maci-crypto": "1.2.2", + "maci-domainobjs": "1.2.2" }, "repository": { "type": "git", diff --git a/contracts/package.json b/contracts/package.json index c4b870f22..9706cfdbe 100644 --- a/contracts/package.json +++ b/contracts/package.json @@ -18,7 +18,7 @@ "@openzeppelin/contracts": "5.0.2", "@pinata/sdk": "^2.1.0", "dotenv": "^8.2.0", - "maci-contracts": "1.2.1", + "maci-contracts": "1.2.2", "solidity-rlp": "2.0.8" }, "devDependencies": { @@ -41,9 +41,9 @@ "hardhat-gas-reporter": "^1.0.8", "ipfs-only-hash": "^2.0.1", "lowdb": "1.0.0", - "maci-circuits": "1.2.1", - "maci-cli": "1.2.1", - "maci-domainobjs": "1.2.1", + "maci-circuits": "1.2.2", + "maci-cli": "1.2.2", + "maci-domainobjs": "1.2.2", "mocha": "^10.2.0", "solidity-coverage": "^0.8.1", "ts-node": "^10.9.2", diff --git a/yarn.lock b/yarn.lock index 3b91a1800..d013c2646 100644 --- a/yarn.lock +++ b/yarn.lock @@ -14520,7 +14520,7 @@ loupe@^2.3.6: dependencies: get-func-name "^2.0.1" -lowdb@1.0.0: +lowdb@1.0.0, lowdb@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/lowdb/-/lowdb-1.0.0.tgz#5243be6b22786ccce30e50c9a33eac36b20c8064" integrity sha512-2+x8esE/Wb9SQ1F9IHaYWfsC9FIecLOPrK4g17FGEayjUWH172H6nwicRovGvSE2CPZouc2MCIqCI7h9d+GftQ== @@ -14606,23 +14606,23 @@ 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@1.2.1, maci-circuits@^1.2.1: - version "1.2.1" - resolved "https://registry.yarnpkg.com/maci-circuits/-/maci-circuits-1.2.1.tgz#8012ac317736c7324af492eaf6e25e34b8e44519" - integrity sha512-Rch7UFOlrt9ENT8E8QQuAH7vNRVaMFcsk6Eg3C/BRQqKwb+f2A+PSb8qFEGGrqj51DaVEVZWL5KDPDbFpW5DoQ== +maci-circuits@1.2.2, maci-circuits@^1.2.2: + version "1.2.2" + resolved "https://registry.yarnpkg.com/maci-circuits/-/maci-circuits-1.2.2.tgz#2c3823dce9a8d29675eaeb8f1d9e9b1eb8d7437a" + integrity sha512-CBKeLfT5uywgUC+l4W+ZpDf7Av3ZGNpVX//tjgiy0Bgaps5bOhAScmKpAZIfB3aTitpOtiao9E9veb9syTNhnw== dependencies: "@zk-kit/circuits" "^0.4.0" circomkit "^0.1.0" circomlib "^2.0.5" - maci-core "^1.2.1" - maci-crypto "^1.2.1" - maci-domainobjs "^1.2.1" + maci-core "^1.2.2" + maci-crypto "^1.2.2" + maci-domainobjs "^1.2.2" snarkjs "^0.7.4" -maci-cli@1.2.1: - version "1.2.1" - resolved "https://registry.yarnpkg.com/maci-cli/-/maci-cli-1.2.1.tgz#0a23092163c24d215ddb392b98834f1d526e8340" - integrity sha512-48XZzRKONc4NGVJB1dnqL0Jou+f0WdMkwn7uP5PUhXBTbUY9lySZuHzWFUtWJ9ooW8s1acYgjAhpbmkHZatL4Q== +maci-cli@1.2.2: + version "1.2.2" + resolved "https://registry.yarnpkg.com/maci-cli/-/maci-cli-1.2.2.tgz#187f4c204f1ab46919b13c042508a8216a10d3c9" + integrity sha512-l5L7FpUH5eH5NkNFPsqXrWvJkdgkdSSZmjy28FR3SBNIGzfbgfT32x0hBoNSDs2QIb+72KZ3rgGyorc/icTXlg== dependencies: "@commander-js/extra-typings" "^12.0.1" "@nomicfoundation/hardhat-toolbox" "^5.0.0" @@ -14630,17 +14630,17 @@ maci-cli@1.2.1: dotenv "^16.4.5" ethers "^6.12.0" hardhat "^2.22.3" - maci-circuits "^1.2.1" - maci-contracts "^1.2.1" - maci-core "^1.2.1" - maci-crypto "^1.2.1" - maci-domainobjs "^1.2.1" + maci-circuits "^1.2.2" + maci-contracts "^1.2.2" + maci-core "^1.2.2" + maci-crypto "^1.2.2" + maci-domainobjs "^1.2.2" prompt "^1.3.0" -maci-contracts@1.2.1, maci-contracts@^1.2.1: - version "1.2.1" - resolved "https://registry.yarnpkg.com/maci-contracts/-/maci-contracts-1.2.1.tgz#ac9f44dc895573d8fe026f19a21edb255fe822ea" - integrity sha512-/B5P82nZgKpSBvxZ3xUoF1mTPDZRMviCWG0ItF93TLnxPTJSMBqFrqJy3mXOHS7sK2/7M5E4NXC1TQ/oFVUATg== +maci-contracts@1.2.2, maci-contracts@^1.2.2: + version "1.2.2" + resolved "https://registry.yarnpkg.com/maci-contracts/-/maci-contracts-1.2.2.tgz#65892940f04cff2f7abeed0e32ca3a3275b96887" + integrity sha512-Iws+V2EOe6z8hobEwGnVTV90i6eyCHixFAYdAcVU34bCwksFgL03EssXLi5baS+a3Uig3VgjUE4QbidpBFi0Jw== dependencies: "@nomicfoundation/hardhat-ethers" "^3.0.5" "@nomicfoundation/hardhat-toolbox" "^5.0.0" @@ -14648,36 +14648,37 @@ maci-contracts@1.2.1, maci-contracts@^1.2.1: circomlibjs "^0.1.7" ethers "^6.12.0" hardhat "^2.22.3" - maci-circuits "^1.2.1" - maci-core "^1.2.1" - maci-crypto "^1.2.1" - maci-domainobjs "^1.2.1" + lowdb "^1.0.0" + maci-circuits "^1.2.2" + maci-core "^1.2.2" + maci-crypto "^1.2.2" + maci-domainobjs "^1.2.2" solidity-docgen "^0.6.0-beta.36" -maci-core@^1.2.1: - version "1.2.1" - resolved "https://registry.yarnpkg.com/maci-core/-/maci-core-1.2.1.tgz#546f5a4ea0df0e1525df0ccfb3c54c4bb569c81f" - integrity sha512-8AXzvgcmQFdq5oQCvVZClK7FmTVLzPMDNgKAkc8waTtxLJIhP7Of3SMxfX5zu9Gay1ZGc9YMbC4NVdvdJTsC7g== +maci-core@^1.2.2: + version "1.2.2" + resolved "https://registry.yarnpkg.com/maci-core/-/maci-core-1.2.2.tgz#a0a570838ff820a347c18738cac4fa9c75c15f55" + integrity sha512-a4OdSnlP7Rk9g4rn5D8oCjQIIYSMxd5DH1Entgj1JnJ7G4GuIEoC1RP2zw/Bh7wolDi1J9IYFmwFIzdS332ggA== dependencies: - maci-crypto "^1.2.1" - maci-domainobjs "^1.2.1" + maci-crypto "^1.2.2" + maci-domainobjs "^1.2.2" -maci-crypto@1.2.1, maci-crypto@^1.2.1: - version "1.2.1" - resolved "https://registry.yarnpkg.com/maci-crypto/-/maci-crypto-1.2.1.tgz#46999c233f43556960a50bec60c5437443dcd108" - integrity sha512-NERlCuBXYBsTSrE4GMozEgP9x8cL0Wk5ng9XZ/aBp4ib2HAJWyJC78gslRpwhjNNiRFw7TsYH0fcHqHjQ7YCKg== +maci-crypto@1.2.2, maci-crypto@^1.2.2: + version "1.2.2" + resolved "https://registry.yarnpkg.com/maci-crypto/-/maci-crypto-1.2.2.tgz#cd90a741ec9e8713e54c142c01c0648a1d414e7c" + integrity sha512-N752cmfC+guhCrV+2szXsf+1ChFBsVRVGiFLJAGw+rKIERlct4jJryzM4kTVIfL0qFSKBsw8NsQQfrRacLMlFQ== 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-domainobjs@1.2.1, maci-domainobjs@^1.2.1: - version "1.2.1" - resolved "https://registry.yarnpkg.com/maci-domainobjs/-/maci-domainobjs-1.2.1.tgz#7bb0ecc6131ed11aba1e73ad6112d7ad6ad807ac" - integrity sha512-oA/Qgigvr8UAvlBx+avNnN2QYd7tREW/SjMiNtHrhnn64cHCqrnuWGSylGYFec0CUaYHQ5RGho1tvHdce1xBLA== +maci-domainobjs@1.2.2, maci-domainobjs@^1.2.2: + version "1.2.2" + resolved "https://registry.yarnpkg.com/maci-domainobjs/-/maci-domainobjs-1.2.2.tgz#7b72d93ad88d7306342b3d9691247396f3bc870a" + integrity sha512-Wdtb/baKeITXGTAfA+6X573bcarCxD0KGXaSxoEuxZDbdamwhBqYdTRBcLNBFLK4eWC0RethzwW7lAQuGJfPdg== dependencies: - maci-crypto "^1.2.1" + maci-crypto "^1.2.2" macos-release@^3.1.0: version "3.2.0" From e3ff6058ea2bef815baf8ceb9de5a0e38dc628ff Mon Sep 17 00:00:00 2001 From: yuetloo Date: Thu, 16 May 2024 21:23:34 -0400 Subject: [PATCH 26/57] remove unused variable --- contracts/tasks/runners/verifyAll.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/contracts/tasks/runners/verifyAll.ts b/contracts/tasks/runners/verifyAll.ts index c010df8ff..74972fe0c 100644 --- a/contracts/tasks/runners/verifyAll.ts +++ b/contracts/tasks/runners/verifyAll.ts @@ -286,7 +286,7 @@ task('verify-all', 'Verify contracts listed in storage') .addOptionalParam('clrfund', 'The ClrFund contract address') .addFlag('force', 'Ignore verified status') .setAction(async ({ clrfund }, hre) => { - const { ethers, config, network } = hre + const { ethers, network } = hre const storage = ContractStorage.getInstance() const clrfundContractAddress = From 5d5d67e1b4d6f5a39ff6dc13572279b96a0a3993 Mon Sep 17 00:00:00 2001 From: yuetloo Date: Thu, 16 May 2024 21:36:57 -0400 Subject: [PATCH 27/57] remove lowdb since it is added in maci-contracts now --- contracts/package.json | 1 - yarn.lock | 2 +- 2 files changed, 1 insertion(+), 2 deletions(-) diff --git a/contracts/package.json b/contracts/package.json index 9706cfdbe..a762f7d4a 100644 --- a/contracts/package.json +++ b/contracts/package.json @@ -40,7 +40,6 @@ "hardhat-contract-sizer": "^2.10.0", "hardhat-gas-reporter": "^1.0.8", "ipfs-only-hash": "^2.0.1", - "lowdb": "1.0.0", "maci-circuits": "1.2.2", "maci-cli": "1.2.2", "maci-domainobjs": "1.2.2", diff --git a/yarn.lock b/yarn.lock index d013c2646..108db9ee4 100644 --- a/yarn.lock +++ b/yarn.lock @@ -14520,7 +14520,7 @@ loupe@^2.3.6: dependencies: get-func-name "^2.0.1" -lowdb@1.0.0, lowdb@^1.0.0: +lowdb@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/lowdb/-/lowdb-1.0.0.tgz#5243be6b22786ccce30e50c9a33eac36b20c8064" integrity sha512-2+x8esE/Wb9SQ1F9IHaYWfsC9FIecLOPrK4g17FGEayjUWH172H6nwicRovGvSE2CPZouc2MCIqCI7h9d+GftQ== From 3a5143684ef1eec9cb834527a3ae48338422e538 Mon Sep 17 00:00:00 2001 From: yuetloo Date: Thu, 16 May 2024 21:37:43 -0400 Subject: [PATCH 28/57] use ethers 6.12.1 --- vue-app/package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/vue-app/package.json b/vue-app/package.json index 1c7267fbd..5d05ae141 100644 --- a/vue-app/package.json +++ b/vue-app/package.json @@ -34,7 +34,7 @@ "@walletconnect/modal": "^2.6.0", "crypto-js": "^4.1.1", "ethereum-blockies-base64": "^1.0.2", - "ethers": "^6.11.1", + "ethers": "^6.12.1", "floating-vue": "^2.0.0-beta.20", "google-spreadsheet": "^3.3.0", "graphql": "^16.6.0", From 916e5e2c3d9c72629c62b4bbc736ba8005ff305a Mon Sep 17 00:00:00 2001 From: yuetloo Date: Fri, 17 May 2024 16:14:20 -0400 Subject: [PATCH 29/57] update waffle-mock-contract to v0.0.11 --- contracts/package.json | 2 +- yarn.lock | 28 +++++----------------------- 2 files changed, 6 insertions(+), 24 deletions(-) diff --git a/contracts/package.json b/contracts/package.json index a762f7d4a..1bb19275e 100644 --- a/contracts/package.json +++ b/contracts/package.json @@ -23,7 +23,7 @@ }, "devDependencies": { "@clrfund/common": "^0.0.1", - "@clrfund/waffle-mock-contract": "^0.0.4", + "@clrfund/waffle-mock-contract": "^0.0.11", "@kleros/gtcr-encoder": "^1.4.0", "@nomicfoundation/hardhat-chai-matchers": "^2.0.6", "@nomicfoundation/hardhat-ethers": "^3.0.6", diff --git a/yarn.lock b/yarn.lock index 108db9ee4..2e8eb68ed 100644 --- a/yarn.lock +++ b/yarn.lock @@ -7,11 +7,6 @@ resolved "https://registry.yarnpkg.com/@aashutoshrathi/word-wrap/-/word-wrap-1.2.6.tgz#bd9154aec9983f77b3a034ecaa015c2e4201f6cf" integrity sha512-1Yjs2SvM8TflER/OD3cOjhWWOZb58A2t7wpE2S9XfBYTiIl+XFhQG2bjy4Pu1I+EAlCNUzRDYDdFwFYUKvXcIA== -"@adraffy/ens-normalize@1.10.0": - version "1.10.0" - resolved "https://registry.yarnpkg.com/@adraffy/ens-normalize/-/ens-normalize-1.10.0.tgz#d2a39395c587e092d77cbbc80acf956a54f38bf7" - integrity sha512-nA9XHtlAkYfJxY7bce8DcN7eKxWWCWkU+1GR9d+U6MbNpfwQp8TI7vqOsBsMcHoT4mBu2kypKoSKnghEzOOq5Q== - "@adraffy/ens-normalize@1.10.1": version "1.10.1" resolved "https://registry.yarnpkg.com/@adraffy/ens-normalize/-/ens-normalize-1.10.1.tgz#63430d04bd8c5e74f8d7d049338f1cd9d4f02069" @@ -578,12 +573,12 @@ resolved "https://registry.yarnpkg.com/@bugsnag/safe-json-stringify/-/safe-json-stringify-6.0.0.tgz#22abdcd83e008c369902976730c34c150148a758" integrity sha512-htzFO1Zc57S8kgdRK9mLcPVTW1BY2ijfH7Dk2CeZmspTWKdKqSo1iwmqrq2WtRjFlo8aRZYgLX0wFrDXF/9DLA== -"@clrfund/waffle-mock-contract@^0.0.4": - version "0.0.4" - resolved "https://registry.yarnpkg.com/@clrfund/waffle-mock-contract/-/waffle-mock-contract-0.0.4.tgz#97bb6b20df60a77b8a501e45fb4f049bdaebbea0" - integrity sha512-YRAMIFIHVpvu99b7mvVY0+XsN1JWJ57St7xv5M2VzBTXB/ARPLZENAdfpyjr1xPdpyFVed6TCurdsR6K8SWWpQ== +"@clrfund/waffle-mock-contract@^0.0.11": + version "0.0.11" + resolved "https://registry.yarnpkg.com/@clrfund/waffle-mock-contract/-/waffle-mock-contract-0.0.11.tgz#4e5917ca19ce90ae9e3160b6a1d5858e7121e408" + integrity sha512-PkaTsujg4Ybbwuq7QjWlakO3io1B88GGVesfc3VlY5EWptA3LuNqfv51KpK7L1qoWpbyZP8vsBheL8GxHwfw6A== dependencies: - ethers "^6.9.2" + ethers "^6.12.1" "@colors/colors@1.5.0": version "1.5.0" @@ -9943,19 +9938,6 @@ ethers@^6.12.0, ethers@^6.12.1: 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" - integrity sha512-nMNwYHzs6V1FR3Y4cdfxSQmNgZsRj1RiTU25JwvnJLmyzw9z3SKxNc2XKDuiXXo/v9ds5Mp9m6HBabgYQQ26tA== - dependencies: - "@adraffy/ens-normalize" "1.10.0" - "@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" - ethjs-unit@0.1.6: version "0.1.6" resolved "https://registry.yarnpkg.com/ethjs-unit/-/ethjs-unit-0.1.6.tgz#c665921e476e87bce2a9d588a6fe0405b2c41699" From 8f79a271817608f456379a91f2defb6e477ee936 Mon Sep 17 00:00:00 2001 From: yuetloo Date: Sat, 18 May 2024 21:16:53 -0400 Subject: [PATCH 30/57] use ethers v6.12.1 --- common/package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/common/package.json b/common/package.json index fe0e1c90e..9e3d72dc2 100644 --- a/common/package.json +++ b/common/package.json @@ -22,7 +22,7 @@ }, "dependencies": { "@openzeppelin/merkle-tree": "^1.0.5", - "ethers": "^6.11.1", + "ethers": "^6.12.1", "maci-crypto": "1.2.2", "maci-domainobjs": "1.2.2" }, From 98611cea39d51e5bcb745de7e8a00946c9abd32b Mon Sep 17 00:00:00 2001 From: yuetloo Date: Sat, 18 May 2024 21:17:56 -0400 Subject: [PATCH 31/57] update for MACI v1.2.2 interface change --- contracts/contracts/MACICommon.sol | 3 -- contracts/contracts/MACIFactory.sol | 1 - contracts/e2e/index.ts | 10 +---- .../tasks/helpers/ConstructorArguments.ts | 1 - contracts/tasks/runners/proveOnChain.ts | 1 - .../tasks/subtasks/clrfund/08-maciFactory.ts | 2 - contracts/utils/testutils.ts | 2 - subgraph/abis/MACIFactory.json | 42 ++++++++++--------- yarn.lock | 13 ------ 9 files changed, 24 insertions(+), 51 deletions(-) diff --git a/contracts/contracts/MACICommon.sol b/contracts/contracts/MACICommon.sol index 05762874e..f41843794 100644 --- a/contracts/contracts/MACICommon.sol +++ b/contracts/contracts/MACICommon.sol @@ -16,9 +16,6 @@ contract MACICommon { struct Factories { address pollFactory; address tallyFactory; - // subsidyFactory is not currently used, it's just a place holder here - address subsidyFactory; address messageProcessorFactory; } - } \ No newline at end of file diff --git a/contracts/contracts/MACIFactory.sol b/contracts/contracts/MACIFactory.sol index 2bccc4655..16a6f6e48 100644 --- a/contracts/contracts/MACIFactory.sol +++ b/contracts/contracts/MACIFactory.sol @@ -41,7 +41,6 @@ contract MACIFactory is Ownable(msg.sender), Params, SnarkCommon, DomainObjs, MA error InvalidVkRegistry(); error InvalidPollFactory(); error InvalidTallyFactory(); - error InvalidSubsidyFactory(); error InvalidMessageProcessorFactory(); error InvalidVerifier(); diff --git a/contracts/e2e/index.ts b/contracts/e2e/index.ts index f3ad49b7c..52d949abe 100644 --- a/contracts/e2e/index.ts +++ b/contracts/e2e/index.ts @@ -16,11 +16,7 @@ import { DEFAULT_GET_LOG_BATCH_SIZE, DEFAULT_SR_QUEUE_OPS, } from '../utils/constants' -import { - getContractAt, - getEventArg, - getQualifiedContractName, -} from '../utils/contracts' +import { getContractAt, getEventArg } from '../utils/contracts' import { deployPoseidonLibraries, deployMaciFactory } from '../utils/testutils' import { getIpfsHash } from '../utils/ipfs' import { @@ -37,7 +33,7 @@ import { DEFAULT_CIRCUIT } from '../utils/circuits' import { MaciParameters } from '../utils/maciParameters' import { existsSync, mkdirSync } from 'fs' import path from 'path' -import { FundingRound, Poll } from '../typechain-types' +import { FundingRound } from '../typechain-types' import { JSONFile } from '../utils/JSONFile' import { EContracts } from '../utils/types' import { getTalyFilePath } from '../utils/misc' @@ -398,7 +394,6 @@ describe('End-to-end Tests', function () { await proveOnChain({ pollId, proofDir: genProofArgs.outputDir, - subsidyEnabled: false, maciAddress, messageProcessorAddress, tallyAddress, @@ -418,7 +413,6 @@ describe('End-to-end Tests', function () { await proveOnChain({ pollId, proofDir: genProofArgs.outputDir, - subsidyEnabled: false, maciAddress, messageProcessorAddress, tallyAddress, diff --git a/contracts/tasks/helpers/ConstructorArguments.ts b/contracts/tasks/helpers/ConstructorArguments.ts index 751a8bbc4..3f77d336b 100644 --- a/contracts/tasks/helpers/ConstructorArguments.ts +++ b/contracts/tasks/helpers/ConstructorArguments.ts @@ -70,7 +70,6 @@ async function getMaciConstructorArguments( maci.pollFactory(), maci.messageProcessorFactory(), maci.tallyFactory(), - maci.subsidyFactory(), maci.signUpGatekeeper(), maci.initialVoiceCreditProxy(), maci.topupCredit(), diff --git a/contracts/tasks/runners/proveOnChain.ts b/contracts/tasks/runners/proveOnChain.ts index af777ed12..40946ba62 100644 --- a/contracts/tasks/runners/proveOnChain.ts +++ b/contracts/tasks/runners/proveOnChain.ts @@ -90,7 +90,6 @@ task('prove-on-chain', 'Prove on chain with the MACI proofs') await proveOnChain({ pollId, proofDir, - subsidyEnabled: false, maciAddress, messageProcessorAddress, tallyAddress, diff --git a/contracts/tasks/subtasks/clrfund/08-maciFactory.ts b/contracts/tasks/subtasks/clrfund/08-maciFactory.ts index cfaf146a6..c21c41817 100644 --- a/contracts/tasks/subtasks/clrfund/08-maciFactory.ts +++ b/contracts/tasks/subtasks/clrfund/08-maciFactory.ts @@ -48,8 +48,6 @@ subtask const factories = { pollFactory: pollFactoryContractAddress, tallyFactory: tallyFactoryContractAddress, - // subsidy is not currently used - subsidyFactory: ZERO_ADDRESS, messageProcessorFactory: messageProcessorFactoryContractAddress, } diff --git a/contracts/utils/testutils.ts b/contracts/utils/testutils.ts index e423421fd..8a306cf41 100644 --- a/contracts/utils/testutils.ts +++ b/contracts/utils/testutils.ts @@ -128,8 +128,6 @@ export async function deployMaciFactory({ const factories = { pollFactory: pollFactory.target, tallyFactory: tallyFactory.target, - // subsidy is not currently used - subsidyFactory: ZERO_ADDRESS, messageProcessorFactory: messageProcessorFactory.target, } diff --git a/subgraph/abis/MACIFactory.json b/subgraph/abis/MACIFactory.json index c8ab362b8..7f3ae7c07 100644 --- a/subgraph/abis/MACIFactory.json +++ b/subgraph/abis/MACIFactory.json @@ -18,11 +18,6 @@ "name": "tallyFactory", "type": "address" }, - { - "internalType": "address", - "name": "subsidyFactory", - "type": "address" - }, { "internalType": "address", "name": "messageProcessorFactory", @@ -52,11 +47,6 @@ "name": "InvalidPollFactory", "type": "error" }, - { - "inputs": [], - "name": "InvalidSubsidyFactory", - "type": "error" - }, { "inputs": [], "name": "InvalidTallyFactory", @@ -77,6 +67,28 @@ "name": "NotInitialized", "type": "error" }, + { + "inputs": [ + { + "internalType": "address", + "name": "owner", + "type": "address" + } + ], + "name": "OwnableInvalidOwner", + "type": "error" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "account", + "type": "address" + } + ], + "name": "OwnableUnauthorizedAccount", + "type": "error" + }, { "inputs": [], "name": "ProcessVkNotSet", @@ -224,11 +236,6 @@ "internalType": "address", "name": "tally", "type": "address" - }, - { - "internalType": "address", - "name": "subsidy", - "type": "address" } ], "internalType": "struct MACI.PollContracts", @@ -253,11 +260,6 @@ "name": "tallyFactory", "type": "address" }, - { - "internalType": "address", - "name": "subsidyFactory", - "type": "address" - }, { "internalType": "address", "name": "messageProcessorFactory", diff --git a/yarn.lock b/yarn.lock index 2e8eb68ed..0f640e5d7 100644 --- a/yarn.lock +++ b/yarn.lock @@ -9912,19 +9912,6 @@ ethers@^5.0.3, ethers@^5.5.1, ethers@^5.7.2: "@ethersproject/web" "5.7.1" "@ethersproject/wordlists" "5.7.0" -ethers@^6.11.1: - version "6.11.1" - resolved "https://registry.yarnpkg.com/ethers/-/ethers-6.11.1.tgz#96aae00b627c2e35f9b0a4d65c7ab658259ee6af" - integrity sha512-mxTAE6wqJQAbp5QAe/+o+rXOID7Nw91OZXvgpjDa1r4fAbq2Nu314oEZSbjoRLacuCzs7kUC3clEvkCQowffGg== - 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.12.0, ethers@^6.12.1: version "6.12.1" resolved "https://registry.yarnpkg.com/ethers/-/ethers-6.12.1.tgz#517ff6d66d4fd5433e38e903051da3e57c87ff37" From d7173562bede3f5f807d8ecc624a7ba688546614 Mon Sep 17 00:00:00 2001 From: yuetloo Date: Sat, 18 May 2024 22:43:32 -0400 Subject: [PATCH 32/57] fix decode recipient metadata error --- vue-app/src/api/recipient-registry-simple.ts | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/vue-app/src/api/recipient-registry-simple.ts b/vue-app/src/api/recipient-registry-simple.ts index 852e85f4c..8b8f581db 100644 --- a/vue-app/src/api/recipient-registry-simple.ts +++ b/vue-app/src/api/recipient-registry-simple.ts @@ -6,6 +6,7 @@ import { provider, ipfsGatewayUrl } from './core' import type { Project } from './projects' import type { RegistryInfo, RecipientApplicationData } from './types' import { formToRecipientData } from './recipient' +import { getNumber } from 'ethers' function decodeRecipientAdded(event: EventLog): Project { const args = event.args as any @@ -28,7 +29,7 @@ function decodeRecipientAdded(event: EventLog): Project { discordUrl: metadata.discordUrl, bannerImageUrl: `${ipfsGatewayUrl}/ipfs/${metadata.bannerImageHash}`, thumbnailImageUrl: `${ipfsGatewayUrl}/ipfs/${metadata.thumbnailImageHash}`, - index: args._index.toNumber(), + index: getNumber(args._index), isHidden: false, isLocked: false, } From 43b161d8b8604e9944672cbba18e2b7b60e4cc7b Mon Sep 17 00:00:00 2001 From: yuetloo Date: Sun, 19 May 2024 20:55:58 -0400 Subject: [PATCH 33/57] remove an issue already fixed in MACI --- docs/tally-verify.md | 2 -- 1 file changed, 2 deletions(-) diff --git a/docs/tally-verify.md b/docs/tally-verify.md index 9ce6bc7dd..080d219c1 100644 --- a/docs/tally-verify.md +++ b/docs/tally-verify.md @@ -87,6 +87,4 @@ Also, lack of memory can also cause `core dump`, try to work around it by settin export NODE_OPTIONS=--max-old-space-size=4096 ``` -If you notice `Error at message index 0 - failed decryption due to either wrong encryption public key or corrupted ciphertext` while running the tally script, don't worry, it's just a warning. This issue is tracked [here](https://github.com/privacy-scaling-explorations/maci/issues/1134) - `Error at message index n - invalid nonce` is also a warning, not an error. This error occurs when users reallocated their contribution. From 30a38a3c856fe044bc63a8cd2d072766f703beb5 Mon Sep 17 00:00:00 2001 From: yuetloo Date: Mon, 20 May 2024 22:10:24 -0400 Subject: [PATCH 34/57] fix incorrect maxContributors, maxMessages and maxVoteOptions --- common/src/utils.ts | 16 +++- contracts/tests/round.ts | 80 ++++++++++++++++--- contracts/utils/maci.ts | 4 +- contracts/utils/testutils.ts | 26 ++++-- subgraph/generated/ClrFund/MACIFactory.ts | 40 ++-------- subgraph/generated/schema.ts | 34 ++++++++ subgraph/schema.graphql | 3 + subgraph/schema.template.graphql | 3 + subgraph/src/ClrFundMapping.ts | 6 ++ vue-app/src/api/round.ts | 22 +++-- vue-app/src/graphql/API.ts | 37 ++++++++- .../src/graphql/queries/GetRoundInfo.graphql | 2 + 12 files changed, 209 insertions(+), 64 deletions(-) diff --git a/common/src/utils.ts b/common/src/utils.ts index d0bd5cdcb..aee9aba9c 100644 --- a/common/src/utils.ts +++ b/common/src/utils.ts @@ -12,7 +12,9 @@ import { Keypair } from './keypair' import { Tally } from './tally' import { bnSqrt } from './math' -const LEAVES_PER_NODE = 5 +// This has to match the MACI TREE_ARITY at: +// github.com/privacy-scaling-explorations/maci/blob/0c18913d4c84bfa9fbfd66dc017e338df9fdda96/contracts/contracts/MACI.sol#L31 +export const MACI_TREE_ARITY = 5 export function createMessage( userStateIndex: number, @@ -65,7 +67,7 @@ export function getRecipientClaimData( const spentTree = new IncrementalQuinTree( recipientTreeDepth, BigInt(0), - LEAVES_PER_NODE, + MACI_TREE_ARITY, hash5 ) for (const leaf of tally.perVOSpentVoiceCredits.tally) { @@ -94,6 +96,15 @@ export function getRecipientClaimData( ] } +/** + * Returns the maximum MACI users allowed by the state tree + * @param stateTreeDepth MACI state tree depth + * @returns the maximum number of contributors allowed by MACI circuit + */ +export function getMaxContributors(stateTreeDepth: number): number { + return MACI_TREE_ARITY ** stateTreeDepth - 1 +} + export { genTallyResultCommitment, Message, @@ -103,5 +114,4 @@ export { hash2, hash3, hashLeftRight, - LEAVES_PER_NODE, } diff --git a/contracts/tests/round.ts b/contracts/tests/round.ts index 887e9224a..52f0bf12a 100644 --- a/contracts/tests/round.ts +++ b/contracts/tests/round.ts @@ -10,9 +10,11 @@ import { randomBytes, hexlify, toNumber, + Wallet, + TransactionResponse, } from 'ethers' import { genRandomSalt } from 'maci-crypto' -import { Keypair } from '@clrfund/common' +import { getMaxContributors, Keypair, MACI_TREE_ARITY } from '@clrfund/common' import { time } from '@nomicfoundation/hardhat-network-helpers' import { @@ -29,11 +31,14 @@ import { getRecipientClaimData, mergeMaciSubtrees, } from '../utils/maci' -import { deployTestFundingRound } from '../utils/testutils' +import { + deployTestFundingRound, + DeployTestFundingRoundOutput, +} from '../utils/testutils' // ethStaker test vectors for Quadratic Funding with alpha import smallTallyTestData from './data/testTallySmall.json' -import { FundingRound } from '../typechain-types' +import { AnyOldERC20Token, FundingRound } from '../typechain-types' import { EContracts } from '../utils/types' const newResultCommitment = hexlify(randomBytes(32)) @@ -66,6 +71,33 @@ function calcAllocationAmount(tally: string, voiceCredit: string): bigint { return allocation / ALPHA_PRECISION } +/** + * Simulate contribution by a random user + * @param contracts list of contracts returned from the deployTestFundingRound function + * @param deployer the account that owns the contracts + * @returns contribute transaction response + */ +async function contributeByRandomUser( + contracts: DeployTestFundingRoundOutput, + deployer: HardhatEthersSigner +): Promise { + const amount = ethers.parseEther('0.1') + const keypair = new Keypair() + const user = Wallet.createRandom(ethers.provider) + await contracts.token.transfer(user.address, amount) + await deployer.sendTransaction({ to: user.address, value: amount }) + const tokenAsUser = contracts.token.connect(user) as AnyOldERC20Token + await tokenAsUser.approve(contracts.fundingRound.target, amount) + const fundingRoundAsUser = contracts.fundingRound.connect( + user + ) as FundingRound + const tx = await fundingRoundAsUser.contribute( + keypair.pubKey.asContractParam(), + amount + ) + return tx +} + describe('Funding Round', () => { const coordinatorPubKey = new Keypair().pubKey const roundDuration = 86400 * 7 @@ -101,13 +133,13 @@ describe('Funding Round', () => { beforeEach(async () => { const tokenInitialSupply = UNIT * BigInt(1000000) - const deployed = await deployTestFundingRound( - tokenInitialSupply + budget, - coordinator.address, - coordinatorPubKey, + const deployed = await deployTestFundingRound({ + tokenSupply: tokenInitialSupply + budget, + coordinatorAddress: coordinator.address, + coordinatorPubKey: coordinatorPubKey, roundDuration, - deployer - ) + deployer, + }) token = deployed.token fundingRound = deployed.fundingRound userRegistry = deployed.mockUserRegistry @@ -115,7 +147,7 @@ describe('Funding Round', () => { tally = deployed.mockTally const mockVerifier = deployed.mockVerifier - // make the verifier to alwasy returns true + // make the verifier to always returns true await mockVerifier.mock.verify.returns(true) await userRegistry.mock.isVerifiedUser.returns(true) await tally.mock.tallyBatchNum.returns(1) @@ -205,8 +237,34 @@ describe('Funding Round', () => { ).to.equal(expectedVoiceCredits) }) + it('calculates max contributors correctly', async () => { + const stateTreeDepth = toNumber(await maci.stateTreeDepth()) + const maxUsers = MACI_TREE_ARITY ** stateTreeDepth - 1 + expect(getMaxContributors(stateTreeDepth)).to.eq(maxUsers) + }) + it('limits the number of contributors', async () => { - // TODO: add test later + // use a smaller stateTreeDepth to run the test faster + const stateTreeDepth = 1 + const contracts = await deployTestFundingRound({ + stateTreeDepth, + tokenSupply: UNIT * BigInt(1000000), + coordinatorAddress: coordinator.address, + coordinatorPubKey, + roundDuration, + deployer, + }) + await contracts.mockUserRegistry.mock.isVerifiedUser.returns(true) + + const maxUsers = getMaxContributors(stateTreeDepth) + for (let i = 0; i < maxUsers; i++) { + await contributeByRandomUser(contracts, deployer) + } + + // this should throw TooManySignups + await expect( + contributeByRandomUser(contracts, deployer) + ).to.be.revertedWithCustomError(maci, 'TooManySignups') }) it('rejects contributions if funding round has been finalized', async () => { diff --git a/contracts/utils/maci.ts b/contracts/utils/maci.ts index caa8467ba..340134752 100644 --- a/contracts/utils/maci.ts +++ b/contracts/utils/maci.ts @@ -7,7 +7,7 @@ import { hash5, hash3, hashLeftRight, - LEAVES_PER_NODE, + MACI_TREE_ARITY, genTallyResultCommitment, Keypair, Tally as TallyData, @@ -50,7 +50,7 @@ export function getTallyResultProof( const resultTree = new IncrementalQuinTree( recipientTreeDepth, BigInt(0), - LEAVES_PER_NODE, + MACI_TREE_ARITY, hash5 ) for (const leaf of tally.results.tally) { diff --git a/contracts/utils/testutils.ts b/contracts/utils/testutils.ts index 8a306cf41..6d80b7a71 100644 --- a/contracts/utils/testutils.ts +++ b/contracts/utils/testutils.ts @@ -169,13 +169,21 @@ export type DeployTestFundingRoundOutput = { * @param deployer singer for the contract deployment * @returns all the deployed objects in DeployTestFundingRoundOutput */ -export async function deployTestFundingRound( - tokenSupply: bigint, - coordinatorAddress: string, - coordinatorPubKey: PubKey, - roundDuration: number, +export async function deployTestFundingRound({ + stateTreeDepth, + tokenSupply, + coordinatorAddress, + coordinatorPubKey, + roundDuration, + deployer, +}: { + stateTreeDepth?: number + tokenSupply: bigint + coordinatorAddress: string + coordinatorPubKey: PubKey + roundDuration: number deployer: Signer -): Promise { +}): Promise { const token = await ethers.deployContract( EContracts.AnyOldERC20Token, [tokenSupply], @@ -208,6 +216,12 @@ export async function deployTestFundingRound( }) const maciParameters = MaciParameters.mock() + + // use the stateTreeDepth from input + if (stateTreeDepth != undefined) { + maciParameters.stateTreeDepth = stateTreeDepth + } + const maciFactory = await deployMaciFactory({ libraries, ethers, diff --git a/subgraph/generated/ClrFund/MACIFactory.ts b/subgraph/generated/ClrFund/MACIFactory.ts index c9f330074..7c1fbe71b 100644 --- a/subgraph/generated/ClrFund/MACIFactory.ts +++ b/subgraph/generated/ClrFund/MACIFactory.ts @@ -76,10 +76,6 @@ export class MACIFactory__deployMaciResult_pollContractsStruct extends ethereum. get tally(): Address { return this[2].toAddress(); } - - get subsidy(): Address { - return this[3].toAddress(); - } } export class MACIFactory__deployMaciResult { @@ -124,18 +120,11 @@ export class MACIFactory__factoriesResult { value0: Address; value1: Address; value2: Address; - value3: Address; - constructor( - value0: Address, - value1: Address, - value2: Address, - value3: Address, - ) { + constructor(value0: Address, value1: Address, value2: Address) { this.value0 = value0; this.value1 = value1; this.value2 = value2; - this.value3 = value3; } toMap(): TypedMap { @@ -143,7 +132,6 @@ export class MACIFactory__factoriesResult { map.set("value0", ethereum.Value.fromAddress(this.value0)); map.set("value1", ethereum.Value.fromAddress(this.value1)); map.set("value2", ethereum.Value.fromAddress(this.value2)); - map.set("value3", ethereum.Value.fromAddress(this.value3)); return map; } @@ -155,12 +143,8 @@ export class MACIFactory__factoriesResult { return this.value1; } - getSubsidyFactory(): Address { - return this.value2; - } - getMessageProcessorFactory(): Address { - return this.value3; + return this.value2; } } @@ -269,7 +253,7 @@ export class MACIFactory extends ethereum.SmartContract { ): MACIFactory__deployMaciResult { let result = super.call( "deployMaci", - "deployMaci(address,address,address,uint256,address,(uint256,uint256),address):(address,(address,address,address,address))", + "deployMaci(address,address,address,uint256,address,(uint256,uint256),address):(address,(address,address,address))", [ ethereum.Value.fromAddress(signUpGatekeeper), ethereum.Value.fromAddress(initialVoiceCreditProxy), @@ -300,7 +284,7 @@ export class MACIFactory extends ethereum.SmartContract { ): ethereum.CallResult { let result = super.tryCall( "deployMaci", - "deployMaci(address,address,address,uint256,address,(uint256,uint256),address):(address,(address,address,address,address))", + "deployMaci(address,address,address,uint256,address,(uint256,uint256),address):(address,(address,address,address))", [ ethereum.Value.fromAddress(signUpGatekeeper), ethereum.Value.fromAddress(initialVoiceCreditProxy), @@ -328,7 +312,7 @@ export class MACIFactory extends ethereum.SmartContract { factories(): MACIFactory__factoriesResult { let result = super.call( "factories", - "factories():(address,address,address,address)", + "factories():(address,address,address)", [], ); @@ -336,14 +320,13 @@ export class MACIFactory extends ethereum.SmartContract { result[0].toAddress(), result[1].toAddress(), result[2].toAddress(), - result[3].toAddress(), ); } try_factories(): ethereum.CallResult { let result = super.tryCall( "factories", - "factories():(address,address,address,address)", + "factories():(address,address,address)", [], ); if (result.reverted) { @@ -355,7 +338,6 @@ export class MACIFactory extends ethereum.SmartContract { value[0].toAddress(), value[1].toAddress(), value[2].toAddress(), - value[3].toAddress(), ), ); } @@ -534,12 +516,8 @@ export class ConstructorCall_factoriesStruct extends ethereum.Tuple { return this[1].toAddress(); } - get subsidyFactory(): Address { - return this[2].toAddress(); - } - get messageProcessorFactory(): Address { - return this[3].toAddress(); + return this[2].toAddress(); } } @@ -631,10 +609,6 @@ export class DeployMaciCall_pollContractsStruct extends ethereum.Tuple { get tally(): Address { return this[2].toAddress(); } - - get subsidy(): Address { - return this[3].toAddress(); - } } export class RenounceOwnershipCall extends ethereum.Call { diff --git a/subgraph/generated/schema.ts b/subgraph/generated/schema.ts index 97e62f0d3..b3f92c01b 100644 --- a/subgraph/generated/schema.ts +++ b/subgraph/generated/schema.ts @@ -1020,6 +1020,40 @@ export class FundingRound extends Entity { this.set("voteOptionTreeDepth", Value.fromI32(value)); } + get maxMessages(): BigInt | null { + let value = this.get("maxMessages"); + if (!value || value.kind == ValueKind.NULL) { + return null; + } else { + return value.toBigInt(); + } + } + + set maxMessages(value: BigInt | null) { + if (!value) { + this.unset("maxMessages"); + } else { + this.set("maxMessages", Value.fromBigInt(value)); + } + } + + get maxVoteOptions(): BigInt | null { + let value = this.get("maxVoteOptions"); + if (!value || value.kind == ValueKind.NULL) { + return null; + } else { + return value.toBigInt(); + } + } + + set maxVoteOptions(value: BigInt | null) { + if (!value) { + this.unset("maxVoteOptions"); + } else { + this.set("maxVoteOptions", Value.fromBigInt(value)); + } + } + get coordinatorPubKeyX(): BigInt | null { let value = this.get("coordinatorPubKeyX"); if (!value || value.kind == ValueKind.NULL) { diff --git a/subgraph/schema.graphql b/subgraph/schema.graphql index 147b3225f..3d9b3610a 100644 --- a/subgraph/schema.graphql +++ b/subgraph/schema.graphql @@ -73,6 +73,9 @@ type FundingRound @entity { messageTreeDepth: Int voteOptionTreeDepth: Int + maxMessages: BigInt + maxVoteOptions: BigInt + coordinatorPubKeyX: BigInt coordinatorPubKeyY: BigInt coordinator: Bytes diff --git a/subgraph/schema.template.graphql b/subgraph/schema.template.graphql index af4e1689d..44b3d2127 100644 --- a/subgraph/schema.template.graphql +++ b/subgraph/schema.template.graphql @@ -85,6 +85,9 @@ type FundingRound @entity { messageTreeDepth: Int voteOptionTreeDepth: Int + maxMessages: BigInt + maxVoteOptions: BigInt + coordinatorPubKeyX: BigInt coordinatorPubKeyY: BigInt coordinator: Bytes diff --git a/subgraph/src/ClrFundMapping.ts b/subgraph/src/ClrFundMapping.ts index f26e32586..85cbe3170 100644 --- a/subgraph/src/ClrFundMapping.ts +++ b/subgraph/src/ClrFundMapping.ts @@ -289,6 +289,12 @@ export function handleRoundStarted(event: RoundStarted): void { fundingRound.voteOptionTreeDepth = treeDepths.value.value3 } + let maxValues = pollContract.try_maxValues() + if (!maxValues.reverted) { + fundingRound.maxMessages = maxValues.value.value0 + fundingRound.maxVoteOptions = maxValues.value.value1 + } + let coordinatorPubKey = pollContract.try_coordinatorPubKey() if (!coordinatorPubKey.reverted) { fundingRound.coordinatorPubKeyX = coordinatorPubKey.value.value0 diff --git a/vue-app/src/api/round.ts b/vue-app/src/api/round.ts index bc724117c..219dbecad 100644 --- a/vue-app/src/api/round.ts +++ b/vue-app/src/api/round.ts @@ -1,6 +1,6 @@ -import { Contract, toNumber, getAddress, hexlify, randomBytes } from 'ethers' +import { Contract, getAddress, hexlify, randomBytes, getNumber } from 'ethers' import { DateTime } from 'luxon' -import { PubKey, type Tally } from '@clrfund/common' +import { PubKey, type Tally, getMaxContributors } from '@clrfund/common' import { FundingRound, Poll } from './abi' import { provider, clrFundContract, isActiveApp } from './core' @@ -174,8 +174,9 @@ export async function getRoundInfo( isFinalized, isCancelled, stateTreeDepth, - messageTreeDepth, voteOptionTreeDepth, + maxMessages: maxMessagesBigInt, + maxVoteOptions: maxVoteOptionsBigInt, startTime: startTimeInSeconds, signUpDeadline: signUpDeadlineInSeconds, votingDeadline: votingDeadlineInSeconds, @@ -193,8 +194,8 @@ export async function getRoundInfo( const nativeTokenSymbol = data.fundingRound.nativeTokenInfo?.symbol || '' const nativeTokenDecimals = Number(data.fundingRound.nativeTokenInfo?.decimals || '') - const maxContributors = stateTreeDepth ? 2 ** stateTreeDepth - 1 : 0 - const maxMessages = messageTreeDepth ? 2 ** messageTreeDepth - 1 : 0 + const maxContributors = getMaxContributors(stateTreeDepth || 0) + const maxMessages = getNumber(maxMessagesBigInt) || 0 const now = DateTime.local() const startTime = DateTime.fromSeconds(Number(startTimeInSeconds || 0)) const signUpDeadline = DateTime.fromSeconds(Number(signUpDeadlineInSeconds || 0)) @@ -217,9 +218,10 @@ export async function getRoundInfo( contributions = contributionsInfo.amount matchingPool = await clrFundContract.getMatchingFunds(nativeTokenAddress) } else { - if (now < signUpDeadline && contributors < maxContributors) { + if (now < votingDeadline && contributors < maxContributors) { status = RoundStatus.Contributing } else if (now < votingDeadline) { + // Too many contributors, do not allow new contributors, allow reallocation only status = RoundStatus.Reallocating } else { status = RoundStatus.Tallying @@ -231,6 +233,10 @@ export async function getRoundInfo( const totalFunds = matchingPool + contributions + // recipient 0 is reserved, so maxRecipients is 1 fewer than the maxVoteOptions + const maxVoteOptions = getNumber(maxVoteOptionsBigInt) + const maxRecipients = maxVoteOptions > 0 ? maxVoteOptions - 1 : 0 + return { fundingRoundAddress, recipientRegistryAddress: getAddress(recipientRegistryAddress), @@ -239,7 +245,7 @@ export async function getRoundInfo( pollId: BigInt(pollId || 0), recipientTreeDepth: voteOptionTreeDepth || 1, maxContributors, - maxRecipients: voteOptionTreeDepth ? 5 ** voteOptionTreeDepth - 1 : 0, + maxRecipients, maxMessages, coordinatorPubKey, nativeTokenAddress: getAddress(nativeTokenAddress), @@ -254,6 +260,6 @@ export async function getRoundInfo( matchingPool, contributions, contributors, - messages: toNumber(messages), + messages: getNumber(messages), } } diff --git a/vue-app/src/graphql/API.ts b/vue-app/src/graphql/API.ts index fc61e9d4f..72b5be6c3 100644 --- a/vue-app/src/graphql/API.ts +++ b/vue-app/src/graphql/API.ts @@ -17,6 +17,7 @@ export type Scalars = { BigInt: any; Bytes: any; Int8: any; + Timestamp: any; }; export enum Aggregation_Interval { @@ -334,6 +335,8 @@ export enum ClrFund_OrderBy { CurrentRoundMaci = 'currentRound__maci', CurrentRoundMaciTxHash = 'currentRound__maciTxHash', CurrentRoundMatchingPoolSize = 'currentRound__matchingPoolSize', + CurrentRoundMaxMessages = 'currentRound__maxMessages', + CurrentRoundMaxVoteOptions = 'currentRound__maxVoteOptions', CurrentRoundMessageTreeDepth = 'currentRound__messageTreeDepth', CurrentRoundNativeToken = 'currentRound__nativeToken', CurrentRoundPollAddress = 'currentRound__pollAddress', @@ -503,6 +506,8 @@ export enum Contribution_OrderBy { FundingRoundMaci = 'fundingRound__maci', FundingRoundMaciTxHash = 'fundingRound__maciTxHash', FundingRoundMatchingPoolSize = 'fundingRound__matchingPoolSize', + FundingRoundMaxMessages = 'fundingRound__maxMessages', + FundingRoundMaxVoteOptions = 'fundingRound__maxVoteOptions', FundingRoundMessageTreeDepth = 'fundingRound__messageTreeDepth', FundingRoundNativeToken = 'fundingRound__nativeToken', FundingRoundPollAddress = 'fundingRound__pollAddress', @@ -1031,6 +1036,8 @@ export enum Donation_OrderBy { FundingRoundMaci = 'fundingRound__maci', FundingRoundMaciTxHash = 'fundingRound__maciTxHash', FundingRoundMatchingPoolSize = 'fundingRound__matchingPoolSize', + FundingRoundMaxMessages = 'fundingRound__maxMessages', + FundingRoundMaxVoteOptions = 'fundingRound__maxVoteOptions', FundingRoundMessageTreeDepth = 'fundingRound__messageTreeDepth', FundingRoundNativeToken = 'fundingRound__nativeToken', FundingRoundPollAddress = 'fundingRound__pollAddress', @@ -1070,6 +1077,8 @@ export type FundingRound = { maci: Maybe; maciTxHash: Maybe; matchingPoolSize: Maybe; + maxMessages: Maybe; + maxVoteOptions: Maybe; messageTreeDepth: Maybe; messages: Maybe>; nativeToken: Maybe; @@ -1303,6 +1312,22 @@ export type FundingRound_Filter = { matchingPoolSize_lte: InputMaybe; matchingPoolSize_not: InputMaybe; matchingPoolSize_not_in: InputMaybe>; + maxMessages: InputMaybe; + maxMessages_gt: InputMaybe; + maxMessages_gte: InputMaybe; + maxMessages_in: InputMaybe>; + maxMessages_lt: InputMaybe; + maxMessages_lte: InputMaybe; + maxMessages_not: InputMaybe; + maxMessages_not_in: InputMaybe>; + maxVoteOptions: InputMaybe; + maxVoteOptions_gt: InputMaybe; + maxVoteOptions_gte: InputMaybe; + maxVoteOptions_in: InputMaybe>; + maxVoteOptions_lt: InputMaybe; + maxVoteOptions_lte: InputMaybe; + maxVoteOptions_not: InputMaybe; + maxVoteOptions_not_in: InputMaybe>; messageTreeDepth: InputMaybe; messageTreeDepth_gt: InputMaybe; messageTreeDepth_gte: InputMaybe; @@ -1524,6 +1549,8 @@ export enum FundingRound_OrderBy { Maci = 'maci', MaciTxHash = 'maciTxHash', MatchingPoolSize = 'matchingPoolSize', + MaxMessages = 'maxMessages', + MaxVoteOptions = 'maxVoteOptions', MessageTreeDepth = 'messageTreeDepth', Messages = 'messages', NativeToken = 'nativeToken', @@ -1728,6 +1755,8 @@ export enum Message_OrderBy { FundingRoundMaci = 'fundingRound__maci', FundingRoundMaciTxHash = 'fundingRound__maciTxHash', FundingRoundMatchingPoolSize = 'fundingRound__matchingPoolSize', + FundingRoundMaxMessages = 'fundingRound__maxMessages', + FundingRoundMaxVoteOptions = 'fundingRound__maxVoteOptions', FundingRoundMessageTreeDepth = 'fundingRound__messageTreeDepth', FundingRoundNativeToken = 'fundingRound__nativeToken', FundingRoundPollAddress = 'fundingRound__pollAddress', @@ -1832,6 +1861,8 @@ export enum Poll_OrderBy { FundingRoundMaci = 'fundingRound__maci', FundingRoundMaciTxHash = 'fundingRound__maciTxHash', FundingRoundMatchingPoolSize = 'fundingRound__matchingPoolSize', + FundingRoundMaxMessages = 'fundingRound__maxMessages', + FundingRoundMaxVoteOptions = 'fundingRound__maxVoteOptions', FundingRoundMessageTreeDepth = 'fundingRound__messageTreeDepth', FundingRoundNativeToken = 'fundingRound__nativeToken', FundingRoundPollAddress = 'fundingRound__pollAddress', @@ -1955,6 +1986,8 @@ export enum PublicKey_OrderBy { FundingRoundMaci = 'fundingRound__maci', FundingRoundMaciTxHash = 'fundingRound__maciTxHash', FundingRoundMatchingPoolSize = 'fundingRound__matchingPoolSize', + FundingRoundMaxMessages = 'fundingRound__maxMessages', + FundingRoundMaxVoteOptions = 'fundingRound__maxVoteOptions', FundingRoundMessageTreeDepth = 'fundingRound__messageTreeDepth', FundingRoundNativeToken = 'fundingRound__nativeToken', FundingRoundPollAddress = 'fundingRound__pollAddress', @@ -3223,7 +3256,7 @@ export type GetRoundInfoQueryVariables = Exact<{ }>; -export type GetRoundInfoQuery = { __typename?: 'Query', fundingRound: { __typename?: 'FundingRound', id: string, maci: any | null, pollId: any | null, pollAddress: any | null, recipientRegistryAddress: any | null, contributorRegistryAddress: any | null, voiceCreditFactor: any | null, isFinalized: boolean | null, isCancelled: boolean | null, contributorCount: any, totalSpent: any | null, matchingPoolSize: any | null, startTime: any | null, signUpDeadline: any | null, votingDeadline: any | null, coordinatorPubKeyX: any | null, coordinatorPubKeyY: any | null, stateTreeDepth: number | null, messageTreeDepth: number | null, voteOptionTreeDepth: number | null, nativeTokenInfo: { __typename?: 'Token', tokenAddress: any | null, symbol: string | null, decimals: any | null } | null } | null }; +export type GetRoundInfoQuery = { __typename?: 'Query', fundingRound: { __typename?: 'FundingRound', id: string, maci: any | null, pollId: any | null, pollAddress: any | null, recipientRegistryAddress: any | null, contributorRegistryAddress: any | null, voiceCreditFactor: any | null, isFinalized: boolean | null, isCancelled: boolean | null, contributorCount: any, totalSpent: any | null, matchingPoolSize: any | null, startTime: any | null, signUpDeadline: any | null, votingDeadline: any | null, coordinatorPubKeyX: any | null, coordinatorPubKeyY: any | null, maxMessages: any | null, maxVoteOptions: any | null, stateTreeDepth: number | null, messageTreeDepth: number | null, voteOptionTreeDepth: number | null, nativeTokenInfo: { __typename?: 'Token', tokenAddress: any | null, symbol: string | null, decimals: any | null } | null } | null }; export type GetRoundsQueryVariables = Exact<{ clrFundAddress: Scalars['String']; @@ -3436,6 +3469,8 @@ export const GetRoundInfoDocument = gql` votingDeadline coordinatorPubKeyX coordinatorPubKeyY + maxMessages + maxVoteOptions stateTreeDepth messageTreeDepth voteOptionTreeDepth diff --git a/vue-app/src/graphql/queries/GetRoundInfo.graphql b/vue-app/src/graphql/queries/GetRoundInfo.graphql index d5995c8ff..73f2cb9fb 100644 --- a/vue-app/src/graphql/queries/GetRoundInfo.graphql +++ b/vue-app/src/graphql/queries/GetRoundInfo.graphql @@ -22,6 +22,8 @@ query GetRoundInfo($fundingRoundAddress: ID!) { votingDeadline coordinatorPubKeyX coordinatorPubKeyY + maxMessages + maxVoteOptions stateTreeDepth messageTreeDepth voteOptionTreeDepth From 465a116bf3dbca77b39c76a7a9532e7290aff822 Mon Sep 17 00:00:00 2001 From: yuetloo Date: Tue, 21 May 2024 19:52:32 -0400 Subject: [PATCH 35/57] votingDuration is obsolete post MACI v1 --- contracts/tasks/runners/exportRound.ts | 1 - 1 file changed, 1 deletion(-) diff --git a/contracts/tasks/runners/exportRound.ts b/contracts/tasks/runners/exportRound.ts index 27be1e51b..42c3638f2 100644 --- a/contracts/tasks/runners/exportRound.ts +++ b/contracts/tasks/runners/exportRound.ts @@ -227,7 +227,6 @@ async function getRoundInfo( await pollContract.getDeployTimeAndDuration() startTime = getNumber(roundStartTime) signUpDuration = roundDuration - votingDuration = roundDuration endTime = startTime + getNumber(roundDuration) pollId = await roundContract.pollId() From f9d90abc55db015d719293cffddaa6f35387018e Mon Sep 17 00:00:00 2001 From: yuetloo Date: Tue, 21 May 2024 20:01:13 -0400 Subject: [PATCH 36/57] remove hardcoding of TREE_ARITY as its value can change between MACI versions --- contracts/contracts/ClrFund.sol | 32 ++- contracts/contracts/FundingRound.sol | 33 ++- contracts/contracts/MACICommon.sol | 3 - contracts/contracts/MACIFactory.sol | 25 +- .../contracts/interfaces/IMACIFactory.sol | 5 +- .../recipientRegistry/IRecipientRegistry.sol | 1 + contracts/tasks/index.ts | 1 + contracts/tasks/runners/simulateContribute.ts | 214 ++++++++++++++++++ contracts/tests/deployer.ts | 50 +++- contracts/tests/round.ts | 6 +- contracts/utils/circuits.ts | 10 +- contracts/utils/constants.ts | 1 - contracts/utils/maciParameters.ts | 17 +- subgraph/abis/ClrFund.json | 55 +++-- subgraph/abis/ClrFundDeployer.json | 22 ++ subgraph/abis/FundingRound.json | 83 +++++-- subgraph/abis/MACIFactory.json | 64 ++++-- subgraph/generated/ClrFund/ClrFund.ts | 23 -- subgraph/generated/ClrFund/FundingRound.ts | 19 -- subgraph/generated/ClrFund/MACIFactory.ts | 62 ++--- .../templates/FundingRound/FundingRound.ts | 19 -- .../generated/templates/MACI/FundingRound.ts | 19 -- .../generated/templates/Poll/FundingRound.ts | 19 -- subgraph/src/ClrFundMapping.ts | 2 +- subgraph/src/RecipientRegistry.ts | 19 +- 25 files changed, 531 insertions(+), 273 deletions(-) create mode 100644 contracts/tasks/runners/simulateContribute.ts diff --git a/contracts/contracts/ClrFund.sol b/contracts/contracts/ClrFund.sol index 4f5ad30bc..3927ab2c1 100644 --- a/contracts/contracts/ClrFund.sol +++ b/contracts/contracts/ClrFund.sol @@ -60,8 +60,8 @@ contract ClrFund is OwnableUpgradeable, DomainObjs, Params { error InvalidFundingRoundFactory(); error InvalidMaciFactory(); error RecipientRegistryNotSet(); + error MaxRecipientsNotSet(); error NotInitialized(); - error VoteOptionTreeDepthNotSet(); /** @@ -128,20 +128,6 @@ contract ClrFund is OwnableUpgradeable, DomainObjs, Params { _setFundingRoundFactory(_roundFactory); } - /** - * @dev Get the maximum recipients allowed in the recipient registry - */ - function getMaxRecipients() public view returns (uint256 _maxRecipients) { - TreeDepths memory treeDepths = maciFactory.treeDepths(); - if (treeDepths.voteOptionTreeDepth == 0) revert VoteOptionTreeDepthNotSet(); - - uint256 maxVoteOption = maciFactory.TREE_ARITY() ** treeDepths.voteOptionTreeDepth; - - // -1 because the first slot of the recipients array is not used - // and maxRecipients is used to generate 0 based index to the array - _maxRecipients = maxVoteOption - 1; - } - /** * @dev Set registry of verified users. * @param _userRegistry Address of a user registry. @@ -155,6 +141,15 @@ contract ClrFund is OwnableUpgradeable, DomainObjs, Params { emit UserRegistryChanged(address(_userRegistry)); } + /** + * @dev Set the max recipients in the recipient registry + */ + function _setMaxRecipients() private { + if (address(maciFactory) == address(0)) revert NotInitialized(); + if (maciFactory.maxRecipients() == 0) revert MaxRecipientsNotSet(); + recipientRegistry.setMaxRecipients(maciFactory.maxRecipients()); + } + /** * @dev Set recipient registry. * @param _recipientRegistry Address of a recipient registry. @@ -163,9 +158,9 @@ contract ClrFund is OwnableUpgradeable, DomainObjs, Params { external onlyOwner { + recipientRegistry = _recipientRegistry; - uint256 maxRecipients = getMaxRecipients(); - recipientRegistry.setMaxRecipients(maxRecipients); + _setMaxRecipients(); emit RecipientRegistryChanged(address(_recipientRegistry)); } @@ -229,8 +224,7 @@ contract ClrFund is OwnableUpgradeable, DomainObjs, Params { if (address(recipientRegistry) == address(0)) revert RecipientRegistryNotSet(); // Make sure that the max number of recipients is set correctly - uint256 maxRecipients = getMaxRecipients(); - recipientRegistry.setMaxRecipients(maxRecipients); + _setMaxRecipients(); // Deploy funding round and MACI contracts address newRound = roundFactory.deploy(duration, address(this)); diff --git a/contracts/contracts/FundingRound.sol b/contracts/contracts/FundingRound.sol index 9f8fe143b..701872a8f 100644 --- a/contracts/contracts/FundingRound.sol +++ b/contracts/contracts/FundingRound.sol @@ -66,6 +66,7 @@ contract FundingRound is error TallyHashNotPublished(); error IncompleteTallyResults(uint256 total, uint256 actual); error NoVotes(); + error NoSignUps(); error MaciNotSet(); error PollNotSet(); error InvalidMaci(); @@ -175,19 +176,6 @@ contract FundingRound is return (addressValue == address(0)); } - /** - * @dev Have the votes been tallied - */ - function isTallied() private view returns (bool) { - (uint256 numSignUps, ) = poll.numSignUpsAndMessages(); - (uint8 intStateTreeDepth, , , ) = poll.treeDepths(); - uint256 tallyBatchSize = TREE_ARITY ** uint256(intStateTreeDepth); - uint256 tallyBatchNum = tally.tallyBatchNum(); - uint256 totalTallied = tallyBatchNum * tallyBatchSize; - - return numSignUps > 0 && totalTallied >= numSignUps; - } - /** * @dev Set the tally contract * @param _tally The tally contract address @@ -470,18 +458,18 @@ contract FundingRound is _votingPeriodOver(poll); - if (!isTallied()) { + if (!tally.isTallied()) { revert VotesNotTallied(); } + if (bytes(tallyHash).length == 0) { revert TallyHashNotPublished(); } // make sure we have received all the tally results - (,,, uint8 voteOptionTreeDepth) = poll.treeDepths(); - uint256 totalResults = uint256(TREE_ARITY) ** uint256(voteOptionTreeDepth); - if ( totalTallyResults != totalResults ) { - revert IncompleteTallyResults(totalResults, totalTallyResults); + (, uint256 maxVoteOptions) = poll.maxValues(); + if (totalTallyResults != maxVoteOptions) { + revert IncompleteTallyResults(maxVoteOptions, totalTallyResults); } // If nobody voted, the round should be cancelled to avoid locking of matching funds @@ -494,7 +482,6 @@ contract FundingRound is revert IncorrectSpentVoiceCredits(); } - totalSpent = _totalSpent; // Total amount of spent voice credits is the size of the pool of direct rewards. // Everything else, including unspent voice credits and downscaling error, @@ -675,9 +662,15 @@ contract FundingRound is { if (isAddressZero(address(maci))) revert MaciNotSet(); - if (!isTallied()) { + if (maci.numSignUps() == 0) { + // no sign ups, so no tally results + revert NoSignUps(); + } + + if (!tally.isTallied()) { revert VotesNotTallied(); } + if (isFinalized) { revert RoundAlreadyFinalized(); } diff --git a/contracts/contracts/MACICommon.sol b/contracts/contracts/MACICommon.sol index f41843794..01224230b 100644 --- a/contracts/contracts/MACICommon.sol +++ b/contracts/contracts/MACICommon.sol @@ -6,9 +6,6 @@ pragma solidity 0.8.20; * @dev a contract that holds common MACI structures */ contract MACICommon { - // MACI tree arity - uint256 public constant TREE_ARITY = 5; - /** * @dev These are contract factories used to deploy MACI poll processing contracts * when creating a new ClrFund funding round. diff --git a/contracts/contracts/MACIFactory.sol b/contracts/contracts/MACIFactory.sol index 16a6f6e48..f3952280d 100644 --- a/contracts/contracts/MACIFactory.sol +++ b/contracts/contracts/MACIFactory.sol @@ -29,6 +29,8 @@ contract MACIFactory is Ownable(msg.sender), Params, SnarkCommon, DomainObjs, MA // circuit parameters uint8 public stateTreeDepth; TreeDepths public treeDepths; + uint256 public messageBatchSize; + uint256 public maxRecipients; // Events event MaciParametersChanged(); @@ -38,11 +40,15 @@ contract MACIFactory is Ownable(msg.sender), Params, SnarkCommon, DomainObjs, MA error NotInitialized(); error ProcessVkNotSet(); error TallyVkNotSet(); + error VoteOptionTreeDepthNotSet(); error InvalidVkRegistry(); error InvalidPollFactory(); error InvalidTallyFactory(); error InvalidMessageProcessorFactory(); error InvalidVerifier(); + error InvalidMaxRecipients(); + error InvalidMessageBatchSize(); + error InvalidVoteOptionTreeDepth(); constructor( address _vkRegistry, @@ -60,14 +66,6 @@ contract MACIFactory is Ownable(msg.sender), Params, SnarkCommon, DomainObjs, MA verifier = Verifier(_verifier); } - /** - * @dev calculate the message batch size - */ - function getMessageBatchSize(uint8 messageTreeSubDepth) public pure - returns(uint256 _messageBatchSize) { - _messageBatchSize = TREE_ARITY ** messageTreeSubDepth; - } - /** * @dev set vk registry */ @@ -122,13 +120,19 @@ contract MACIFactory is Ownable(msg.sender), Params, SnarkCommon, DomainObjs, MA */ function setMaciParameters( uint8 _stateTreeDepth, + uint256 _messageBatchSize, + uint256 _maxRecipients, TreeDepths calldata _treeDepths ) public onlyOwner { + if (_treeDepths.voteOptionTreeDepth == 0) revert InvalidVoteOptionTreeDepth(); + if (_maxRecipients == 0) revert InvalidMaxRecipients(); + if (_messageBatchSize == 0) revert InvalidMessageBatchSize(); - uint256 messageBatchSize = getMessageBatchSize(_treeDepths.messageTreeSubDepth); + messageBatchSize = _messageBatchSize; + maxRecipients = _maxRecipients; if (!vkRegistry.hasProcessVk( _stateTreeDepth, @@ -155,6 +159,7 @@ contract MACIFactory is Ownable(msg.sender), Params, SnarkCommon, DomainObjs, MA emit MaciParametersChanged(); } + /** * @dev Deploy new MACI instance. */ @@ -170,8 +175,6 @@ contract MACIFactory is Ownable(msg.sender), Params, SnarkCommon, DomainObjs, MA external returns (MACI _maci, MACI.PollContracts memory _pollContracts) { - uint256 messageBatchSize = getMessageBatchSize(treeDepths.messageTreeSubDepth); - if (!vkRegistry.hasProcessVk( stateTreeDepth, treeDepths.messageTreeDepth, diff --git a/contracts/contracts/interfaces/IMACIFactory.sol b/contracts/contracts/interfaces/IMACIFactory.sol index eacfd7df2..7e207afe8 100644 --- a/contracts/contracts/interfaces/IMACIFactory.sol +++ b/contracts/contracts/interfaces/IMACIFactory.sol @@ -28,10 +28,7 @@ interface IMACIFactory { function stateTreeDepth() external view returns (uint8); function treeDepths() external view returns (Params.TreeDepths memory); - function getMessageBatchSize(uint8 _messageTreeSubDepth) external pure - returns(uint256 _messageBatchSize); - - function TREE_ARITY() external pure returns (uint256); + function maxRecipients() external view returns (uint256); function deployMaci( SignUpGatekeeper signUpGatekeeper, diff --git a/contracts/contracts/recipientRegistry/IRecipientRegistry.sol b/contracts/contracts/recipientRegistry/IRecipientRegistry.sol index 82fc0c4a9..edfbc5029 100644 --- a/contracts/contracts/recipientRegistry/IRecipientRegistry.sol +++ b/contracts/contracts/recipientRegistry/IRecipientRegistry.sol @@ -17,6 +17,7 @@ pragma solidity 0.8.20; */ interface IRecipientRegistry { + function maxRecipients() external returns (uint256); function setMaxRecipients(uint256 _maxRecipients) external returns (bool); function getRecipientAddress(uint256 _index, uint256 _startBlock, uint256 _endBlock) external view returns (address); diff --git a/contracts/tasks/index.ts b/contracts/tasks/index.ts index b25d56890..19050a901 100644 --- a/contracts/tasks/index.ts +++ b/contracts/tasks/index.ts @@ -29,3 +29,4 @@ import './runners/proveOnChain' import './runners/publishTallyResults' import './runners/resetTally' import './runners/maciPubkey' +import './runners/simulateContribute' diff --git a/contracts/tasks/runners/simulateContribute.ts b/contracts/tasks/runners/simulateContribute.ts new file mode 100644 index 000000000..dcfc2cb1b --- /dev/null +++ b/contracts/tasks/runners/simulateContribute.ts @@ -0,0 +1,214 @@ +/** + * Simulate contributions to a funding round. This script is mainly used for testing. + * + * Sample usage: + * yarn hardhat simulate-contribute --count \ + * --fund --network + * + * Make sure deployed-contracts.json exists with the funding round address + * Make sure to use a token with mint() function like 0x65bc8dd04808d99cf8aa6749f128d55c2051edde + */ + +import { Keypair, createMessage, Message, PubKey } from '@clrfund/common' + +import { UNIT } from '../../utils/constants' +import { getContractAt, getEventArg } from '../../utils/contracts' +import type { FundingRound, ERC20, Poll } from '../../typechain-types' +import { task, types } from 'hardhat/config' +import { EContracts } from '../../utils/types' +import { ContractStorage } from '../helpers/ContractStorage' +import { parseEther, Wallet } from 'ethers' + +const tokenAbi = [ + 'function mint(address,uint256)', + 'function transfer(address,uint256)', + 'function approve(address,uint256)', +] +/** + * Cast a vote by the contributor + * + * @param stateIndex The contributor stateIndex + * @param pollId The pollId + * @param contributorKeyPair The contributor MACI key pair + * @param coordinatorPubKey The coordinator MACI public key + * @param voiceCredits The total voice credits the contributor can use + * @param pollContract The poll contract with the vote function + */ +async function vote( + stateIndex: number, + pollId: bigint, + contributorKeyPair: Keypair, + coordinatorPubKey: PubKey, + voiceCredits: bigint, + pollContract: Poll +) { + const messages: Message[] = [] + const encPubKeys: PubKey[] = [] + let nonce = 1 + // Change key + const newContributorKeypair = new Keypair() + const [message, encPubKey] = createMessage( + stateIndex, + contributorKeyPair, + newContributorKeypair, + coordinatorPubKey, + null, + null, + nonce, + pollId + ) + messages.push(message) + encPubKeys.push(encPubKey) + nonce += 1 + // Vote + for (const recipientIndex of [1, 2]) { + const votes = BigInt(voiceCredits) / BigInt(2) + const [message, encPubKey] = createMessage( + stateIndex, + newContributorKeypair, + null, + coordinatorPubKey, + recipientIndex, + votes, + nonce, + pollId + ) + messages.push(message) + encPubKeys.push(encPubKey) + nonce += 1 + } + + const tx = await pollContract.publishMessageBatch( + messages.reverse().map((msg) => msg.asContractParam()), + encPubKeys.reverse().map((key) => key.asContractParam()) + ) + const receipt = await tx.wait() + if (receipt?.status !== 1) { + throw new Error(`Contributor ${stateIndex} failed to vote`) + } +} + +task('simulate-contribute', 'Contribute to a funding round') + .addParam('count', 'Number of contributors to simulate', 70, types.int) + .addParam('fund', 'Number of contributors to simulate', '0.01') + .setAction(async ({ count, fund }, { ethers, network }) => { + // gas for transactions + const value = parseEther(fund) + const contributionAmount = UNIT + + const [deployer] = await ethers.getSigners() + const storage = ContractStorage.getInstance() + const fundingRoundContractAddress = storage.mustGetAddress( + EContracts.FundingRound, + network.name + ) + const fundingRound = await ethers.getContractAt( + EContracts.FundingRound, + fundingRoundContractAddress + ) + + const pollId = await fundingRound.pollId() + const pollAddress = await fundingRound.poll() + const pollContract = await getContractAt( + EContracts.Poll, + pollAddress, + ethers + ) + + const rawCoordinatorPubKey = await pollContract.coordinatorPubKey() + const coordinatorPubKey = new PubKey([ + BigInt(rawCoordinatorPubKey.x), + BigInt(rawCoordinatorPubKey.y), + ]) + + const tokenAddress = await fundingRound.nativeToken() + const token = await ethers.getContractAt(tokenAbi, tokenAddress) + + const maciAddress = await fundingRound.maci() + const maci = await ethers.getContractAt(EContracts.MACI, maciAddress) + + const userRegistryAddress = await fundingRound.userRegistry() + const userRegistry = await ethers.getContractAt( + EContracts.SimpleUserRegistry, + userRegistryAddress + ) + + for (let i = 0; i < count; i++) { + const contributor = Wallet.createRandom(ethers.provider) + + let tx = await userRegistry.addUser(contributor.address) + let receipt = await tx.wait() + if (receipt.status !== 1) { + throw new Error(`Failed to add user to the user registry`) + } + + // transfer token to contributor first + tx = await token.mint(contributor.address, contributionAmount) + receipt = await tx.wait() + if (receipt.status !== 1) { + throw new Error(`Failed to mint token for ${contributor.address}`) + } + + tx = await deployer.sendTransaction({ value, to: contributor.address }) + receipt = await tx.wait() + if (receipt.status !== 1) { + throw new Error(`Failed to fund ${contributor.address}`) + } + + const contributorKeypair = new Keypair() + const tokenAsContributor = token.connect(contributor) as ERC20 + tx = await tokenAsContributor.approve( + fundingRound.target, + contributionAmount + ) + receipt = await tx.wait() + if (receipt.status !== 1) { + throw new Error('Failed to approve token') + } + + const fundingRoundAsContributor = fundingRound.connect( + contributor + ) as FundingRound + const contributionTx = await fundingRoundAsContributor.contribute( + contributorKeypair.pubKey.asContractParam(), + contributionAmount + ) + receipt = await contributionTx.wait() + if (receipt.status !== 1) { + throw new Error('Failed to contribute') + } + + const stateIndex = await getEventArg( + contributionTx, + maci, + 'SignUp', + '_stateIndex' + ) + const voiceCredits = await getEventArg( + contributionTx, + maci, + 'SignUp', + '_voiceCreditBalance' + ) + + console.log( + `Contributor ${ + contributor.address + } registered. State index: ${stateIndex}. Voice credits: ${voiceCredits.toString()}.` + ) + + const pollContractAsContributor = pollContract.connect( + contributor + ) as Poll + + await vote( + stateIndex, + pollId, + contributorKeypair, + coordinatorPubKey, + voiceCredits, + pollContractAsContributor + ) + console.log(`Contributor ${contributor.address} voted.`) + } + }) diff --git a/contracts/tests/deployer.ts b/contracts/tests/deployer.ts index bbe8c027a..3eace1611 100644 --- a/contracts/tests/deployer.ts +++ b/contracts/tests/deployer.ts @@ -1,11 +1,11 @@ -import { ethers, config, artifacts } from 'hardhat' +import { ethers, artifacts } from 'hardhat' import { time } from '@nomicfoundation/hardhat-network-helpers' import { expect } from 'chai' import { BaseContract, Contract } from 'ethers' import { genRandomSalt } from 'maci-crypto' -import { Keypair } from '@clrfund/common' +import { Keypair, MACI_TREE_ARITY } from '@clrfund/common' -import { TREE_ARITY, ZERO_ADDRESS, UNIT } from '../utils/constants' +import { ZERO_ADDRESS, UNIT } from '../utils/constants' import { getGasUsage, getEventArg, @@ -18,6 +18,7 @@ import { HardhatEthersSigner } from '@nomicfoundation/hardhat-ethers/signers' import { ClrFund, ClrFundDeployer, + FundingRound, FundingRoundFactory, MACIFactory, Poll, @@ -199,7 +200,8 @@ describe('Clr fund deployer', async () => { expect(await recipientRegistry.controller()).to.equal(clrfund.target) const params = MaciParameters.mock() expect(await recipientRegistry.maxRecipients()).to.equal( - BigInt(TREE_ARITY) ** BigInt(params.treeDepths.voteOptionTreeDepth) - + BigInt(MACI_TREE_ARITY) ** + BigInt(params.treeDepths.voteOptionTreeDepth) - BigInt(1) ) }) @@ -453,6 +455,14 @@ describe('Clr fund deployer', async () => { contributionAmount ) await clrfund.deployNewRound(roundDuration) + const roundAddress = await clrfund.getCurrentRound() + const roundContract = (await getContractAt( + EContracts.FundingRound, + roundAddress, + ethers, + coordinator + )) as FundingRound + await roundContract.publishTallyHash('xxx') await time.increase(roundDuration) await expect( clrfund.transferMatchingFunds( @@ -461,11 +471,19 @@ describe('Clr fund deployer', async () => { resultsCommitment, perVOVoiceCreditCommitment ) - ).to.be.revertedWithCustomError(roundInterface, 'VotesNotTallied') + ).to.be.revertedWithCustomError(roundInterface, 'IncompleteTallyResults') }) it('allows owner to finalize round even without matching funds', async () => { await clrfund.deployNewRound(roundDuration) + const roundAddress = await clrfund.getCurrentRound() + const roundContract = (await getContractAt( + EContracts.FundingRound, + roundAddress, + ethers, + coordinator + )) as FundingRound + await roundContract.publishTallyHash('xxx') await time.increase(roundDuration) await expect( clrfund.transferMatchingFunds( @@ -474,7 +492,7 @@ describe('Clr fund deployer', async () => { resultsCommitment, perVOVoiceCreditCommitment ) - ).to.be.revertedWithCustomError(roundInterface, 'VotesNotTallied') + ).to.be.revertedWithCustomError(roundInterface, 'IncompleteTallyResults') }) it('pulls funds from funding source', async () => { @@ -485,7 +503,15 @@ describe('Clr fund deployer', async () => { ) await clrfund.addFundingSource(deployer.address) // Doesn't have tokens await clrfund.deployNewRound(roundDuration) + const roundAddress = await clrfund.getCurrentRound() + const roundContract = (await getContractAt( + EContracts.FundingRound, + roundAddress, + ethers, + coordinator + )) as FundingRound await time.increase(roundDuration) + await roundContract.publishTallyHash('xxx') await expect( clrfund.transferMatchingFunds( totalSpent, @@ -493,7 +519,7 @@ describe('Clr fund deployer', async () => { resultsCommitment, perVOVoiceCreditCommitment ) - ).to.be.revertedWithCustomError(roundInterface, 'VotesNotTallied') + ).to.be.revertedWithCustomError(roundInterface, 'IncompleteTallyResults') }) it('pulls funds from funding source if allowance is greater than balance', async () => { @@ -503,7 +529,15 @@ describe('Clr fund deployer', async () => { contributionAmount * 2n ) await clrfund.deployNewRound(roundDuration) + const roundAddress = await clrfund.getCurrentRound() + const roundContract = (await getContractAt( + EContracts.FundingRound, + roundAddress, + ethers, + coordinator + )) as FundingRound await time.increase(roundDuration) + await roundContract.publishTallyHash('xxx') await expect( clrfund.transferMatchingFunds( totalSpent, @@ -511,7 +545,7 @@ describe('Clr fund deployer', async () => { resultsCommitment, perVOVoiceCreditCommitment ) - ).to.be.revertedWithCustomError(roundInterface, 'VotesNotTallied') + ).to.be.revertedWithCustomError(roundInterface, 'IncompleteTallyResults') }) it('allows only owner to finalize round', async () => { diff --git a/contracts/tests/round.ts b/contracts/tests/round.ts index 52f0bf12a..fd6e8095b 100644 --- a/contracts/tests/round.ts +++ b/contracts/tests/round.ts @@ -153,6 +153,7 @@ describe('Funding Round', () => { await tally.mock.tallyBatchNum.returns(1) await tally.mock.verifyTallyResult.returns(true) await tally.mock.verifySpentVoiceCredits.returns(true) + await tally.mock.isTallied.returns(true) tokenAsContributor = token.connect(contributor) as Contract fundingRoundAsCoordinator = fundingRound.connect( @@ -695,6 +696,7 @@ describe('Funding Round', () => { userKeypair.pubKey.asContractParam(), totalContributions ) + await tally.mock.isTallied.returns(false) await time.increase(roundDuration) await mergeMaciSubtrees({ maciAddress, pollId, signer: deployer }) @@ -1494,7 +1496,7 @@ describe('Funding Round', () => { }) it('prevents adding tally results if maci has not completed tallying', async function () { - await tally.mock.tallyBatchNum.returns(0) + await tally.mock.isTallied.returns(false) await expect( addTallyResultsBatch( fundingRoundAsCoordinator, @@ -1506,7 +1508,7 @@ describe('Funding Round', () => { }) it('prevents adding batches of tally results if maci has not completed tallying', async function () { - await tally.mock.tallyBatchNum.returns(0) + await tally.mock.isTallied.returns(false) await expect( addTallyResultsBatch( fundingRoundAsCoordinator, diff --git a/contracts/utils/circuits.ts b/contracts/utils/circuits.ts index f7cba55e6..acc73fca7 100644 --- a/contracts/utils/circuits.ts +++ b/contracts/utils/circuits.ts @@ -4,9 +4,7 @@ // the EmptyBallotRoots.sol published in MACI npm package is hardcoded for stateTreeDepth = 6 import path from 'path' - -// This should match MACI.TREE_ARITY in the contract -const TREE_ARITY = 5 +import { MACI_TREE_ARITY } from '@clrfund/common' export const DEFAULT_CIRCUIT = 'micro' @@ -65,11 +63,11 @@ export const CIRCUITS: { [name: string]: CircuitInfo } = { // maxMessages and maxVoteOptions are calculated using treeArity = 5 as seen in the following code: // https://github.com/privacy-scaling-explorations/maci/blob/master/contracts/contracts/Poll.sol#L115 // treeArity ** messageTreeDepth - maxMessages: BigInt(TREE_ARITY ** 9), + maxMessages: BigInt(MACI_TREE_ARITY ** 9), // treeArity ** voteOptionTreeDepth - maxVoteOptions: BigInt(TREE_ARITY ** 3), + maxVoteOptions: BigInt(MACI_TREE_ARITY ** 3), }, - messageBatchSize: BigInt(TREE_ARITY ** 2), + messageBatchSize: BigInt(MACI_TREE_ARITY ** 2), }, } diff --git a/contracts/utils/constants.ts b/contracts/utils/constants.ts index dfdbcd011..70687b10a 100644 --- a/contracts/utils/constants.ts +++ b/contracts/utils/constants.ts @@ -5,7 +5,6 @@ export const VOICE_CREDIT_FACTOR = 10n ** BigInt(4 + 18 - 9) export const ALPHA_PRECISION = 10n ** 18n export const DEFAULT_SR_QUEUE_OPS = '4' export const DEFAULT_GET_LOG_BATCH_SIZE = 20000 -export const TREE_ARITY = 5 // brightid.clr.fund node uses this to sign messages // see the ethSigningAddress in https://brightid.clr.fund diff --git a/contracts/utils/maciParameters.ts b/contracts/utils/maciParameters.ts index e498a15e9..0e04d25ce 100644 --- a/contracts/utils/maciParameters.ts +++ b/contracts/utils/maciParameters.ts @@ -3,7 +3,7 @@ import { Contract, BigNumberish } from 'ethers' import { VerifyingKey } from 'maci-domainobjs' import { extractVk } from 'maci-circuits' import { CIRCUITS, getCircuitFiles } from './circuits' -import { TREE_ARITY } from './constants' +import { MACI_TREE_ARITY } from '@clrfund/common' import { Params } from '../typechain-types/contracts/MACIFactory' type TreeDepths = { @@ -36,15 +36,28 @@ export class MaciParameters { * @returns message batch size */ getMessageBatchSize(): number { - return TREE_ARITY ** this.treeDepths.messageTreeSubDepth + return MACI_TREE_ARITY ** this.treeDepths.messageTreeSubDepth + } + + /** + * Calculate the maximum recipients allowed by the MACI circuit + * @returns maximum recipient count + */ + getMaxRecipients(): number { + // -1 because recipients is 0 index based and the 0th slot is reserved + return MACI_TREE_ARITY ** this.treeDepths.voteOptionTreeDepth - 1 } asContractParam(): [ _stateTreeDepth: BigNumberish, + _messageBatchSize: BigNumberish, + _maxRecipients: BigNumberish, _treeDepths: Params.TreeDepthsStruct, ] { return [ this.stateTreeDepth, + this.getMessageBatchSize(), + this.getMaxRecipients(), { intStateTreeDepth: this.treeDepths.intStateTreeDepth, messageTreeSubDepth: this.treeDepths.messageTreeSubDepth, diff --git a/subgraph/abis/ClrFund.json b/subgraph/abis/ClrFund.json index 30e4badb0..1146484de 100644 --- a/subgraph/abis/ClrFund.json +++ b/subgraph/abis/ClrFund.json @@ -1,9 +1,36 @@ [ + { + "inputs": [ + { + "internalType": "address", + "name": "target", + "type": "address" + } + ], + "name": "AddressEmptyCode", + "type": "error" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "account", + "type": "address" + } + ], + "name": "AddressInsufficientBalance", + "type": "error" + }, { "inputs": [], "name": "AlreadyFinalized", "type": "error" }, + { + "inputs": [], + "name": "FailedInnerCall", + "type": "error" + }, { "inputs": [], "name": "FundingSourceAlreadyAdded", @@ -24,6 +51,11 @@ "name": "InvalidMaciFactory", "type": "error" }, + { + "inputs": [], + "name": "MaxRecipientsNotSet", + "type": "error" + }, { "inputs": [], "name": "NoCurrentRound", @@ -55,8 +87,14 @@ "type": "error" }, { - "inputs": [], - "name": "VoteOptionTreeDepthNotSet", + "inputs": [ + { + "internalType": "address", + "name": "token", + "type": "address" + } + ], + "name": "SafeERC20FailedOperation", "type": "error" }, { @@ -343,19 +381,6 @@ "stateMutability": "view", "type": "function" }, - { - "inputs": [], - "name": "getMaxRecipients", - "outputs": [ - { - "internalType": "uint256", - "name": "_maxRecipients", - "type": "uint256" - } - ], - "stateMutability": "view", - "type": "function" - }, { "inputs": [ { diff --git a/subgraph/abis/ClrFundDeployer.json b/subgraph/abis/ClrFundDeployer.json index 68b32d168..3dd329580 100644 --- a/subgraph/abis/ClrFundDeployer.json +++ b/subgraph/abis/ClrFundDeployer.json @@ -40,6 +40,28 @@ "name": "InvalidMaciFactory", "type": "error" }, + { + "inputs": [ + { + "internalType": "address", + "name": "owner", + "type": "address" + } + ], + "name": "OwnableInvalidOwner", + "type": "error" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "account", + "type": "address" + } + ], + "name": "OwnableUnauthorizedAccount", + "type": "error" + }, { "anonymous": false, "inputs": [ diff --git a/subgraph/abis/FundingRound.json b/subgraph/abis/FundingRound.json index 7bfd15417..9d7aa994b 100644 --- a/subgraph/abis/FundingRound.json +++ b/subgraph/abis/FundingRound.json @@ -25,6 +25,28 @@ "stateMutability": "nonpayable", "type": "constructor" }, + { + "inputs": [ + { + "internalType": "address", + "name": "target", + "type": "address" + } + ], + "name": "AddressEmptyCode", + "type": "error" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "account", + "type": "address" + } + ], + "name": "AddressInsufficientBalance", + "type": "error" + }, { "inputs": [], "name": "AlreadyContributed", @@ -45,6 +67,11 @@ "name": "EmptyTallyHash", "type": "error" }, + { + "inputs": [], + "name": "FailedInnerCall", + "type": "error" + }, { "inputs": [], "name": "FundsAlreadyClaimed", @@ -141,6 +168,11 @@ "name": "NoProjectHasMoreThanOneVote", "type": "error" }, + { + "inputs": [], + "name": "NoSignUps", + "type": "error" + }, { "inputs": [], "name": "NoVoiceCredits", @@ -166,6 +198,28 @@ "name": "OnlyMaciCanRegisterVoters", "type": "error" }, + { + "inputs": [ + { + "internalType": "address", + "name": "owner", + "type": "address" + } + ], + "name": "OwnableInvalidOwner", + "type": "error" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "account", + "type": "address" + } + ], + "name": "OwnableUnauthorizedAccount", + "type": "error" + }, { "inputs": [], "name": "PollNotSet", @@ -191,6 +245,17 @@ "name": "RoundNotFinalized", "type": "error" }, + { + "inputs": [ + { + "internalType": "address", + "name": "token", + "type": "address" + } + ], + "name": "SafeERC20FailedOperation", + "type": "error" + }, { "inputs": [], "name": "TallyHashNotPublished", @@ -402,19 +467,6 @@ "stateMutability": "view", "type": "function" }, - { - "inputs": [], - "name": "TREE_ARITY", - "outputs": [ - { - "internalType": "uint256", - "name": "", - "type": "uint256" - } - ], - "stateMutability": "view", - "type": "function" - }, { "inputs": [], "name": "alpha", @@ -891,11 +943,6 @@ "internalType": "address", "name": "tally", "type": "address" - }, - { - "internalType": "address", - "name": "subsidy", - "type": "address" } ], "internalType": "struct MACI.PollContracts", diff --git a/subgraph/abis/MACIFactory.json b/subgraph/abis/MACIFactory.json index 7f3ae7c07..3488fff8d 100644 --- a/subgraph/abis/MACIFactory.json +++ b/subgraph/abis/MACIFactory.json @@ -37,6 +37,16 @@ "stateMutability": "nonpayable", "type": "constructor" }, + { + "inputs": [], + "name": "InvalidMaxRecipients", + "type": "error" + }, + { + "inputs": [], + "name": "InvalidMessageBatchSize", + "type": "error" + }, { "inputs": [], "name": "InvalidMessageProcessorFactory", @@ -62,6 +72,11 @@ "name": "InvalidVkRegistry", "type": "error" }, + { + "inputs": [], + "name": "InvalidVoteOptionTreeDepth", + "type": "error" + }, { "inputs": [], "name": "NotInitialized", @@ -99,6 +114,11 @@ "name": "TallyVkNotSet", "type": "error" }, + { + "inputs": [], + "name": "VoteOptionTreeDepthNotSet", + "type": "error" + }, { "anonymous": false, "inputs": [ @@ -150,19 +170,6 @@ "stateMutability": "view", "type": "function" }, - { - "inputs": [], - "name": "TREE_ARITY", - "outputs": [ - { - "internalType": "uint256", - "name": "", - "type": "uint256" - } - ], - "stateMutability": "view", - "type": "function" - }, { "inputs": [ { @@ -270,22 +277,29 @@ "type": "function" }, { - "inputs": [ + "inputs": [], + "name": "maxRecipients", + "outputs": [ { - "internalType": "uint8", - "name": "messageTreeSubDepth", - "type": "uint8" + "internalType": "uint256", + "name": "", + "type": "uint256" } ], - "name": "getMessageBatchSize", + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "messageBatchSize", "outputs": [ { "internalType": "uint256", - "name": "_messageBatchSize", + "name": "", "type": "uint256" } ], - "stateMutability": "pure", + "stateMutability": "view", "type": "function" }, { @@ -315,6 +329,16 @@ "name": "_stateTreeDepth", "type": "uint8" }, + { + "internalType": "uint256", + "name": "_messageBatchSize", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "_maxRecipients", + "type": "uint256" + }, { "components": [ { diff --git a/subgraph/generated/ClrFund/ClrFund.ts b/subgraph/generated/ClrFund/ClrFund.ts index 3446a9e7b..5810bf338 100644 --- a/subgraph/generated/ClrFund/ClrFund.ts +++ b/subgraph/generated/ClrFund/ClrFund.ts @@ -389,29 +389,6 @@ export class ClrFund extends ethereum.SmartContract { return ethereum.CallResult.fromValue(value[0].toBigInt()); } - getMaxRecipients(): BigInt { - let result = super.call( - "getMaxRecipients", - "getMaxRecipients():(uint256)", - [], - ); - - return result[0].toBigInt(); - } - - try_getMaxRecipients(): ethereum.CallResult { - let result = super.tryCall( - "getMaxRecipients", - "getMaxRecipients():(uint256)", - [], - ); - if (result.reverted) { - return new ethereum.CallResult(); - } - let value = result.value; - return ethereum.CallResult.fromValue(value[0].toBigInt()); - } - maciFactory(): Address { let result = super.call("maciFactory", "maciFactory():(address)", []); diff --git a/subgraph/generated/ClrFund/FundingRound.ts b/subgraph/generated/ClrFund/FundingRound.ts index 32be22df9..a2660d7ad 100644 --- a/subgraph/generated/ClrFund/FundingRound.ts +++ b/subgraph/generated/ClrFund/FundingRound.ts @@ -277,21 +277,6 @@ export class FundingRound extends ethereum.SmartContract { return ethereum.CallResult.fromValue(value[0].toI32()); } - TREE_ARITY(): BigInt { - let result = super.call("TREE_ARITY", "TREE_ARITY():(uint256)", []); - - return result[0].toBigInt(); - } - - try_TREE_ARITY(): ethereum.CallResult { - let result = super.tryCall("TREE_ARITY", "TREE_ARITY():(uint256)", []); - if (result.reverted) { - return new ethereum.CallResult(); - } - let value = result.value; - return ethereum.CallResult.fromValue(value[0].toBigInt()); - } - alpha(): BigInt { let result = super.call("alpha", "alpha():(uint256)", []); @@ -1237,10 +1222,6 @@ export class SetMaciCall_pollContractsStruct extends ethereum.Tuple { get tally(): Address { return this[2].toAddress(); } - - get subsidy(): Address { - return this[3].toAddress(); - } } export class SetMaciInstanceCall extends ethereum.Call { diff --git a/subgraph/generated/ClrFund/MACIFactory.ts b/subgraph/generated/ClrFund/MACIFactory.ts index 7c1fbe71b..0f6f79fc3 100644 --- a/subgraph/generated/ClrFund/MACIFactory.ts +++ b/subgraph/generated/ClrFund/MACIFactory.ts @@ -227,21 +227,6 @@ export class MACIFactory extends ethereum.SmartContract { return ethereum.CallResult.fromValue(value[0].toI32()); } - TREE_ARITY(): BigInt { - let result = super.call("TREE_ARITY", "TREE_ARITY():(uint256)", []); - - return result[0].toBigInt(); - } - - try_TREE_ARITY(): ethereum.CallResult { - let result = super.tryCall("TREE_ARITY", "TREE_ARITY():(uint256)", []); - if (result.reverted) { - return new ethereum.CallResult(); - } - let value = result.value; - return ethereum.CallResult.fromValue(value[0].toBigInt()); - } - deployMaci( signUpGatekeeper: Address, initialVoiceCreditProxy: Address, @@ -342,23 +327,40 @@ export class MACIFactory extends ethereum.SmartContract { ); } - getMessageBatchSize(messageTreeSubDepth: i32): BigInt { + maxRecipients(): BigInt { + let result = super.call("maxRecipients", "maxRecipients():(uint256)", []); + + return result[0].toBigInt(); + } + + try_maxRecipients(): ethereum.CallResult { + let result = super.tryCall( + "maxRecipients", + "maxRecipients():(uint256)", + [], + ); + if (result.reverted) { + return new ethereum.CallResult(); + } + let value = result.value; + return ethereum.CallResult.fromValue(value[0].toBigInt()); + } + + messageBatchSize(): BigInt { let result = super.call( - "getMessageBatchSize", - "getMessageBatchSize(uint8):(uint256)", - [ethereum.Value.fromUnsignedBigInt(BigInt.fromI32(messageTreeSubDepth))], + "messageBatchSize", + "messageBatchSize():(uint256)", + [], ); return result[0].toBigInt(); } - try_getMessageBatchSize( - messageTreeSubDepth: i32, - ): ethereum.CallResult { + try_messageBatchSize(): ethereum.CallResult { let result = super.tryCall( - "getMessageBatchSize", - "getMessageBatchSize(uint8):(uint256)", - [ethereum.Value.fromUnsignedBigInt(BigInt.fromI32(messageTreeSubDepth))], + "messageBatchSize", + "messageBatchSize():(uint256)", + [], ); if (result.reverted) { return new ethereum.CallResult(); @@ -658,9 +660,17 @@ export class SetMaciParametersCall__Inputs { return this._call.inputValues[0].value.toI32(); } + get _messageBatchSize(): BigInt { + return this._call.inputValues[1].value.toBigInt(); + } + + get _maxRecipients(): BigInt { + return this._call.inputValues[2].value.toBigInt(); + } + get _treeDepths(): SetMaciParametersCall_treeDepthsStruct { return changetype( - this._call.inputValues[1].value.toTuple(), + this._call.inputValues[3].value.toTuple(), ); } } diff --git a/subgraph/generated/templates/FundingRound/FundingRound.ts b/subgraph/generated/templates/FundingRound/FundingRound.ts index 32be22df9..a2660d7ad 100644 --- a/subgraph/generated/templates/FundingRound/FundingRound.ts +++ b/subgraph/generated/templates/FundingRound/FundingRound.ts @@ -277,21 +277,6 @@ export class FundingRound extends ethereum.SmartContract { return ethereum.CallResult.fromValue(value[0].toI32()); } - TREE_ARITY(): BigInt { - let result = super.call("TREE_ARITY", "TREE_ARITY():(uint256)", []); - - return result[0].toBigInt(); - } - - try_TREE_ARITY(): ethereum.CallResult { - let result = super.tryCall("TREE_ARITY", "TREE_ARITY():(uint256)", []); - if (result.reverted) { - return new ethereum.CallResult(); - } - let value = result.value; - return ethereum.CallResult.fromValue(value[0].toBigInt()); - } - alpha(): BigInt { let result = super.call("alpha", "alpha():(uint256)", []); @@ -1237,10 +1222,6 @@ export class SetMaciCall_pollContractsStruct extends ethereum.Tuple { get tally(): Address { return this[2].toAddress(); } - - get subsidy(): Address { - return this[3].toAddress(); - } } export class SetMaciInstanceCall extends ethereum.Call { diff --git a/subgraph/generated/templates/MACI/FundingRound.ts b/subgraph/generated/templates/MACI/FundingRound.ts index 32be22df9..a2660d7ad 100644 --- a/subgraph/generated/templates/MACI/FundingRound.ts +++ b/subgraph/generated/templates/MACI/FundingRound.ts @@ -277,21 +277,6 @@ export class FundingRound extends ethereum.SmartContract { return ethereum.CallResult.fromValue(value[0].toI32()); } - TREE_ARITY(): BigInt { - let result = super.call("TREE_ARITY", "TREE_ARITY():(uint256)", []); - - return result[0].toBigInt(); - } - - try_TREE_ARITY(): ethereum.CallResult { - let result = super.tryCall("TREE_ARITY", "TREE_ARITY():(uint256)", []); - if (result.reverted) { - return new ethereum.CallResult(); - } - let value = result.value; - return ethereum.CallResult.fromValue(value[0].toBigInt()); - } - alpha(): BigInt { let result = super.call("alpha", "alpha():(uint256)", []); @@ -1237,10 +1222,6 @@ export class SetMaciCall_pollContractsStruct extends ethereum.Tuple { get tally(): Address { return this[2].toAddress(); } - - get subsidy(): Address { - return this[3].toAddress(); - } } export class SetMaciInstanceCall extends ethereum.Call { diff --git a/subgraph/generated/templates/Poll/FundingRound.ts b/subgraph/generated/templates/Poll/FundingRound.ts index 32be22df9..a2660d7ad 100644 --- a/subgraph/generated/templates/Poll/FundingRound.ts +++ b/subgraph/generated/templates/Poll/FundingRound.ts @@ -277,21 +277,6 @@ export class FundingRound extends ethereum.SmartContract { return ethereum.CallResult.fromValue(value[0].toI32()); } - TREE_ARITY(): BigInt { - let result = super.call("TREE_ARITY", "TREE_ARITY():(uint256)", []); - - return result[0].toBigInt(); - } - - try_TREE_ARITY(): ethereum.CallResult { - let result = super.tryCall("TREE_ARITY", "TREE_ARITY():(uint256)", []); - if (result.reverted) { - return new ethereum.CallResult(); - } - let value = result.value; - return ethereum.CallResult.fromValue(value[0].toBigInt()); - } - alpha(): BigInt { let result = super.call("alpha", "alpha():(uint256)", []); @@ -1237,10 +1222,6 @@ export class SetMaciCall_pollContractsStruct extends ethereum.Tuple { get tally(): Address { return this[2].toAddress(); } - - get subsidy(): Address { - return this[3].toAddress(); - } } export class SetMaciInstanceCall extends ethereum.Call { diff --git a/subgraph/src/ClrFundMapping.ts b/subgraph/src/ClrFundMapping.ts index 85cbe3170..02c978eb3 100644 --- a/subgraph/src/ClrFundMapping.ts +++ b/subgraph/src/ClrFundMapping.ts @@ -132,7 +132,7 @@ function createOrUpdateClrFund( let recipientRegistryId = recipientRegistryAddress.toHexString() let recipientRegistry = RecipientRegistry.load(recipientRegistryId) if (!recipientRegistry) { - createRecipientRegistry(clrFundId, recipientRegistryAddress) + createRecipientRegistry(recipientRegistryAddress) } let contributorRegistryAddress = clrFundContract.userRegistry() diff --git a/subgraph/src/RecipientRegistry.ts b/subgraph/src/RecipientRegistry.ts index a9af36950..751a30e45 100644 --- a/subgraph/src/RecipientRegistry.ts +++ b/subgraph/src/RecipientRegistry.ts @@ -8,7 +8,6 @@ import { OptimisticRecipientRegistry as RecipientRegistryTemplate } from '../gen * Create the recipient registry entity */ export function createRecipientRegistry( - clrFundId: string, recipientRegistryAddress: Address ): RecipientRegistry { let recipientRegistryId = recipientRegistryAddress.toHexString() @@ -41,7 +40,6 @@ export function createRecipientRegistry( if (!owner.reverted) { recipientRegistry.owner = owner.value } - recipientRegistry.clrFund = clrFundId recipientRegistry.save() return recipientRegistry @@ -56,22 +54,7 @@ export function loadRecipientRegistry( let recipientRegistryId = address.toHexString() let recipientRegistry = RecipientRegistry.load(recipientRegistryId) if (!recipientRegistry) { - let recipientRegistryContract = RecipientRegistryContract.bind(address) - let controller = recipientRegistryContract.try_controller() - if (!controller.reverted) { - // Recipient registry's controller must be the ClrFund contract - let clrFundId = controller.value.toHexString() - let clrFund = ClrFund.load(clrFundId) - if (clrFund) { - /* This is our registry, create it */ - recipientRegistry = createRecipientRegistry(clrFund.id, address) - - // update factory - clrFund.recipientRegistry = recipientRegistryId - clrFund.recipientRegistryAddress = address - clrFund.save() - } - } + recipientRegistry = createRecipientRegistry(address) } return recipientRegistry From dd028f90cfd12bc28f1c70cf9471b6b2474088e4 Mon Sep 17 00:00:00 2001 From: yuetloo Date: Tue, 21 May 2024 20:27:04 -0400 Subject: [PATCH 37/57] fix incorrect entity id mapping when contract was called from another contract --- subgraph/src/ClrFundDeployerMapping.ts | 2 +- subgraph/src/MACIMapping.ts | 2 +- subgraph/src/PollMapping.ts | 12 ++---------- 3 files changed, 4 insertions(+), 12 deletions(-) diff --git a/subgraph/src/ClrFundDeployerMapping.ts b/subgraph/src/ClrFundDeployerMapping.ts index c04392dac..840ccf8c8 100644 --- a/subgraph/src/ClrFundDeployerMapping.ts +++ b/subgraph/src/ClrFundDeployerMapping.ts @@ -5,7 +5,7 @@ import { ClrFundDeployer, ClrFund } from '../generated/schema' import { ClrFund as ClrFundTemplate } from '../generated/templates' export function handleNewInstance(event: NewInstance): void { - let clrfundDeployerAddress = event.transaction.to! + let clrfundDeployerAddress = event.address let clrfundDeployerId = clrfundDeployerAddress.toHex() let clrFundDeployer = ClrFundDeployer.load(clrfundDeployerId) diff --git a/subgraph/src/MACIMapping.ts b/subgraph/src/MACIMapping.ts index 75da4929b..e1cbdb28f 100644 --- a/subgraph/src/MACIMapping.ts +++ b/subgraph/src/MACIMapping.ts @@ -21,7 +21,7 @@ import { makePublicKeyId } from './PublicKey' // - contract.verifier(...) export function handleSignUp(event: SignUp): void { - let fundingRoundAddress = event.transaction.to! + let fundingRoundAddress = event.address let fundingRoundId = fundingRoundAddress.toHex() let publicKeyId = makePublicKeyId( diff --git a/subgraph/src/PollMapping.ts b/subgraph/src/PollMapping.ts index 99aa537fb..e3c6fe043 100644 --- a/subgraph/src/PollMapping.ts +++ b/subgraph/src/PollMapping.ts @@ -1,19 +1,11 @@ import { log } from '@graphprotocol/graph-ts' import { PublishMessage } from '../generated/templates/Poll/Poll' -import { FundingRound, Poll, Message, PublicKey } from '../generated/schema' +import { Poll, Message, PublicKey } from '../generated/schema' import { makePublicKeyId } from './PublicKey' export function handlePublishMessage(event: PublishMessage): void { - if (!event.transaction.to) { - log.error( - 'Error: handlePublishMessage failed fundingRound not registered', - [] - ) - return - } - - let pollEntityId = event.transaction.to!.toHex() + let pollEntityId = event.address.toHex() let poll = Poll.load(pollEntityId) if (poll == null) { log.error('Error: handlePublishMessage failed poll not found {}', [ From c71e354526fcd549a55437db5686069495365ae0 Mon Sep 17 00:00:00 2001 From: yuetloo Date: Tue, 21 May 2024 21:11:27 -0400 Subject: [PATCH 38/57] update recipient registry address --- subgraph/src/ClrFundMapping.ts | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/subgraph/src/ClrFundMapping.ts b/subgraph/src/ClrFundMapping.ts index 02c978eb3..92f408fdd 100644 --- a/subgraph/src/ClrFundMapping.ts +++ b/subgraph/src/ClrFundMapping.ts @@ -131,7 +131,10 @@ function createOrUpdateClrFund( let recipientRegistryAddress = clrFundContract.recipientRegistry() let recipientRegistryId = recipientRegistryAddress.toHexString() let recipientRegistry = RecipientRegistry.load(recipientRegistryId) - if (!recipientRegistry) { + if (recipientRegistry) { + recipientRegistry.clrFund = clrFundId + recipientRegistry.save() + } else { createRecipientRegistry(recipientRegistryAddress) } From 3d47629493a1a619f1b7d0eba6954c9d39e91a30 Mon Sep 17 00:00:00 2001 From: yuetloo Date: Tue, 21 May 2024 21:30:00 -0400 Subject: [PATCH 39/57] update clrfund with recipient registry address --- subgraph/src/ClrFundMapping.ts | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/subgraph/src/ClrFundMapping.ts b/subgraph/src/ClrFundMapping.ts index 92f408fdd..3e97056c8 100644 --- a/subgraph/src/ClrFundMapping.ts +++ b/subgraph/src/ClrFundMapping.ts @@ -131,12 +131,11 @@ function createOrUpdateClrFund( let recipientRegistryAddress = clrFundContract.recipientRegistry() let recipientRegistryId = recipientRegistryAddress.toHexString() let recipientRegistry = RecipientRegistry.load(recipientRegistryId) - if (recipientRegistry) { - recipientRegistry.clrFund = clrFundId - recipientRegistry.save() - } else { - createRecipientRegistry(recipientRegistryAddress) + if (!recipientRegistry) { + recipientRegistry = createRecipientRegistry(recipientRegistryAddress) } + recipientRegistry.clrFund = clrFundId + recipientRegistry.save() let contributorRegistryAddress = clrFundContract.userRegistry() let contributorRegistryId = contributorRegistryAddress.toHexString() From 729eadcc193df0dc00f7cd975b3cec24d5bf19c3 Mon Sep 17 00:00:00 2001 From: yuetloo Date: Wed, 22 May 2024 11:21:24 -0300 Subject: [PATCH 40/57] refactor code for readability --- contracts/contracts/ClrFund.sol | 23 ++++++++++++----------- 1 file changed, 12 insertions(+), 11 deletions(-) diff --git a/contracts/contracts/ClrFund.sol b/contracts/contracts/ClrFund.sol index 3927ab2c1..499994383 100644 --- a/contracts/contracts/ClrFund.sol +++ b/contracts/contracts/ClrFund.sol @@ -63,6 +63,12 @@ contract ClrFund is OwnableUpgradeable, DomainObjs, Params { error MaxRecipientsNotSet(); error NotInitialized(); + modifier maciFactoryInitialized() { + if (address(maciFactory) == address(0)) revert InvalidMaciFactory(); + if (maciFactory.maxRecipients() == 0) revert MaxRecipientsNotSet(); + _; + } + /** * @dev Initialize clrfund instance with MACI factory and round factory @@ -141,15 +147,6 @@ contract ClrFund is OwnableUpgradeable, DomainObjs, Params { emit UserRegistryChanged(address(_userRegistry)); } - /** - * @dev Set the max recipients in the recipient registry - */ - function _setMaxRecipients() private { - if (address(maciFactory) == address(0)) revert NotInitialized(); - if (maciFactory.maxRecipients() == 0) revert MaxRecipientsNotSet(); - recipientRegistry.setMaxRecipients(maciFactory.maxRecipients()); - } - /** * @dev Set recipient registry. * @param _recipientRegistry Address of a recipient registry. @@ -157,10 +154,13 @@ contract ClrFund is OwnableUpgradeable, DomainObjs, Params { function setRecipientRegistry(IRecipientRegistry _recipientRegistry) external onlyOwner + maciFactoryInitialized { recipientRegistry = _recipientRegistry; - _setMaxRecipients(); + + // Make sure that the max number of recipients is set correctly + recipientRegistry.setMaxRecipients(maciFactory.maxRecipients()); emit RecipientRegistryChanged(address(_recipientRegistry)); } @@ -215,6 +215,7 @@ contract ClrFund is OwnableUpgradeable, DomainObjs, Params { ) external onlyOwner + maciFactoryInitialized { IFundingRound currentRound = getCurrentRound(); if (address(currentRound) != address(0) && !currentRound.isFinalized()) { @@ -224,7 +225,7 @@ contract ClrFund is OwnableUpgradeable, DomainObjs, Params { if (address(recipientRegistry) == address(0)) revert RecipientRegistryNotSet(); // Make sure that the max number of recipients is set correctly - _setMaxRecipients(); + recipientRegistry.setMaxRecipients(maciFactory.maxRecipients()); // Deploy funding round and MACI contracts address newRound = roundFactory.deploy(duration, address(this)); From 9aea7fe14ca7d286d213b097910c82eccde15693 Mon Sep 17 00:00:00 2001 From: yuetloo Date: Fri, 24 May 2024 12:06:49 -0300 Subject: [PATCH 41/57] fix typescript error by building on the same job --- .github/workflows/create-version.yml | 8 ++------ 1 file changed, 2 insertions(+), 6 deletions(-) diff --git a/.github/workflows/create-version.yml b/.github/workflows/create-version.yml index 9cccd61a7..997f82322 100644 --- a/.github/workflows/create-version.yml +++ b/.github/workflows/create-version.yml @@ -31,18 +31,14 @@ jobs: node-version: ${{ env.NODE_VERSION }} - name: Checkout source code uses: actions/checkout@v3 - - name: Install dependencies + - name: Create new version run: | # use https to avoid error: unable to connect to github.com git config --global url."https://".insteadOf git:// - yarn && yarn build - - name: setup git config - run: | # setup the username and email. I tend to use 'GitHub Actions Bot' with no email by default git config user.name "GitHub Actions Bot" git config user.email "<>" - - name: Create new version - run: | + yarn && yarn build echo "Version: ${{ github.event.inputs.version }}" cd contracts npm version ${{ github.event.inputs.version }} From 47ae670da2e38bd9dd456c8e6834a6eeb34bd7e8 Mon Sep 17 00:00:00 2001 From: yuetloo Date: Fri, 24 May 2024 12:20:31 -0300 Subject: [PATCH 42/57] remove test common due to mocha error --- .husky/pre-push | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.husky/pre-push b/.husky/pre-push index c0d892312..c0bc1da1c 100755 --- a/.husky/pre-push +++ b/.husky/pre-push @@ -11,4 +11,4 @@ export VITE_RECIPIENT_REGISTRY_TYPE=simple export VITE_USER_REGISTRY_TYPE=simple export VITE_WALLET_CONNECT_PROJECT_ID=1 -yarn test:format && yarn test:common && yarn test:web && yarn test:lint-i18n +yarn test:format && yarn test:web && yarn test:lint-i18n From 418f53b9ba544d5d87136a2f78b2a281f723ec82 Mon Sep 17 00:00:00 2001 From: GitHub Actions Bot <> Date: Fri, 24 May 2024 15:25:14 +0000 Subject: [PATCH 43/57] v5.2.1 --- contracts/package.json | 2 +- subgraph/package.json | 2 +- vue-app/package.json | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/contracts/package.json b/contracts/package.json index 795dc7ef2..6aae0c54a 100644 --- a/contracts/package.json +++ b/contracts/package.json @@ -1,6 +1,6 @@ { "name": "@clrfund/contracts", - "version": "5.2.0", + "version": "5.2.1", "license": "GPL-3.0", "scripts": { "hardhat": "hardhat", diff --git a/subgraph/package.json b/subgraph/package.json index 8efc48965..9c47ed39f 100644 --- a/subgraph/package.json +++ b/subgraph/package.json @@ -1,6 +1,6 @@ { "name": "@clrfund/subgraph", - "version": "5.2.0", + "version": "5.2.1", "repository": "https://github.com/clrfund/monorepo/subgraph", "keywords": [ "clr.fund", diff --git a/vue-app/package.json b/vue-app/package.json index 87ff3524f..65410d750 100644 --- a/vue-app/package.json +++ b/vue-app/package.json @@ -1,6 +1,6 @@ { "name": "@clrfund/vue-app", - "version": "5.2.0", + "version": "5.2.1", "private": true, "license": "GPL-3.0", "type": "module", From 58b93b47e4d08bb45bae7f6621c108288a4d6e01 Mon Sep 17 00:00:00 2001 From: GitHub Actions Bot <> Date: Fri, 24 May 2024 16:07:29 +0000 Subject: [PATCH 44/57] v6.0.0 --- contracts/package.json | 2 +- subgraph/package.json | 2 +- vue-app/package.json | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/contracts/package.json b/contracts/package.json index 6aae0c54a..126d0a1ec 100644 --- a/contracts/package.json +++ b/contracts/package.json @@ -1,6 +1,6 @@ { "name": "@clrfund/contracts", - "version": "5.2.1", + "version": "6.0.0", "license": "GPL-3.0", "scripts": { "hardhat": "hardhat", diff --git a/subgraph/package.json b/subgraph/package.json index 9c47ed39f..3da61b629 100644 --- a/subgraph/package.json +++ b/subgraph/package.json @@ -1,6 +1,6 @@ { "name": "@clrfund/subgraph", - "version": "5.2.1", + "version": "6.0.0", "repository": "https://github.com/clrfund/monorepo/subgraph", "keywords": [ "clr.fund", diff --git a/vue-app/package.json b/vue-app/package.json index 65410d750..ccd226c26 100644 --- a/vue-app/package.json +++ b/vue-app/package.json @@ -1,6 +1,6 @@ { "name": "@clrfund/vue-app", - "version": "5.2.1", + "version": "6.0.0", "private": true, "license": "GPL-3.0", "type": "module", From 1d8a6eb20bd437524d1a78cb8da96971274470ec Mon Sep 17 00:00:00 2001 From: yuetloo Date: Tue, 4 Jun 2024 00:21:33 -0400 Subject: [PATCH 45/57] fix missing arguments --- contracts/tasks/helpers/ConstructorArguments.ts | 2 ++ 1 file changed, 2 insertions(+) diff --git a/contracts/tasks/helpers/ConstructorArguments.ts b/contracts/tasks/helpers/ConstructorArguments.ts index 3f77d336b..9997e9683 100644 --- a/contracts/tasks/helpers/ConstructorArguments.ts +++ b/contracts/tasks/helpers/ConstructorArguments.ts @@ -150,6 +150,7 @@ async function getTallyConstructorArguments( tallyContract.vkRegistry(), tallyContract.poll(), tallyContract.messageProcessor(), + tallyContract.mode(), ]) return args @@ -174,6 +175,7 @@ async function getMessageProcessorConstructorArguments( messageProcesor.verifier(), messageProcesor.vkRegistry(), messageProcesor.poll(), + messageProcesor.mode(), ]) return args From 29900ee1315e517549513b5f022a244b6fd57019 Mon Sep 17 00:00:00 2001 From: yuetloo Date: Tue, 4 Jun 2024 00:22:24 -0400 Subject: [PATCH 46/57] add missing user and recipient registries --- contracts/tasks/runners/verifyAll.ts | 51 +++++++++++++++++++--------- 1 file changed, 35 insertions(+), 16 deletions(-) diff --git a/contracts/tasks/runners/verifyAll.ts b/contracts/tasks/runners/verifyAll.ts index 74972fe0c..7aa910b72 100644 --- a/contracts/tasks/runners/verifyAll.ts +++ b/contracts/tasks/runners/verifyAll.ts @@ -16,6 +16,7 @@ import { BaseContract } from 'ethers' import { HardhatEthersHelpers } from '@nomicfoundation/hardhat-ethers/types' import { ZERO_ADDRESS } from '../../utils/constants' import { ConstructorArguments } from '../helpers/ConstructorArguments' +import { getContractAt } from '../../utils/contracts' type ContractInfo = { name: string @@ -138,6 +139,8 @@ async function getContractList( clrfund: string, ethers: HardhatEthersHelpers ): Promise { + const userRegistries = new Set() + const recipientRegistries = new Set() const contractList: ContractInfo[] = [ { name: EContracts.ClrFund, @@ -145,10 +148,11 @@ async function getContractList( }, ] - const clrfundContract = (await ethers.getContractAt( + const clrfundContract = await getContractAt( EContracts.ClrFund, - clrfund - )) as BaseContract as ClrFund + clrfund, + ethers + ) const fundingRoundFactoryAddress = await clrfundContract.roundFactory() if (fundingRoundFactoryAddress !== ZERO_ADDRESS) { @@ -192,6 +196,16 @@ async function getContractList( }) } + const userRegistryAddress = await clrfundContract.userRegistry() + if (userRegistryAddress !== ZERO_ADDRESS) { + userRegistries.add(userRegistryAddress) + } + + const recipientRegistryAddress = await clrfundContract.recipientRegistry() + if (recipientRegistryAddress !== ZERO_ADDRESS) { + recipientRegistries.add(recipientRegistryAddress) + } + const fundingRoundAddress = await clrfundContract.getCurrentRound() if (fundingRoundAddress !== ZERO_ADDRESS) { contractList.push({ @@ -255,27 +269,32 @@ async function getContractList( // User Registry const userRegistryAddress = await fundingRound.userRegistry() if (userRegistryAddress !== ZERO_ADDRESS) { - const name = await getUserRegistryName(userRegistryAddress, ethers) - contractList.push({ - name, - address: userRegistryAddress, - }) + userRegistries.add(userRegistryAddress) } // Recipient Registry const recipientRegistryAddress = await fundingRound.recipientRegistry() if (recipientRegistryAddress !== ZERO_ADDRESS) { - const name = await getRecipientRegistryName( - recipientRegistryAddress, - ethers - ) - contractList.push({ - name, - address: recipientRegistryAddress, - }) + recipientRegistries.add(recipientRegistryAddress) } } + for (const address of userRegistries) { + const name = await getUserRegistryName(address, ethers) + contractList.push({ + name, + address, + }) + } + + for (const address of recipientRegistries) { + const name = await getRecipientRegistryName(address, ethers) + contractList.push({ + name, + address, + }) + } + return contractList } From 1d08b13809c31dd2058219436360e5cd6b03a75f Mon Sep 17 00:00:00 2001 From: yuetloo Date: Tue, 4 Jun 2024 00:22:50 -0400 Subject: [PATCH 47/57] add missing sepolia etherscan url --- contracts/utils/providers/EtherscanProvider.ts | 1 + 1 file changed, 1 insertion(+) diff --git a/contracts/utils/providers/EtherscanProvider.ts b/contracts/utils/providers/EtherscanProvider.ts index 8534156ae..047ccdbea 100644 --- a/contracts/utils/providers/EtherscanProvider.ts +++ b/contracts/utils/providers/EtherscanProvider.ts @@ -3,6 +3,7 @@ import { FetchRequest } from 'ethers' import { HardhatConfig } from 'hardhat/types' const EtherscanApiUrl: Record = { + sepolia: 'https://api-sepolia.etherscan.io', xdai: 'https://api.gnosisscan.io', arbitrum: 'https://api.arbiscan.io', 'arbitrum-goerli': 'https://api-goerli.arbiscan.io', From 12a46430e0be178de0503ebba73c134752c141ff Mon Sep 17 00:00:00 2001 From: yuetloo Date: Tue, 4 Jun 2024 03:27:26 -0400 Subject: [PATCH 48/57] fix reallocation error due to incorrect subgraph mapping for public key --- subgraph/generated/schema.ts | 14 ++-- subgraph/schema.graphql | 2 +- subgraph/schema.template.graphql | 2 +- subgraph/src/MACIMapping.ts | 15 +--- subgraph/src/PollMapping.ts | 21 +++-- subgraph/src/PublicKey.ts | 8 +- vue-app/src/api/contributions.ts | 15 ++-- vue-app/src/graphql/API.ts | 81 ++++++------------- .../queries/GetContributorIndex.graphql | 3 +- vue-app/src/stores/app.ts | 2 +- 10 files changed, 63 insertions(+), 100 deletions(-) diff --git a/subgraph/generated/schema.ts b/subgraph/generated/schema.ts index b3f92c01b..50ce4aecf 100644 --- a/subgraph/generated/schema.ts +++ b/subgraph/generated/schema.ts @@ -551,21 +551,17 @@ export class PublicKey extends Entity { this.set("id", Value.fromString(value)); } - get fundingRound(): string | null { - let value = this.get("fundingRound"); + get maci(): string { + let value = this.get("maci"); if (!value || value.kind == ValueKind.NULL) { - return null; + throw new Error("Cannot return null for a required field."); } else { return value.toString(); } } - set fundingRound(value: string | null) { - if (!value) { - this.unset("fundingRound"); - } else { - this.set("fundingRound", Value.fromString(value)); - } + set maci(value: string) { + this.set("maci", Value.fromString(value)); } get messages(): MessageLoader { diff --git a/subgraph/schema.graphql b/subgraph/schema.graphql index 3d9b3610a..2d779393a 100644 --- a/subgraph/schema.graphql +++ b/subgraph/schema.graphql @@ -37,7 +37,7 @@ type Message @entity { type PublicKey @entity { id: ID! - fundingRound: FundingRound + maci: String! messages: [Message!] @derivedFrom(field: "publicKey") x: BigInt! y: BigInt! diff --git a/subgraph/schema.template.graphql b/subgraph/schema.template.graphql index 44b3d2127..e8f1db50d 100644 --- a/subgraph/schema.template.graphql +++ b/subgraph/schema.template.graphql @@ -49,7 +49,7 @@ type Message @entity { type PublicKey @entity { id: ID! - fundingRound: FundingRound + maci: String! messages: [Message!] @derivedFrom(field: "publicKey") x: BigInt! y: BigInt! diff --git a/subgraph/src/MACIMapping.ts b/subgraph/src/MACIMapping.ts index e1cbdb28f..667822f48 100644 --- a/subgraph/src/MACIMapping.ts +++ b/subgraph/src/MACIMapping.ts @@ -21,11 +21,11 @@ import { makePublicKeyId } from './PublicKey' // - contract.verifier(...) export function handleSignUp(event: SignUp): void { - let fundingRoundAddress = event.address - let fundingRoundId = fundingRoundAddress.toHex() + let maciAddress = event.address + let maciId = maciAddress.toHex() let publicKeyId = makePublicKeyId( - fundingRoundId, + maciId, event.params._userPubKeyX, event.params._userPubKeyY ) @@ -39,14 +39,7 @@ export function handleSignUp(event: SignUp): void { publicKey.y = event.params._userPubKeyY publicKey.stateIndex = event.params._stateIndex publicKey.voiceCreditBalance = event.params._voiceCreditBalance - - let fundingRound = FundingRound.load(fundingRoundId) - if (fundingRound == null) { - log.error('Error: handleSignUp failed, fundingRound not registered', []) - return - } - - publicKey.fundingRound = fundingRoundId + publicKey.maci = maciId publicKey.save() log.info('SignUp', []) diff --git a/subgraph/src/PollMapping.ts b/subgraph/src/PollMapping.ts index e3c6fe043..e566813e6 100644 --- a/subgraph/src/PollMapping.ts +++ b/subgraph/src/PollMapping.ts @@ -1,7 +1,7 @@ import { log } from '@graphprotocol/graph-ts' import { PublishMessage } from '../generated/templates/Poll/Poll' -import { Poll, Message, PublicKey } from '../generated/schema' +import { FundingRound, Poll, Message, PublicKey } from '../generated/schema' import { makePublicKeyId } from './PublicKey' export function handlePublishMessage(event: PublishMessage): void { @@ -17,12 +17,24 @@ export function handlePublishMessage(event: PublishMessage): void { let fundingRoundId = poll.fundingRound if (!fundingRoundId) { log.error( - 'Error: handlePublishMessage failed poll {} missing funding round', + 'Error: handlePublishMessage failed poll {} missing funding round id', [pollEntityId] ) return } + let fundingRound = FundingRound.load(fundingRoundId) + if (!fundingRound) { + log.error( + 'Error: handlePublishMessage failed poll {} missing funding round entity', + [pollEntityId] + ) + return + } + + let maci = fundingRound.maci + let maciId = maci ? maci.toHex() : '' + let messageID = event.transaction.hash.toHexString() + '-' + @@ -37,7 +49,7 @@ export function handlePublishMessage(event: PublishMessage): void { message.submittedBy = event.transaction.from let publicKeyId = makePublicKeyId( - fundingRoundId, + maciId, event.params._encPubKey.x, event.params._encPubKey.y ) @@ -48,8 +60,7 @@ export function handlePublishMessage(event: PublishMessage): void { let publicKey = new PublicKey(publicKeyId) publicKey.x = event.params._encPubKey.x publicKey.y = event.params._encPubKey.y - publicKey.fundingRound = fundingRoundId - + publicKey.maci = maciId publicKey.save() } diff --git a/subgraph/src/PublicKey.ts b/subgraph/src/PublicKey.ts index d34f33706..d3edacbc0 100644 --- a/subgraph/src/PublicKey.ts +++ b/subgraph/src/PublicKey.ts @@ -2,15 +2,11 @@ import { ByteArray, crypto, BigInt } from '@graphprotocol/graph-ts' // Create the PublicKey entity id used in subgraph // using MACI public key x and y values -export function makePublicKeyId( - fundingRoundId: string, - x: BigInt, - y: BigInt -): string { +export function makePublicKeyId(maciId: string, x: BigInt, y: BigInt): string { let publicKeyX = x.toString() let publicKeyY = y.toString() let publicKeyXY = ByteArray.fromUTF8( - fundingRoundId + '.' + publicKeyX + '.' + publicKeyY + maciId + '.' + publicKeyX + '.' + publicKeyY ) let publicKeyId = crypto.keccak256(publicKeyXY).toHexString() return publicKeyId diff --git a/vue-app/src/api/contributions.ts b/vue-app/src/api/contributions.ts index 5e0618447..d25775dd2 100644 --- a/vue-app/src/api/contributions.ts +++ b/vue-app/src/api/contributions.ts @@ -27,13 +27,13 @@ export interface Contributor { /** * get the id of the subgraph public key entity from the pubKey value - * @param fundingRoundAddress funding round address + * @param maciAddress MACI address * @param pubKey MACI public key * @returns the id for the subgraph public key entity */ -function getPubKeyId(fundingRoundAddress = '', pubKey: PubKey): string { +function getPubKeyId(maciAddress = '', pubKey: PubKey): string { const pubKeyPair = pubKey.asContractParam() - return id(fundingRoundAddress.toLowerCase() + '.' + pubKeyPair.x + '.' + pubKeyPair.y) + return id(maciAddress.toLowerCase() + '.' + pubKeyPair.x + '.' + pubKeyPair.y) } export function getCartStorageKey(roundAddress: string): string { @@ -141,17 +141,16 @@ export function isContributionAmountValid(value: string, currentRound: RoundInfo /** * Get the MACI contributor state index - * @param fundingRoundAddress Funding round contract address + * @param maciAddress MACI contract address * @param pubKey Contributor public key * @returns Contributor stateIndex returned from MACI */ -export async function getContributorIndex(fundingRoundAddress: string, pubKey: PubKey): Promise { - if (!fundingRoundAddress) { +export async function getContributorIndex(maciAddress: string, pubKey: PubKey): Promise { + if (!maciAddress) { return null } - const id = getPubKeyId(fundingRoundAddress, pubKey) + const id = getPubKeyId(maciAddress, pubKey) const data = await sdk.GetContributorIndex({ - fundingRoundAddress: fundingRoundAddress.toLowerCase(), publicKeyId: id, }) diff --git a/vue-app/src/graphql/API.ts b/vue-app/src/graphql/API.ts index 72b5be6c3..121c59320 100644 --- a/vue-app/src/graphql/API.ts +++ b/vue-app/src/graphql/API.ts @@ -1778,6 +1778,7 @@ export enum Message_OrderBy { PollId = 'poll__id', PublicKey = 'publicKey', PublicKeyId = 'publicKey__id', + PublicKeyMaci = 'publicKey__maci', PublicKeyStateIndex = 'publicKey__stateIndex', PublicKeyVoiceCreditBalance = 'publicKey__voiceCreditBalance', PublicKeyX = 'publicKey__x', @@ -1884,8 +1885,8 @@ export enum Poll_OrderBy { export type PublicKey = { __typename?: 'PublicKey'; - fundingRound: Maybe; id: Scalars['ID']; + maci: Scalars['String']; messages: Maybe>; stateIndex: Maybe; voiceCreditBalance: Maybe; @@ -1906,27 +1907,6 @@ export type PublicKey_Filter = { /** Filter for the block changed event. */ _change_block: InputMaybe; and: InputMaybe>>; - fundingRound: InputMaybe; - fundingRound_: InputMaybe; - fundingRound_contains: InputMaybe; - fundingRound_contains_nocase: InputMaybe; - fundingRound_ends_with: InputMaybe; - fundingRound_ends_with_nocase: InputMaybe; - fundingRound_gt: InputMaybe; - fundingRound_gte: InputMaybe; - fundingRound_in: InputMaybe>; - fundingRound_lt: InputMaybe; - fundingRound_lte: InputMaybe; - fundingRound_not: InputMaybe; - fundingRound_not_contains: InputMaybe; - fundingRound_not_contains_nocase: InputMaybe; - fundingRound_not_ends_with: InputMaybe; - fundingRound_not_ends_with_nocase: InputMaybe; - fundingRound_not_in: InputMaybe>; - fundingRound_not_starts_with: InputMaybe; - fundingRound_not_starts_with_nocase: InputMaybe; - fundingRound_starts_with: InputMaybe; - fundingRound_starts_with_nocase: InputMaybe; id: InputMaybe; id_gt: InputMaybe; id_gte: InputMaybe; @@ -1935,6 +1915,26 @@ export type PublicKey_Filter = { id_lte: InputMaybe; id_not: InputMaybe; id_not_in: InputMaybe>; + maci: InputMaybe; + maci_contains: InputMaybe; + maci_contains_nocase: InputMaybe; + maci_ends_with: InputMaybe; + maci_ends_with_nocase: InputMaybe; + maci_gt: InputMaybe; + maci_gte: InputMaybe; + maci_in: InputMaybe>; + maci_lt: InputMaybe; + maci_lte: InputMaybe; + maci_not: InputMaybe; + maci_not_contains: InputMaybe; + maci_not_contains_nocase: InputMaybe; + maci_not_ends_with: InputMaybe; + maci_not_ends_with_nocase: InputMaybe; + maci_not_in: InputMaybe>; + maci_not_starts_with: InputMaybe; + maci_not_starts_with_nocase: InputMaybe; + maci_starts_with: InputMaybe; + maci_starts_with_nocase: InputMaybe; messages_: InputMaybe; or: InputMaybe>>; stateIndex: InputMaybe; @@ -1972,38 +1972,8 @@ export type PublicKey_Filter = { }; export enum PublicKey_OrderBy { - FundingRound = 'fundingRound', - FundingRoundContributorCount = 'fundingRound__contributorCount', - FundingRoundContributorRegistryAddress = 'fundingRound__contributorRegistryAddress', - FundingRoundCoordinator = 'fundingRound__coordinator', - FundingRoundCoordinatorPubKeyX = 'fundingRound__coordinatorPubKeyX', - FundingRoundCoordinatorPubKeyY = 'fundingRound__coordinatorPubKeyY', - FundingRoundCreatedAt = 'fundingRound__createdAt', - FundingRoundId = 'fundingRound__id', - FundingRoundIsCancelled = 'fundingRound__isCancelled', - FundingRoundIsFinalized = 'fundingRound__isFinalized', - FundingRoundLastUpdatedAt = 'fundingRound__lastUpdatedAt', - FundingRoundMaci = 'fundingRound__maci', - FundingRoundMaciTxHash = 'fundingRound__maciTxHash', - FundingRoundMatchingPoolSize = 'fundingRound__matchingPoolSize', - FundingRoundMaxMessages = 'fundingRound__maxMessages', - FundingRoundMaxVoteOptions = 'fundingRound__maxVoteOptions', - FundingRoundMessageTreeDepth = 'fundingRound__messageTreeDepth', - FundingRoundNativeToken = 'fundingRound__nativeToken', - FundingRoundPollAddress = 'fundingRound__pollAddress', - FundingRoundPollId = 'fundingRound__pollId', - FundingRoundRecipientCount = 'fundingRound__recipientCount', - FundingRoundRecipientRegistryAddress = 'fundingRound__recipientRegistryAddress', - FundingRoundSignUpDeadline = 'fundingRound__signUpDeadline', - FundingRoundStartTime = 'fundingRound__startTime', - FundingRoundStateTreeDepth = 'fundingRound__stateTreeDepth', - FundingRoundTallyHash = 'fundingRound__tallyHash', - FundingRoundTotalSpent = 'fundingRound__totalSpent', - FundingRoundTotalVotes = 'fundingRound__totalVotes', - FundingRoundVoiceCreditFactor = 'fundingRound__voiceCreditFactor', - FundingRoundVoteOptionTreeDepth = 'fundingRound__voteOptionTreeDepth', - FundingRoundVotingDeadline = 'fundingRound__votingDeadline', Id = 'id', + Maci = 'maci', Messages = 'messages', StateIndex = 'stateIndex', VoiceCreditBalance = 'voiceCreditBalance', @@ -3170,7 +3140,6 @@ export type GetContributionsAmountQueryVariables = Exact<{ export type GetContributionsAmountQuery = { __typename?: 'Query', contributions: Array<{ __typename?: 'Contribution', amount: any | null }> }; export type GetContributorIndexQueryVariables = Exact<{ - fundingRoundAddress: Scalars['String']; publicKeyId: Scalars['ID']; }>; @@ -3303,8 +3272,8 @@ export const GetContributionsAmountDocument = gql` } `; export const GetContributorIndexDocument = gql` - query GetContributorIndex($fundingRoundAddress: String!, $publicKeyId: ID!) { - publicKeys(where: {id: $publicKeyId, fundingRound: $fundingRoundAddress}) { + query GetContributorIndex($publicKeyId: ID!) { + publicKeys(where: {id: $publicKeyId}) { id stateIndex } diff --git a/vue-app/src/graphql/queries/GetContributorIndex.graphql b/vue-app/src/graphql/queries/GetContributorIndex.graphql index c3954dac6..d240e6b13 100644 --- a/vue-app/src/graphql/queries/GetContributorIndex.graphql +++ b/vue-app/src/graphql/queries/GetContributorIndex.graphql @@ -1,8 +1,7 @@ query GetContributorIndex( - $fundingRoundAddress: String! $publicKeyId: ID! ) { - publicKeys(where: {id: $publicKeyId, fundingRound: $fundingRoundAddress}) { + publicKeys(where: {id: $publicKeyId}) { id stateIndex } diff --git a/vue-app/src/stores/app.ts b/vue-app/src/stores/app.ts index d977e04b7..65b7fc494 100644 --- a/vue-app/src/stores/app.ts +++ b/vue-app/src/stores/app.ts @@ -458,7 +458,7 @@ export const useAppStore = defineStore('app', { } const contributorKeypair = Keypair.createFromSeed(userStore.currentUser.encryptionKey) - const stateIndex = await getContributorIndex(this.currentRound.fundingRoundAddress, contributorKeypair.pubKey) + const stateIndex = await getContributorIndex(this.currentRound.maciAddress, contributorKeypair.pubKey) if (!stateIndex) { // if no contributor index, user has not contributed From 07644d2d6d88436a26408f4ac0a379203421f8f9 Mon Sep 17 00:00:00 2001 From: yuetloo Date: Tue, 4 Jun 2024 09:12:33 -0400 Subject: [PATCH 49/57] generate subgraph pubKeyId using maciAddress --- vue-app/src/api/cart.ts | 5 ++--- vue-app/src/api/contributions.ts | 11 +++++------ vue-app/src/graphql/API.ts | 5 ++--- .../graphql/queries/GetContributorMessages.graphql | 2 -- 4 files changed, 9 insertions(+), 14 deletions(-) diff --git a/vue-app/src/api/cart.ts b/vue-app/src/api/cart.ts index c95993530..fd5c3ca62 100644 --- a/vue-app/src/api/cart.ts +++ b/vue-app/src/api/cart.ts @@ -17,15 +17,14 @@ export async function getCommittedCart( encryptionKey: string, contributorAddress: string, ): Promise { - const { coordinatorPubKey, fundingRoundAddress, voiceCreditFactor, nativeTokenDecimals, recipientRegistryAddress } = - round + const { coordinatorPubKey, maciAddress, voiceCreditFactor, nativeTokenDecimals, recipientRegistryAddress } = round const encKeypair = await Keypair.createFromSeed(encryptionKey) const sharedKey = Keypair.genEcdhSharedKey(encKeypair.privKey, coordinatorPubKey) const messages = await getContributorMessages({ - fundingRoundAddress, + maciAddress, contributorKey: encKeypair, coordinatorPubKey, contributorAddress, diff --git a/vue-app/src/api/contributions.ts b/vue-app/src/api/contributions.ts index d25775dd2..a6aed99ef 100644 --- a/vue-app/src/api/contributions.ts +++ b/vue-app/src/api/contributions.ts @@ -177,29 +177,28 @@ function getMaciMessage(type: any, data: any[] | null): Message { /** * Get the latest set of vote messages submitted by contributor - * @param fundingRoundAddress Funding round contract address + * @param maciAddress MACI contract address * @param contributorKey Contributor key used to encrypt messages * @param coordinatorPubKey Coordinator public key * @returns MACI messages */ export async function getContributorMessages({ - fundingRoundAddress, + maciAddress, contributorKey, coordinatorPubKey, contributorAddress, }: { - fundingRoundAddress: string + maciAddress: string contributorKey: Keypair coordinatorPubKey: PubKey contributorAddress: string }): Promise { - if (!fundingRoundAddress) { + if (!maciAddress) { return [] } - const key = getPubKeyId(fundingRoundAddress, contributorKey.pubKey) + const key = getPubKeyId(maciAddress, contributorKey.pubKey) const result = await sdk.GetContributorMessages({ - fundingRoundAddress: fundingRoundAddress.toLowerCase(), pubKey: key, contributorAddress: contributorAddress.toLowerCase(), }) diff --git a/vue-app/src/graphql/API.ts b/vue-app/src/graphql/API.ts index 121c59320..36ba4ad46 100644 --- a/vue-app/src/graphql/API.ts +++ b/vue-app/src/graphql/API.ts @@ -3147,7 +3147,6 @@ export type GetContributorIndexQueryVariables = Exact<{ export type GetContributorIndexQuery = { __typename?: 'Query', publicKeys: Array<{ __typename?: 'PublicKey', id: string, stateIndex: any | null }> }; export type GetContributorMessagesQueryVariables = Exact<{ - fundingRoundAddress: Scalars['String']; pubKey: Scalars['String']; contributorAddress: Scalars['Bytes']; }>; @@ -3280,9 +3279,9 @@ export const GetContributorIndexDocument = gql` } `; export const GetContributorMessagesDocument = gql` - query GetContributorMessages($fundingRoundAddress: String!, $pubKey: String!, $contributorAddress: Bytes!) { + query GetContributorMessages($pubKey: String!, $contributorAddress: Bytes!) { messages( - where: {fundingRound: $fundingRoundAddress, publicKey: $pubKey, submittedBy: $contributorAddress} + where: {publicKey: $pubKey, submittedBy: $contributorAddress} first: 1000 orderBy: blockNumber orderDirection: desc diff --git a/vue-app/src/graphql/queries/GetContributorMessages.graphql b/vue-app/src/graphql/queries/GetContributorMessages.graphql index d163b923b..5a3acbac4 100644 --- a/vue-app/src/graphql/queries/GetContributorMessages.graphql +++ b/vue-app/src/graphql/queries/GetContributorMessages.graphql @@ -1,11 +1,9 @@ query GetContributorMessages( - $fundingRoundAddress: String! $pubKey: String! $contributorAddress: Bytes! ) { messages( where: { - fundingRound: $fundingRoundAddress, publicKey: $pubKey, submittedBy: $contributorAddress }, From 65dc41ba450850e05b18349f8aeca288662f60f8 Mon Sep 17 00:00:00 2001 From: yuetloo Date: Tue, 4 Jun 2024 09:16:29 -0400 Subject: [PATCH 50/57] remove incorrect subgraph id calculation --- contracts/tasks/runners/maciPubkey.ts | 4 ---- 1 file changed, 4 deletions(-) diff --git a/contracts/tasks/runners/maciPubkey.ts b/contracts/tasks/runners/maciPubkey.ts index c69ff002a..dad72f66e 100644 --- a/contracts/tasks/runners/maciPubkey.ts +++ b/contracts/tasks/runners/maciPubkey.ts @@ -4,7 +4,6 @@ * * Usage: hardhat maci-pubkey --macisk */ -import { id } from 'ethers' import { task } from 'hardhat/config' import { PubKey, PrivKey, Keypair } from '@clrfund/common' @@ -26,8 +25,5 @@ task('maci-pubkey', 'Get the serialized MACI public key') } const pubKey = new PubKey([BigInt(x), BigInt(y)]) console.log(`Public Key: ${pubKey.serialize()}`) - - const subgraphId = id(x + '.' + y) - console.log(`Subgraph id: ${subgraphId}`) } }) From d535d90a27480134c42099f7d20a2ce32c5d5c1e Mon Sep 17 00:00:00 2001 From: yuetloo Date: Mon, 8 Jul 2024 13:13:15 -0400 Subject: [PATCH 51/57] redirect to projects view if no tally data --- vue-app/src/views/Leaderboard.vue | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/vue-app/src/views/Leaderboard.vue b/vue-app/src/views/Leaderboard.vue index b5c08a706..f2e306546 100644 --- a/vue-app/src/views/Leaderboard.vue +++ b/vue-app/src/views/Leaderboard.vue @@ -77,8 +77,8 @@ onMounted(async () => { const network = getRouteParamValue(route.params.network) const data = await loadLeaderboard(address, network) - // redirect to projects view if not finalized or no static round data for leaderboard - if (!data?.projects) { + // redirect to projects view if no tally data or no static round data for leaderboard + if (!data?.projects || !data?.tally) { router.push({ name: 'round' }) return } @@ -88,7 +88,7 @@ onMounted(async () => { .filter(project => project.state != 'Removed') .map(project => toLeaderboardProject(project)) .sort((p1: LeaderboardProject, p2: LeaderboardProject) => { - const diff = p2.allocatedAmount - p1.allocatedAmount + const diff = BigInt(p2.allocatedAmount || 0) - BigInt(p1.allocatedAmount || 0) if (diff === BigInt(0)) return 0 if (diff > BigInt(0)) return 1 return -1 From ecd6155e393dbe50b701a88b2e9f00ac821e1643 Mon Sep 17 00:00:00 2001 From: yuetloo Date: Mon, 8 Jul 2024 13:13:15 -0400 Subject: [PATCH 52/57] redirect to projects view if no tally data --- vue-app/src/views/Leaderboard.vue | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/vue-app/src/views/Leaderboard.vue b/vue-app/src/views/Leaderboard.vue index b5c08a706..f2e306546 100644 --- a/vue-app/src/views/Leaderboard.vue +++ b/vue-app/src/views/Leaderboard.vue @@ -77,8 +77,8 @@ onMounted(async () => { const network = getRouteParamValue(route.params.network) const data = await loadLeaderboard(address, network) - // redirect to projects view if not finalized or no static round data for leaderboard - if (!data?.projects) { + // redirect to projects view if no tally data or no static round data for leaderboard + if (!data?.projects || !data?.tally) { router.push({ name: 'round' }) return } @@ -88,7 +88,7 @@ onMounted(async () => { .filter(project => project.state != 'Removed') .map(project => toLeaderboardProject(project)) .sort((p1: LeaderboardProject, p2: LeaderboardProject) => { - const diff = p2.allocatedAmount - p1.allocatedAmount + const diff = BigInt(p2.allocatedAmount || 0) - BigInt(p1.allocatedAmount || 0) if (diff === BigInt(0)) return 0 if (diff > BigInt(0)) return 1 return -1 From b17fed6330cdd09eb3050d4b2a394a425f8f6c70 Mon Sep 17 00:00:00 2001 From: yuetloo Date: Tue, 9 Jul 2024 22:05:53 -0400 Subject: [PATCH 53/57] refactor to get data from static rounds if subgraph is not available --- vue-app/src/App.vue | 127 +++++++++++++++- vue-app/src/api/clrFund.ts | 34 +---- vue-app/src/api/contributions.ts | 41 ++++-- vue-app/src/api/core.ts | 5 +- vue-app/src/api/leaderboard.ts | 23 ++- vue-app/src/api/maci-factory.ts | 9 +- vue-app/src/api/projects.ts | 17 ++- .../src/api/recipient-registry-optimistic.ts | 37 +++-- vue-app/src/api/round.ts | 40 +++-- vue-app/src/api/rounds.ts | 12 +- vue-app/src/api/subgraph.ts | 17 --- vue-app/src/components/ActiveApp.vue | 139 ------------------ vue-app/src/components/NavBar.vue | 4 +- vue-app/src/components/ProjectListItem.vue | 25 +--- vue-app/src/components/RoundInformation.vue | 8 +- vue-app/src/components/StaticApp.vue | 66 --------- vue-app/src/graphql/sdk.ts | 7 +- vue-app/src/router/index.ts | 4 +- vue-app/src/stores/app.ts | 41 +----- vue-app/src/views/Leaderboard.vue | 4 +- vue-app/src/views/Profile.vue | 24 +-- vue-app/src/views/ProjectList.vue | 41 ++---- 22 files changed, 301 insertions(+), 424 deletions(-) delete mode 100644 vue-app/src/api/subgraph.ts delete mode 100644 vue-app/src/components/ActiveApp.vue delete mode 100644 vue-app/src/components/StaticApp.vue diff --git a/vue-app/src/App.vue b/vue-app/src/App.vue index 3c7ad9b98..01f555ac1 100644 --- a/vue-app/src/App.vue +++ b/vue-app/src/App.vue @@ -8,8 +8,20 @@ - - +
+ + +
+
+ +
@@ -20,22 +32,29 @@ diff --git a/vue-app/src/graphql/sdk.ts b/vue-app/src/graphql/sdk.ts index fc22db618..aea01c2b7 100644 --- a/vue-app/src/graphql/sdk.ts +++ b/vue-app/src/graphql/sdk.ts @@ -4,4 +4,9 @@ import { SUBGRAPH_ENDPOINT } from '@/api/core' import { getSdk } from './API' const client = new GraphQLClient(SUBGRAPH_ENDPOINT) -export default getSdk(client) + +function getQuerySdk() { + return SUBGRAPH_ENDPOINT ? getSdk(client) : {} +} + +export default getQuerySdk() diff --git a/vue-app/src/router/index.ts b/vue-app/src/router/index.ts index 86a75d5b9..e6e415a07 100644 --- a/vue-app/src/router/index.ts +++ b/vue-app/src/router/index.ts @@ -1,6 +1,6 @@ import { createRouter, createWebHashHistory } from 'vue-router' import type { RouteRecordRaw } from 'vue-router' -import { isUserRegistrationRequired, isOptimisticRecipientRegistry, isActiveApp } from '@/api/core' +import { isUserRegistrationRequired, isOptimisticRecipientRegistry } from '@/api/core' const Landing = () => import('@/views/Landing.vue') const JoinLanding = () => import('@/views/JoinLanding.vue') @@ -262,7 +262,7 @@ if (isUserRegistrationRequired) { ) } -if (isOptimisticRecipientRegistry && isActiveApp) { +if (isOptimisticRecipientRegistry) { routes.push({ path: '/recipients', name: 'recipients', diff --git a/vue-app/src/stores/app.ts b/vue-app/src/stores/app.ts index 65b7fc494..ad873972d 100644 --- a/vue-app/src/stores/app.ts +++ b/vue-app/src/stores/app.ts @@ -9,8 +9,8 @@ import { serializeCart, } from '@/api/contributions' import { getCommittedCart } from '@/api/cart' -import { operator, chain, ThemeMode, recipientRegistryType, recipientJoinDeadlineConfig, isActiveApp } from '@/api/core' -import { type RoundInfo, RoundStatus, getRoundInfo, getLeaderboardRoundInfo } from '@/api/round' +import { operator, chain, ThemeMode, recipientRegistryType, recipientJoinDeadlineConfig } from '@/api/core' +import { type RoundInfo, RoundStatus, getRoundInfo, getStaticRoundInfo } from '@/api/round' import { getTally, type Tally } from '@/api/tally' import { type ClrFund, getClrFundInfo, getMatchingFunds } from '@/api/clrFund' import { getMACIFactoryInfo, type MACIFactory } from '@/api/maci-factory' @@ -70,11 +70,6 @@ export const useAppStore = defineStore('app', { return recipientJoinDeadlineConfig } - if (!isActiveApp) { - // when running in static mode, do not allow adding recipients - return DateTime.now() - } - const recipientStore = useRecipientStore() if (!state.currentRound || !recipientStore.recipientRegistryInfo) { return null @@ -470,38 +465,6 @@ export const useAppStore = defineStore('app', { stateIndex, } }, - async loadStaticClrFundInfo() { - const rounds = await getRounds() - // rounds are sorted in reverse order, first one is the newest round - const currentRound = rounds[0] - - let maxRecipients = 0 - if (currentRound) { - const network = currentRound.network || '' - const currentRoundInfo = await getLeaderboardRoundInfo(currentRound.address, network) - if (currentRoundInfo) { - const matchingPool = await getMatchingFunds(currentRoundInfo.nativeTokenAddress) - this.clrFund = { - nativeTokenAddress: currentRoundInfo.nativeTokenAddress, - nativeTokenSymbol: currentRoundInfo.nativeTokenSymbol, - nativeTokenDecimals: currentRoundInfo.nativeTokenDecimals, - userRegistryAddress: currentRoundInfo.userRegistryAddress, - recipientRegistryAddress: currentRoundInfo.recipientRegistryAddress, - matchingPool, - } - this.selectRound(currentRound.address) - this.currentRound = currentRoundInfo - if (currentRoundInfo.tally) { - this.tally = currentRoundInfo.tally - } - maxRecipients = currentRoundInfo.maxRecipients - } - } - if (!this.clrFund) { - this.clrFund = await getClrFundInfo() - } - await this.loadMACIFactoryInfo(maxRecipients) - }, async loadClrFundInfo() { const clrFund = await getClrFundInfo() this.clrFund = clrFund diff --git a/vue-app/src/views/Leaderboard.vue b/vue-app/src/views/Leaderboard.vue index f2e306546..03db7c637 100644 --- a/vue-app/src/views/Leaderboard.vue +++ b/vue-app/src/views/Leaderboard.vue @@ -79,7 +79,7 @@ onMounted(async () => { // redirect to projects view if no tally data or no static round data for leaderboard if (!data?.projects || !data?.tally) { - router.push({ name: 'round' }) + router.push({ name: 'round', params: { address } }) return } @@ -98,7 +98,7 @@ onMounted(async () => { } try { - round.value = toRoundInfo(data.round, network) + round.value = toRoundInfo(data.round) } catch (e) { console.log('Error converting to round info', e) } diff --git a/vue-app/src/views/Profile.vue b/vue-app/src/views/Profile.vue index b4c6612e9..71a74ee7e 100644 --- a/vue-app/src/views/Profile.vue +++ b/vue-app/src/views/Profile.vue @@ -103,19 +103,18 @@ import CopyButton from '@/components/CopyButton.vue' import Loader from '@/components/Loader.vue' import FundsNeededWarning from '@/components/FundsNeededWarning.vue' -import { userRegistryType, UserRegistryType, chain, isActiveApp } from '@/api/core' +import { userRegistryType, UserRegistryType, chain } from '@/api/core' import { type Project, getProjects, getProjectsForStaticRound } from '@/api/projects' import { isSameAddress } from '@/utils/accounts' import { getTokenLogo } from '@/utils/tokens' import { useAppStore, useUserStore, useRecipientStore, useWalletStore } from '@/stores' import { storeToRefs } from 'pinia' import { useRouter } from 'vue-router' -import { getLeaderboardData } from '@/api/leaderboard' import { formatAmount } from '@/utils/amounts' import WithdrawalModal from '@/components/WithdrawalModal.vue' import { useModal } from 'vue-final-modal' -import { RoundStatus } from '@/api/round' +import { RoundStatus, getRoundInfo } from '@/api/round' interface Props { balance: string @@ -179,19 +178,24 @@ watch(recipientRegistryAddress, () => loadProjects()) async function loadProjects(): Promise { isLoading.value = true - let _projects: Project[] = [] + let _projects: Project[] | undefined = undefined - if (isActiveApp) { - if (!recipientRegistryAddress.value) return + if (!recipientRegistryAddress.value) return + + const currentRoundAddress = currentRound.value?.fundingRoundAddress + if (currentRoundAddress) { + const round = await getRoundInfo(currentRoundAddress, currentRound.value) + if (round?.projects) { + _projects = round.projects + } + } + + if (!_projects) { _projects = await getProjects( recipientRegistryAddress.value, currentRound.value?.startTime.toSeconds(), currentRound.value?.votingDeadline.toSeconds(), ) - } else { - const currentRoundAddress = currentRound.value?.fundingRoundAddress || '' - const network = currentRound.value?.network || '' - _projects = await getProjectsForStaticRound(currentRoundAddress, network) } const userProjects: Project[] = _projects.filter( diff --git a/vue-app/src/views/ProjectList.vue b/vue-app/src/views/ProjectList.vue index 8bc21b7c5..83fa0450a 100644 --- a/vue-app/src/views/ProjectList.vue +++ b/vue-app/src/views/ProjectList.vue @@ -60,7 +60,7 @@ import { ref, computed, onMounted } from 'vue' import { getCurrentRound, getRoundInfo } from '@/api/round' -import { type Project, getProjects, getRecipientRegistryAddress, getProjectsForStaticRound } from '@/api/projects' +import { type Project, getProjects, getRecipientRegistryAddress } from '@/api/projects' import CallToActionCard from '@/components/CallToActionCard.vue' import ProjectListItem from '@/components/ProjectListItem.vue' @@ -70,7 +70,6 @@ import { useRoute } from 'vue-router' import { useAppStore, useUserStore } from '@/stores' import { storeToRefs } from 'pinia' import { DateTime } from 'luxon' -import { isActiveApp } from '@/api/core' import { getSecondsFromNow } from '@/utils/dates' type ProjectRoundInfo = { @@ -124,10 +123,7 @@ onMounted(async () => { roundAddress.value = (route.params.address as string) || currentRoundAddress.value || (await getCurrentRound()) || '' - const round = isActiveApp - ? await loadProjectRoundInfo(roundAddress.value) - : await loadStaticRoundInfo(roundAddress.value) - await loadProjects(round) + await loadProjectRoundInfo(roundAddress.value) } catch (err) { /* eslint-disable-next-line no-console */ console.error('Error loading projects', err) @@ -135,11 +131,13 @@ onMounted(async () => { isLoading.value = false }) -async function loadProjectRoundInfo(roundAddress: string): Promise { +async function loadProjectRoundInfo(roundAddress: string) { // defaults when a round has not been created yet let recipientRegistryAddress = '' let startTime = 0 let votingDeadline = DateTime.local().toSeconds() + let network = '' + let roundProjects: Project[] | undefined = undefined if (roundAddress) { const round = await getRoundInfo(roundAddress, currentRound.value) @@ -147,6 +145,10 @@ async function loadProjectRoundInfo(roundAddress: string): Promise { - await appStore.loadClrFundInfo() - const network = currentRound.value?.network || '' - const recipientRegistryAddress = currentRound.value?.recipientRegistryAddress || '' - const startTime = getSecondsFromNow(currentRound.value?.startTime || DateTime.now()) - const votingDeadline = getSecondsFromNow(currentRound.value?.votingDeadline || DateTime.now()) - return { recipientRegistryAddress, startTime, votingDeadline, fundingRoundAddress: roundAddress, network } -} + if (!roundProjects) { + roundProjects = await getProjects(recipientRegistryAddress, startTime, votingDeadline) + } -async function loadProjects(round: ProjectRoundInfo) { - const _projects = isActiveApp - ? await getProjects(round.recipientRegistryAddress, round.startTime, round.votingDeadline) - : await getProjectsForStaticRound(roundAddress.value, round.network) - const visibleProjects = _projects.filter(project => { + const visibleProjects = roundProjects.filter(project => { return !project.isHidden && !project.isLocked }) shuffleArray(visibleProjects) From b4416e099c4ca71bffb125cdd4627c4b7d1b0145 Mon Sep 17 00:00:00 2001 From: yuetloo Date: Wed, 10 Jul 2024 11:45:25 -0400 Subject: [PATCH 54/57] remove obsolete functions --- vue-app/src/views/RecipientRegistry.vue | 4 ---- 1 file changed, 4 deletions(-) diff --git a/vue-app/src/views/RecipientRegistry.vue b/vue-app/src/views/RecipientRegistry.vue index 15c1ed302..3c3cc24c3 100644 --- a/vue-app/src/views/RecipientRegistry.vue +++ b/vue-app/src/views/RecipientRegistry.vue @@ -183,10 +183,6 @@ function isAccepted(request: Request): boolean { return request.status === RequestStatus.Accepted } -function isRejected(request: Request): boolean { - return request.status === RequestStatus.Rejected -} - function isExecuted(request: Request): boolean { return request.status === RequestStatus.Executed } From b627ae2a14f5ecca2e1827426c80e1836f8a218a Mon Sep 17 00:00:00 2001 From: yuetloo Date: Wed, 10 Jul 2024 13:45:31 -0400 Subject: [PATCH 55/57] use wrapper to handle subgraph error in graphql sdk --- vue-app/src/api/clrFund.ts | 27 +++++++++++++++++++++------ vue-app/src/graphql/sdk.ts | 11 +++++++---- 2 files changed, 28 insertions(+), 10 deletions(-) diff --git a/vue-app/src/api/clrFund.ts b/vue-app/src/api/clrFund.ts index 375cd71bb..558bee3c7 100644 --- a/vue-app/src/api/clrFund.ts +++ b/vue-app/src/api/clrFund.ts @@ -20,12 +20,27 @@ export async function getClrFundInfo() { let userRegistryAddress = '' let recipientRegistryAddress = '' - nativeTokenAddress = await clrFundContract.nativeToken().catch(() => '') - const nativeTokenContract = new Contract(nativeTokenAddress, ERC20, provider) - nativeTokenSymbol = await nativeTokenContract.symbol().catch(() => '') - nativeTokenDecimals = await nativeTokenContract.decimals().catch(() => 0) - userRegistryAddress = await clrFundContract.userRegistry().catch(() => '') - recipientRegistryAddress = await clrFundContract.recipientRegistry().catch(() => '') + try { + const data = await sdk.GetClrFundInfo({ + clrFundAddress: clrfundContractAddress.toLowerCase(), + }) + const nativeTokenInfo = data.clrFund?.nativeTokenInfo + if (nativeTokenInfo) { + nativeTokenAddress = nativeTokenInfo.tokenAddress || '' + nativeTokenSymbol = nativeTokenInfo.symbol || '' + nativeTokenDecimals = Number(nativeTokenInfo.decimals) || 0 + } + + userRegistryAddress = data.clrFund?.contributorRegistryAddress || '' + recipientRegistryAddress = data.clrFund?.recipientRegistryAddress || '' + } catch (err) { + nativeTokenAddress = await clrFundContract.nativeToken().catch(() => '') + const nativeTokenContract = new Contract(nativeTokenAddress, ERC20, provider) + nativeTokenSymbol = await nativeTokenContract.symbol().catch(() => '') + nativeTokenDecimals = await nativeTokenContract.decimals().catch(() => nativeTokenDecimals) + userRegistryAddress = await clrFundContract.userRegistry().catch(() => '') + recipientRegistryAddress = await clrFundContract.recipientRegistry().catch(() => '') + } try { matchingPool = await getMatchingFunds(nativeTokenAddress) diff --git a/vue-app/src/graphql/sdk.ts b/vue-app/src/graphql/sdk.ts index aea01c2b7..dcd511bdb 100644 --- a/vue-app/src/graphql/sdk.ts +++ b/vue-app/src/graphql/sdk.ts @@ -1,12 +1,15 @@ import { GraphQLClient } from 'graphql-request' import { SUBGRAPH_ENDPOINT } from '@/api/core' -import { getSdk } from './API' +import { getSdk, type SdkFunctionWrapper } from './API' const client = new GraphQLClient(SUBGRAPH_ENDPOINT) -function getQuerySdk() { - return SUBGRAPH_ENDPOINT ? getSdk(client) : {} +const wrapper: SdkFunctionWrapper = (action, _operationName, _operationType) => { + if (!SUBGRAPH_ENDPOINT) { + throw new Error('Subgraph not available') + } + return action() } -export default getQuerySdk() +export default getSdk(client, wrapper) From 0ddf2804c68100459f69f9af00e65cc9d3a3ba20 Mon Sep 17 00:00:00 2001 From: yuetloo Date: Wed, 10 Jul 2024 16:37:39 -0400 Subject: [PATCH 56/57] get recipient data statically if subgraph is not available --- .../src/api/recipient-registry-optimistic.ts | 48 ++++++++++++++++++- ...F08B7DD31fE0267e8c70C4bF8C4BfbBddE760.json | 2 +- 2 files changed, 47 insertions(+), 3 deletions(-) diff --git a/vue-app/src/api/recipient-registry-optimistic.ts b/vue-app/src/api/recipient-registry-optimistic.ts index 478761432..d09f1dafb 100644 --- a/vue-app/src/api/recipient-registry-optimistic.ts +++ b/vue-app/src/api/recipient-registry-optimistic.ts @@ -1,7 +1,7 @@ import { Contract, toNumber, isHexString, ContractTransactionResponse } from 'ethers' import type { TransactionResponse, Signer } from 'ethers' import { DateTime } from 'luxon' -import { chain } from '@/api/core' +import { chain, clrFundContract } from '@/api/core' import { OptimisticRecipientRegistry } from './abi' import { provider, ipfsGatewayUrl } from './core' @@ -11,6 +11,8 @@ import type { GetProjectQuery, GetRecipientsQuery, Recipient } from '@/graphql/A import { hasDateElapsed } from '@/utils/dates' import type { RegistryInfo, RecipientApplicationData } from './types' import { formToRecipientData } from './recipient' +import { isSameAddress } from '@/utils/accounts' +import { getLeaderboardData } from './leaderboard' async function getRegistryInfo(registryAddress: string): Promise { const registry = new Contract(registryAddress, OptimisticRecipientRegistry, provider) @@ -129,6 +131,48 @@ function mapRequestStatus(request: RecipientRequestData): RequestStatus { return status } +/** + * Try to get the recipients from the static round data + * @param registryAddress The recipient registry address + * @returns The recipient application requests + */ +async function tryGetRecipientsStatically(registryAddress: string): Promise { + let requests: Request[] = [] + + try { + const fundingRoundAddress = await clrFundContract.getCurrentRound() + const fundingRoundInfo = await getLeaderboardData(fundingRoundAddress) + if (isSameAddress(fundingRoundInfo?.round?.recipientRegistryAddress, registryAddress)) { + if (fundingRoundInfo?.projects) { + requests = fundingRoundInfo.projects.map(project => { + let metadata = project.metadata + try { + if (typeof metadata === 'string') { + metadata = JSON.parse(project.metadata || '{}') + } + } catch (e) { + metadata = { name: project.name } + } + return { + transactionHash: '', // transaction hash not available in the static data + type: RequestType.Registration, + status: project.state as RequestStatus, + acceptanceDate: DateTime.fromISO(project.createdAt), + recipientId: project.id, + recipient: project.recipientAddress, + metadata, + requester: project.requester, + } + }) + } + } + } catch { + requests = [] + } + + return requests +} + export async function getRequests(registryInfo: RegistryInfo, registryAddress: string): Promise { let data: GetRecipientsQuery try { @@ -136,7 +180,7 @@ export async function getRequests(registryInfo: RegistryInfo, registryAddress: s registryAddress: registryAddress.toLowerCase(), }) } catch { - return [] + return tryGetRecipientsStatically(registryAddress) } if (!data.recipients.length) { diff --git a/vue-app/src/rounds/arbitrum/0x806F08B7DD31fE0267e8c70C4bF8C4BfbBddE760.json b/vue-app/src/rounds/arbitrum/0x806F08B7DD31fE0267e8c70C4bF8C4BfbBddE760.json index 662adbfd6..341a7a713 100644 --- a/vue-app/src/rounds/arbitrum/0x806F08B7DD31fE0267e8c70C4bF8C4BfbBddE760.json +++ b/vue-app/src/rounds/arbitrum/0x806F08B7DD31fE0267e8c70C4bF8C4BfbBddE760.json @@ -2372,7 +2372,7 @@ "state": "Removed", "recipientAddress": "0x361f732EbA09Fb99fd38B650E90a4AC6D9cc63c3", "requester": "0x7246E313daDAF4083dF2d8132801f1bFCad53aeB", - "name": "?", + "name": "Protobox.xyz", "metadata": "{\"name\":\"Protobox.xyz\" \"tagline\":\"Unlock the Power of Decentralized Storage: Seamlessly Connect. Be Unstoppable.\n\" \"description\":\"Protobox is a suite of tools that enables organizations utilizing centralized object storage such as Amazon S3 or its many variants to easily migrate to decentralized storage options such as Ethereum Swarm. Protobox enables users to connect via the S3 compatible storage connector that is standard in most applications. Protobox also provides simple management and payment of storage pools that is simple to use even for non Web3 natives. \" \"category\":\"Tooling\" \"problemSpace\":\"Current decentralized storage protocols are not user friendly to non Web3 natives and are not plug and play with existing storage connectors. \n\nObject storage alone is a $4.83 billion dollar market with a compound annual growth of 13.6%. All of which currently resides with a handful of companies in centralized locations. Additionally data stored by these providers can be removed at will if it no longer is expedient for the provider to carry it. Censorship can and is carried out as a common function not by the push of a button but by an algorithm that is often a black box. \n\n\nFinally the monopoly created by these three companies allows them to charge exorbitant prices for their services despite offering little to now innovation year over year. \n\nIf decentralized storage protocols can tap into this market it would not only provide a superior product to users at a fraction of the cost but also demonstrate a very clear use case for an industry that has taken more than a couple black eyes over the past two years. \n\nRecent talk at Ethereum Swarm Summit: https://summit.ethswarm.org/swarm-summit-2023/talk/DUAQZ7/\" \"plans\":\"1) Complete our S3 API implementation to enable all standard functionality specifically for private buckets. \n2) Launch additional infrastructure (Swarm bee nodes Gnosis mainnet validators edge caching nodes) to enable the network to handle the most complex work loads such as high definition video recording and playback on a global scale. \n\n3) Create a comprehensive web dashboard for users to manage purchase and manipulate their storage from a familiar GUI/UX. \n4) Enable fiat onramp and wallet-less payments to enable non-Web3 users to utilize all functionality without any interaction with new technology such as tokens or 0x wallets.\n5) Create a data migration tool to enable current centralized storage users to easily copy data to the desired decentralized option for migration or use in parallel.\n6) Public outreach - present the project at relevant conferences hold hackathons and workshops onboard large public good datasets free of charge - forever.\n7) Continue to work to ensure product meets requirements set forth by community projects building integrations such as Livepeer and others.\" \"teamName\":\"\" \"teamDescription\":\"Samuel Lauridsen\nThe firm’s founder draws upon over 15 years of prior experience designing deploying and managing mission-critical infrastructure for Silicon Valley’s leading tech companies including Apple Intel Facebook Equinix and Tesla. In addition to his work in Northern California he has 6+ years of experience working at one of the largest media conglomerates in the world including one of the “big five” motion picture studios. Currently based in Los Angeles this connection to the art world brings unique opportunities for collaboration to the project team.\n\n\nHannah Lauridsen\nHannah is a co-founder of Huntington Analytics. Her experience spans several industries and includes eight years as a small business owner; 10+ years of visual design/multimedia freelance; and three years in education. Core components of these roles have combined in Hannah’s current data visualization position. She is passionate about projects and tools that empower others to obtain equitable access to information and opportunities.\n\nIoseb Khutsishvili\nIoseb is a co-founder of MaxinAI. He has 20+ years of experience in developing core back-end applications and managing teams of 150+ software engineers. MaxinAI has piloted its transition to blockchain under Ioseb’s technical leadership. \n\nDavid Khosroshvili\nDavid is a serial entrepreneur Forbes Georgia 30/30 award winner and decentralization evangelist. He has built multiple technology companies during the last 10 years that currently employ over 120 talents in the blockchain and data science industries. David is a CEO and a founding member of MaxinAI.\n\" \"githubUrl\":\"https://github.com/Protobox-xyz\" \"radicleUrl\":\"\" \"websiteUrl\":\"https://www.protobox.xyz\" \"twitterUrl\":\"https://twitter.com/protobox_xyz\" \"discordUrl\":\"https://discord.gg/4wyqeypmm\" \"bannerImageHash\":\"QmXkEJ7WBmWk78qmj1nYqPSnNfXxCNbs7p3umwJwNEdJe6\" \"thumbnailImageHash\":\"QmPzuETqY9v9BQNTESqePYq15E7XYA676uMegYRrthEcSz\"}", "createdAt": "2023-07-12T03:52:00.000Z", "removedAt": "2023-07-12T15:29:08.000Z", From 6d0ae77d3c2b11bbabc2c05f447576164c9eedc1 Mon Sep 17 00:00:00 2001 From: yuetloo Date: Wed, 10 Jul 2024 19:31:32 -0400 Subject: [PATCH 57/57] refactor static round recipient finding logic --- vue-app/src/api/leaderboard.ts | 31 ----------- vue-app/src/api/projects.ts | 22 ++------ .../src/api/recipient-registry-optimistic.ts | 54 +++++++++++++++++-- vue-app/src/api/round.ts | 40 +++++++++++++- vue-app/src/views/Leaderboard.vue | 5 +- vue-app/src/views/Profile.vue | 2 +- vue-app/src/views/RecipientProfile.vue | 6 +-- 7 files changed, 96 insertions(+), 64 deletions(-) delete mode 100644 vue-app/src/api/leaderboard.ts diff --git a/vue-app/src/api/leaderboard.ts b/vue-app/src/api/leaderboard.ts deleted file mode 100644 index 1678029dd..000000000 --- a/vue-app/src/api/leaderboard.ts +++ /dev/null @@ -1,31 +0,0 @@ -import leaderboardRounds from '@/rounds/rounds.json' -import { isSameAddress } from '@/utils/accounts' - -type LeaderboardRecord = { - address: string - network: string -} - -function isSameNetwork(network1 = '', network2 = ''): boolean { - return network1.toLowerCase() === network2.toLowerCase() -} - -export async function getLeaderboardData(roundAddress: string, network?: string) { - const rounds = leaderboardRounds as LeaderboardRecord[] - const checkNetwork = Boolean(network) - - const found = rounds.find((r: LeaderboardRecord) => { - return isSameAddress(r.address, roundAddress) && (!checkNetwork || isSameNetwork(network, r.network)) - }) - - if (!found) { - return null - } - - const data = await import(`../rounds/${found.network}/${found.address}.json`) - if (!data.round) { - data.round = {} - } - data.round.network = found.network - return data -} diff --git a/vue-app/src/api/projects.ts b/vue-app/src/api/projects.ts index db3144d21..22b4a3089 100644 --- a/vue-app/src/api/projects.ts +++ b/vue-app/src/api/projects.ts @@ -7,7 +7,7 @@ import SimpleRegistry from './recipient-registry-simple' import OptimisticRegistry from './recipient-registry-optimistic' import KlerosRegistry from './recipient-registry-kleros' import sdk from '@/graphql/sdk' -import { getLeaderboardData } from '@/api/leaderboard' +import { findStaticRound } from '@/api/round' import type { RecipientApplicationData } from '@/api/types' import type { GetRecipientByIndexQuery } from '@/graphql/API' @@ -205,7 +205,7 @@ export async function getLeaderboardProject( projectId: string, network: string, ): Promise { - const data = await getLeaderboardData(roundAddress, network) + const data = await findStaticRound(roundAddress, network) if (!data) { return null } @@ -277,7 +277,7 @@ export function staticDataToProjectInterface(project: any): Project { return { id: project.id, address: project.recipientAddress, - name: project.metadata.name, + name: project.metadata.name || project.name, tagline: project.metadata.tagline, description: project.metadata.description, category: project.metadata.category, @@ -298,19 +298,3 @@ export function staticDataToProjectInterface(project: any): Project { isLocked: false, } } - -/** - * Get the list of projects for a static round - * @param roundAddress The funding round contract address - * @param network The network - * @returns Array of projects - */ -export async function getProjectsForStaticRound(roundAddress: string, network: string): Promise { - const data = await getLeaderboardData(roundAddress, network) - if (!data) { - return [] - } - - const projects = data.projects.map(staticDataToProjectInterface) - return projects -} diff --git a/vue-app/src/api/recipient-registry-optimistic.ts b/vue-app/src/api/recipient-registry-optimistic.ts index d09f1dafb..9963d9f77 100644 --- a/vue-app/src/api/recipient-registry-optimistic.ts +++ b/vue-app/src/api/recipient-registry-optimistic.ts @@ -5,14 +5,14 @@ import { chain, clrFundContract } from '@/api/core' import { OptimisticRecipientRegistry } from './abi' import { provider, ipfsGatewayUrl } from './core' -import type { Project } from './projects' +import { staticDataToProjectInterface, type Project } from './projects' import sdk from '@/graphql/sdk' import type { GetProjectQuery, GetRecipientsQuery, Recipient } from '@/graphql/API' import { hasDateElapsed } from '@/utils/dates' import type { RegistryInfo, RecipientApplicationData } from './types' import { formToRecipientData } from './recipient' import { isSameAddress } from '@/utils/accounts' -import { getLeaderboardData } from './leaderboard' +import { findStaticRound } from './round' async function getRegistryInfo(registryAddress: string): Promise { const registry = new Contract(registryAddress, OptimisticRecipientRegistry, provider) @@ -131,6 +131,22 @@ function mapRequestStatus(request: RecipientRequestData): RequestStatus { return status } +/** + * Map the recipient state from static round data to request status + * @param state Recipient state: Active, Rejected, Removed + * @returns Request status + */ +function staticStateToRequestStatus(state: string): RequestStatus { + switch (state) { + case 'Accepted': + return RequestStatus.Executed + case 'Rejected': + return RequestStatus.Rejected + default: + return RequestStatus.Removed + } +} + /** * Try to get the recipients from the static round data * @param registryAddress The recipient registry address @@ -141,7 +157,7 @@ async function tryGetRecipientsStatically(registryAddress: string): Promise { @@ -156,7 +172,7 @@ async function tryGetRecipientsStatically(registryAddress: string): Promise { + let project: Project | null = null + try { + const fundingRoundAddress = await clrFundContract.getCurrentRound() + const network = chain.label.toLowerCase() + const round = await findStaticRound(fundingRoundAddress, network) + if (round?.projects) { + const staticProject = round.projects.find(project => project.id === projectId) + if (staticProject) { + project = staticDataToProjectInterface(staticProject) + if (filter && project.isHidden) { + project = null + } + } + } + } catch { + // return not found on error + return null + } + + return project +} + /** * Get project information * @@ -388,7 +432,7 @@ export async function getProject(recipientId: string, filter = true): Promise { + return isSameAddress(r.address, roundAddress) && (!checkNetwork || isSameNetwork(network, r.network)) + }) + + if (!found) { + return null + } + + const data = await import(`../rounds/${found.network}/${found.address}.json`) + if (!data.round) { + data.round = {} + } + data.round.network = found.network + return data +} + //TODO: update to take ClrFund address as a parameter, default to env. variable export async function getCurrentRound(): Promise { const fundingRoundAddress = await clrFundContract.getCurrentRound() @@ -116,7 +152,7 @@ export function toRoundInfo(data: any): RoundInfo { } export async function getStaticRoundInfo(fundingRoundAddress: string, network?: string): Promise { - const data = await getLeaderboardData(fundingRoundAddress, network) + const data = await findStaticRound(fundingRoundAddress, network) if (!data) { return null } diff --git a/vue-app/src/views/Leaderboard.vue b/vue-app/src/views/Leaderboard.vue index 03db7c637..c7d338ffb 100644 --- a/vue-app/src/views/Leaderboard.vue +++ b/vue-app/src/views/Leaderboard.vue @@ -46,10 +46,9 @@ import { useAppStore } from '@/stores' import { useRouter, useRoute } from 'vue-router' import type { RoundInfo } from '@/api/round' -import { toRoundInfo } from '@/api/round' +import { toRoundInfo, findStaticRound } from '@/api/round' import type { LeaderboardProject } from '@/api/projects' import { toLeaderboardProject } from '@/api/projects' -import { getLeaderboardData } from '@/api/leaderboard' import { getRouteParamValue } from '@/utils/route' const router = useRouter() @@ -63,7 +62,7 @@ const appStore = useAppStore() const { showSimpleLeaderboard } = storeToRefs(appStore) async function loadLeaderboard(address: string, network: string) { - const data = await getLeaderboardData(address, network) + const data = await findStaticRound(address, network) return data } diff --git a/vue-app/src/views/Profile.vue b/vue-app/src/views/Profile.vue index 71a74ee7e..b004e544d 100644 --- a/vue-app/src/views/Profile.vue +++ b/vue-app/src/views/Profile.vue @@ -104,7 +104,7 @@ import Loader from '@/components/Loader.vue' import FundsNeededWarning from '@/components/FundsNeededWarning.vue' import { userRegistryType, UserRegistryType, chain } from '@/api/core' -import { type Project, getProjects, getProjectsForStaticRound } from '@/api/projects' +import { type Project, getProjects } from '@/api/projects' import { isSameAddress } from '@/utils/accounts' import { getTokenLogo } from '@/utils/tokens' import { useAppStore, useUserStore, useRecipientStore, useWalletStore } from '@/stores' diff --git a/vue-app/src/views/RecipientProfile.vue b/vue-app/src/views/RecipientProfile.vue index cb2c548eb..3b0245067 100644 --- a/vue-app/src/views/RecipientProfile.vue +++ b/vue-app/src/views/RecipientProfile.vue @@ -22,15 +22,15 @@

{{ $t('projectProfile.h2_1') }}

- +

{{ $t('projectProfile.h2_2') }}

- +

{{ $t('projectProfile.h2_3') }}

- +