Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix reallocation and contract verification errors #759

Merged
merged 6 commits into from
Jun 17, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions contracts/tasks/helpers/ConstructorArguments.ts
Original file line number Diff line number Diff line change
Expand Up @@ -150,6 +150,7 @@ async function getTallyConstructorArguments(
tallyContract.vkRegistry(),
tallyContract.poll(),
tallyContract.messageProcessor(),
tallyContract.mode(),
])

return args
Expand All @@ -174,6 +175,7 @@ async function getMessageProcessorConstructorArguments(
messageProcesor.verifier(),
messageProcesor.vkRegistry(),
messageProcesor.poll(),
messageProcesor.mode(),
])

return args
Expand Down
4 changes: 0 additions & 4 deletions contracts/tasks/runners/maciPubkey.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,6 @@
*
* Usage: hardhat maci-pubkey --macisk <secret key>
*/
import { id } from 'ethers'
import { task } from 'hardhat/config'
import { PubKey, PrivKey, Keypair } from '@clrfund/common'

Expand All @@ -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}`)
}
})
51 changes: 35 additions & 16 deletions contracts/tasks/runners/verifyAll.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -138,17 +139,20 @@ async function getContractList(
clrfund: string,
ethers: HardhatEthersHelpers
): Promise<ContractInfo[]> {
const userRegistries = new Set<string>()
const recipientRegistries = new Set<string>()
const contractList: ContractInfo[] = [
{
name: EContracts.ClrFund,
address: clrfund,
},
]

const clrfundContract = (await ethers.getContractAt(
const clrfundContract = await getContractAt<ClrFund>(
EContracts.ClrFund,
clrfund
)) as BaseContract as ClrFund
clrfund,
ethers
)

const fundingRoundFactoryAddress = await clrfundContract.roundFactory()
if (fundingRoundFactoryAddress !== ZERO_ADDRESS) {
Expand Down Expand Up @@ -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({
Expand Down Expand Up @@ -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
}

Expand Down
1 change: 1 addition & 0 deletions contracts/utils/providers/EtherscanProvider.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ import { FetchRequest } from 'ethers'
import { HardhatConfig } from 'hardhat/types'

const EtherscanApiUrl: Record<string, string> = {
sepolia: 'https://api-sepolia.etherscan.io',
xdai: 'https://api.gnosisscan.io',
arbitrum: 'https://api.arbiscan.io',
'arbitrum-goerli': 'https://api-goerli.arbiscan.io',
Expand Down
14 changes: 5 additions & 9 deletions subgraph/generated/schema.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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(<string>value));
}
set maci(value: string) {
this.set("maci", Value.fromString(value));
}

get messages(): MessageLoader {
Expand Down
2 changes: 1 addition & 1 deletion subgraph/schema.graphql
Original file line number Diff line number Diff line change
Expand Up @@ -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!
Expand Down
2 changes: 1 addition & 1 deletion subgraph/schema.template.graphql
Original file line number Diff line number Diff line change
Expand Up @@ -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!
Expand Down
15 changes: 4 additions & 11 deletions subgraph/src/MACIMapping.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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
)
Expand All @@ -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', [])
Expand Down
21 changes: 16 additions & 5 deletions subgraph/src/PollMapping.ts
Original file line number Diff line number Diff line change
@@ -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 {
Expand All @@ -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() +
'-' +
Expand All @@ -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
)
Expand All @@ -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()
}

Expand Down
8 changes: 2 additions & 6 deletions subgraph/src/PublicKey.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
5 changes: 2 additions & 3 deletions vue-app/src/api/cart.ts
Original file line number Diff line number Diff line change
Expand Up @@ -17,15 +17,14 @@ export async function getCommittedCart(
encryptionKey: string,
contributorAddress: string,
): Promise<CartItem[]> {
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,
Expand Down
26 changes: 12 additions & 14 deletions vue-app/src/api/contributions.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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 {
Expand Down Expand Up @@ -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<number | null> {
if (!fundingRoundAddress) {
export async function getContributorIndex(maciAddress: string, pubKey: PubKey): Promise<number | null> {
if (!maciAddress) {
return null
}
const id = getPubKeyId(fundingRoundAddress, pubKey)
const id = getPubKeyId(maciAddress, pubKey)
const data = await sdk.GetContributorIndex({
fundingRoundAddress: fundingRoundAddress.toLowerCase(),
publicKeyId: id,
})

Expand All @@ -178,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<Message[]> {
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(),
})
Expand Down
Loading