mirror of
https://github.com/selfxyz/self.git
synced 2026-01-14 17:17:59 -05:00
412 lines
15 KiB
TypeScript
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");
|
|
});
|
|
});
|