import { expect } from "chai"; import { ethers } from "hardhat"; import { TestCustomVerifier, CustomVerifier } from "../../typechain-types"; export const AttestationId = { E_PASSPORT: "0x0000000000000000000000000000000000000000000000000000000000000001", EU_ID_CARD: "0x0000000000000000000000000000000000000000000000000000000000000002", } as const; describe("CustomVerifier", function () { let testVerifier: TestCustomVerifier; let customVerifier: CustomVerifier; before(async function () { const CustomVerifierFactory = await ethers.getContractFactory("CustomVerifier"); customVerifier = await CustomVerifierFactory.deploy(); await customVerifier.waitForDeployment(); const TestVerifierFactory = await ethers.getContractFactory("TestCustomVerifier", { libraries: { CustomVerifier: await customVerifier.getAddress(), }, }); testVerifier = await TestVerifierFactory.deploy(); await testVerifier.waitForDeployment(); }); describe("Passport Verification", function () { const mrz = ethers.toUtf8Bytes( "P await testVerifier.testCustomVerify( AttestationId.E_PASSPORT, ethers.AbiCoder.defaultAbiCoder().encode(["tuple(bool,uint256,bool,uint256[4],bool[3])"], [config]), ethers.AbiCoder.defaultAbiCoder().encode( ["tuple(uint256,bytes,uint256,uint256,uint256[4])"], [samplePassportOutput], ), ), ).to.be.revertedWithCustomError(customVerifier, "INVALID_OFAC"); }); it("should return proper OFAC results", async function () { const config = [ false, 0, false, [ethers.getBigInt(0), ethers.getBigInt(0), ethers.getBigInt(0), ethers.getBigInt(0)], [false, false, false], ]; const result = await testVerifier.testCustomVerify( AttestationId.E_PASSPORT, ethers.AbiCoder.defaultAbiCoder().encode(["tuple(bool,uint256,bool,uint256[4],bool[3])"], [config]), ethers.AbiCoder.defaultAbiCoder().encode( ["tuple(uint256,bytes,uint256,uint256,uint256[4])"], [samplePassportOutput], ), ); expect(result.attestationId).to.equal(AttestationId.E_PASSPORT); expect(result.ofac[0]).to.equal(true); expect(result.ofac[1]).to.equal(false); expect(result.ofac[2]).to.equal(true); }); it("should verify passport with forbidden countries check", async function () { const config = [ false, 0, true, [ethers.getBigInt(0), ethers.getBigInt(0), ethers.getBigInt(0), ethers.getBigInt(0)], [false, false, false], ]; const result = await testVerifier.testCustomVerify( AttestationId.E_PASSPORT, ethers.AbiCoder.defaultAbiCoder().encode(["tuple(bool,uint256,bool,uint256[4],bool[3])"], [config]), ethers.AbiCoder.defaultAbiCoder().encode( ["tuple(uint256,bytes,uint256,uint256,uint256[4])"], [samplePassportOutput], ), ); expect(result.attestationId).to.equal(AttestationId.E_PASSPORT); }); it("should throw an error if age is not valid", async function () { const config = [ true, 19, false, [ethers.getBigInt(0), ethers.getBigInt(0), ethers.getBigInt(0), ethers.getBigInt(0)], [false, false, false], ]; expect( async () => await testVerifier.testCustomVerify( AttestationId.E_PASSPORT, ethers.AbiCoder.defaultAbiCoder().encode(["tuple(bool,uint256,bool,uint256[4],bool[3])"], [config]), ethers.AbiCoder.defaultAbiCoder().encode( ["tuple(uint256,bytes,uint256,uint256,uint256[4])"], [samplePassportOutput], ), ), ).to.be.revertedWithCustomError(customVerifier, "INVALID_OLDER_THAN"); }); it("should not throw an error if older than is not enabled", async function () { const config = [ false, 19, false, [ethers.getBigInt(0), ethers.getBigInt(0), ethers.getBigInt(0), ethers.getBigInt(0)], [false, false, false], ]; const result = await testVerifier.testCustomVerify( AttestationId.E_PASSPORT, ethers.AbiCoder.defaultAbiCoder().encode(["tuple(bool,uint256,bool,uint256[4],bool[3])"], [config]), ethers.AbiCoder.defaultAbiCoder().encode( ["tuple(uint256,bytes,uint256,uint256,uint256[4])"], [samplePassportOutput], ), ); expect(result.attestationId).to.equal(AttestationId.E_PASSPORT); }); it("should not throw an error if age is valid", async function () { const config = [ true, 18, false, [ethers.getBigInt(0), ethers.getBigInt(0), ethers.getBigInt(0), ethers.getBigInt(0)], [false, false, false], ]; const result = await testVerifier.testCustomVerify( AttestationId.E_PASSPORT, ethers.AbiCoder.defaultAbiCoder().encode(["tuple(bool,uint256,bool,uint256[4],bool[3])"], [config]), ethers.AbiCoder.defaultAbiCoder().encode( ["tuple(uint256,bytes,uint256,uint256,uint256[4])"], [samplePassportOutput], ), ); expect(result.attestationId).to.equal(AttestationId.E_PASSPORT); expect(result.olderThan).to.equal(18); }); }); describe("ID Card Verification", function () { let mrz = "I await testVerifier.testCustomVerify( AttestationId.EU_ID_CARD, ethers.AbiCoder.defaultAbiCoder().encode(["tuple(bool,uint256,bool,uint256[4],bool[3])"], [config]), ethers.AbiCoder.defaultAbiCoder().encode( ["tuple(uint256,bytes,uint256,uint256,uint256[4])"], [sampleIdCardOutput], ), ), ).to.be.revertedWithCustomError(customVerifier, "INVALID_OFAC"); }); it("should return proper OFAC results", async function () { const config = [ false, 0, false, [ethers.getBigInt(0), ethers.getBigInt(0), ethers.getBigInt(0), ethers.getBigInt(0)], [false, false, false], ]; const result = await testVerifier.testCustomVerify( AttestationId.EU_ID_CARD, ethers.AbiCoder.defaultAbiCoder().encode(["tuple(bool,uint256,bool,uint256[4],bool[3])"], [config]), ethers.AbiCoder.defaultAbiCoder().encode( ["tuple(uint256,bytes,uint256,uint256,uint256[4])"], [sampleIdCardOutput], ), ); expect(result.attestationId).to.equal(AttestationId.EU_ID_CARD); expect(result.ofac[0]).to.equal(false); expect(result.ofac[1]).to.equal(true); expect(result.ofac[2]).to.equal(false); }); it("should verify ID card with OFAC checks", async function () { const config = [ false, 0, false, [ethers.getBigInt(0), ethers.getBigInt(0), ethers.getBigInt(0), ethers.getBigInt(0)], [false, false, false], ]; const result = await testVerifier.testCustomVerify( AttestationId.EU_ID_CARD, ethers.AbiCoder.defaultAbiCoder().encode(["tuple(bool,uint256,bool,uint256[4],bool[3])"], [config]), ethers.AbiCoder.defaultAbiCoder().encode( ["tuple(uint256,bytes,uint256,uint256,uint256[4])"], [sampleIdCardOutput], ), ); expect(result.attestationId).to.equal(AttestationId.EU_ID_CARD); }); it("should verify ID card with forbidden countries check", async function () { const config = [ false, 0, true, [ethers.getBigInt(0), ethers.getBigInt(0), ethers.getBigInt(0), ethers.getBigInt(0)], [false, false, false], ]; const result = await testVerifier.testCustomVerify( AttestationId.EU_ID_CARD, ethers.AbiCoder.defaultAbiCoder().encode(["tuple(bool,uint256,bool,uint256[4],bool[3])"], [config]), ethers.AbiCoder.defaultAbiCoder().encode( ["tuple(uint256,bytes,uint256,uint256,uint256[4])"], [sampleIdCardOutput], ), ); expect(result.attestationId).to.equal(AttestationId.EU_ID_CARD); }); it("should throw an error if age is not valid", async function () { const config = [ true, 19, false, [ethers.getBigInt(0), ethers.getBigInt(0), ethers.getBigInt(0), ethers.getBigInt(0)], [false, false, false], ]; expect( async () => await testVerifier.testCustomVerify( AttestationId.EU_ID_CARD, ethers.AbiCoder.defaultAbiCoder().encode(["tuple(bool,uint256,bool,uint256[4],bool[3])"], [config]), ethers.AbiCoder.defaultAbiCoder().encode( ["tuple(uint256,bytes,uint256,uint256,uint256[4])"], [sampleIdCardOutput], ), ), ).to.be.revertedWithCustomError(customVerifier, "INVALID_OLDER_THAN"); }); it("should not throw an error if older than is not enabled", async function () { const config = [ false, 19, false, [ethers.getBigInt(0), ethers.getBigInt(0), ethers.getBigInt(0), ethers.getBigInt(0)], [false, false, false], ]; const result = await testVerifier.testCustomVerify( AttestationId.EU_ID_CARD, ethers.AbiCoder.defaultAbiCoder().encode(["tuple(bool,uint256,bool,uint256[4],bool[3])"], [config]), ethers.AbiCoder.defaultAbiCoder().encode( ["tuple(uint256,bytes,uint256,uint256,uint256[4])"], [sampleIdCardOutput], ), ); expect(result.attestationId).to.equal(AttestationId.EU_ID_CARD); }); it("should verify ID card with age check", async function () { const config = [ true, 18, false, [ethers.getBigInt(0), ethers.getBigInt(0), ethers.getBigInt(0), ethers.getBigInt(0)], [false, false, false], ]; const result = await testVerifier.testCustomVerify( AttestationId.EU_ID_CARD, ethers.AbiCoder.defaultAbiCoder().encode(["tuple(bool,uint256,bool,uint256[4],bool[3])"], [config]), ethers.AbiCoder.defaultAbiCoder().encode( ["tuple(uint256,bytes,uint256,uint256,uint256[4])"], [sampleIdCardOutput], ), ); expect(result.attestationId).to.equal(AttestationId.EU_ID_CARD); expect(result.olderThan).to.equal(18); }); }); it("should revert with invalid attestation ID", async function () { const config = [ false, 0, false, [ethers.getBigInt(0), ethers.getBigInt(0), ethers.getBigInt(0), ethers.getBigInt(0)], [false, false, false], ]; const invalidAttestationId = ethers.zeroPadValue(ethers.toBeHex(999), 32); await expect( testVerifier.testCustomVerify( invalidAttestationId, ethers.AbiCoder.defaultAbiCoder().encode(["tuple(bool,uint256,bool,uint256[4],bool[3])"], [config]), ethers.AbiCoder.defaultAbiCoder().encode( ["tuple(uint256,bytes,uint256,uint256,uint256[4])"], [ [ ethers.getBigInt(ethers.hexlify(ethers.randomBytes(32))), // attestationId (uint256) ethers.randomBytes(88), // revealedDataPacked (bytes) ethers.getBigInt(ethers.hexlify(ethers.randomBytes(32))), // userIdentifier (uint256) ethers.getBigInt(ethers.hexlify(ethers.randomBytes(32))), // nullifier (uint256) [ethers.getBigInt(0), ethers.getBigInt(0), ethers.getBigInt(0), ethers.getBigInt(0)], // forbiddenCountriesListPacked ], ], ), ), ).to.be.revertedWithCustomError(customVerifier, "INVALID_ATTESTATION_ID"); }); });