Files
self/contracts/test/unit/CustomVerifier.test.ts
2025-06-16 21:49:51 +09:00

412 lines
15 KiB
TypeScript

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<UTOERIKSSON<<ANNA<MARIA<<<<<<<<<<<<<<<<<<<" + "L898902C36UTO7408122F1204159ZE184226B<<<<<1018",
);
const mrzBytes = new Uint8Array([...mrz, 1, 0, 1]);
const samplePassportOutput = [
ethers.getBigInt(ethers.hexlify(ethers.randomBytes(32))), // attestationId (uint256)
mrzBytes, // 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
];
it("should verify passport with all checks disabled", 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);
});
it("should not verify passport with OFAC checks", async function () {
const config = [
false,
0,
false,
[ethers.getBigInt(0), ethers.getBigInt(0), ethers.getBigInt(0), ethers.getBigInt(0)],
[true, false, true],
];
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_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<FRA1234567890<<<<<<<<<<<<<<<5410070M3001010FRA<<<<<<<<<<<1HENAO<MONTOYA<<ARCANGEL<DE<JES18";
let mrzBytes = new Uint8Array([...ethers.toUtf8Bytes(mrz), 1, 0]);
const sampleIdCardOutput = [
ethers.getBigInt(ethers.hexlify(ethers.randomBytes(32))), // attestationId (uint256)
mrzBytes, // 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
];
it("should verify ID card with all checks disabled", 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 not 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)],
[true, false, true],
];
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_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");
});
});