From ecd5f8e676a6b45fbd7d07c46ca540b9398bed5a Mon Sep 17 00:00:00 2001 From: Gerald Iakobinyi-Pich Date: Wed, 15 Nov 2023 10:54:02 +0200 Subject: [PATCH 1/2] test: changes to allow easier estimating gas for verifyAndAttest --- hardhat.config.ts | 1 + test/helpers/mockAttestations.ts | 32 ++++++++++++++++++++++++++++++-- 2 files changed, 31 insertions(+), 2 deletions(-) diff --git a/hardhat.config.ts b/hardhat.config.ts index 9f4935f..a4eface 100644 --- a/hardhat.config.ts +++ b/hardhat.config.ts @@ -49,6 +49,7 @@ let config: HardhatUserConfig = { }, gasReporter: { enabled: process.env.REPORT_GAS ? true : false, + coinmarketcap: process.env.COINMARKETCAP_API_KEY, }, solidity: { settings: { diff --git a/test/helpers/mockAttestations.ts b/test/helpers/mockAttestations.ts index 0091276..e89ce9c 100644 --- a/test/helpers/mockAttestations.ts +++ b/test/helpers/mockAttestations.ts @@ -13,13 +13,17 @@ export type Stamp = { export type Score = { score: number; scorer_id: number; + score_decimals: number; }; export const easEncodeScore = (score: Score) => { - const schemaEncoder = new SchemaEncoder("uint32 score,uint32 scorer_id"); + const schemaEncoder = new SchemaEncoder( + "uint256 score,uint32 scorer_id,uint8 score_decimals" + ); const encodedData = schemaEncoder.encodeData([ - { name: "score", value: score.score, type: "uint32" }, + { name: "score", value: score.score, type: "uint256" }, { name: "scorer_id", value: score.scorer_id, type: "uint32" }, + { name: "score_decimals", value: score.score_decimals, type: "uint8" }, ]); return encodedData; }; @@ -40,6 +44,30 @@ export const encodedData = easEncodeStamp({ stampHash: "234567890", }); +export const encodeEasPassport = ( + providers: number[], + hashes: string[], + issuanceDates: number[], + expirationDates: number[], + providerMapVersion: number +): string => { + const attestationSchemaEncoder = new SchemaEncoder( + "uint256[] providers, bytes32[] hashes, uint64[] issuanceDates, uint64[] expirationDates, uint16 providerMapVersion" + ); + + const encodedData = attestationSchemaEncoder.encodeData([ + { name: "providers", value: providers, type: "uint256[]" }, + { name: "hashes", value: hashes, type: "bytes32[]" }, + { name: "issuanceDates", value: issuanceDates, type: "uint64[]" }, + { name: "expirationDates", value: expirationDates, type: "uint64[]" }, + // This will be used later for decoding provider mapping for scoring and within the resolver contract + // Currently set to zero but should be updated whenever providerBitMapInfo.json is updated + { name: "providerMapVersion", value: providerMapVersion, type: "uint16" }, + ]); + + return encodedData; +}; + export const attestationRequest = { recipient: "0x4A13F4394cF05a52128BdA527664429D5376C67f", expirationTime: NO_EXPIRATION, From 24f1fb80cbf44e2d7f3b7452ad0c9fe586be6853 Mon Sep 17 00:00:00 2001 From: Gerald Iakobinyi-Pich Date: Wed, 15 Nov 2023 12:48:54 +0200 Subject: [PATCH 2/2] fix: test for GitcoinVerifierWithVeraxPortal --- test/GitcoinVerifierWithVeraxPortal.ts | 20 +-- test/helpers/verifierTests.ts | 181 +++++++++++++++++++------ 2 files changed, 151 insertions(+), 50 deletions(-) diff --git a/test/GitcoinVerifierWithVeraxPortal.ts b/test/GitcoinVerifierWithVeraxPortal.ts index b08ed9b..27af5d7 100644 --- a/test/GitcoinVerifierWithVeraxPortal.ts +++ b/test/GitcoinVerifierWithVeraxPortal.ts @@ -1,13 +1,15 @@ import { ethers } from "hardhat"; import { runVerifierTests } from "./helpers/verifierTests"; -import { - GITCOIN_SCORE_SCHEMA, - GITCOIN_STAMP_SCHEMA, -} from "./helpers/verifierTests"; runVerifierTests( "GitcoinVerifierWithVeraxPortal", - async (contract, issuer, attester) => { + async ( + contract, + issuer, + attester, + gitcoinPassportSchemaUID, + gitcoinScoreSchemaUID + ) => { const GitcoinVeraxPortal = await ethers.getContractFactory( "GitcoinVeraxPortal" ); @@ -35,12 +37,12 @@ runVerifierTests( await gitcoinVeraxPortal.addToAllowlist(await contract.getAddress()); await gitcoinVeraxPortal.addSchemaMapping( - GITCOIN_SCORE_SCHEMA, - GITCOIN_SCORE_SCHEMA + gitcoinScoreSchemaUID, + gitcoinScoreSchemaUID ); await gitcoinVeraxPortal.addSchemaMapping( - GITCOIN_STAMP_SCHEMA, - GITCOIN_STAMP_SCHEMA + gitcoinPassportSchemaUID, + gitcoinPassportSchemaUID ); } ); diff --git a/test/helpers/verifierTests.ts b/test/helpers/verifierTests.ts index e50b936..a741809 100644 --- a/test/helpers/verifierTests.ts +++ b/test/helpers/verifierTests.ts @@ -4,7 +4,8 @@ import { NO_EXPIRATION, ZERO_BYTES32, } from "@ethereum-attestation-service/eas-sdk"; -import { easEncodeScore, easEncodeStamp } from "./mockAttestations"; +import { easEncodeScore, encodeEasPassport } from "./mockAttestations"; +import { SCHEMA_REGISTRY_ABI } from "../abi/SCHEMA_REGISTRY_ABI"; export const googleStamp = { provider: "Google", @@ -24,10 +25,8 @@ export const twitterStamp = { // SEPOLIA SPECIFIC export const EAS_CONTRACT_ADDRESS = "0xC2679fBD37d54388Ce493F1DB75320D236e1815e"; -export const GITCOIN_STAMP_SCHEMA = - "0x853a55f39e2d1bf1e6731ae7148976fbbb0c188a898a233dba61a233d8c0e4a4"; -export const GITCOIN_SCORE_SCHEMA = - "0x0f2928937d46e9ec78b350750185d2f495e708f79b383cef23b903fe120d9a2e"; +export const EAS_SCHEMA_REGISTRY_ADDRESS = + "0x0a7E2Ff54e76B8E6659aedc9103FB21c038050D0"; export const fee1 = ethers.parseEther("0.001"); export const fee1Less1Wei = ethers.parseEther("0.000999999999999999"); @@ -56,13 +55,75 @@ export const passportTypes = { export const scorer1Score = { score: 100, scorer_id: 420, + score_decimals: 18, }; export const scorer2Score = { score: 200, scorer_id: 240, + score_decimals: 18, }; +const easEncodedPassport = encodeEasPassport( + [12345678], + [ + "0x1234123412341234123412341234123412341234123412341234123412341234", + "0x1234123412341234123412341234123412341234123412341234123412341234", + "0x1234123412341234123412341234123412341234123412341234123412341234", + "0x1234123412341234123412341234123412341234123412341234123412341234", + "0x1234123412341234123412341234123412341234123412341234123412341234", + "0x1234123412341234123412341234123412341234123412341234123412341234", + "0x1234123412341234123412341234123412341234123412341234123412341234", + "0x1234123412341234123412341234123412341234123412341234123412341234", + "0x1234123412341234123412341234123412341234123412341234123412341234", + "0x1234123412341234123412341234123412341234123412341234123412341234", + "0x1234123412341234123412341234123412341234123412341234123412341234", + "0x1234123412341234123412341234123412341234123412341234123412341234", + "0x1234123412341234123412341234123412341234123412341234123412341234", + "0x1234123412341234123412341234123412341234123412341234123412341234", + "0x1234123412341234123412341234123412341234123412341234123412341234", + "0x1234123412341234123412341234123412341234123412341234123412341234", + "0x1234123412341234123412341234123412341234123412341234123412341234", + "0x1234123412341234123412341234123412341234123412341234123412341234", + "0x1234123412341234123412341234123412341234123412341234123412341234", + "0x1234123412341234123412341234123412341234123412341234123412341234", + "0x1234123412341234123412341234123412341234123412341234123412341234", + ], + [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 21], + [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 21], + 0 +); + +const easOtherEncodedPassport = encodeEasPassport( + [12345678], + [ + "0x1234123412341234123412341234123412341234123412341234123412aaaaaa", + "0x1234123412341234123412341234123412341234123412341234123412aaaaaa", + "0x1234123412341234123412341234123412341234123412341234123412aaaaaa", + "0x1234123412341234123412341234123412341234123412341234123412aaaaaa", + "0x1234123412341234123412341234123412341234123412341234123412aaaaaa", + "0x1234123412341234123412341234123412341234123412341234123412aaaaaa", + "0x1234123412341234123412341234123412341234123412341234123412aaaaaa", + "0x1234123412341234123412341234123412341234123412341234123412aaaaaa", + "0x1234123412341234123412341234123412341234123412341234123412aaaaaa", + "0x1234123412341234123412341234123412341234123412341234123412aaaaaa", + "0x1234123412341234123412341234123412341234123412341234123412aaaaaa", + "0x1234123412341234123412341234123412341234123412341234123412aaaaaa", + "0x1234123412341234123412341234123412341234123412341234123412aaaaaa", + "0x1234123412341234123412341234123412341234123412341234123412aaaaaa", + "0x1234123412341234123412341234123412341234123412341234123412aaaaaa", + "0x1234123412341234123412341234123412341234123412341234123412aaaaaa", + "0x1234123412341234123412341234123412341234123412341234123412aaaaaa", + "0x1234123412341234123412341234123412341234123412341234123412aaaaaa", + "0x1234123412341234123412341234123412341234123412341234123412aaaaaa", + "0x1234123412341234123412341234123412341234123412341234123412aaaaaa", + "0x1234123412341234123412341234123412341234123412341234123412aaaaaa", + ], + [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 21], + [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 21], + 0 +); + export function sumDataLengths(requests: { data: any[] }[]): number { return requests.reduce((total, request) => total + request.data.length, 0); } @@ -72,7 +133,9 @@ export const runVerifierTests = ( initializeVerifier: ( deployment: any, issuer: string, - attester: string + attester: string, + gitcoinPassportSchemaUID: string, + gitcoinScoreSchemaUID: string ) => Promise ) => { describe(contractName, function () { @@ -94,11 +157,6 @@ export const runVerifierTests = ( // Deploy GitcoinVerifier const GitcoinVerifier = await ethers.getContractFactory(contractName); this.gitcoinVerifier = await GitcoinVerifier.deploy(); - await initializeVerifier( - this.gitcoinVerifier, - await this.iamAccount.getAddress(), - await this.gitcoinAttester.getAddress() - ); // Add verifier to GitcoinAttester allow-list const tx = await this.gitcoinAttester.addVerifier( @@ -106,6 +164,69 @@ export const runVerifierTests = ( ); await tx.wait(); + // Deploy the gitcoin resolver + const GitcoinResolver = await ethers.getContractFactory( + "GitcoinResolver", + owner + ); + this.gitcoinResolver = await GitcoinResolver.deploy(); + await this.gitcoinResolver + .connect(owner) + .initialize(EAS_CONTRACT_ADDRESS, this.gitcoinAttester.getAddress()); + + // Register the passport schema, also specify the resolver in the schema + const schemaRegistry = new ethers.Contract( + EAS_SCHEMA_REGISTRY_ADDRESS, + SCHEMA_REGISTRY_ABI, + owner + ); + + const passportSchema = + "uint256[] providers,bytes32[] hashes,uint64[] issuanceDates,uint64[] expirationDates,uint16 providerMapVersion"; + const scoreSchema = "uint256 score,uint32 scorer_id,uint8 score_decimals"; + const revocable = true; + + const transactionRegisterPassportSchema = await schemaRegistry.register( + passportSchema, + this.gitcoinResolver.getAddress(), + revocable + ); + + const transactionRegisterPassportSchemaReceipt = + await transactionRegisterPassportSchema.wait(); + + const registerEvent = + transactionRegisterPassportSchemaReceipt.logs.filter((log: any) => { + return log.fragment.name == "Registered"; + }); + + this.passportAttestationSchemaUID = registerEvent[0].args[0]; + + // Register the score schema, also specify the resolver in the schema + const transactionRegisterScoreSchema = await schemaRegistry.register( + scoreSchema, + this.gitcoinResolver.getAddress(), + revocable + ); + + const transactionRegisterScoreSchemaReceipt = + await transactionRegisterScoreSchema.wait(); + const registerEventScoreSchema = + transactionRegisterScoreSchemaReceipt.logs.filter((log: any) => { + return log.fragment.name == "Registered"; + }); + + this.scoreAttestationSchemaUID = registerEventScoreSchema[0].args[0]; + + await initializeVerifier( + this.gitcoinVerifier, + await this.iamAccount.getAddress(), + await this.gitcoinAttester.getAddress(), + this.passportAttestationSchemaUID, + this.scoreAttestationSchemaUID + ); + + // Create some test data const chainId = await ethers.provider.getNetwork().then((n) => n.chainId); this.domain = { @@ -122,29 +243,23 @@ export const runVerifierTests = ( this.passport = { multiAttestationRequest: [ { - schema: GITCOIN_STAMP_SCHEMA, + schema: this.passportAttestationSchemaUID, data: [ + // Passport attestation with 21 stamps { recipient: await this.recipientAccount.getAddress(), expirationTime: NO_EXPIRATION, revocable: true, refUID: ZERO_BYTES32, - data: easEncodeStamp(googleStamp), - value: 0, - }, - { - recipient: await this.recipientAccount.getAddress(), - expirationTime: NO_EXPIRATION, - revocable: true, - refUID: ZERO_BYTES32, - data: easEncodeStamp(facebookStamp), + data: easEncodedPassport, value: 0, }, ], }, { - schema: GITCOIN_SCORE_SCHEMA, + schema: this.scoreAttestationSchemaUID, data: [ + // Score attestation { recipient: await this.recipientAccount.getAddress(), expirationTime: NO_EXPIRATION, @@ -153,22 +268,6 @@ export const runVerifierTests = ( data: easEncodeScore(scorer1Score), value: 0, }, - { - recipient: await this.recipientAccount.getAddress(), - expirationTime: NO_EXPIRATION, - revocable: true, - refUID: ZERO_BYTES32, - data: easEncodeScore(scorer2Score), - value: 0, - }, - { - recipient: await this.recipientAccount.getAddress(), - expirationTime: NO_EXPIRATION, - revocable: true, - refUID: ZERO_BYTES32, - data: easEncodeScore(scorer2Score), - value: 0, - }, ], }, ], @@ -180,20 +279,20 @@ export const runVerifierTests = ( return { multiAttestationRequest: [ { - schema: GITCOIN_STAMP_SCHEMA, + schema: this.passportAttestationSchemaUID, data: [ { recipient: await this.recipientAccount.getAddress(), expirationTime: NO_EXPIRATION, revocable: true, refUID: ZERO_BYTES32, - data: easEncodeStamp(googleStamp), + data: easOtherEncodedPassport, value: 0, }, ], }, { - schema: GITCOIN_SCORE_SCHEMA, + schema: this.scoreAttestationSchemaUID, data: [ { recipient: await this.recipientAccount.getAddress(),