From 9b8dc2d41fee60397ee4a8c1b8f252bb6ce112f7 Mon Sep 17 00:00:00 2001 From: yuetloo Date: Tue, 23 Jan 2024 00:38:35 -0500 Subject: [PATCH] subgraph handling of recipient registry change events --- contracts/tasks/index.ts | 1 + contracts/tasks/setRecipientRegistry.ts | 132 +++++------------- subgraph/abis/ClrFund.json | 137 +++++++++++++++---- subgraph/config/arbitrum-sepolia.json | 6 +- subgraph/generated/ClrFund/ClrFund.ts | 170 ++++++++++++++++++++++-- subgraph/generated/schema.ts | 68 ---------- subgraph/schema.graphql | 4 - subgraph/src/ClrFundMapping.ts | 18 +++ subgraph/subgraph.template.yaml | 4 + subgraph/subgraph.yaml | 4 + 10 files changed, 336 insertions(+), 208 deletions(-) diff --git a/contracts/tasks/index.ts b/contracts/tasks/index.ts index 8180a9282..a254693b0 100644 --- a/contracts/tasks/index.ts +++ b/contracts/tasks/index.ts @@ -7,3 +7,4 @@ import './verifyUserRegistry' import './pubkey' import './loadUsers' import './exportRound' +import './setRecipientRegistry' diff --git a/contracts/tasks/setRecipientRegistry.ts b/contracts/tasks/setRecipientRegistry.ts index e92553933..4cd3d7331 100644 --- a/contracts/tasks/setRecipientRegistry.ts +++ b/contracts/tasks/setRecipientRegistry.ts @@ -3,111 +3,26 @@ * * Sample usage: * - * yarn hardhat set-recipient-registry --network \ - * --clrfund \ - * [--type ] \ - * [--registry ] \ - * [--context ] \ - * [--verifier ] \ - * [--sponsor ] + * yarn hardhat set-recipient-registry --clrfund --type optimistic --network * - * Valid user registry types are simple, brightid, merkle, storage - * - * Verifier is the brightid node verifier address. - * Clrfund's brightId node is in the ethSigningAddress field from https://brightid.clr.fund + * Valid recipient registry types are simple, brightid, merkle, storage * */ import { task } from 'hardhat/config' -import { BigNumber, Contract, utils } from 'ethers' -import { HardhatEthersHelpers } from '@nomiclabs/hardhat-ethers/types' +import { parseUnits } from 'ethers' import { deployRecipientRegistry, challengePeriodSeconds, } from '../utils/deployment' -async function getDepositInUnits( - clrfundContract: Contract, - ethers: HardhatEthersHelpers, - deposit: string -): Promise { - let depositInUnits = BigNumber.from(0) - try { - const token = await clrfundContract.nativeToken() - const tokenContract = await ethers.getContractAt('ERC20', token) - const decimals = await tokenContract.decimals() - depositInUnits = utils.parseUnits(deposit, decimals) - } catch (e) { - console.log('Error formatting deposit amount ' + (e as Error).message) - console.log('Set deposit to 0') - } - - return depositInUnits -} - -/** - * Set the token address in the ClrFund contract - * - * @param clrfundContract ClrFund contract - * @param registryType The user registry type, e.g brightid, simple, merkle, snapshot - * @param registryAddress The user registry address to set in ClrFund - * @param ethers the hardhat ethers handle - */ -async function setRecipientRegistry({ - clrfundContract, - registryType, - registryAddress, - deposit, - challengePeriod, - ethers, -}: { - clrfundContract: Contract - registryType?: string - registryAddress?: string - deposit: string - challengePeriod: string - ethers: HardhatEthersHelpers -}) { - let recipientRegistryAddress = registryAddress - if (!recipientRegistryAddress) { - const recipientRegistryType = registryType || '' - const [signer] = await ethers.getSigners() - console.log(`Deploying recipient registry by: ${signer.address}`) - - const controller = clrfundContract.address - const depositInUnits = await getDepositInUnits( - clrfundContract, - ethers, - deposit - ) - const registry = await deployRecipientRegistry({ - type: recipientRegistryType, - controller, - deposit: depositInUnits, - challengePeriod, - ethers, - }) - recipientRegistryAddress = registry.address - } - - const tx = await clrfundContract.setRecipientRegistry( - recipientRegistryAddress - ) - await tx.wait() - - console.log( - `Recipient registry (${registryType}): ${recipientRegistryAddress}` - ) - console.log(`Recipient registry set at tx: ${tx.hash}`) -} - task('set-recipient-registry', 'Set the recipient registry in ClrFund') .addParam('clrfund', 'The ClrFund contract address') .addOptionalParam( 'type', 'The recipient registry type, e.g simple, optimistic' ) - .addOptionalParam('registry', 'The user registry contract address') + .addOptionalParam('registry', 'The recipient registry to set to') .addOptionalParam( 'deposit', 'The base deposit for the optimistic registry', @@ -125,13 +40,36 @@ task('set-recipient-registry', 'Set the recipient registry in ClrFund') ) => { const clrfundContract = await ethers.getContractAt('ClrFund', clrfund) - await setRecipientRegistry({ - clrfundContract: clrfundContract, - registryType: type, - registryAddress: registry, - deposit, - challengePeriod, - ethers, - }) + const recipientRegistryType = type || '' + let recipientRegistryAddress = registry + if (!recipientRegistryAddress) { + const [signer] = await ethers.getSigners() + console.log(`Deploying recipient registry by: ${signer.address}`) + + const token = await clrfundContract.nativeToken() + const tokenContract = await ethers.getContractAt('ERC20', token) + const decimals = await tokenContract.decimals() + const depositInUnits = parseUnits(deposit, decimals) + + const controller = await clrfundContract.getAddress() + const registry = await deployRecipientRegistry({ + type: recipientRegistryType, + controller, + deposit: depositInUnits, + challengePeriod, + ethers, + }) + recipientRegistryAddress = await registry.getAddress() + } + + const tx = await clrfundContract.setRecipientRegistry( + recipientRegistryAddress + ) + await tx.wait() + + console.log( + `Recipient registry (${recipientRegistryType}): ${recipientRegistryAddress}` + ) + console.log(`Recipient registry set at tx: ${tx.hash}`) } ) diff --git a/subgraph/abis/ClrFund.json b/subgraph/abis/ClrFund.json index a9b7eb499..a87993fb7 100644 --- a/subgraph/abis/ClrFund.json +++ b/subgraph/abis/ClrFund.json @@ -24,11 +24,6 @@ "name": "InvalidMaciFactory", "type": "error" }, - { - "inputs": [], - "name": "NoCoordinator", - "type": "error" - }, { "inputs": [], "name": "NoCurrentRound", @@ -36,32 +31,27 @@ }, { "inputs": [], - "name": "NoRecipientRegistry", - "type": "error" - }, - { - "inputs": [], - "name": "NoToken", + "name": "NotAuthorized", "type": "error" }, { "inputs": [], - "name": "NoUserRegistry", + "name": "NotFinalized", "type": "error" }, { "inputs": [], - "name": "NotAuthorized", + "name": "NotInitialized", "type": "error" }, { "inputs": [], - "name": "NotFinalized", + "name": "NotOwnerOfMaciFactory", "type": "error" }, { "inputs": [], - "name": "NotOwnerOfMaciFactory", + "name": "RecipientRegistryNotSet", "type": "error" }, { @@ -79,7 +69,27 @@ }, { "anonymous": false, - "inputs": [], + "inputs": [ + { + "indexed": false, + "internalType": "address", + "name": "_roundFactory", + "type": "address" + } + ], + "name": "FundingRoundFactoryChanged", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "address", + "name": "_template", + "type": "address" + } + ], "name": "FundingRoundTemplateChanged", "type": "event" }, @@ -115,6 +125,19 @@ "name": "Initialized", "type": "event" }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "address", + "name": "_maciFactory", + "type": "address" + } + ], + "name": "MaciFactoryChanged", + "type": "event" + }, { "anonymous": false, "inputs": [ @@ -136,8 +159,15 @@ }, { "anonymous": false, - "inputs": [], - "name": "RecipientRegistrySet", + "inputs": [ + { + "indexed": false, + "internalType": "address", + "name": "_recipientRegistry", + "type": "address" + } + ], + "name": "RecipientRegistryChanged", "type": "event" }, { @@ -181,10 +211,30 @@ }, { "anonymous": false, - "inputs": [], - "name": "UserRegistrySet", + "inputs": [ + { + "indexed": false, + "internalType": "address", + "name": "_userRegistry", + "type": "address" + } + ], + "name": "UserRegistryChanged", "type": "event" }, + { + "inputs": [], + "name": "MESSAGE_DATA_LENGTH", + "outputs": [ + { + "internalType": "uint8", + "name": "", + "type": "uint8" + } + ], + "stateMutability": "view", + "type": "function" + }, { "inputs": [ { @@ -261,7 +311,7 @@ "name": "getCurrentRound", "outputs": [ { - "internalType": "contract FundingRound", + "internalType": "contract IFundingRound", "name": "_currentRound", "type": "address" } @@ -306,12 +356,25 @@ "stateMutability": "nonpayable", "type": "function" }, + { + "inputs": [], + "name": "isInit", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "view", + "type": "function" + }, { "inputs": [], "name": "maciFactory", "outputs": [ { - "internalType": "contract MACIFactory", + "internalType": "contract IMACIFactory", "name": "", "type": "address" } @@ -383,7 +446,7 @@ "name": "roundFactory", "outputs": [ { - "internalType": "contract FundingRoundFactory", + "internalType": "contract IFundingRoundFactory", "name": "", "type": "address" } @@ -411,7 +474,7 @@ "type": "uint256" } ], - "internalType": "struct IPubKey.PubKey", + "internalType": "struct DomainObjs.PubKey", "name": "_coordinatorPubKey", "type": "tuple" } @@ -421,6 +484,32 @@ "stateMutability": "nonpayable", "type": "function" }, + { + "inputs": [ + { + "internalType": "address", + "name": "_roundFactory", + "type": "address" + } + ], + "name": "setFundingRoundFactory", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_maciFactory", + "type": "address" + } + ], + "name": "setMaciFactory", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, { "inputs": [ { diff --git a/subgraph/config/arbitrum-sepolia.json b/subgraph/config/arbitrum-sepolia.json index 329e3092c..aee545b9a 100644 --- a/subgraph/config/arbitrum-sepolia.json +++ b/subgraph/config/arbitrum-sepolia.json @@ -1,6 +1,6 @@ { "network": "arbitrum-sepolia", - "address": "0xACf7E4370Dc5e0Ffdb207164967A196A471ddb90", - "clrFundStartBlock": 8721470, - "recipientRegistryStartBlock": 8721470 + "address": "0x22Ff798925A76B21f8122C04D10f177ea52D6411", + "clrFundStartBlock": 9007610, + "recipientRegistryStartBlock": 9007610 } diff --git a/subgraph/generated/ClrFund/ClrFund.ts b/subgraph/generated/ClrFund/ClrFund.ts index e89208f27..5358cdfc0 100644 --- a/subgraph/generated/ClrFund/ClrFund.ts +++ b/subgraph/generated/ClrFund/ClrFund.ts @@ -28,6 +28,24 @@ export class CoordinatorChanged__Params { } } +export class FundingRoundFactoryChanged extends ethereum.Event { + get params(): FundingRoundFactoryChanged__Params { + return new FundingRoundFactoryChanged__Params(this); + } +} + +export class FundingRoundFactoryChanged__Params { + _event: FundingRoundFactoryChanged; + + constructor(event: FundingRoundFactoryChanged) { + this._event = event; + } + + get _roundFactory(): Address { + return this._event.parameters[0].value.toAddress(); + } +} + export class FundingRoundTemplateChanged extends ethereum.Event { get params(): FundingRoundTemplateChanged__Params { return new FundingRoundTemplateChanged__Params(this); @@ -40,6 +58,10 @@ export class FundingRoundTemplateChanged__Params { constructor(event: FundingRoundTemplateChanged) { this._event = event; } + + get _template(): Address { + return this._event.parameters[0].value.toAddress(); + } } export class FundingSourceAdded extends ethereum.Event { @@ -92,6 +114,24 @@ export class Initialized__Params { } } +export class MaciFactoryChanged extends ethereum.Event { + get params(): MaciFactoryChanged__Params { + return new MaciFactoryChanged__Params(this); + } +} + +export class MaciFactoryChanged__Params { + _event: MaciFactoryChanged; + + constructor(event: MaciFactoryChanged) { + this._event = event; + } + + get _maciFactory(): Address { + return this._event.parameters[0].value.toAddress(); + } +} + export class OwnershipTransferred extends ethereum.Event { get params(): OwnershipTransferred__Params { return new OwnershipTransferred__Params(this); @@ -114,18 +154,22 @@ export class OwnershipTransferred__Params { } } -export class RecipientRegistrySet extends ethereum.Event { - get params(): RecipientRegistrySet__Params { - return new RecipientRegistrySet__Params(this); +export class RecipientRegistryChanged extends ethereum.Event { + get params(): RecipientRegistryChanged__Params { + return new RecipientRegistryChanged__Params(this); } } -export class RecipientRegistrySet__Params { - _event: RecipientRegistrySet; +export class RecipientRegistryChanged__Params { + _event: RecipientRegistryChanged; - constructor(event: RecipientRegistrySet) { + constructor(event: RecipientRegistryChanged) { this._event = event; } + + get _recipientRegistry(): Address { + return this._event.parameters[0].value.toAddress(); + } } export class RoundFinalized extends ethereum.Event { @@ -182,18 +226,22 @@ export class TokenChanged__Params { } } -export class UserRegistrySet extends ethereum.Event { - get params(): UserRegistrySet__Params { - return new UserRegistrySet__Params(this); +export class UserRegistryChanged extends ethereum.Event { + get params(): UserRegistryChanged__Params { + return new UserRegistryChanged__Params(this); } } -export class UserRegistrySet__Params { - _event: UserRegistrySet; +export class UserRegistryChanged__Params { + _event: UserRegistryChanged; - constructor(event: UserRegistrySet) { + constructor(event: UserRegistryChanged) { this._event = event; } + + get _userRegistry(): Address { + return this._event.parameters[0].value.toAddress(); + } } export class ClrFund__coordinatorPubKeyResult { @@ -226,6 +274,29 @@ export class ClrFund extends ethereum.SmartContract { return new ClrFund("ClrFund", address); } + MESSAGE_DATA_LENGTH(): i32 { + let result = super.call( + "MESSAGE_DATA_LENGTH", + "MESSAGE_DATA_LENGTH():(uint8)", + [] + ); + + return result[0].toI32(); + } + + try_MESSAGE_DATA_LENGTH(): ethereum.CallResult { + let result = super.tryCall( + "MESSAGE_DATA_LENGTH", + "MESSAGE_DATA_LENGTH():(uint8)", + [] + ); + if (result.reverted) { + return new ethereum.CallResult(); + } + let value = result.value; + return ethereum.CallResult.fromValue(value[0].toI32()); + } + coordinator(): Address { let result = super.call("coordinator", "coordinator():(address)", []); @@ -320,6 +391,21 @@ export class ClrFund extends ethereum.SmartContract { return ethereum.CallResult.fromValue(value[0].toBigInt()); } + isInit(): boolean { + let result = super.call("isInit", "isInit():(bool)", []); + + return result[0].toBoolean(); + } + + try_isInit(): ethereum.CallResult { + let result = super.tryCall("isInit", "isInit():(bool)", []); + if (result.reverted) { + return new ethereum.CallResult(); + } + let value = result.value; + return ethereum.CallResult.fromValue(value[0].toBoolean()); + } + maciFactory(): Address { let result = super.call("maciFactory", "maciFactory():(address)", []); @@ -667,6 +753,66 @@ export class SetCoordinatorCall_coordinatorPubKeyStruct extends ethereum.Tuple { } } +export class SetFundingRoundFactoryCall extends ethereum.Call { + get inputs(): SetFundingRoundFactoryCall__Inputs { + return new SetFundingRoundFactoryCall__Inputs(this); + } + + get outputs(): SetFundingRoundFactoryCall__Outputs { + return new SetFundingRoundFactoryCall__Outputs(this); + } +} + +export class SetFundingRoundFactoryCall__Inputs { + _call: SetFundingRoundFactoryCall; + + constructor(call: SetFundingRoundFactoryCall) { + this._call = call; + } + + get _roundFactory(): Address { + return this._call.inputValues[0].value.toAddress(); + } +} + +export class SetFundingRoundFactoryCall__Outputs { + _call: SetFundingRoundFactoryCall; + + constructor(call: SetFundingRoundFactoryCall) { + this._call = call; + } +} + +export class SetMaciFactoryCall extends ethereum.Call { + get inputs(): SetMaciFactoryCall__Inputs { + return new SetMaciFactoryCall__Inputs(this); + } + + get outputs(): SetMaciFactoryCall__Outputs { + return new SetMaciFactoryCall__Outputs(this); + } +} + +export class SetMaciFactoryCall__Inputs { + _call: SetMaciFactoryCall; + + constructor(call: SetMaciFactoryCall) { + this._call = call; + } + + get _maciFactory(): Address { + return this._call.inputValues[0].value.toAddress(); + } +} + +export class SetMaciFactoryCall__Outputs { + _call: SetMaciFactoryCall; + + constructor(call: SetMaciFactoryCall) { + this._call = call; + } +} + export class SetRecipientRegistryCall extends ethereum.Call { get inputs(): SetRecipientRegistryCall__Inputs { return new SetRecipientRegistryCall__Inputs(this); diff --git a/subgraph/generated/schema.ts b/subgraph/generated/schema.ts index 4aa73bc1b..f611654e8 100644 --- a/subgraph/generated/schema.ts +++ b/subgraph/generated/schema.ts @@ -314,74 +314,6 @@ export class ClrFund extends Entity { } } - get batchUstVerifier(): Bytes | null { - let value = this.get("batchUstVerifier"); - if (!value || value.kind == ValueKind.NULL) { - return null; - } else { - return value.toBytes(); - } - } - - set batchUstVerifier(value: Bytes | null) { - if (!value) { - this.unset("batchUstVerifier"); - } else { - this.set("batchUstVerifier", Value.fromBytes(value)); - } - } - - get qvtVerifier(): Bytes | null { - let value = this.get("qvtVerifier"); - if (!value || value.kind == ValueKind.NULL) { - return null; - } else { - return value.toBytes(); - } - } - - set qvtVerifier(value: Bytes | null) { - if (!value) { - this.unset("qvtVerifier"); - } else { - this.set("qvtVerifier", Value.fromBytes(value)); - } - } - - get signUpDuration(): BigInt | null { - let value = this.get("signUpDuration"); - if (!value || value.kind == ValueKind.NULL) { - return null; - } else { - return value.toBigInt(); - } - } - - set signUpDuration(value: BigInt | null) { - if (!value) { - this.unset("signUpDuration"); - } else { - this.set("signUpDuration", Value.fromBigInt(value)); - } - } - - get votingDuration(): BigInt | null { - let value = this.get("votingDuration"); - if (!value || value.kind == ValueKind.NULL) { - return null; - } else { - return value.toBigInt(); - } - } - - set votingDuration(value: BigInt | null) { - if (!value) { - this.unset("votingDuration"); - } else { - this.set("votingDuration", Value.fromBigInt(value)); - } - } - get maxUsers(): BigInt | null { let value = this.get("maxUsers"); if (!value || value.kind == ValueKind.NULL) { diff --git a/subgraph/schema.graphql b/subgraph/schema.graphql index 1f86045f5..3465701bb 100644 --- a/subgraph/schema.graphql +++ b/subgraph/schema.graphql @@ -17,10 +17,6 @@ type ClrFund @entity { voteOptionTreeDepth: BigInt tallyBatchSize: BigInt messageBatchSize: BigInt - batchUstVerifier: Bytes - qvtVerifier: Bytes - signUpDuration: BigInt - votingDuration: BigInt maxUsers: BigInt maxMessages: BigInt diff --git a/subgraph/src/ClrFundMapping.ts b/subgraph/src/ClrFundMapping.ts index e5e8da56a..bcabfedcb 100644 --- a/subgraph/src/ClrFundMapping.ts +++ b/subgraph/src/ClrFundMapping.ts @@ -7,6 +7,8 @@ import { RoundFinalized, RoundStarted, TokenChanged, + UserRegistryChanged, + RecipientRegistryChanged, ClrFund as ClrFundContract, } from '../generated/ClrFund/ClrFund' @@ -309,3 +311,19 @@ export function handleTokenChanged(event: TokenChanged): void { log.info('handleTokenChanged {}', [event.params._token.toHexString()]) createOrUpdateClrFund(event.address, event.block.timestamp) } + +export function handleRecipientRegistryChanged( + event: RecipientRegistryChanged +): void { + log.info('handleRecipientRegistryChanged {}', [ + event.params._recipientRegistry.toHexString(), + ]) + createOrUpdateClrFund(event.address, event.block.timestamp) +} + +export function handleUserRegistryChanged(event: UserRegistryChanged): void { + log.info('handleUserRegistryChanged {}', [ + event.params._userRegistry.toHexString(), + ]) + createOrUpdateClrFund(event.address, event.block.timestamp) +} diff --git a/subgraph/subgraph.template.yaml b/subgraph/subgraph.template.yaml index de35fe47f..1b8bf245b 100644 --- a/subgraph/subgraph.template.yaml +++ b/subgraph/subgraph.template.yaml @@ -53,6 +53,10 @@ dataSources: handler: handleRoundStarted - event: TokenChanged(address) handler: handleTokenChanged + - event: UserRegistryChanged(address) + handler: handleUserRegistryChanged + - event: RecipientRegistryChanged(address) + handler: handleRecipientRegistryChanged file: ./src/ClrFundMapping.ts - kind: ethereum/contract name: OptimisticRecipientRegistry diff --git a/subgraph/subgraph.yaml b/subgraph/subgraph.yaml index 815835a5e..0a5b17677 100644 --- a/subgraph/subgraph.yaml +++ b/subgraph/subgraph.yaml @@ -53,6 +53,10 @@ dataSources: handler: handleRoundStarted - event: TokenChanged(address) handler: handleTokenChanged + - event: UserRegistryChanged(address) + handler: handleUserRegistryChanged + - event: RecipientRegistryChanged(address) + handler: handleRecipientRegistryChanged file: ./src/ClrFundMapping.ts - kind: ethereum/contract name: OptimisticRecipientRegistry