Files
self/contracts/test/integration/verifyAll.test.ts
Evi Nova bc4e52bb1e Refactor/multitiered multisig roles (#1483)
* refactor: switch to multitiered governance with multisigs

* feat: add scripts for assisting with upgrading contracts and

* test: add tests for governance upgrade

* chore: install Foundry with Hardhat compatability

* fix: add separate intializeGovernance function for upgrading

Uses reinitializer modifier for proper security around function call

* feat: migrate new function to AccessControl governance

* test: full end to end upgrade typescript test

* chore: add hardhat-upgrade

* chore: add foundry outputs to gitignore

* test: add Foundry upgrade script and test for deployed contracts

* refactor: update PCR0 inputs to be 32 bytes for GCP image hashes

Still pad to 48 bytes to ensure compatibility with mobile app.

* feat: add PCR0 migration script + test file

* fix: use custom natspec to prevent constructor warnings on upgrade

* test: cleanup tests and add role transfer to upgrade script

* test: add deployed libraries to foundry.toml for proper library linking

* chore: add /contracts/broadcast to gitignore for foundry deployments

* fix: set variable in initializer instead of defining in declaration

* test: improve upgrade test script to check all state variables

* docs: better explain safety behind using unsafeSkipStorageCheck

* doc: add guide for upgrading to AccessControl governance

* style: change multisig role names

CRITICAL_ROLE -> SECURITY_ROLE (3/5)
STANDARD_ROLE -> OPERATIONRS_ROLE (2/5)

* refactor: change OFAC + CSCA root update functions to 2/5 multisig

* fix: package version clashes + outdated code from old ver of packages

OpenZeppelin v5.5.0 no longer requires __UUPS_Upgradeable_Init, new OZ version requires opcodes that need cancun evmVersion, hard defining @noble/hashes led to clashes with other dependencies

* fix: fix PCR0 tests broken from change in byte size

* feat: add contract upgrade tooling with Safe multisig integration

- Add unified 'upgrade' Hardhat task with automatic safety checks
- Add deployment registry for version tracking
- Add Safe SDK integration for auto-proposing upgrades
- Update UPGRADE_GUIDE.md with new workflow documentation
- Validate version increments, reinitializer, and storage layout

* fix: revert fix on Hub V1 contract that is not supported

* style: update upgraded contracts to not use custom:version-history

* fix: V1 test requires old style as well

* fix: correct registry currentVersion to reflect actual deployed versions

On-chain verification confirmed all contracts are using OLD Ownable2StepUpgradeable:
- Hub: 2.11.0 (was incorrectly 2.12.0)
- Registry: 1.1.0 (was incorrectly 1.2.0)
- IdCard: 1.1.0 (was incorrectly 1.2.0)
- Aadhaar: 1.1.0 (was incorrectly 1.2.0)

Owner address: 0xcaee7aaf115f04d836e2d362a7c07f04db436bd0

* fix: upgrade script now correctly handles pre-defined versions in registry

When upgrading to a version that already exists in registry.json (like 2.12.0),
the script now uses that version's initializerVersion instead of incrementing
from the latest version. This fixes the reinitializer validation for the
governance upgrade.

* fix: upgrade script handles Ownable contracts and outputs transaction data

- Detect Ownable pattern before creating Safe proposals
- Output transaction data for owner direct execution in --prepare-only mode
- Use initializerFunction from registry (initializeGovernance) instead of constructing names
- Skip Safe proposal creation for initial Ownable → AccessControl upgrade
- After upgrade, owner grants SECURITY_ROLE to Safe for future upgrades

* feat: IdentityVerificationHub v2.12.0 deployed on Celo

- Implementation: 0x05FB9D7830889cc389E88198f6A224eA87F01151
- Changelog: Governance upgrade

* feat: IdentityRegistryIdCard v1.2.0 deployed on Celo

- Implementation: 0x7d5e4b7D4c3029aF134D50642674Af8F875118a4
- Changelog: Governance upgrade

* feat: IdentityRegistryAadhaar v1.2.0 deployed on Celo

- Implementation: 0xbD861A9cecf7B0A9631029d55A8CE1155e50697c
- Changelog: Governance upgrade

* feat: IdentityRegistry v1.2.0 deployed on Celo

- Implementation: 0x81E7F74560FAF7eE8DE3a36A5a68B6cbc429Cd36
- Changelog: Governance upgrade

* feat: add multisig addresses to registry

* feat: PCR0Manager v1.2.0 deployed on Celo

- Implementation: 0x9743fe2C1c3D2b068c56dE314e9B10DA9c904717
- Changelog: Governance upgrade

* refactor: cleanup old scripts

* chore: yarn prettier formatting
2025-12-10 17:30:50 +10:00

523 lines
20 KiB
TypeScript

import { expect } from "chai";
import { ethers } from "hardhat";
import { deploySystemFixtures } from "../utils/deployment";
import { DeployedActors, VcAndDiscloseHubProof } from "../utils/types";
import { generateRandomFieldElement, splitHexFromBack } from "../utils/utils";
import { generateCommitment } from "@selfxyz/common/utils/passports/passport";
import { ATTESTATION_ID } from "../utils/constants";
import { CIRCUIT_CONSTANTS } from "@selfxyz/common/constants/constants";
import { poseidon2 } from "poseidon-lite";
import { generateVcAndDiscloseProof, parseSolidityCalldata } from "../utils/generateProof";
import { Formatter } from "../utils/formatter";
import { formatCountriesList, reverseBytes } from "@selfxyz/common/utils/circuits/formatInputs";
import { VerifyAll } from "../../typechain-types";
import { getSMTs } from "../utils/generateProof";
import { Groth16Proof, PublicSignals, groth16 } from "snarkjs";
import { VcAndDiscloseProof } from "../utils/types";
describe("VerifyAll", () => {
let deployedActors: DeployedActors;
let verifyAll: VerifyAll;
let snapshotId: string;
let baseVcAndDiscloseProof: any;
let vcAndDiscloseProof: any;
let registerSecret: any;
let imt: any;
let commitment: any;
let nullifier: any;
let forbiddenCountriesList: string[];
let invalidForbiddenCountriesList: string[];
let forbiddenCountriesListPacked: string[];
let invalidForbiddenCountriesListPacked: string[];
before(async () => {
deployedActors = await deploySystemFixtures();
const VerifyAllFactory = await ethers.getContractFactory("VerifyAll");
verifyAll = await VerifyAllFactory.deploy(deployedActors.hub.getAddress(), deployedActors.registry.getAddress());
registerSecret = generateRandomFieldElement();
nullifier = generateRandomFieldElement();
commitment = generateCommitment(registerSecret, ATTESTATION_ID.E_PASSPORT, deployedActors.mockPassport);
const hashFunction = (a: bigint, b: bigint) => poseidon2([a, b]);
// must be imported dynamic since @openpassport/zk-kit-lean-imt is exclusively esm and hardhat does not support esm with typescript until verison 3
const LeanIMT = await import("@openpassport/zk-kit-lean-imt").then((mod) => mod.LeanIMT);
imt = new LeanIMT<bigint>(hashFunction);
await imt.insert(BigInt(commitment));
forbiddenCountriesList = [
"AAA",
"ABC",
"CBA",
"AAA",
"AAA",
"ABC",
"CBA",
"AAA",
"ABC",
"CBA",
"AAA",
"ABC",
"CBA",
"AAA",
"ABC",
"CBA",
"AAA",
"ABC",
"CBA",
"AAA",
"ABC",
"CBA",
"AAA",
"ABC",
"CBA",
"AAA",
"ABC",
"CBA",
"AAA",
"ABC",
"CBA",
"AAA",
"ABC",
"CBA",
"AAA",
"ABC",
"CBA",
"AAA",
"ABC",
"CBA",
];
const wholePacked = reverseBytes(
Formatter.bytesToHexString(new Uint8Array(formatCountriesList(forbiddenCountriesList))),
);
forbiddenCountriesListPacked = splitHexFromBack(wholePacked);
invalidForbiddenCountriesList = ["AAA", "ABC", "CBA", "CBA"];
const invalidWholePacked = reverseBytes(
Formatter.bytesToHexString(new Uint8Array(formatCountriesList(invalidForbiddenCountriesList))),
);
invalidForbiddenCountriesListPacked = splitHexFromBack(invalidWholePacked);
baseVcAndDiscloseProof = await generateVcAndDiscloseProof(
registerSecret,
BigInt(ATTESTATION_ID.E_PASSPORT).toString(),
deployedActors.mockPassport,
"test-scope",
new Array(88).fill("1"),
"1",
imt,
"20",
undefined,
undefined,
undefined,
undefined,
forbiddenCountriesList,
(await deployedActors.user1.getAddress()).slice(2),
);
snapshotId = await ethers.provider.send("evm_snapshot", []);
});
beforeEach(async () => {
vcAndDiscloseProof = structuredClone(baseVcAndDiscloseProof);
});
afterEach(async () => {
await ethers.provider.send("evm_revert", [snapshotId]);
snapshotId = await ethers.provider.send("evm_snapshot", []);
});
describe("verifyAll", () => {
it("should verify and get result successfully", async () => {
const { registry, owner } = deployedActors;
const tx = await registry
.connect(owner)
.devAddIdentityCommitment(ATTESTATION_ID.E_PASSPORT, nullifier, commitment);
const receipt = (await tx.wait()) as any;
const timestamp = (await ethers.provider.getBlock(receipt.blockNumber))!.timestamp;
const vcAndDiscloseHubProof: VcAndDiscloseHubProof = {
olderThanEnabled: true,
olderThan: "20",
forbiddenCountriesEnabled: true,
forbiddenCountriesListPacked: forbiddenCountriesListPacked,
ofacEnabled: [true, true, true],
vcAndDiscloseProof: vcAndDiscloseProof,
};
const types = ["0", "1", "2", "3", "4", "5", "6", "7", "8", "9", "10"]; // Example types
const [readableData, success] = await verifyAll.verifyAll(timestamp, vcAndDiscloseHubProof, types);
expect(success).to.be.true;
expect(readableData.name).to.not.be.empty;
});
it("should verify and get result successfully with out timestamp verification", async () => {
const { registry, owner } = deployedActors;
await registry.connect(owner).devAddIdentityCommitment(ATTESTATION_ID.E_PASSPORT, nullifier, commitment);
const vcAndDiscloseHubProof: VcAndDiscloseHubProof = {
olderThanEnabled: true,
olderThan: "20",
forbiddenCountriesEnabled: true,
forbiddenCountriesListPacked: forbiddenCountriesListPacked,
ofacEnabled: [true, true, true],
vcAndDiscloseProof: vcAndDiscloseProof,
};
const types = ["0", "1", "2"]; // Example types
const [readableData, success] = await verifyAll.verifyAll(0, vcAndDiscloseHubProof, types);
expect(success).to.be.true;
expect(readableData.name).to.not.be.empty;
});
it("should return empty result when verification fails", async () => {
const { registry, owner } = deployedActors;
await registry.connect(owner).devAddIdentityCommitment(ATTESTATION_ID.E_PASSPORT, nullifier, commitment);
vcAndDiscloseProof.pubSignals[CIRCUIT_CONSTANTS.VC_AND_DISCLOSE_MERKLE_ROOT_INDEX] = generateRandomFieldElement();
const vcAndDiscloseHubProof: VcAndDiscloseHubProof = {
olderThanEnabled: true,
olderThan: "20",
forbiddenCountriesEnabled: true,
forbiddenCountriesListPacked: forbiddenCountriesListPacked,
ofacEnabled: [true, true, true],
vcAndDiscloseProof: vcAndDiscloseProof,
};
const types = ["0", "1", "2"];
const [readableData, success] = await verifyAll.verifyAll(0, vcAndDiscloseHubProof, types);
expect(success).to.be.false;
expect(readableData.name).to.be.empty;
});
it("should fail with invalid root timestamp", async () => {
const { registry, owner } = deployedActors;
await registry.connect(owner).devAddIdentityCommitment(ATTESTATION_ID.E_PASSPORT, nullifier, commitment);
const vcAndDiscloseHubProof: VcAndDiscloseHubProof = {
olderThanEnabled: true,
olderThan: "20",
forbiddenCountriesEnabled: true,
forbiddenCountriesListPacked: forbiddenCountriesListPacked,
ofacEnabled: [true, true, true],
vcAndDiscloseProof: vcAndDiscloseProof,
};
const types = ["0", "1", "2"];
const [readableData, success] = await verifyAll.verifyAll(123456, vcAndDiscloseHubProof, types);
expect(success).to.be.false;
expect(readableData.name).to.be.empty;
});
describe("Error Handling", () => {
it("should return error code 'INVALID_VC_AND_DISCLOSE_PROOF' when proof is invalid", async () => {
const { registry, owner } = deployedActors;
await registry.connect(owner).devAddIdentityCommitment(ATTESTATION_ID.E_PASSPORT, nullifier, commitment);
vcAndDiscloseProof.a[0] = generateRandomFieldElement();
const vcAndDiscloseHubProof: VcAndDiscloseHubProof = {
olderThanEnabled: false,
olderThan: "20",
forbiddenCountriesEnabled: false,
forbiddenCountriesListPacked: forbiddenCountriesListPacked,
ofacEnabled: [false, false, false],
vcAndDiscloseProof: vcAndDiscloseProof,
};
const types = ["0", "1", "2"];
const [readableData, success, errorCode] = await verifyAll.verifyAll(0, vcAndDiscloseHubProof, types);
expect(success).to.be.false;
expect(errorCode).to.equal("INVALID_VC_AND_DISCLOSE_PROOF");
expect(readableData.name).to.be.empty;
});
it("should return error code 'CURRENT_DATE_NOT_IN_VALID_RANGE' when date is invalid", async () => {
const { registry, owner } = deployedActors;
await registry.connect(owner).devAddIdentityCommitment(ATTESTATION_ID.E_PASSPORT, nullifier, commitment);
vcAndDiscloseProof.pubSignals[CIRCUIT_CONSTANTS.VC_AND_DISCLOSE_CURRENT_DATE_INDEX] = 0;
const vcAndDiscloseHubProof: VcAndDiscloseHubProof = {
olderThanEnabled: true,
olderThan: "20",
forbiddenCountriesEnabled: true,
forbiddenCountriesListPacked: forbiddenCountriesListPacked,
ofacEnabled: [true, true, true],
vcAndDiscloseProof: vcAndDiscloseProof,
};
const types = ["0", "1", "2"];
const [readableData, success, errorCode] = await verifyAll.verifyAll(0, vcAndDiscloseHubProof, types);
expect(success).to.be.false;
expect(errorCode).to.equal("CURRENT_DATE_NOT_IN_VALID_RANGE");
expect(readableData.name).to.be.empty;
});
it("should return error code 'INVALID_OLDER_THAN' when age check fails", async () => {
const { registry, owner } = deployedActors;
await registry.connect(owner).devAddIdentityCommitment(ATTESTATION_ID.E_PASSPORT, nullifier, commitment);
const vcAndDiscloseHubProof: VcAndDiscloseHubProof = {
olderThanEnabled: true,
olderThan: "21", // Higher than the age in proof
forbiddenCountriesEnabled: false,
forbiddenCountriesListPacked: forbiddenCountriesListPacked,
ofacEnabled: [false, false, false],
vcAndDiscloseProof: vcAndDiscloseProof,
};
const types = ["0", "1", "2"];
const [readableData, success, errorCode] = await verifyAll.verifyAll(0, vcAndDiscloseHubProof, types);
expect(success).to.be.false;
expect(errorCode).to.equal("INVALID_OLDER_THAN");
expect(readableData.name).to.be.empty;
});
it("should return error code 'INVALID_OFAC' when OFAC check fails", async () => {
const { registry, owner } = deployedActors;
await registry.connect(owner).devAddIdentityCommitment(ATTESTATION_ID.E_PASSPORT, nullifier, commitment);
const { passportNo_smt, nameAndDob_smt, nameAndYob_smt } = getSMTs();
vcAndDiscloseProof = await generateVcAndDiscloseProof(
registerSecret,
BigInt(ATTESTATION_ID.E_PASSPORT).toString(),
deployedActors.mockPassport,
"test-scope",
new Array(88).fill("1"),
"1",
imt,
"20",
passportNo_smt,
nameAndDob_smt,
nameAndYob_smt,
"0",
);
const vcAndDiscloseHubProof: VcAndDiscloseHubProof = {
olderThanEnabled: true,
olderThan: "20",
forbiddenCountriesEnabled: false,
forbiddenCountriesListPacked: forbiddenCountriesListPacked,
ofacEnabled: [true, true, true],
vcAndDiscloseProof: vcAndDiscloseProof,
};
const types = ["0", "1", "2"];
const [readableData, success, errorCode] = await verifyAll.verifyAll(0, vcAndDiscloseHubProof, types);
console.log("return values");
console.log("readable data: ", readableData);
console.log("success: ", success);
console.log("errorCode: ", errorCode);
expect(success).to.be.false;
expect(errorCode).to.equal("INVALID_OFAC");
expect(readableData.name).to.be.empty;
});
it("should return error code 'INVALID_FORBIDDEN_COUNTRIES' when countries check fails", async () => {
const { registry, owner } = deployedActors;
await registry.connect(owner).devAddIdentityCommitment(ATTESTATION_ID.E_PASSPORT, nullifier, commitment);
const vcAndDiscloseHubProof: VcAndDiscloseHubProof = {
olderThanEnabled: true,
olderThan: "20",
forbiddenCountriesEnabled: true,
forbiddenCountriesListPacked: invalidForbiddenCountriesListPacked,
ofacEnabled: [true, true, true],
vcAndDiscloseProof: vcAndDiscloseProof,
};
const types = ["0", "1", "2"];
const [readableData, success, errorCode] = await verifyAll.verifyAll(0, vcAndDiscloseHubProof, types);
expect(success).to.be.false;
expect(errorCode).to.equal("INVALID_FORBIDDEN_COUNTRIES");
expect(readableData.name).to.be.empty;
});
it("should return error code 'INVALID_TIMESTAMP' when root timestamp doesn't match", async () => {
const { registry, owner } = deployedActors;
await registry.connect(owner).devAddIdentityCommitment(ATTESTATION_ID.E_PASSPORT, nullifier, commitment);
const vcAndDiscloseHubProof: VcAndDiscloseHubProof = {
olderThanEnabled: true,
olderThan: "20",
forbiddenCountriesEnabled: true,
forbiddenCountriesListPacked: forbiddenCountriesListPacked,
ofacEnabled: [true, true, true],
vcAndDiscloseProof: vcAndDiscloseProof,
};
const types = ["0", "1", "2"];
const [readableData, success, errorCode] = await verifyAll.verifyAll(
123456, // Invalid timestamp
vcAndDiscloseHubProof,
types,
);
expect(success).to.be.false;
expect(errorCode).to.equal("INVALID_TIMESTAMP");
expect(readableData.name).to.be.empty;
});
it("should return error code 'INVALID_OFAC_ROOT' when passport number OFAC root is invalid", async () => {
const { registry, owner } = deployedActors;
await registry.connect(owner).devAddIdentityCommitment(ATTESTATION_ID.E_PASSPORT, nullifier, commitment);
vcAndDiscloseProof.pubSignals[CIRCUIT_CONSTANTS.VC_AND_DISCLOSE_PASSPORT_NO_SMT_ROOT_INDEX] =
generateRandomFieldElement();
const vcAndDiscloseHubProof: VcAndDiscloseHubProof = {
olderThanEnabled: true,
olderThan: "20",
forbiddenCountriesEnabled: true,
forbiddenCountriesListPacked: forbiddenCountriesListPacked,
ofacEnabled: [true, true, true],
vcAndDiscloseProof: vcAndDiscloseProof,
};
const types = ["0", "1", "2"];
const [readableData, success, errorCode] = await verifyAll.verifyAll(0, vcAndDiscloseHubProof, types);
expect(success).to.be.false;
expect(errorCode).to.equal("INVALID_OFAC_ROOT");
expect(readableData.name).to.be.empty;
});
it("should return error code 'INVALID_OFAC_ROOT' when name and dob OFAC root is invalid", async () => {
const { registry, owner } = deployedActors;
await registry.connect(owner).devAddIdentityCommitment(ATTESTATION_ID.E_PASSPORT, nullifier, commitment);
vcAndDiscloseProof.pubSignals[CIRCUIT_CONSTANTS.VC_AND_DISCLOSE_NAME_DOB_SMT_ROOT_INDEX] =
generateRandomFieldElement();
const vcAndDiscloseHubProof: VcAndDiscloseHubProof = {
olderThanEnabled: true,
olderThan: "20",
forbiddenCountriesEnabled: true,
forbiddenCountriesListPacked: forbiddenCountriesListPacked,
ofacEnabled: [false, true, false],
vcAndDiscloseProof: vcAndDiscloseProof,
};
const types = ["0", "1", "2"];
const [readableData, success, errorCode] = await verifyAll.verifyAll(0, vcAndDiscloseHubProof, types);
expect(success).to.be.false;
expect(errorCode).to.equal("INVALID_OFAC_ROOT");
expect(readableData.name).to.be.empty;
});
it("should return error code 'INVALID_OFAC_ROOT' when name and yob OFAC root is invalid", async () => {
const { registry, owner } = deployedActors;
await registry.connect(owner).devAddIdentityCommitment(ATTESTATION_ID.E_PASSPORT, nullifier, commitment);
vcAndDiscloseProof.pubSignals[CIRCUIT_CONSTANTS.VC_AND_DISCLOSE_NAME_YOB_SMT_ROOT_INDEX] =
generateRandomFieldElement();
const vcAndDiscloseHubProof: VcAndDiscloseHubProof = {
olderThanEnabled: true,
olderThan: "20",
forbiddenCountriesEnabled: true,
forbiddenCountriesListPacked: forbiddenCountriesListPacked,
ofacEnabled: [false, false, true],
vcAndDiscloseProof: vcAndDiscloseProof,
};
const types = ["0", "1", "2"];
const [readableData, success, errorCode] = await verifyAll.verifyAll(0, vcAndDiscloseHubProof, types);
expect(success).to.be.false;
expect(errorCode).to.equal("INVALID_OFAC_ROOT");
expect(readableData.name).to.be.empty;
});
});
});
describe("admin functions", () => {
it("should allow owner to set new hub address", async () => {
const newHubAddress = await deployedActors.user1.getAddress();
await verifyAll.setHub(newHubAddress);
});
it("should allow owner to set new registry address", async () => {
const newRegistryAddress = await deployedActors.user1.getAddress();
await verifyAll.setRegistry(newRegistryAddress);
});
it("should not allow non-owner to set new hub address", async () => {
const newHubAddress = await deployedActors.user1.getAddress();
await expect(verifyAll.connect(deployedActors.user1).setHub(newHubAddress)).to.be.revertedWithCustomError(
verifyAll,
"AccessControlUnauthorizedAccount",
);
});
it("should not allow non-owner to set new registry address", async () => {
const newRegistryAddress = await deployedActors.user1.getAddress();
await expect(
verifyAll.connect(deployedActors.user1).setRegistry(newRegistryAddress),
).to.be.revertedWithCustomError(verifyAll, "AccessControlUnauthorizedAccount");
});
});
describe("VerifyAll (Custom Error Handling)", () => {
it("should return error code 'INVALID_VC_AND_DISCLOSE_PROOF' when vcAndDisclose proof is invalid", async () => {
const { registry, owner } = deployedActors;
await registry.connect(owner).devAddIdentityCommitment(ATTESTATION_ID.E_PASSPORT, nullifier, commitment);
vcAndDiscloseProof.a[0] = generateRandomFieldElement();
const vcAndDiscloseHubProof: VcAndDiscloseHubProof = {
olderThanEnabled: true,
olderThan: "20",
forbiddenCountriesEnabled: true,
forbiddenCountriesListPacked: forbiddenCountriesListPacked,
ofacEnabled: [true, true, true],
vcAndDiscloseProof: vcAndDiscloseProof,
};
const types = ["0", "1", "2"];
const [readableData, success, errorCode] = await verifyAll.verifyAll(0, vcAndDiscloseHubProof, types);
expect(success).to.be.false;
expect(errorCode).to.equal("INVALID_VC_AND_DISCLOSE_PROOF");
expect(readableData.name).to.be.empty;
});
it("should return error code 'CURRENT_DATE_NOT_IN_VALID_RANGE' when current date is out of range", async () => {
const { registry, owner } = deployedActors;
await registry.connect(owner).devAddIdentityCommitment(ATTESTATION_ID.E_PASSPORT, nullifier, commitment);
vcAndDiscloseProof.pubSignals[CIRCUIT_CONSTANTS.VC_AND_DISCLOSE_CURRENT_DATE_INDEX] = 0;
const vcAndDiscloseHubProof: VcAndDiscloseHubProof = {
olderThanEnabled: true,
olderThan: "20",
forbiddenCountriesEnabled: true,
forbiddenCountriesListPacked: forbiddenCountriesListPacked,
ofacEnabled: [true, true, true],
vcAndDiscloseProof: vcAndDiscloseProof,
};
const types = ["0", "1", "2"];
const [readableData, success, errorCode] = await verifyAll.verifyAll(0, vcAndDiscloseHubProof, types);
expect(success).to.be.false;
expect(errorCode).to.equal("CURRENT_DATE_NOT_IN_VALID_RANGE");
expect(readableData.name).to.be.empty;
});
});
});