mirror of
https://github.com/selfxyz/self.git
synced 2026-04-05 03:00:53 -04:00
add eu id support (#527)
* add eu id support * add ofac and disclosure euid support * add contract support for euid cards --------- Co-authored-by: motemotech <i.am.nicoshark@gmail.com>
This commit is contained in:
committed by
GitHub
parent
8351609046
commit
5d01e29bf4
937
contracts/contracts/IdentityVerificationHubImplV2.sol
Normal file
937
contracts/contracts/IdentityVerificationHubImplV2.sol
Normal file
@@ -0,0 +1,937 @@
|
||||
// SPDX-License-Identifier: MIT
|
||||
pragma solidity 0.8.28;
|
||||
|
||||
import {UUPSUpgradeable} from "@openzeppelin/contracts-upgradeable/proxy/utils/UUPSUpgradeable.sol";
|
||||
import {Ownable2StepUpgradeable} from "@openzeppelin/contracts-upgradeable/access/Ownable2StepUpgradeable.sol";
|
||||
import {CircuitConstants} from "./constants/CircuitConstants.sol";
|
||||
import {AttestationId} from "./constants/AttestationId.sol";
|
||||
import {Formatter} from "./libraries/Formatter.sol";
|
||||
import {CircuitAttributeHandler} from "./libraries/CircuitAttributeHandler.sol";
|
||||
import {IIdentityVerificationHubV2} from "./interfaces/IIdentityVerificationHubV2.sol";
|
||||
import {IIdentityRegistryV1} from "./interfaces/IIdentityRegistryV1.sol";
|
||||
import {IRegisterCircuitVerifier} from "./interfaces/IRegisterCircuitVerifier.sol";
|
||||
import {IVcAndDiscloseCircuitVerifier} from "./interfaces/IVcAndDiscloseCircuitVerifier.sol";
|
||||
import {IDscCircuitVerifier} from "./interfaces/IDscCircuitVerifier.sol";
|
||||
import {ImplRoot} from "./upgradeable/ImplRoot.sol";
|
||||
import {IIdentityRegistryIdCardV1} from "./interfaces/IIdentityRegistryIdCardV1.sol";
|
||||
|
||||
/**
|
||||
* @notice ⚠️ CRITICAL STORAGE LAYOUT WARNING ⚠️
|
||||
* =============================================
|
||||
*
|
||||
* This contract uses the UUPS upgradeable pattern which makes storage layout EXTREMELY SENSITIVE.
|
||||
*
|
||||
* 🚫 NEVER MODIFY OR REORDER existing storage variables
|
||||
* 🚫 NEVER INSERT new variables between existing ones
|
||||
* 🚫 NEVER CHANGE THE TYPE of existing variables
|
||||
*
|
||||
* ✅ New storage variables MUST be added in one of these two ways ONLY:
|
||||
* 1. At the END of the storage layout
|
||||
* 2. In a new V2 contract that inherits from this V1
|
||||
*
|
||||
* Examples of forbidden changes:
|
||||
* - Changing uint256 to uint128
|
||||
* - Changing bytes32 to bytes
|
||||
* - Changing array type to mapping
|
||||
*
|
||||
* For more detailed information about forbidden changes, please refer to:
|
||||
* https://docs.openzeppelin.com/upgrades-plugins/writing-upgradeable#modifying-your-contracts
|
||||
*
|
||||
* ⚠️ VIOLATION OF THESE RULES WILL CAUSE CATASTROPHIC STORAGE COLLISIONS IN FUTURE UPGRADES ⚠️
|
||||
* =============================================
|
||||
*/
|
||||
|
||||
/**
|
||||
* @title IdentityVerificationHubStorageV2
|
||||
* @notice Storage contract for IdentityVerificationHubImplV2.
|
||||
* @dev Inherits from ImplRoot to include upgradeability functionality.
|
||||
*/
|
||||
abstract contract IdentityVerificationHubStorageV2 is
|
||||
ImplRoot
|
||||
{
|
||||
// ====================================================
|
||||
// Storage Variables
|
||||
// ====================================================
|
||||
|
||||
/// @notice Address of the Identity Registry.
|
||||
address internal _registry;
|
||||
|
||||
/// @notice Address of the VC and Disclose circuit verifier.
|
||||
address internal _vcAndDiscloseCircuitVerifier;
|
||||
|
||||
/// @notice Mapping from signature type to register circuit verifier addresses.
|
||||
mapping(uint256 => address) internal _sigTypeToRegisterCircuitVerifiers;
|
||||
|
||||
/// @notice Mapping from signature type to DSC circuit verifier addresses..
|
||||
mapping(uint256 => address) internal _sigTypeToDscCircuitVerifiers;
|
||||
|
||||
/// @notice Address of the Identity Registry for Id Cards.
|
||||
address internal _registryIdCard;
|
||||
|
||||
/// @notice Address of the VC and Disclose circuit verifier for Id Cards.
|
||||
address internal _vcAndDiscloseCircuitVerifierIdCard;
|
||||
|
||||
/// @notice Mapping from signature type to register circuit verifier addresses for Id Cards.
|
||||
mapping(uint256 => address) internal _sigTypeToRegisterCircuitVerifiersIdCard;
|
||||
|
||||
/// @notice Mapping from signature type to DSC circuit verifier addresses for Id Cards.
|
||||
mapping(uint256 => address) internal _sigTypeToDscCircuitVerifiersIdCard;
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* @title IdentityVerificationHubImplV2
|
||||
* @notice Implementation contract for the Identity Verification Hub.
|
||||
* @dev Provides functions for registering commitments and verifying groth16 proofs and inclusion proofs.
|
||||
*/
|
||||
contract IdentityVerificationHubImplV2 is
|
||||
IdentityVerificationHubStorageV2,
|
||||
IIdentityVerificationHubV2
|
||||
{
|
||||
using Formatter for uint256;
|
||||
|
||||
uint256 constant MAX_FORBIDDEN_COUNTRIES_LIST_LENGTH = 40;
|
||||
|
||||
// ====================================================
|
||||
// Events
|
||||
// ====================================================
|
||||
|
||||
/**
|
||||
* @notice Emitted when the hub is initialized.
|
||||
* @param registry The address of the registry.
|
||||
* @param vcAndDiscloseCircuitVerifier The address of the VC and Disclose circuit verifier.
|
||||
* @param registerCircuitVerifierIds Array of register circuit verifier ids.
|
||||
* @param registerCircuitVerifiers Array of register circuit verifier addresses.
|
||||
* @param dscCircuitVerifierIds Array of DSC circuit verifier ids.
|
||||
* @param dscCircuitVerifiers Array of DSC circuit verifier addresses.
|
||||
*/
|
||||
event HubInitialized(
|
||||
address registry,
|
||||
address vcAndDiscloseCircuitVerifier,
|
||||
uint256[] registerCircuitVerifierIds,
|
||||
address[] registerCircuitVerifiers,
|
||||
uint256[] dscCircuitVerifierIds,
|
||||
address[] dscCircuitVerifiers,
|
||||
address registryIdCard,
|
||||
address vcAndDiscloseCircuitVerifierIdCard,
|
||||
uint256[] registerCircuitVerifierIdsIdCard,
|
||||
address[] registerCircuitVerifiersIdCard,
|
||||
uint256[] dscCircuitVerifierIdsIdCard,
|
||||
address[] dscCircuitVerifiersIdCard
|
||||
);
|
||||
/**
|
||||
* @notice Emitted when the registry address is updated.
|
||||
* @param registry The new registry address.
|
||||
*/
|
||||
event RegistryUpdated(address registry);
|
||||
/**
|
||||
* @notice Emitted when the VC and Disclose circuit verifier is updated.
|
||||
* @param vcAndDiscloseCircuitVerifier The new VC and Disclose circuit verifier address.
|
||||
*/
|
||||
event VcAndDiscloseCircuitUpdated(address vcAndDiscloseCircuitVerifier);
|
||||
/**
|
||||
* @notice Emitted when a register circuit verifier is updated.
|
||||
* @param typeId The signature type id.
|
||||
* @param verifier The new verifier address for the register circuit.
|
||||
*/
|
||||
event RegisterCircuitVerifierUpdated(uint256 typeId, address verifier);
|
||||
/**
|
||||
* @notice Emitted when a DSC circuit verifier is updated.
|
||||
* @param typeId The signature type id.
|
||||
* @param verifier The new verifier address for the DSC circuit.
|
||||
*/
|
||||
event DscCircuitVerifierUpdated(uint256 typeId, address verifier);
|
||||
|
||||
// ====================================================
|
||||
// Errors
|
||||
// ====================================================
|
||||
|
||||
/// @notice Thrown when the lengths of provided arrays do not match.
|
||||
/// @dev Used when initializing or updating arrays that must have equal length.
|
||||
error LENGTH_MISMATCH();
|
||||
|
||||
/// @notice Thrown when no verifier is set for a given signature type.
|
||||
/// @dev Indicates that the mapping lookup for the verifier returned the zero address.
|
||||
error NO_VERIFIER_SET();
|
||||
|
||||
/// @notice Thrown when the current date in the proof is not within the valid range.
|
||||
/// @dev Ensures that the provided proof's date is within one day of the expected start time.
|
||||
error CURRENT_DATE_NOT_IN_VALID_RANGE();
|
||||
|
||||
/// @notice Thrown when the 'older than' attribute in the proof is invalid.
|
||||
/// @dev The 'older than' value derived from the proof does not match the expected criteria.
|
||||
error INVALID_OLDER_THAN();
|
||||
|
||||
/// @notice Thrown when the provided forbidden countries list is invalid.
|
||||
/// @dev The forbidden countries list in the proof does not match the expected packed data.
|
||||
error INVALID_FORBIDDEN_COUNTRIES();
|
||||
|
||||
/// @notice Thrown when the OFAC check fails.
|
||||
/// @dev Indicates that the proof did not satisfy the required OFAC conditions.
|
||||
error INVALID_OFAC();
|
||||
|
||||
/// @notice Thrown when the register circuit proof is invalid.
|
||||
/// @dev The register circuit verifier did not validate the provided proof.
|
||||
error INVALID_REGISTER_PROOF();
|
||||
|
||||
/// @notice Thrown when the DSC circuit proof is invalid.
|
||||
/// @dev The DSC circuit verifier did not validate the provided proof.
|
||||
error INVALID_DSC_PROOF();
|
||||
|
||||
/// @notice Thrown when the VC and Disclose proof is invalid.
|
||||
/// @dev The VC and Disclose circuit verifier did not validate the provided proof.
|
||||
error INVALID_VC_AND_DISCLOSE_PROOF();
|
||||
|
||||
/// @notice Thrown when the provided commitment root is invalid.
|
||||
/// @dev Used in proofs to ensure that the commitment root matches the expected value in the registry.
|
||||
error INVALID_COMMITMENT_ROOT();
|
||||
|
||||
/// @notice Thrown when the provided OFAC root is invalid.
|
||||
/// @dev Indicates that the OFAC root from the proof does not match the expected OFAC root.
|
||||
error INVALID_OFAC_ROOT();
|
||||
|
||||
/// @notice Thrown when the provided CSCA root is invalid.
|
||||
/// @dev Indicates that the CSCA root from the DSC proof does not match the expected CSCA root.
|
||||
error INVALID_CSCA_ROOT();
|
||||
|
||||
/// @notice Thrown when the revealed data type is invalid or not supported.
|
||||
/// @dev Raised during the processing of revealed data if it does not match any supported type.
|
||||
error INVALID_REVEALED_DATA_TYPE();
|
||||
|
||||
// ====================================================
|
||||
// Constructor
|
||||
// ====================================================
|
||||
|
||||
/**
|
||||
* @notice Constructor that disables initializers.
|
||||
* @dev Prevents direct initialization of the implementation contract.
|
||||
*/
|
||||
constructor() {
|
||||
_disableInitializers();
|
||||
}
|
||||
|
||||
// ====================================================
|
||||
// Initializer
|
||||
// ====================================================
|
||||
|
||||
/**
|
||||
* @notice Initializes the hub implementation.
|
||||
* @dev Sets the registry, VC and Disclose circuit verifier address, register circuit verifiers, and DSC circuit verifiers.
|
||||
* @param registryAddress The address of the Identity Registry.
|
||||
* @param vcAndDiscloseCircuitVerifierAddress The address of the VC and Disclose circuit verifier.
|
||||
* @param registerCircuitVerifierIds Array of ids for register circuit verifiers.
|
||||
* @param registerCircuitVerifierAddresses Array of addresses for register circuit verifiers.
|
||||
* @param dscCircuitVerifierIds Array of ids for DSC circuit verifiers.
|
||||
* @param dscCircuitVerifierAddresses Array of addresses for DSC circuit verifiers.
|
||||
*/
|
||||
function initialize(
|
||||
address registryAddress,
|
||||
address vcAndDiscloseCircuitVerifierAddress,
|
||||
uint256[] memory registerCircuitVerifierIds,
|
||||
address[] memory registerCircuitVerifierAddresses,
|
||||
uint256[] memory dscCircuitVerifierIds,
|
||||
address[] memory dscCircuitVerifierAddresses,
|
||||
address registryIdCardAddress,
|
||||
address vcAndDiscloseCircuitVerifierIdCardAddress,
|
||||
uint256[] memory registerCircuitVerifierIdsIdCard,
|
||||
address[] memory registerCircuitVerifiersIdCardAddresses,
|
||||
uint256[] memory dscCircuitVerifierIdsIdCard,
|
||||
address[] memory dscCircuitVerifiersIdCardAddresses
|
||||
) external initializer {
|
||||
__ImplRoot_init();
|
||||
_registry = registryAddress;
|
||||
_vcAndDiscloseCircuitVerifier = vcAndDiscloseCircuitVerifierAddress;
|
||||
if (registerCircuitVerifierIds.length != registerCircuitVerifierAddresses.length) {
|
||||
revert LENGTH_MISMATCH();
|
||||
}
|
||||
if (dscCircuitVerifierIds.length != dscCircuitVerifierAddresses.length) {
|
||||
revert LENGTH_MISMATCH();
|
||||
}
|
||||
for (uint256 i = 0; i < registerCircuitVerifierIds.length; i++) {
|
||||
_sigTypeToRegisterCircuitVerifiers[registerCircuitVerifierIds[i]] = registerCircuitVerifierAddresses[i];
|
||||
}
|
||||
for (uint256 i = 0; i < dscCircuitVerifierIds.length; i++) {
|
||||
_sigTypeToDscCircuitVerifiers[dscCircuitVerifierIds[i]] = dscCircuitVerifierAddresses[i];
|
||||
}
|
||||
_registryIdCard = registryIdCardAddress;
|
||||
_vcAndDiscloseCircuitVerifierIdCard = vcAndDiscloseCircuitVerifierIdCardAddress;
|
||||
if (registerCircuitVerifierIdsIdCard.length != registerCircuitVerifiersIdCardAddresses.length) {
|
||||
revert LENGTH_MISMATCH();
|
||||
}
|
||||
if (dscCircuitVerifierIdsIdCard.length != dscCircuitVerifiersIdCardAddresses.length) {
|
||||
revert LENGTH_MISMATCH();
|
||||
}
|
||||
for (uint256 i = 0; i < registerCircuitVerifierIdsIdCard.length; i++) {
|
||||
_sigTypeToRegisterCircuitVerifiersIdCard[registerCircuitVerifierIdsIdCard[i]] = registerCircuitVerifiersIdCardAddresses[i];
|
||||
}
|
||||
for (uint256 i = 0; i < dscCircuitVerifierIdsIdCard.length; i++) {
|
||||
_sigTypeToDscCircuitVerifiersIdCard[dscCircuitVerifierIdsIdCard[i]] = dscCircuitVerifiersIdCardAddresses[i];
|
||||
}
|
||||
emit HubInitialized(
|
||||
registryAddress,
|
||||
vcAndDiscloseCircuitVerifierAddress,
|
||||
registerCircuitVerifierIds,
|
||||
registerCircuitVerifierAddresses,
|
||||
dscCircuitVerifierIds,
|
||||
dscCircuitVerifierAddresses,
|
||||
registryIdCardAddress,
|
||||
vcAndDiscloseCircuitVerifierIdCardAddress,
|
||||
registerCircuitVerifierIdsIdCard,
|
||||
registerCircuitVerifiersIdCardAddresses,
|
||||
dscCircuitVerifierIdsIdCard,
|
||||
dscCircuitVerifiersIdCardAddresses
|
||||
);
|
||||
}
|
||||
|
||||
// ====================================================
|
||||
// External View Functions
|
||||
// ====================================================
|
||||
|
||||
/**
|
||||
* @notice Retrieves the registry address.
|
||||
* @return The address of the Identity Registry.
|
||||
*/
|
||||
function registry()
|
||||
external
|
||||
virtual
|
||||
onlyProxy
|
||||
view
|
||||
returns (address)
|
||||
{
|
||||
return _registry;
|
||||
}
|
||||
|
||||
/**
|
||||
* @notice Retrieves the VC and Disclose circuit verifier address.
|
||||
* @return The address of the VC and Disclose circuit verifier.
|
||||
*/
|
||||
function vcAndDiscloseCircuitVerifier()
|
||||
external
|
||||
virtual
|
||||
onlyProxy
|
||||
view
|
||||
returns (address)
|
||||
{
|
||||
return _vcAndDiscloseCircuitVerifier;
|
||||
}
|
||||
|
||||
/**
|
||||
* @notice Retrieves the register circuit verifier address for a given signature type.
|
||||
* @param typeId The signature type identifier.
|
||||
* @return The register circuit verifier address.
|
||||
*/
|
||||
function sigTypeToRegisterCircuitVerifiers(
|
||||
uint256 typeId
|
||||
)
|
||||
external
|
||||
virtual
|
||||
onlyProxy
|
||||
view
|
||||
returns (address)
|
||||
{
|
||||
return _sigTypeToRegisterCircuitVerifiers[typeId];
|
||||
}
|
||||
|
||||
/**
|
||||
* @notice Retrieves the DSC circuit verifier address for a given signature type.
|
||||
* @param typeId The signature type identifier.
|
||||
* @return The DSC circuit verifier address.
|
||||
*/
|
||||
function sigTypeToDscCircuitVerifiers(
|
||||
uint256 typeId
|
||||
)
|
||||
external
|
||||
virtual
|
||||
onlyProxy
|
||||
view
|
||||
returns (address)
|
||||
{
|
||||
return _sigTypeToDscCircuitVerifiers[typeId];
|
||||
}
|
||||
|
||||
/**
|
||||
* @notice Converts packed revealed data into a human-readable format.
|
||||
* @dev Uses Formatter and CircuitAttributeHandler to decode the data.
|
||||
* @param revealedDataPacked An array of three packed uint256 values.
|
||||
* @param types An array of RevealedDataType indicating the types of data expected.
|
||||
* @return A ReadableRevealedData struct containing the decoded data.
|
||||
*/
|
||||
function getReadableRevealedData(
|
||||
uint256[3] memory revealedDataPacked,
|
||||
RevealedDataType[] memory types
|
||||
)
|
||||
external
|
||||
virtual
|
||||
onlyProxy
|
||||
view
|
||||
returns (ReadableRevealedData memory)
|
||||
{
|
||||
bytes memory charcodes = Formatter.fieldElementsToBytes(
|
||||
revealedDataPacked
|
||||
);
|
||||
|
||||
ReadableRevealedData memory attrs;
|
||||
|
||||
for (uint256 i = 0; i < types.length; i++) {
|
||||
RevealedDataType dataType = types[i];
|
||||
if (dataType == RevealedDataType.ISSUING_STATE) {
|
||||
attrs.issuingState = CircuitAttributeHandler.getIssuingState(charcodes);
|
||||
} else if (dataType == RevealedDataType.NAME) {
|
||||
attrs.name = CircuitAttributeHandler.getName(charcodes);
|
||||
} else if (dataType == RevealedDataType.PASSPORT_NUMBER) {
|
||||
attrs.passportNumber = CircuitAttributeHandler.getPassportNumber(charcodes);
|
||||
} else if (dataType == RevealedDataType.NATIONALITY) {
|
||||
attrs.nationality = CircuitAttributeHandler.getNationality(charcodes);
|
||||
} else if (dataType == RevealedDataType.DATE_OF_BIRTH) {
|
||||
attrs.dateOfBirth = CircuitAttributeHandler.getDateOfBirth(charcodes);
|
||||
} else if (dataType == RevealedDataType.GENDER) {
|
||||
attrs.gender = CircuitAttributeHandler.getGender(charcodes);
|
||||
} else if (dataType == RevealedDataType.EXPIRY_DATE) {
|
||||
attrs.expiryDate = CircuitAttributeHandler.getExpiryDate(charcodes);
|
||||
} else if (dataType == RevealedDataType.OLDER_THAN) {
|
||||
attrs.olderThan = CircuitAttributeHandler.getOlderThan(charcodes);
|
||||
} else if (dataType == RevealedDataType.PASSPORT_NO_OFAC) {
|
||||
attrs.passportNoOfac = CircuitAttributeHandler.getPassportNoOfac(charcodes);
|
||||
} else if (dataType == RevealedDataType.NAME_AND_DOB_OFAC) {
|
||||
attrs.nameAndDobOfac = CircuitAttributeHandler.getNameAndDobOfac(charcodes);
|
||||
} else if (dataType == RevealedDataType.NAME_AND_YOB_OFAC) {
|
||||
attrs.nameAndYobOfac = CircuitAttributeHandler.getNameAndYobOfac(charcodes);
|
||||
}
|
||||
}
|
||||
|
||||
return attrs;
|
||||
}
|
||||
|
||||
/**
|
||||
* @notice Extracts the forbidden countries list from packed data.
|
||||
* @param forbiddenCountriesListPacked Packed data representing forbidden countries.
|
||||
* @return An array of strings with a maximum length of MAX_FORBIDDEN_COUNTRIES_LIST_LENGTH.
|
||||
*/
|
||||
function getReadableForbiddenCountries(
|
||||
uint256[4] memory forbiddenCountriesListPacked
|
||||
)
|
||||
external
|
||||
virtual
|
||||
onlyProxy
|
||||
view
|
||||
returns (string[MAX_FORBIDDEN_COUNTRIES_LIST_LENGTH] memory)
|
||||
{
|
||||
return Formatter.extractForbiddenCountriesFromPacked(forbiddenCountriesListPacked);
|
||||
}
|
||||
|
||||
/**
|
||||
* @notice Verifies the VC and Disclose proof.
|
||||
* @dev Checks commitment roots, OFAC root, current date range, and other attributes depending on verification configuration.
|
||||
* @param proof The VcAndDiscloseHubProof containing the proof data.
|
||||
* @return result A VcAndDiscloseVerificationResult struct with the verification results.
|
||||
*/
|
||||
function verifyVcAndDisclose(
|
||||
VcAndDiscloseHubProof memory proof
|
||||
)
|
||||
external
|
||||
virtual
|
||||
view
|
||||
onlyProxy
|
||||
returns (VcAndDiscloseVerificationResult memory)
|
||||
{
|
||||
VcAndDiscloseVerificationResult memory result;
|
||||
|
||||
result.identityCommitmentRoot = _verifyVcAndDiscloseProof(proof);
|
||||
|
||||
for (uint256 i = 0; i < 3; i++) {
|
||||
result.revealedDataPacked[i] = proof.vcAndDiscloseProof.pubSignals[CircuitConstants.VC_AND_DISCLOSE_REVEALED_DATA_PACKED_INDEX + i];
|
||||
}
|
||||
for (uint256 i = 0; i < 4; i++) {
|
||||
result.forbiddenCountriesListPacked[i] = proof.vcAndDiscloseProof.pubSignals[CircuitConstants.VC_AND_DISCLOSE_FORBIDDEN_COUNTRIES_LIST_PACKED_INDEX + i];
|
||||
}
|
||||
result.nullifier = proof.vcAndDiscloseProof.pubSignals[CircuitConstants.VC_AND_DISCLOSE_NULLIFIER_INDEX];
|
||||
result.attestationId = proof.vcAndDiscloseProof.pubSignals[CircuitConstants.VC_AND_DISCLOSE_ATTESTATION_ID_INDEX];
|
||||
result.userIdentifier = proof.vcAndDiscloseProof.pubSignals[CircuitConstants.VC_AND_DISCLOSE_USER_IDENTIFIER_INDEX];
|
||||
result.scope = proof.vcAndDiscloseProof.pubSignals[CircuitConstants.VC_AND_DISCLOSE_SCOPE_INDEX];
|
||||
return result;
|
||||
}
|
||||
|
||||
// ====================================================
|
||||
// External Functions - Registration
|
||||
// ====================================================
|
||||
|
||||
/**
|
||||
* @notice Registers a passport commitment using a register circuit proof.
|
||||
* @dev Verifies the proof and then calls the Identity Registry to register the commitment.
|
||||
* @param registerCircuitVerifierId The identifier for the register circuit verifier to use.
|
||||
* @param registerCircuitProof The register circuit proof data.
|
||||
*/
|
||||
function registerPassportCommitment(
|
||||
uint256 registerCircuitVerifierId,
|
||||
IRegisterCircuitVerifier.RegisterCircuitProof memory registerCircuitProof
|
||||
)
|
||||
external
|
||||
virtual
|
||||
onlyProxy
|
||||
{
|
||||
_verifyPassportRegisterProof(registerCircuitVerifierId, registerCircuitProof);
|
||||
IIdentityRegistryV1(_registry).registerCommitment(
|
||||
AttestationId.E_PASSPORT,
|
||||
registerCircuitProof.pubSignals[CircuitConstants.REGISTER_NULLIFIER_INDEX],
|
||||
registerCircuitProof.pubSignals[CircuitConstants.REGISTER_COMMITMENT_INDEX]
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* @notice Registers a DSC key commitment using a DSC circuit proof.
|
||||
* @dev Verifies the DSC proof and then calls the Identity Registry to register the dsc key commitment.
|
||||
* @param dscCircuitVerifierId The identifier for the DSC circuit verifier to use.
|
||||
* @param dscCircuitProof The DSC circuit proof data.
|
||||
*/
|
||||
function registerDscKeyCommitment(
|
||||
uint256 dscCircuitVerifierId,
|
||||
IDscCircuitVerifier.DscCircuitProof memory dscCircuitProof
|
||||
)
|
||||
external
|
||||
virtual
|
||||
onlyProxy
|
||||
{
|
||||
_verifyPassportDscProof(dscCircuitVerifierId, dscCircuitProof);
|
||||
IIdentityRegistryV1(_registry).registerDscKeyCommitment(
|
||||
dscCircuitProof.pubSignals[CircuitConstants.DSC_TREE_LEAF_INDEX]
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* @notice Registers an Id Card commitment using a register circuit proof.
|
||||
* @dev Verifies the proof and then calls the Id Card Identity Registry to register the commitment.
|
||||
* @param registerCircuitVerifierId The identifier for the register circuit verifier to use.
|
||||
* @param registerCircuitProof The register circuit proof data.
|
||||
*/
|
||||
function registerIdCardCommitment(
|
||||
uint256 registerCircuitVerifierId,
|
||||
IRegisterCircuitVerifier.RegisterCircuitProof memory registerCircuitProof
|
||||
)
|
||||
external
|
||||
onlyProxy
|
||||
{
|
||||
_verifyIdCardRegisterProof(registerCircuitVerifierId, registerCircuitProof);
|
||||
IIdentityRegistryIdCardV1(_registryIdCard).registerCommitment(
|
||||
AttestationId.ID_CARD,
|
||||
registerCircuitProof.pubSignals[CircuitConstants.REGISTER_NULLIFIER_INDEX],
|
||||
registerCircuitProof.pubSignals[CircuitConstants.REGISTER_COMMITMENT_INDEX]
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* @notice Registers an Id Card DSC key commitment using a DSC circuit proof.
|
||||
* @dev Verifies the DSC proof and then calls the Id Card Identity Registry to register the dsc key commitment.
|
||||
* @param dscCircuitVerifierId The identifier for the DSC circuit verifier to use.
|
||||
* @param dscCircuitProof The DSC circuit proof data.
|
||||
*/
|
||||
function registerIdCardDscKeyCommitment(
|
||||
uint256 dscCircuitVerifierId,
|
||||
IDscCircuitVerifier.DscCircuitProof memory dscCircuitProof
|
||||
)
|
||||
external
|
||||
onlyProxy
|
||||
{
|
||||
_verifyIdCardDscProof(dscCircuitVerifierId, dscCircuitProof);
|
||||
IIdentityRegistryIdCardV1(_registryIdCard).registerDscKeyCommitment(
|
||||
dscCircuitProof.pubSignals[CircuitConstants.DSC_TREE_LEAF_INDEX]
|
||||
);
|
||||
}
|
||||
|
||||
// ====================================================
|
||||
// External Functions - Only Owner
|
||||
// ====================================================
|
||||
|
||||
/**
|
||||
* @notice Updates the registry address.
|
||||
* @param registryAddress The new registry address.
|
||||
*/
|
||||
function updateRegistry(
|
||||
address registryAddress
|
||||
)
|
||||
external
|
||||
virtual
|
||||
onlyProxy
|
||||
onlyOwner
|
||||
{
|
||||
_registry = registryAddress;
|
||||
emit RegistryUpdated(registryAddress);
|
||||
}
|
||||
|
||||
/**
|
||||
* @notice Updates the VC and Disclose circuit verifier address.
|
||||
* @param vcAndDiscloseCircuitVerifierAddress The new VC and Disclose circuit verifier address.
|
||||
*/
|
||||
function updateVcAndDiscloseCircuit(
|
||||
address vcAndDiscloseCircuitVerifierAddress
|
||||
)
|
||||
external
|
||||
virtual
|
||||
onlyProxy
|
||||
onlyOwner
|
||||
{
|
||||
_vcAndDiscloseCircuitVerifier = vcAndDiscloseCircuitVerifierAddress;
|
||||
emit VcAndDiscloseCircuitUpdated(vcAndDiscloseCircuitVerifierAddress);
|
||||
}
|
||||
|
||||
/**
|
||||
* @notice Updates the register circuit verifier for a specific signature type.
|
||||
* @param typeId The signature type identifier.
|
||||
* @param verifierAddress The new register circuit verifier address.
|
||||
*/
|
||||
function updateRegisterCircuitVerifier(
|
||||
uint256 typeId,
|
||||
address verifierAddress
|
||||
)
|
||||
external
|
||||
virtual
|
||||
onlyProxy
|
||||
onlyOwner
|
||||
{
|
||||
_sigTypeToRegisterCircuitVerifiers[typeId] = verifierAddress;
|
||||
emit RegisterCircuitVerifierUpdated(typeId, verifierAddress);
|
||||
}
|
||||
|
||||
/**
|
||||
* @notice Updates the DSC circuit verifier for a specific signature type.
|
||||
* @param typeId The signature type identifier.
|
||||
* @param verifierAddress The new DSC circuit verifier address.
|
||||
*/
|
||||
function updateDscVerifier(
|
||||
uint256 typeId,
|
||||
address verifierAddress
|
||||
)
|
||||
external
|
||||
virtual
|
||||
onlyProxy
|
||||
onlyOwner
|
||||
{
|
||||
_sigTypeToDscCircuitVerifiers[typeId] = verifierAddress;
|
||||
emit DscCircuitVerifierUpdated(typeId, verifierAddress);
|
||||
}
|
||||
|
||||
/**
|
||||
* @notice Batch updates register circuit verifiers.
|
||||
* @param typeIds An array of signature type identifiers.
|
||||
* @param verifierAddresses An array of new register circuit verifier addresses.
|
||||
*/
|
||||
function batchUpdateRegisterCircuitVerifiers(
|
||||
uint256[] calldata typeIds,
|
||||
address[] calldata verifierAddresses
|
||||
)
|
||||
external
|
||||
virtual
|
||||
onlyProxy
|
||||
onlyOwner
|
||||
{
|
||||
if (typeIds.length != verifierAddresses.length) {
|
||||
revert LENGTH_MISMATCH();
|
||||
}
|
||||
for (uint256 i = 0; i < typeIds.length; i++) {
|
||||
_sigTypeToRegisterCircuitVerifiers[typeIds[i]] = verifierAddresses[i];
|
||||
emit RegisterCircuitVerifierUpdated(typeIds[i], verifierAddresses[i]);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @notice Batch updates DSC circuit verifiers.
|
||||
* @param typeIds An array of signature type identifiers.
|
||||
* @param verifierAddresses An array of new DSC circuit verifier addresses.
|
||||
*/
|
||||
function batchUpdateDscCircuitVerifiers(
|
||||
uint256[] calldata typeIds,
|
||||
address[] calldata verifierAddresses
|
||||
)
|
||||
external
|
||||
virtual
|
||||
onlyProxy
|
||||
onlyOwner
|
||||
{
|
||||
if (typeIds.length != verifierAddresses.length) {
|
||||
revert LENGTH_MISMATCH();
|
||||
}
|
||||
for (uint256 i = 0; i < typeIds.length; i++) {
|
||||
_sigTypeToDscCircuitVerifiers[typeIds[i]] = verifierAddresses[i];
|
||||
emit DscCircuitVerifierUpdated(typeIds[i], verifierAddresses[i]);
|
||||
}
|
||||
}
|
||||
|
||||
// ====================================================
|
||||
// External View Functions - Id Card
|
||||
// ====================================================
|
||||
|
||||
/**
|
||||
* @notice Retrieves the Id Card registry address.
|
||||
* @return The address of the Id Card Identity Registry.
|
||||
*/
|
||||
function registryIdCard()
|
||||
external
|
||||
view
|
||||
onlyProxy
|
||||
returns (address)
|
||||
{
|
||||
return _registryIdCard;
|
||||
}
|
||||
|
||||
/**
|
||||
* @notice Retrieves the Id Card VC and Disclose circuit verifier address.
|
||||
* @return The address of the Id Card VC and Disclose circuit verifier.
|
||||
*/
|
||||
function vcAndDiscloseCircuitVerifierIdCard()
|
||||
external
|
||||
view
|
||||
onlyProxy
|
||||
returns (address)
|
||||
{
|
||||
return _vcAndDiscloseCircuitVerifierIdCard;
|
||||
}
|
||||
|
||||
/**
|
||||
* @notice Retrieves the Id Card register circuit verifier address for a given signature type.
|
||||
* @param typeId The signature type identifier.
|
||||
* @return The Id Card register circuit verifier address.
|
||||
*/
|
||||
function sigTypeToRegisterCircuitVerifiersIdCard(
|
||||
uint256 typeId
|
||||
)
|
||||
external
|
||||
view
|
||||
onlyProxy
|
||||
returns (address)
|
||||
{
|
||||
return _sigTypeToRegisterCircuitVerifiersIdCard[typeId];
|
||||
}
|
||||
|
||||
/**
|
||||
* @notice Retrieves the Id Card DSC circuit verifier address for a given signature type.
|
||||
* @param typeId The signature type identifier.
|
||||
* @return The Id Card DSC circuit verifier address.
|
||||
*/
|
||||
function sigTypeToDscCircuitVerifiersIdCard(
|
||||
uint256 typeId
|
||||
)
|
||||
external
|
||||
view
|
||||
onlyProxy
|
||||
returns (address)
|
||||
{
|
||||
return _sigTypeToDscCircuitVerifiersIdCard[typeId];
|
||||
}
|
||||
|
||||
// ====================================================
|
||||
// Internal Functions
|
||||
// ====================================================
|
||||
|
||||
/**
|
||||
* @notice Verifies the VC and Disclose proof.
|
||||
* @dev Checks commitment roots, OFAC root, current date range, and other attributes depending on verification configuration.
|
||||
* @param proof The VcAndDiscloseHubProof containing the proof data.
|
||||
* @return identityCommitmentRoot The verified identity commitment root from the proof.
|
||||
*/
|
||||
function _verifyVcAndDiscloseProof(
|
||||
VcAndDiscloseHubProof memory proof
|
||||
)
|
||||
internal
|
||||
view
|
||||
returns (uint256 identityCommitmentRoot)
|
||||
{
|
||||
// verify identity commitment root
|
||||
if (!IIdentityRegistryV1(_registry).checkIdentityCommitmentRoot(proof.vcAndDiscloseProof.pubSignals[CircuitConstants.VC_AND_DISCLOSE_MERKLE_ROOT_INDEX])) {
|
||||
revert INVALID_COMMITMENT_ROOT();
|
||||
}
|
||||
|
||||
// verify current date
|
||||
uint[6] memory dateNum;
|
||||
for (uint256 i = 0; i < 6; i++) {
|
||||
dateNum[i] = proof.vcAndDiscloseProof.pubSignals[CircuitConstants.VC_AND_DISCLOSE_CURRENT_DATE_INDEX + i];
|
||||
}
|
||||
|
||||
uint currentTimestamp = Formatter.proofDateToUnixTimestamp(dateNum);
|
||||
if(
|
||||
currentTimestamp < _getStartOfDayTimestamp() - 1 days + 1 ||
|
||||
currentTimestamp > _getStartOfDayTimestamp() + 1 days - 1
|
||||
) {
|
||||
revert CURRENT_DATE_NOT_IN_VALID_RANGE();
|
||||
}
|
||||
|
||||
// verify attributes
|
||||
uint256[3] memory revealedDataPacked;
|
||||
for (uint256 i = 0; i < 3; i++) {
|
||||
revealedDataPacked[i] = proof.vcAndDiscloseProof.pubSignals[CircuitConstants.VC_AND_DISCLOSE_REVEALED_DATA_PACKED_INDEX + i];
|
||||
}
|
||||
if (proof.olderThanEnabled) {
|
||||
if (!CircuitAttributeHandler.compareOlderThan(Formatter.fieldElementsToBytes(revealedDataPacked), proof.olderThan)) {
|
||||
revert INVALID_OLDER_THAN();
|
||||
}
|
||||
}
|
||||
if (proof.ofacEnabled[0] || proof.ofacEnabled[1] || proof.ofacEnabled[2]) {
|
||||
if (!CircuitAttributeHandler.compareOfac(
|
||||
Formatter.fieldElementsToBytes(revealedDataPacked),
|
||||
proof.ofacEnabled[0],
|
||||
proof.ofacEnabled[1],
|
||||
proof.ofacEnabled[2]
|
||||
)) {
|
||||
revert INVALID_OFAC();
|
||||
}
|
||||
if (!IIdentityRegistryV1(_registry).checkOfacRoots(
|
||||
proof.vcAndDiscloseProof.pubSignals[CircuitConstants.VC_AND_DISCLOSE_PASSPORT_NO_SMT_ROOT_INDEX],
|
||||
proof.vcAndDiscloseProof.pubSignals[CircuitConstants.VC_AND_DISCLOSE_NAME_DOB_SMT_ROOT_INDEX],
|
||||
proof.vcAndDiscloseProof.pubSignals[CircuitConstants.VC_AND_DISCLOSE_NAME_YOB_SMT_ROOT_INDEX]
|
||||
)) {
|
||||
revert INVALID_OFAC_ROOT();
|
||||
}
|
||||
}
|
||||
if (proof.forbiddenCountriesEnabled) {
|
||||
for (uint256 i = 0; i < 4; i++) {
|
||||
if (
|
||||
proof.forbiddenCountriesListPacked[i] != proof.vcAndDiscloseProof.pubSignals[CircuitConstants.VC_AND_DISCLOSE_FORBIDDEN_COUNTRIES_LIST_PACKED_INDEX + i]
|
||||
) {
|
||||
revert INVALID_FORBIDDEN_COUNTRIES();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// verify the proof using the VC and Disclose circuit verifier
|
||||
if (!IVcAndDiscloseCircuitVerifier(_vcAndDiscloseCircuitVerifier).verifyProof(proof.vcAndDiscloseProof.a, proof.vcAndDiscloseProof.b, proof.vcAndDiscloseProof.c, proof.vcAndDiscloseProof.pubSignals)) {
|
||||
revert INVALID_VC_AND_DISCLOSE_PROOF();
|
||||
}
|
||||
|
||||
return proof.vcAndDiscloseProof.pubSignals[CircuitConstants.VC_AND_DISCLOSE_MERKLE_ROOT_INDEX];
|
||||
}
|
||||
|
||||
/**
|
||||
* @notice Verifies the passport register circuit proof.
|
||||
* @dev Uses the register circuit verifier specified by registerCircuitVerifierId.
|
||||
* @param registerCircuitVerifierId The identifier for the register circuit verifier.
|
||||
* @param registerCircuitProof The register circuit proof data.
|
||||
*/
|
||||
function _verifyPassportRegisterProof(
|
||||
uint256 registerCircuitVerifierId,
|
||||
IRegisterCircuitVerifier.RegisterCircuitProof memory registerCircuitProof
|
||||
)
|
||||
internal
|
||||
view
|
||||
{
|
||||
address verifier = _sigTypeToRegisterCircuitVerifiers[registerCircuitVerifierId];
|
||||
if (verifier == address(0)) {
|
||||
revert NO_VERIFIER_SET();
|
||||
}
|
||||
|
||||
if (!IIdentityRegistryV1(_registry).checkDscKeyCommitmentMerkleRoot(registerCircuitProof.pubSignals[CircuitConstants.REGISTER_MERKLE_ROOT_INDEX])) {
|
||||
revert INVALID_COMMITMENT_ROOT();
|
||||
}
|
||||
|
||||
if(!IRegisterCircuitVerifier(verifier).verifyProof(
|
||||
registerCircuitProof.a,
|
||||
registerCircuitProof.b,
|
||||
registerCircuitProof.c,
|
||||
registerCircuitProof.pubSignals
|
||||
)) {
|
||||
revert INVALID_REGISTER_PROOF();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @notice Verifies the passport DSC circuit proof.
|
||||
* @dev Uses the DSC circuit verifier specified by dscCircuitVerifierId.
|
||||
* @param dscCircuitVerifierId The identifier for the DSC circuit verifier.
|
||||
* @param dscCircuitProof The DSC circuit proof data.
|
||||
*/
|
||||
function _verifyPassportDscProof(
|
||||
uint256 dscCircuitVerifierId,
|
||||
IDscCircuitVerifier.DscCircuitProof memory dscCircuitProof
|
||||
)
|
||||
internal
|
||||
view
|
||||
{
|
||||
address verifier = _sigTypeToDscCircuitVerifiers[dscCircuitVerifierId];
|
||||
if (verifier == address(0)) {
|
||||
revert NO_VERIFIER_SET();
|
||||
}
|
||||
|
||||
if (!IIdentityRegistryV1(_registry).checkCscaRoot(dscCircuitProof.pubSignals[CircuitConstants.DSC_CSCA_ROOT_INDEX])) {
|
||||
revert INVALID_CSCA_ROOT();
|
||||
}
|
||||
|
||||
if(!IDscCircuitVerifier(verifier).verifyProof(
|
||||
dscCircuitProof.a,
|
||||
dscCircuitProof.b,
|
||||
dscCircuitProof.c,
|
||||
dscCircuitProof.pubSignals
|
||||
)) {
|
||||
revert INVALID_DSC_PROOF();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @notice Verifies the Id Card register circuit proof.
|
||||
* @dev Uses the register circuit verifier specified by registerCircuitVerifierId for Id Cards.
|
||||
* @param registerCircuitVerifierId The identifier for the register circuit verifier.
|
||||
* @param registerCircuitProof The register circuit proof data.
|
||||
*/
|
||||
function _verifyIdCardRegisterProof(
|
||||
uint256 registerCircuitVerifierId,
|
||||
IRegisterCircuitVerifier.RegisterCircuitProof memory registerCircuitProof
|
||||
)
|
||||
internal
|
||||
view
|
||||
{
|
||||
address verifier = _sigTypeToRegisterCircuitVerifiersIdCard[registerCircuitVerifierId];
|
||||
if (verifier == address(0)) {
|
||||
revert NO_VERIFIER_SET();
|
||||
}
|
||||
|
||||
if (!IIdentityRegistryIdCardV1(_registryIdCard).checkDscKeyCommitmentMerkleRoot(registerCircuitProof.pubSignals[CircuitConstants.REGISTER_MERKLE_ROOT_INDEX])) {
|
||||
revert INVALID_COMMITMENT_ROOT();
|
||||
}
|
||||
|
||||
if(!IRegisterCircuitVerifier(verifier).verifyProof(
|
||||
registerCircuitProof.a,
|
||||
registerCircuitProof.b,
|
||||
registerCircuitProof.c,
|
||||
registerCircuitProof.pubSignals
|
||||
)) {
|
||||
revert INVALID_REGISTER_PROOF();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @notice Verifies the Id Card DSC circuit proof.
|
||||
* @dev Uses the DSC circuit verifier specified by dscCircuitVerifierId for Id Cards.
|
||||
* @param dscCircuitVerifierId The identifier for the DSC circuit verifier.
|
||||
* @param dscCircuitProof The DSC circuit proof data.
|
||||
*/
|
||||
function _verifyIdCardDscProof(
|
||||
uint256 dscCircuitVerifierId,
|
||||
IDscCircuitVerifier.DscCircuitProof memory dscCircuitProof
|
||||
)
|
||||
internal
|
||||
view
|
||||
{
|
||||
address verifier = _sigTypeToDscCircuitVerifiersIdCard[dscCircuitVerifierId];
|
||||
if (verifier == address(0)) {
|
||||
revert NO_VERIFIER_SET();
|
||||
}
|
||||
|
||||
if (!IIdentityRegistryIdCardV1(_registryIdCard).checkCscaRoot(dscCircuitProof.pubSignals[CircuitConstants.DSC_CSCA_ROOT_INDEX])) {
|
||||
revert INVALID_CSCA_ROOT();
|
||||
}
|
||||
|
||||
if(!IDscCircuitVerifier(verifier).verifyProof(
|
||||
dscCircuitProof.a,
|
||||
dscCircuitProof.b,
|
||||
dscCircuitProof.c,
|
||||
dscCircuitProof.pubSignals
|
||||
)) {
|
||||
revert INVALID_DSC_PROOF();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @notice Retrieves the timestamp for the start of the current day.
|
||||
* @dev Calculated by subtracting the remainder of block.timestamp modulo 1 day.
|
||||
* @return The Unix timestamp representing the start of the day.
|
||||
*/
|
||||
function _getStartOfDayTimestamp() internal view returns (uint256) {
|
||||
return block.timestamp - (block.timestamp % 1 days);
|
||||
}
|
||||
}
|
||||
@@ -14,4 +14,5 @@ library AttestationId {
|
||||
* Here it is hardcoded as bytes32(uint256(1)) for demonstration purposes.
|
||||
*/
|
||||
bytes32 constant E_PASSPORT = bytes32(uint256(1));
|
||||
bytes32 constant ID_CARD = bytes32(uint256(2));
|
||||
}
|
||||
|
||||
164
contracts/contracts/interfaces/IIdentityRegistryIdCardV1.sol
Normal file
164
contracts/contracts/interfaces/IIdentityRegistryIdCardV1.sol
Normal file
@@ -0,0 +1,164 @@
|
||||
// SPDX-License-Identifier: MIT
|
||||
pragma solidity 0.8.28;
|
||||
|
||||
/**
|
||||
* @title IIdentityRegistryV1
|
||||
* @notice Interface for the Identity Registry v1.
|
||||
* @dev This interface exposes only the external functions accessible by regular callers,
|
||||
* i.e. functions that are not owner-restricted.
|
||||
*/
|
||||
interface IIdentityRegistryIdCardV1 {
|
||||
/**
|
||||
* @notice Retrieves the address of the registered identity verification hub.
|
||||
* @return The address of the hub.
|
||||
*/
|
||||
function hub() external view returns (address);
|
||||
|
||||
/**
|
||||
* @notice Checks if a specific nullifier is already registered for the given attestation.
|
||||
* @param attestationId The attestation identifier.
|
||||
* @param nullifier The nullifier to check.
|
||||
* @return True if the nullifier is registered; otherwise, false.
|
||||
*/
|
||||
function nullifiers(
|
||||
bytes32 attestationId,
|
||||
uint256 nullifier
|
||||
) external view returns (bool);
|
||||
|
||||
/**
|
||||
* @notice Checks whether a DSC key commitment is registered.
|
||||
* @param commitment The DSC key commitment to check.
|
||||
* @return True if the commitment is registered, false otherwise.
|
||||
*/
|
||||
function isRegisteredDscKeyCommitment(
|
||||
uint256 commitment
|
||||
) external view returns (bool);
|
||||
|
||||
/**
|
||||
* @notice Retrieves the timestamp at which a given Merkle tree root was created.
|
||||
* @param root The Merkle tree root.
|
||||
* @return The creation timestamp for the provided root.
|
||||
*/
|
||||
function rootTimestamps(uint256 root) external view returns (uint256);
|
||||
|
||||
/**
|
||||
* @notice Checks if the identity commitment Merkle tree contains the specified root.
|
||||
* @param root The Merkle tree root to check.
|
||||
* @return True if the root exists in the tree, false otherwise.
|
||||
*/
|
||||
function checkIdentityCommitmentRoot(
|
||||
uint256 root
|
||||
) external view returns (bool);
|
||||
|
||||
/**
|
||||
* @notice Retrieves the total number of identity commitments in the Merkle tree.
|
||||
* @return The size (i.e., count) of the identity commitment Merkle tree.
|
||||
*/
|
||||
function getIdentityCommitmentMerkleTreeSize() external view returns (uint256);
|
||||
|
||||
/**
|
||||
* @notice Retrieves the current Merkle root of the identity commitments.
|
||||
* @return The current identity commitment Merkle root.
|
||||
*/
|
||||
function getIdentityCommitmentMerkleRoot() external view returns (uint256);
|
||||
|
||||
/**
|
||||
* @notice Retrieves the index of a specific identity commitment in the Merkle tree.
|
||||
* @param commitment The identity commitment to locate.
|
||||
* @return The index position of the provided commitment.
|
||||
*/
|
||||
function getIdentityCommitmentIndex(
|
||||
uint256 commitment
|
||||
) external view returns (uint256);
|
||||
|
||||
|
||||
/**
|
||||
* @notice Retrieves the current name and date of birth OFAC root.
|
||||
* @return The current name and date of birth OFAC root value.
|
||||
*/
|
||||
function getNameAndDobOfacRoot() external view returns (uint256);
|
||||
|
||||
/**
|
||||
* @notice Retrieves the current name and year of birth OFAC root.
|
||||
* @return The current name and year of birth OFAC root value.
|
||||
*/
|
||||
function getNameAndYobOfacRoot() external view returns (uint256);
|
||||
|
||||
/**
|
||||
* @notice Checks if the provided OFAC roots match the stored OFAC roots.
|
||||
* @param nameAndDobRoot The name and date of birth OFAC root to verify.
|
||||
* @param nameAndYobRoot The name and year of birth OFAC root to verify.
|
||||
* @return True if all provided roots match the stored values, false otherwise.
|
||||
*/
|
||||
function checkOfacRoots(
|
||||
uint256 nameAndDobRoot,
|
||||
uint256 nameAndYobRoot
|
||||
) external view returns (bool);
|
||||
|
||||
/**
|
||||
* @notice Retrieves the current CSCA root.
|
||||
* @return The current CSCA root value.
|
||||
*/
|
||||
function getCscaRoot() external view returns (uint256);
|
||||
|
||||
/**
|
||||
* @notice Checks if the provided CSCA root matches the stored CSCA root.
|
||||
* @param root The CSCA root to verify.
|
||||
* @return True if the given root equals the stored CSCA root, otherwise false.
|
||||
*/
|
||||
function checkCscaRoot(
|
||||
uint256 root
|
||||
) external view returns (bool);
|
||||
|
||||
/**
|
||||
* @notice Retrieves the current Merkle root of the DSC key commitments.
|
||||
* @return The current DSC key commitment Merkle root.
|
||||
*/
|
||||
function getDscKeyCommitmentMerkleRoot() external view returns (uint256);
|
||||
|
||||
/**
|
||||
* @notice Checks if the provided root matches the DSC key commitment Merkle root.
|
||||
* @param root The root to check.
|
||||
* @return True if it matches the current root, false otherwise.
|
||||
*/
|
||||
function checkDscKeyCommitmentMerkleRoot(
|
||||
uint256 root
|
||||
) external view returns (bool);
|
||||
|
||||
/**
|
||||
* @notice Retrieves the total number of DSC key commitments in the Merkle tree.
|
||||
* @return The DSC key commitment Merkle tree size.
|
||||
*/
|
||||
function getDscKeyCommitmentTreeSize() external view returns (uint256);
|
||||
|
||||
/**
|
||||
* @notice Retrieves the index of a specific DSC key commitment in the Merkle tree.
|
||||
* @param commitment The DSC key commitment to locate.
|
||||
* @return The index of the provided commitment.
|
||||
*/
|
||||
function getDscKeyCommitmentIndex(
|
||||
uint256 commitment
|
||||
) external view returns (uint256);
|
||||
|
||||
/**
|
||||
* @notice Registers a new identity commitment.
|
||||
* @dev Must be called by the identity verification hub. Reverts if the nullifier has already been used.
|
||||
* @param attestationId The attestation identifier associated with the commitment.
|
||||
* @param nullifier A unique nullifier to prevent double registration.
|
||||
* @param commitment The identity commitment to register.
|
||||
*/
|
||||
function registerCommitment(
|
||||
bytes32 attestationId,
|
||||
uint256 nullifier,
|
||||
uint256 commitment
|
||||
) external;
|
||||
|
||||
/**
|
||||
* @notice Registers a new DSC key commitment.
|
||||
* @dev Must be called by the identity verification hub. Reverts if the DSC key commitment is already registered.
|
||||
* @param dscCommitment The DSC key commitment to register.
|
||||
*/
|
||||
function registerDscKeyCommitment(
|
||||
uint256 dscCommitment
|
||||
) external;
|
||||
}
|
||||
255
contracts/contracts/interfaces/IIdentityVerificationHubV2.sol
Normal file
255
contracts/contracts/interfaces/IIdentityVerificationHubV2.sol
Normal file
@@ -0,0 +1,255 @@
|
||||
// SPDX-License-Identifier: MIT
|
||||
pragma solidity 0.8.28;
|
||||
|
||||
import {IRegisterCircuitVerifier} from "./IRegisterCircuitVerifier.sol";
|
||||
import {IDscCircuitVerifier} from "./IDscCircuitVerifier.sol";
|
||||
import {IVcAndDiscloseCircuitVerifier} from "./IVcAndDiscloseCircuitVerifier.sol";
|
||||
import {CircuitConstants} from "../constants/CircuitConstants.sol";
|
||||
|
||||
/**
|
||||
* @title IIdentityVerificationHubV2
|
||||
* @notice Interface for the Identity Verification Hub for verifying zero-knowledge proofs using VC and Disclose circuits.
|
||||
* @dev Defines data structures and external functions for verifying proofs and recovering human-readable data.
|
||||
*/
|
||||
interface IIdentityVerificationHubV2 {
|
||||
|
||||
/**
|
||||
* @notice Enum representing types of data that may be revealed.
|
||||
*/
|
||||
enum RevealedDataType {
|
||||
ISSUING_STATE, // The issuing state of the passport.
|
||||
NAME, // The full name of the passport holder.
|
||||
PASSPORT_NUMBER, // The passport number.
|
||||
NATIONALITY, // The nationality.
|
||||
DATE_OF_BIRTH, // The date of birth.
|
||||
GENDER, // The gender.
|
||||
EXPIRY_DATE, // The passport expiry date.
|
||||
OLDER_THAN, // The "older than" age verification value.
|
||||
PASSPORT_NO_OFAC, // The passport number OFAC status.
|
||||
NAME_AND_DOB_OFAC, // The name and date of birth OFAC verification result.
|
||||
NAME_AND_YOB_OFAC // The name and year of birth OFAC verification result.
|
||||
}
|
||||
|
||||
/**
|
||||
* @notice Structure representing the verification result of a VC and Disclose proof.
|
||||
* @param attestationId The attestation identifier from the proof.
|
||||
* @param scope The scope of the verification.
|
||||
* @param userIdentifier Unique identifier for the user.
|
||||
* @param nullifier A value used to prevent double registration.
|
||||
* @param identityCommitmentRoot The root of the identity commitment.
|
||||
* @param revealedDataPacked Packed revealed data.
|
||||
* @param forbiddenCountriesListPacked Packed forbidden countries list.
|
||||
*/
|
||||
struct VcAndDiscloseVerificationResult {
|
||||
uint256 attestationId;
|
||||
uint256 scope;
|
||||
uint256 userIdentifier;
|
||||
uint256 nullifier;
|
||||
uint256 identityCommitmentRoot;
|
||||
uint256[3] revealedDataPacked;
|
||||
uint256[4] forbiddenCountriesListPacked;
|
||||
}
|
||||
|
||||
/**
|
||||
* @notice Structure representing human-readable revealed data after unpacking.
|
||||
* @param issuingState The issuing state as a string.
|
||||
* @param name Array of strings representing the passport holder's name.
|
||||
* @param passportNumber The passport number.
|
||||
* @param nationality The nationality.
|
||||
* @param dateOfBirth Formatted date of birth.
|
||||
* @param gender The gender.
|
||||
* @param expiryDate Formatted expiration date.
|
||||
* @param olderThan The verified "older than" age.
|
||||
* @param passportNoOfac The passport number OFAC verification result.
|
||||
* @param nameAndDobOfac The name and date of birth OFAC verification result.
|
||||
* @param nameAndYobOfac The name and year of birth OFAC verification result.
|
||||
*/
|
||||
struct ReadableRevealedData {
|
||||
string issuingState;
|
||||
string[] name;
|
||||
string passportNumber;
|
||||
string nationality;
|
||||
string dateOfBirth;
|
||||
string gender;
|
||||
string expiryDate;
|
||||
uint256 olderThan;
|
||||
uint256 passportNoOfac;
|
||||
uint256 nameAndDobOfac;
|
||||
uint256 nameAndYobOfac;
|
||||
}
|
||||
|
||||
/**
|
||||
* @notice Structure representing a hub proof for VC and Disclose verification.
|
||||
* @param olderThanEnabled Flag indicating if the 'olderThan' check is required.
|
||||
* @param olderThan Threshold age for verification.
|
||||
* @param forbiddenCountriesEnabled Flag indicating if forbidden countries verification is required.
|
||||
* @param forbiddenCountriesListPacked Packed forbidden countries list.
|
||||
* @param ofacEnabled Array of flags indicating which OFAC checks are enabled. [passportNo, nameAndDob, nameAndYob]
|
||||
* @param vcAndDiscloseProof The underlying VC and Disclose proof.
|
||||
*/
|
||||
struct VcAndDiscloseHubProof {
|
||||
bool olderThanEnabled;
|
||||
uint256 olderThan;
|
||||
bool forbiddenCountriesEnabled;
|
||||
uint256[4] forbiddenCountriesListPacked;
|
||||
bool[3] ofacEnabled;
|
||||
IVcAndDiscloseCircuitVerifier.VcAndDiscloseProof vcAndDiscloseProof;
|
||||
}
|
||||
|
||||
/**
|
||||
* @notice Verifies a VC and Disclose proof.
|
||||
* @dev Checks the provided proof against verification configuration and returns key result data.
|
||||
* @param proof The hub proof containing configuration flags and the underlying VC and Disclose proof.
|
||||
* @return result The verification result including attestationId, scope, userIdentifier, nullifier, identityCommitmentRoot, revealed data, and forbidden countries list.
|
||||
*/
|
||||
function verifyVcAndDisclose(
|
||||
VcAndDiscloseHubProof memory proof
|
||||
)
|
||||
external
|
||||
view
|
||||
returns (VcAndDiscloseVerificationResult memory result);
|
||||
|
||||
/**
|
||||
* @notice Converts packed revealed data into a human-readable format.
|
||||
* @dev Uses an array of RevealedDataType to determine which attributes to extract from the packed data.
|
||||
* @param revealedDataPacked An array of three uint256 containing the packed data.
|
||||
* @param types An array of RevealedDataType indicating the order of attributes.
|
||||
* @return readableData The decoded and formatted revealed data.
|
||||
*/
|
||||
function getReadableRevealedData(
|
||||
uint256[3] memory revealedDataPacked,
|
||||
RevealedDataType[] memory types
|
||||
)
|
||||
external
|
||||
view
|
||||
returns (ReadableRevealedData memory readableData);
|
||||
|
||||
/**
|
||||
* @notice Retrieves a human-readable list of forbidden countries.
|
||||
* @dev Converts the packed forbidden countries list into a fixed-size array of strings.
|
||||
* @param forbiddenCountriesListPacked The packed representation of forbidden countries.
|
||||
* @return forbiddenCountries A fixed-size array (length defined by CircuitConstants.MAX_FORBIDDEN_COUNTRIES_LIST_LENGTH) of strings representing forbidden countries.
|
||||
*/
|
||||
function getReadableForbiddenCountries(
|
||||
uint256[4] memory forbiddenCountriesListPacked
|
||||
)
|
||||
external
|
||||
view
|
||||
returns (string[40] memory forbiddenCountries);
|
||||
|
||||
/**
|
||||
* @notice Registers a passport commitment using a register circuit proof.
|
||||
* @dev Verifies the register circuit proof before registering the passport commitment.
|
||||
* @param registerCircuitVerifierId The identifier for the register circuit verifier to be used.
|
||||
* @param registerCircuitProof The proof data for the register circuit.
|
||||
*/
|
||||
function registerPassportCommitment(
|
||||
uint256 registerCircuitVerifierId,
|
||||
IRegisterCircuitVerifier.RegisterCircuitProof memory registerCircuitProof
|
||||
)
|
||||
external;
|
||||
|
||||
/**
|
||||
* @notice Registers an Id Card commitment using a register circuit proof.
|
||||
* @dev Verifies the register circuit proof before registering the Id Card commitment.
|
||||
* @param registerCircuitVerifierId The identifier for the register circuit verifier to be used.
|
||||
* @param registerCircuitProof The proof data for the register circuit.
|
||||
*/
|
||||
function registerIdCardCommitment(
|
||||
uint256 registerCircuitVerifierId,
|
||||
IRegisterCircuitVerifier.RegisterCircuitProof memory registerCircuitProof
|
||||
)
|
||||
external;
|
||||
|
||||
/**
|
||||
* @notice Registers a DSC key commitment using a DSC circuit proof.
|
||||
* @dev Verifies the DSC circuit proof before registering the DSC key commitment.
|
||||
* @param dscCircuitVerifierId The identifier for the DSC circuit verifier to be used.
|
||||
* @param dscCircuitProof The proof data for the DSC circuit.
|
||||
*/
|
||||
function registerDscKeyCommitment(
|
||||
uint256 dscCircuitVerifierId,
|
||||
IDscCircuitVerifier.DscCircuitProof memory dscCircuitProof
|
||||
)
|
||||
external;
|
||||
|
||||
/**
|
||||
* @notice Registers an Id Card DSC key commitment using a DSC circuit proof.
|
||||
* @dev Verifies the DSC proof and then calls the Id Card Identity Registry to register the dsc key commitment.
|
||||
* @param dscCircuitVerifierId The identifier for the DSC circuit verifier to use.
|
||||
* @param dscCircuitProof The DSC circuit proof data.
|
||||
*/
|
||||
function registerIdCardDscKeyCommitment(
|
||||
uint256 dscCircuitVerifierId,
|
||||
IDscCircuitVerifier.DscCircuitProof memory dscCircuitProof
|
||||
)
|
||||
external;
|
||||
|
||||
/**
|
||||
* @notice Returns the address of the Identity Registry.
|
||||
* @return registryAddr The address of the Identity Registry contract.
|
||||
*/
|
||||
function registry() external view returns (address registryAddr);
|
||||
|
||||
|
||||
/**
|
||||
* @notice Returns the address of the Identity Registry for Id Cards.
|
||||
* @return registryIdCardAddr The address of the Identity Registry for Id Cards.
|
||||
*/
|
||||
function registryIdCard() external view returns (address registryIdCardAddr);
|
||||
|
||||
/**
|
||||
* @notice Returns the address of the VC and Disclose circuit verifier.
|
||||
* @return verifierAddr The address of the VC and Disclose circuit verifier.
|
||||
*/
|
||||
function vcAndDiscloseCircuitVerifier() external view returns (address verifierAddr);
|
||||
|
||||
/**
|
||||
* @notice Retrieves the register circuit verifier for a given signature type.
|
||||
* @param typeId The signature type identifier.
|
||||
* @return verifier The address of the register circuit verifier.
|
||||
*/
|
||||
function sigTypeToRegisterCircuitVerifiers(
|
||||
uint256 typeId
|
||||
)
|
||||
external
|
||||
view
|
||||
returns (address verifier);
|
||||
|
||||
/**
|
||||
* @notice Retrieves the DSC circuit verifier for a given signature type.
|
||||
* @param typeId The signature type identifier.
|
||||
* @return verifier The address of the DSC circuit verifier.
|
||||
*/
|
||||
function sigTypeToDscCircuitVerifiers(
|
||||
uint256 typeId
|
||||
)
|
||||
external
|
||||
view
|
||||
returns (address verifier);
|
||||
|
||||
/**
|
||||
* @notice Retrieves the register circuit verifier for a given signature type for Id Cards.
|
||||
* @param typeId The signature type identifier.
|
||||
* @return verifier The address of the register circuit verifier.
|
||||
*/
|
||||
function sigTypeToRegisterCircuitVerifiersIdCard(
|
||||
uint256 typeId
|
||||
)
|
||||
external
|
||||
view
|
||||
returns (address verifier);
|
||||
|
||||
/**
|
||||
* @notice Retrieves the DSC circuit verifier for a given signature type for Id Cards.
|
||||
* @param typeId The signature type identifier.
|
||||
* @return verifier The address of the DSC circuit verifier.
|
||||
*/
|
||||
function sigTypeToDscCircuitVerifiersIdCard(
|
||||
uint256 typeId
|
||||
)
|
||||
external
|
||||
view
|
||||
returns (address verifier);
|
||||
|
||||
}
|
||||
@@ -1,5 +1,5 @@
|
||||
// SPDX-License-Identifier: MIT
|
||||
pragma solidity ^0.8.28;
|
||||
pragma solidity 0.8.28;
|
||||
|
||||
import {CircuitConstants} from "../constants/CircuitConstants.sol";
|
||||
import {Formatter} from "./Formatter.sol";
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
// SPDX-License-Identifier: MIT
|
||||
pragma solidity ^0.8.28;
|
||||
pragma solidity 0.8.28;
|
||||
|
||||
/**
|
||||
* @title Formatter Library
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
// SPDX-License-Identifier: MIT
|
||||
pragma solidity ^0.8.28;
|
||||
pragma solidity 0.8.28;
|
||||
|
||||
import {Formatter} from "./Formatter.sol";
|
||||
import {CircuitAttributeHandler} from "./CircuitAttributeHandler.sol";
|
||||
|
||||
19
contracts/contracts/registry/IdentityRegistryIdCard.sol
Normal file
19
contracts/contracts/registry/IdentityRegistryIdCard.sol
Normal file
@@ -0,0 +1,19 @@
|
||||
// SPDX-License-Identifier: MIT
|
||||
pragma solidity 0.8.28;
|
||||
|
||||
import {ProxyRoot} from "../upgradeable/ProxyRoot.sol";
|
||||
|
||||
/**
|
||||
* @title IdentityRegistry
|
||||
* @notice Acts as an upgradeable proxy for the identity registry.
|
||||
* @dev Inherits from ProxyRoot to delegate calls to an implementation contract.
|
||||
* The constructor initializes the proxy using the provided implementation address and initialization data.
|
||||
*/
|
||||
contract IdentityRegistryIdCard is ProxyRoot {
|
||||
/**
|
||||
* @notice Creates a new instance of the IdentityRegistry proxy.
|
||||
* @param _logic The address of the initial implementation contract that contains the registry logic.
|
||||
* @param _data The initialization data passed to the implementation during deployment.
|
||||
*/
|
||||
constructor(address _logic, bytes memory _data) ProxyRoot(_logic, _data) {}
|
||||
}
|
||||
779
contracts/contracts/registry/IdentityRegistryIdCardImplV1.sol
Normal file
779
contracts/contracts/registry/IdentityRegistryIdCardImplV1.sol
Normal file
@@ -0,0 +1,779 @@
|
||||
// SPDX-License-Identifier: MIT
|
||||
pragma solidity 0.8.28;
|
||||
|
||||
import {UUPSUpgradeable} from "@openzeppelin/contracts-upgradeable/proxy/utils/UUPSUpgradeable.sol";
|
||||
import {Ownable2StepUpgradeable} from "@openzeppelin/contracts-upgradeable/access/Ownable2StepUpgradeable.sol";
|
||||
import {Strings} from "@openzeppelin/contracts/utils/Strings.sol";
|
||||
import { InternalLeanIMT, LeanIMTData } from "@zk-kit/imt.sol/internal/InternalLeanIMT.sol";
|
||||
import {IIdentityRegistryIdCardV1} from "../interfaces/IIdentityRegistryIdCardV1.sol";
|
||||
import {IIdentityVerificationHubV1} from "../interfaces/IIdentityVerificationHubV1.sol";
|
||||
import {ImplRoot} from "../upgradeable/ImplRoot.sol";
|
||||
/**
|
||||
* @notice ⚠️ CRITICAL STORAGE LAYOUT WARNING ⚠️
|
||||
* =============================================
|
||||
*
|
||||
* This contract uses the UUPS upgradeable pattern which makes storage layout EXTREMELY SENSITIVE.
|
||||
*
|
||||
* 🚫 NEVER MODIFY OR REORDER existing storage variables
|
||||
* 🚫 NEVER INSERT new variables between existing ones
|
||||
* 🚫 NEVER CHANGE THE TYPE of existing variables
|
||||
*
|
||||
* ✅ New storage variables MUST be added in one of these two ways ONLY:
|
||||
* 1. At the END of the storage layout
|
||||
* 2. In a new V2 contract that inherits from this V1
|
||||
* ✅ It is safe to rename variables (e.g., changing 'variable' to 'oldVariable')
|
||||
* as long as the type and order remain the same
|
||||
*
|
||||
* Examples of forbidden changes:
|
||||
* - Changing uint256 to uint128
|
||||
* - Changing bytes32 to bytes
|
||||
* - Changing array type to mapping
|
||||
*
|
||||
* For more detailed information about forbidden changes, please refer to:
|
||||
* https://docs.openzeppelin.com/upgrades-plugins/writing-upgradeable#modifying-your-contracts
|
||||
*
|
||||
* ⚠️ VIOLATION OF THESE RULES WILL CAUSE CATASTROPHIC STORAGE COLLISIONS IN FUTURE UPGRADES ⚠️
|
||||
* =============================================
|
||||
*/
|
||||
|
||||
/**
|
||||
* @title IdentityRegistryStorageV1
|
||||
* @dev Abstract contract for storage layout of IdentityRegistryImplV1.
|
||||
* Inherits from ImplRoot to provide upgradeable functionality.
|
||||
*/
|
||||
abstract contract IdentityRegistryIdCardStorageV1 is
|
||||
ImplRoot
|
||||
{
|
||||
// ====================================================
|
||||
// Storage Variables
|
||||
// ====================================================
|
||||
|
||||
/// @notice Address of the identity verification hub.
|
||||
address internal _hub;
|
||||
|
||||
/// @notice Merkle tree data structure for identity commitments.
|
||||
LeanIMTData internal _identityCommitmentIMT;
|
||||
|
||||
/// @notice Mapping from Merkle tree root to its creation timestamp.
|
||||
mapping(uint256 => uint256) internal _rootTimestamps;
|
||||
|
||||
/// @notice Mapping from attestation ID and nullifier to a boolean indicating registration.
|
||||
/// @dev Example: For passport, the attestation id is 1.
|
||||
mapping(bytes32 => mapping(uint256 => bool)) internal _nullifiers;
|
||||
|
||||
/// @notice Merkle tree data structure for DSC key commitments.
|
||||
LeanIMTData internal _dscKeyCommitmentIMT;
|
||||
|
||||
/// @notice Mapping to determine if a DSC key commitment is registered.
|
||||
mapping(uint256 => bool) internal _isRegisteredDscKeyCommitment;
|
||||
|
||||
/// @notice Current name and date of birth OFAC root.
|
||||
uint256 internal _nameAndDobOfacRoot;
|
||||
|
||||
/// @notice Current name and year of birth OFAC root.
|
||||
uint256 internal _nameAndYobOfacRoot;
|
||||
|
||||
/// @notice Current CSCA root.
|
||||
uint256 internal _cscaRoot;
|
||||
}
|
||||
|
||||
/**
|
||||
* @title IdentityRegistryImplV1
|
||||
* @notice Provides functions to register and manage identity commitments using a Merkle tree structure.
|
||||
* @dev Inherits from IdentityRegistryStorageV1 and implements IIdentityRegistryV1.
|
||||
*/
|
||||
contract IdentityRegistryIdCardImplV1 is
|
||||
IdentityRegistryIdCardStorageV1,
|
||||
IIdentityRegistryIdCardV1
|
||||
{
|
||||
using InternalLeanIMT for LeanIMTData;
|
||||
|
||||
// ====================================================
|
||||
// Events
|
||||
// ====================================================
|
||||
|
||||
/// @notice Emitted when the registry is initialized.
|
||||
event RegistryInitialized(address hub);
|
||||
/// @notice Emitted when the hub address is updated.
|
||||
event HubUpdated(address hub);
|
||||
/// @notice Emitted when the CSCA root is updated.
|
||||
event CscaRootUpdated(uint256 cscaRoot);
|
||||
/// @notice Emitted when the name and date of birth OFAC root is updated.
|
||||
event NameAndDobOfacRootUpdated(uint256 nameAndDobOfacRoot);
|
||||
/// @notice Emitted when the name and year of birth OFAC root is updated.
|
||||
event NameAndYobOfacRootUpdated(uint256 nameAndYobOfacRoot);
|
||||
/// @notice Emitted when an identity commitment is successfully registered.
|
||||
event CommitmentRegistered(bytes32 indexed attestationId, uint256 indexed nullifier, uint256 indexed commitment, uint256 timestamp, uint256 imtRoot, uint256 imtIndex);
|
||||
/// @notice Emitted when a DSC key commitment is successfully registered.
|
||||
event DscKeyCommitmentRegistered(uint256 indexed commitment, uint256 timestamp, uint256 imtRoot, uint256 imtIndex);
|
||||
/// @notice Emitted when a identity commitment is added by dev team.
|
||||
event DevCommitmentRegistered(bytes32 indexed attestationId, uint256 indexed nullifier, uint256 indexed commitment, uint256 timestamp, uint256 imtRoot, uint256 imtIndex);
|
||||
/// @notice Emitted when a identity commitment is updated by dev team.
|
||||
event DevCommitmentUpdated(uint256 indexed oldLeaf, uint256 indexed newLeaf, uint256 imtRoot, uint256 timestamp);
|
||||
/// @notice Emitted when a identity commitment is removed by dev team.
|
||||
event DevCommitmentRemoved(uint256 indexed oldLeaf, uint256 imtRoot, uint256 timestamp);
|
||||
/// @notice Emitted when a DSC key commitment is added by dev team.
|
||||
event DevDscKeyCommitmentRegistered(uint256 indexed commitment, uint256 imtRoot, uint256 imtIndex);
|
||||
/// @notice Emitted when a DSC key commitment is updated by dev team.
|
||||
event DevDscKeyCommitmentUpdated(uint256 indexed oldLeaf, uint256 indexed newLeaf, uint256 imtRoot);
|
||||
/// @notice Emitted when a DSC key commitment is removed by dev team.
|
||||
event DevDscKeyCommitmentRemoved(uint256 indexed oldLeaf, uint256 imtRoot);
|
||||
/// @notice Emitted when the state of a nullifier is changed by dev team.
|
||||
event DevNullifierStateChanged(bytes32 indexed attestationId, uint256 indexed nullifier, bool state);
|
||||
/// @notice Emitted when the state of a DSC key commitment is changed by dev team.
|
||||
event DevDscKeyCommitmentStateChanged(uint256 indexed commitment, bool state);
|
||||
|
||||
// ====================================================
|
||||
// Errors
|
||||
// ====================================================
|
||||
|
||||
/// @notice Thrown when the hub is not set.
|
||||
error HUB_NOT_SET();
|
||||
/// @notice Thrown when a function is accessed by an address other than the designated hub.
|
||||
error ONLY_HUB_CAN_ACCESS();
|
||||
/// @notice Thrown when attempting to register a commitment that has already been registered.
|
||||
error REGISTERED_COMMITMENT();
|
||||
|
||||
// ====================================================
|
||||
// Modifiers
|
||||
// ====================================================
|
||||
|
||||
/**
|
||||
* @notice Modifier to restrict access to functions to only the hub.
|
||||
* @dev Reverts if the hub is not set or if the caller is not the hub.
|
||||
*/
|
||||
modifier onlyHub() {
|
||||
if (address(_hub) == address(0)) revert HUB_NOT_SET();
|
||||
if (msg.sender != address(_hub)) revert ONLY_HUB_CAN_ACCESS();
|
||||
_;
|
||||
}
|
||||
|
||||
// ====================================================
|
||||
// Constructor
|
||||
// ====================================================
|
||||
|
||||
/**
|
||||
* @notice Constructor that disables initializers.
|
||||
* @dev Prevents direct initialization of the implementation contract.
|
||||
*/
|
||||
constructor() {
|
||||
_disableInitializers();
|
||||
}
|
||||
|
||||
// ====================================================
|
||||
// Initializer
|
||||
// ====================================================
|
||||
/**
|
||||
* @notice Initializes the registry implementation.
|
||||
* @dev Sets the hub address and initializes the UUPS upgradeable feature.
|
||||
* @param _hub The address of the identity verification hub.
|
||||
*/
|
||||
function initialize(
|
||||
address _hub
|
||||
)
|
||||
external
|
||||
initializer
|
||||
{
|
||||
__ImplRoot_init();
|
||||
_hub = _hub;
|
||||
emit RegistryInitialized(_hub);
|
||||
}
|
||||
|
||||
// ====================================================
|
||||
// External Functions - View & Checks
|
||||
// ====================================================
|
||||
|
||||
/**
|
||||
* @notice Retrieves the hub address.
|
||||
* @return The current identity verification hub address.
|
||||
*/
|
||||
function hub()
|
||||
external
|
||||
virtual
|
||||
onlyProxy
|
||||
view
|
||||
returns (address)
|
||||
{
|
||||
return _hub;
|
||||
}
|
||||
|
||||
/**
|
||||
* @notice Checks if a specific nullifier is registered for a given attestation.
|
||||
* @param attestationId The attestation identifier.
|
||||
* @param nullifier The nullifier to be checked.
|
||||
* @return True if the nullifier has been registered, false otherwise.
|
||||
*/
|
||||
function nullifiers(
|
||||
bytes32 attestationId,
|
||||
uint256 nullifier
|
||||
)
|
||||
external
|
||||
virtual
|
||||
onlyProxy
|
||||
view
|
||||
returns (bool)
|
||||
{
|
||||
return _nullifiers[attestationId][nullifier];
|
||||
}
|
||||
|
||||
/**
|
||||
* @notice Checks if a DSC key commitment is registered.
|
||||
* @param commitment The DSC key commitment.
|
||||
* @return True if the DSC key commitment is registered, false otherwise.
|
||||
*/
|
||||
function isRegisteredDscKeyCommitment(
|
||||
uint256 commitment
|
||||
)
|
||||
external
|
||||
virtual
|
||||
onlyProxy
|
||||
view
|
||||
returns (bool)
|
||||
{
|
||||
return _isRegisteredDscKeyCommitment[commitment];
|
||||
}
|
||||
|
||||
/**
|
||||
* @notice Retrieves the timestamp when a specific Merkle root was created.
|
||||
* @param root The Merkle tree root.
|
||||
* @return The timestamp corresponding to the given root.
|
||||
*/
|
||||
function rootTimestamps(
|
||||
uint256 root
|
||||
)
|
||||
external
|
||||
virtual
|
||||
onlyProxy
|
||||
view
|
||||
returns (uint256)
|
||||
{
|
||||
return _rootTimestamps[root];
|
||||
}
|
||||
|
||||
/**
|
||||
* @notice Checks if the identity commitment Merkle tree contains the provided root.
|
||||
* @param root The Merkle tree root.
|
||||
* @return True if the root exists, false otherwise.
|
||||
*/
|
||||
function checkIdentityCommitmentRoot(
|
||||
uint256 root
|
||||
)
|
||||
external
|
||||
onlyProxy
|
||||
view
|
||||
returns (bool)
|
||||
{
|
||||
return _rootTimestamps[root] != 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* @notice Retrieves the number of identity commitments in the Merkle tree.
|
||||
* @return The size of the identity commitment Merkle tree.
|
||||
*/
|
||||
function getIdentityCommitmentMerkleTreeSize()
|
||||
external
|
||||
onlyProxy
|
||||
view
|
||||
returns (uint256)
|
||||
{
|
||||
return _identityCommitmentIMT.size;
|
||||
}
|
||||
|
||||
/**
|
||||
* @notice Retrieves the current Merkle root of the identity commitments.
|
||||
* @return The current identity commitment Merkle root.
|
||||
*/
|
||||
function getIdentityCommitmentMerkleRoot()
|
||||
external
|
||||
onlyProxy
|
||||
view
|
||||
returns (uint256)
|
||||
{
|
||||
return _identityCommitmentIMT._root();
|
||||
}
|
||||
|
||||
/**
|
||||
* @notice Retrieves the index of a specific identity commitment in the Merkle tree.
|
||||
* @param commitment The identity commitment to locate.
|
||||
* @return The index of the provided commitment within the Merkle tree.
|
||||
*/
|
||||
function getIdentityCommitmentIndex(
|
||||
uint256 commitment
|
||||
)
|
||||
external
|
||||
onlyProxy
|
||||
view
|
||||
returns (uint256)
|
||||
{
|
||||
return _identityCommitmentIMT._indexOf(commitment);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @notice Retrieves the current name and date of birth OFAC root.
|
||||
* @return The stored name and date of birth OFAC root.
|
||||
*/
|
||||
function getNameAndDobOfacRoot()
|
||||
external
|
||||
onlyProxy
|
||||
view
|
||||
returns (uint256)
|
||||
{
|
||||
return _nameAndDobOfacRoot;
|
||||
}
|
||||
|
||||
/**
|
||||
* @notice Retrieves the current name and year of birth OFAC root.
|
||||
* @return The stored name and year of birth OFAC root.
|
||||
*/
|
||||
function getNameAndYobOfacRoot()
|
||||
external
|
||||
onlyProxy
|
||||
view
|
||||
returns (uint256)
|
||||
{
|
||||
return _nameAndYobOfacRoot;
|
||||
}
|
||||
|
||||
/**
|
||||
* @notice Validates whether the provided OFAC roots match the stored values.
|
||||
* @param nameAndDobRoot The name and date of birth OFAC root to validate.
|
||||
* @param nameAndYobRoot The name and year of birth OFAC root to validate.
|
||||
* @return True if all provided roots match the stored values, false otherwise.
|
||||
*/
|
||||
function checkOfacRoots(
|
||||
uint256 nameAndDobRoot,
|
||||
uint256 nameAndYobRoot
|
||||
)
|
||||
external
|
||||
onlyProxy
|
||||
view
|
||||
returns (bool)
|
||||
{
|
||||
return _nameAndDobOfacRoot == nameAndDobRoot
|
||||
&& _nameAndYobOfacRoot == nameAndYobRoot;
|
||||
}
|
||||
|
||||
/**
|
||||
* @notice Retrieves the current CSCA root.
|
||||
* @return The stored CSCA root.
|
||||
*/
|
||||
function getCscaRoot()
|
||||
external
|
||||
onlyProxy
|
||||
view
|
||||
returns (uint256)
|
||||
{
|
||||
return _cscaRoot;
|
||||
}
|
||||
|
||||
/**
|
||||
* @notice Validates whether the provided CSCA root matches the stored value.
|
||||
* @param root The CSCA root to validate.
|
||||
* @return True if the provided root is equal to the stored CSCA root, false otherwise.
|
||||
*/
|
||||
function checkCscaRoot(
|
||||
uint256 root
|
||||
)
|
||||
external
|
||||
onlyProxy
|
||||
view
|
||||
returns (bool)
|
||||
{
|
||||
return _cscaRoot == root;
|
||||
}
|
||||
|
||||
/**
|
||||
* @notice Retrieves the current Merkle root of the DSC key commitments.
|
||||
* @return The current DSC key commitment Merkle root.
|
||||
*/
|
||||
function getDscKeyCommitmentMerkleRoot()
|
||||
external
|
||||
onlyProxy
|
||||
view
|
||||
returns (uint256)
|
||||
{
|
||||
return _dscKeyCommitmentIMT._root();
|
||||
}
|
||||
|
||||
/**
|
||||
* @notice Validates whether the provided root matches the DSC key commitment Merkle root.
|
||||
* @param root The root to validate.
|
||||
* @return True if the roots match, false otherwise.
|
||||
*/
|
||||
function checkDscKeyCommitmentMerkleRoot(
|
||||
uint256 root
|
||||
)
|
||||
external
|
||||
onlyProxy
|
||||
view
|
||||
returns (bool)
|
||||
{
|
||||
return _dscKeyCommitmentIMT._root() == root;
|
||||
}
|
||||
|
||||
/**
|
||||
* @notice Retrieves the number of DSC key commitments in the Merkle tree.
|
||||
* @return The DSC key commitment Merkle tree size.
|
||||
*/
|
||||
function getDscKeyCommitmentTreeSize()
|
||||
external
|
||||
onlyProxy
|
||||
view
|
||||
returns (uint256)
|
||||
{
|
||||
return _dscKeyCommitmentIMT.size;
|
||||
}
|
||||
|
||||
/**
|
||||
* @notice Retrieves the index of a specific DSC key commitment in the Merkle tree.
|
||||
* @param commitment The DSC key commitment to locate.
|
||||
* @return The index of the provided commitment within the DSC key commitment Merkle tree.
|
||||
*/
|
||||
function getDscKeyCommitmentIndex(
|
||||
uint256 commitment
|
||||
)
|
||||
external
|
||||
onlyProxy
|
||||
view
|
||||
returns (uint256)
|
||||
{
|
||||
return _dscKeyCommitmentIMT._indexOf(commitment);
|
||||
}
|
||||
|
||||
// ====================================================
|
||||
// External Functions - Registration
|
||||
// ====================================================
|
||||
|
||||
/**
|
||||
* @notice Registers a new identity commitment.
|
||||
* @dev Caller must be the hub. Reverts if the nullifier is already registered.
|
||||
* @param attestationId The identifier for the attestation.
|
||||
* @param nullifier The nullifier associated with the identity commitment.
|
||||
* @param commitment The identity commitment to register.
|
||||
*/
|
||||
function registerCommitment(
|
||||
bytes32 attestationId,
|
||||
uint256 nullifier,
|
||||
uint256 commitment
|
||||
)
|
||||
external
|
||||
onlyProxy
|
||||
onlyHub
|
||||
{
|
||||
if (_nullifiers[attestationId][nullifier]) revert REGISTERED_COMMITMENT();
|
||||
|
||||
_nullifiers[attestationId][nullifier] = true;
|
||||
uint256 index = _identityCommitmentIMT.size;
|
||||
uint256 imt_root = _addCommitment(_identityCommitmentIMT, commitment);
|
||||
_rootTimestamps[imt_root] = block.timestamp;
|
||||
emit CommitmentRegistered(attestationId, nullifier, commitment, block.timestamp, imt_root, index);
|
||||
}
|
||||
|
||||
/**
|
||||
* @notice Registers a new DSC key commitment.
|
||||
* @dev Caller must be the hub. Reverts if the commitment has already been registered.
|
||||
* @param dscCommitment The DSC key commitment to register.
|
||||
*/
|
||||
function registerDscKeyCommitment(
|
||||
uint256 dscCommitment
|
||||
)
|
||||
external
|
||||
onlyProxy
|
||||
onlyHub
|
||||
{
|
||||
if (_isRegisteredDscKeyCommitment[dscCommitment]) revert REGISTERED_COMMITMENT();
|
||||
|
||||
_isRegisteredDscKeyCommitment[dscCommitment] = true;
|
||||
uint256 index = _dscKeyCommitmentIMT.size;
|
||||
uint256 imt_root = _addCommitment(_dscKeyCommitmentIMT, dscCommitment);
|
||||
emit DscKeyCommitmentRegistered(dscCommitment, block.timestamp, imt_root, index);
|
||||
}
|
||||
|
||||
// ====================================================
|
||||
// External Functions - Only Owner
|
||||
// ====================================================
|
||||
|
||||
/**
|
||||
* @notice Updates the hub address.
|
||||
* @dev Callable only via a proxy and restricted to the contract owner.
|
||||
* @param newHubAddress The new address of the hub.
|
||||
*/
|
||||
function updateHub(
|
||||
address newHubAddress
|
||||
)
|
||||
external
|
||||
onlyProxy
|
||||
onlyOwner
|
||||
{
|
||||
_hub = newHubAddress;
|
||||
emit HubUpdated(newHubAddress);
|
||||
}
|
||||
|
||||
/**
|
||||
* @notice Updates the name and date of birth OFAC root.
|
||||
* @dev Callable only via a proxy and restricted to the contract owner.
|
||||
* @param newNameAndDobOfacRoot The new name and date of birth OFAC root value.
|
||||
*/
|
||||
function updateNameAndDobOfacRoot(
|
||||
uint256 newNameAndDobOfacRoot
|
||||
)
|
||||
external
|
||||
onlyProxy
|
||||
onlyOwner
|
||||
{
|
||||
_nameAndDobOfacRoot = newNameAndDobOfacRoot;
|
||||
emit NameAndDobOfacRootUpdated(newNameAndDobOfacRoot);
|
||||
}
|
||||
|
||||
/**
|
||||
* @notice Updates the name and year of birth OFAC root.
|
||||
* @dev Callable only via a proxy and restricted to the contract owner.
|
||||
* @param newNameAndYobOfacRoot The new name and year of birth OFAC root value.
|
||||
*/
|
||||
function updateNameAndYobOfacRoot(
|
||||
uint256 newNameAndYobOfacRoot
|
||||
)
|
||||
external
|
||||
onlyProxy
|
||||
onlyOwner
|
||||
{
|
||||
_nameAndYobOfacRoot = newNameAndYobOfacRoot;
|
||||
emit NameAndYobOfacRootUpdated(newNameAndYobOfacRoot);
|
||||
}
|
||||
|
||||
/**
|
||||
* @notice Updates the CSCA root.
|
||||
* @dev Callable only via a proxy and restricted to the contract owner.
|
||||
* @param newCscaRoot The new CSCA root value.
|
||||
*/
|
||||
function updateCscaRoot(
|
||||
uint256 newCscaRoot
|
||||
)
|
||||
external
|
||||
onlyProxy
|
||||
onlyOwner
|
||||
{
|
||||
_cscaRoot = newCscaRoot;
|
||||
emit CscaRootUpdated(newCscaRoot);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @notice (DEV) Force-adds an identity commitment.
|
||||
* @dev Callable only by the owner for testing or administration.
|
||||
* @param attestationId The identifier for the attestation.
|
||||
* @param nullifier The nullifier associated with the identity commitment.
|
||||
* @param commitment The identity commitment to add.
|
||||
*/
|
||||
function devAddIdentityCommitment(
|
||||
bytes32 attestationId,
|
||||
uint256 nullifier,
|
||||
uint256 commitment
|
||||
)
|
||||
external
|
||||
onlyProxy
|
||||
onlyOwner
|
||||
{
|
||||
_nullifiers[attestationId][nullifier] = true;
|
||||
uint256 imt_root = _addCommitment(_identityCommitmentIMT, commitment);
|
||||
_rootTimestamps[imt_root] = block.timestamp;
|
||||
uint256 index = _identityCommitmentIMT._indexOf(commitment);
|
||||
emit DevCommitmentRegistered(attestationId, nullifier, commitment, block.timestamp, imt_root, index);
|
||||
}
|
||||
|
||||
/**
|
||||
* @notice (DEV) Updates an existing identity commitment.
|
||||
* @dev Caller must be the owner. Provides sibling nodes for proof of position.
|
||||
* @param oldLeaf The current identity commitment to update.
|
||||
* @param newLeaf The new identity commitment.
|
||||
* @param siblingNodes An array of sibling nodes for Merkle proof generation.
|
||||
*/
|
||||
function devUpdateCommitment(
|
||||
uint256 oldLeaf,
|
||||
uint256 newLeaf,
|
||||
uint256[] calldata siblingNodes
|
||||
)
|
||||
external
|
||||
onlyProxy
|
||||
onlyOwner
|
||||
{
|
||||
uint256 imt_root = _updateCommitment(_identityCommitmentIMT, oldLeaf, newLeaf, siblingNodes);
|
||||
_rootTimestamps[imt_root] = block.timestamp;
|
||||
emit DevCommitmentUpdated(oldLeaf, newLeaf, imt_root, block.timestamp);
|
||||
}
|
||||
|
||||
/**
|
||||
* @notice (DEV) Removes an existing identity commitment.
|
||||
* @dev Caller must be the owner. Provides sibling nodes for proof of position.
|
||||
* @param oldLeaf The identity commitment to remove.
|
||||
* @param siblingNodes An array of sibling nodes for Merkle proof generation.
|
||||
*/
|
||||
function devRemoveCommitment(
|
||||
uint256 oldLeaf,
|
||||
uint256[] calldata siblingNodes
|
||||
)
|
||||
external
|
||||
onlyProxy
|
||||
onlyOwner
|
||||
{
|
||||
uint256 imt_root = _removeCommitment(_identityCommitmentIMT, oldLeaf, siblingNodes);
|
||||
_rootTimestamps[imt_root] = block.timestamp;
|
||||
emit DevCommitmentRemoved(oldLeaf, imt_root, block.timestamp);
|
||||
}
|
||||
|
||||
/**
|
||||
* @notice (DEV) Force-adds a DSC key commitment.
|
||||
* @dev Callable only by the owner for testing or administration.
|
||||
* @param dscCommitment The DSC key commitment to add.
|
||||
*/
|
||||
function devAddDscKeyCommitment(
|
||||
uint256 dscCommitment
|
||||
)
|
||||
external
|
||||
onlyProxy
|
||||
onlyOwner
|
||||
{
|
||||
_isRegisteredDscKeyCommitment[dscCommitment] = true;
|
||||
uint256 imt_root = _addCommitment(_dscKeyCommitmentIMT, dscCommitment);
|
||||
uint256 index = _dscKeyCommitmentIMT._indexOf(dscCommitment);
|
||||
emit DevDscKeyCommitmentRegistered(dscCommitment, imt_root, index);
|
||||
}
|
||||
|
||||
/**
|
||||
* @notice (DEV) Updates an existing DSC key commitment.
|
||||
* @dev Caller must be the owner. Provides sibling nodes for proof of position.
|
||||
* @param oldLeaf The current DSC key commitment to update.
|
||||
* @param newLeaf The new DSC key commitment.
|
||||
* @param siblingNodes An array of sibling nodes for Merkle proof generation.
|
||||
*/
|
||||
function devUpdateDscKeyCommitment(
|
||||
uint256 oldLeaf,
|
||||
uint256 newLeaf,
|
||||
uint256[] calldata siblingNodes
|
||||
)
|
||||
external
|
||||
onlyProxy
|
||||
onlyOwner
|
||||
{
|
||||
uint256 imt_root = _updateCommitment(_dscKeyCommitmentIMT, oldLeaf, newLeaf, siblingNodes);
|
||||
emit DevDscKeyCommitmentUpdated(oldLeaf, newLeaf, imt_root);
|
||||
}
|
||||
|
||||
/**
|
||||
* @notice (DEV) Removes an existing DSC key commitment.
|
||||
* @dev Caller must be the owner. Provides sibling nodes for proof of position.
|
||||
* @param oldLeaf The DSC key commitment to remove.
|
||||
* @param siblingNodes An array of sibling nodes for Merkle proof generation.
|
||||
*/
|
||||
function devRemoveDscKeyCommitment(
|
||||
uint256 oldLeaf,
|
||||
uint256[] calldata siblingNodes
|
||||
)
|
||||
external
|
||||
onlyProxy
|
||||
onlyOwner
|
||||
{
|
||||
uint256 imt_root = _removeCommitment(_dscKeyCommitmentIMT, oldLeaf, siblingNodes);
|
||||
emit DevDscKeyCommitmentRemoved(oldLeaf, imt_root);
|
||||
}
|
||||
|
||||
/**
|
||||
* @notice (DEV) Changes the state of a nullifier.
|
||||
* @dev Callable only by the owner.
|
||||
* @param attestationId The attestation identifier.
|
||||
* @param nullifier The nullifier whose state is to be updated.
|
||||
* @param state The new state of the nullifier (true for registered, false for not registered).
|
||||
*/
|
||||
function devChangeNullifierState(
|
||||
bytes32 attestationId,
|
||||
uint256 nullifier,
|
||||
bool state
|
||||
)
|
||||
external
|
||||
onlyProxy
|
||||
onlyOwner
|
||||
{
|
||||
_nullifiers[attestationId][nullifier] = state;
|
||||
emit DevNullifierStateChanged(attestationId, nullifier, state);
|
||||
}
|
||||
|
||||
/**
|
||||
* @notice (DEV) Changes the registration state of a DSC key commitment.
|
||||
* @dev Callable only by the owner.
|
||||
* @param dscCommitment The DSC key commitment.
|
||||
* @param state The new state of the DSC key commitment (true for registered, false for not registered).
|
||||
*/
|
||||
function devChangeDscKeyCommitmentState(
|
||||
uint256 dscCommitment,
|
||||
bool state
|
||||
)
|
||||
external
|
||||
onlyProxy
|
||||
onlyOwner
|
||||
{
|
||||
_isRegisteredDscKeyCommitment[dscCommitment] = state;
|
||||
emit DevDscKeyCommitmentStateChanged(dscCommitment, state);
|
||||
}
|
||||
|
||||
// ====================================================
|
||||
// Internal Functions
|
||||
// ====================================================
|
||||
|
||||
/**
|
||||
* @notice Adds a commitment to the specified Merkle tree.
|
||||
* @dev Inserts the commitment using the provided Merkle tree structure.
|
||||
* @param imt The Merkle tree data structure.
|
||||
* @param commitment The commitment to add.
|
||||
* @return imt_root The new Merkle tree root after insertion.
|
||||
*/
|
||||
function _addCommitment(
|
||||
LeanIMTData storage imt,
|
||||
uint256 commitment
|
||||
)
|
||||
internal
|
||||
returns(uint256 imt_root)
|
||||
{
|
||||
imt_root = imt._insert(commitment);
|
||||
}
|
||||
|
||||
/**
|
||||
* @notice Updates an existing commitment in the specified Merkle tree.
|
||||
* @dev Uses sibling nodes to prove the commitment's position and update it.
|
||||
* @param imt The Merkle tree data structure.
|
||||
* @param oldLeaf The current commitment to update.
|
||||
* @param newLeaf The new commitment.
|
||||
* @param siblingNodes An array of sibling nodes for generating a valid proof.
|
||||
* @return imt_root The new Merkle tree root after update.
|
||||
*/
|
||||
function _updateCommitment(
|
||||
LeanIMTData storage imt,
|
||||
uint256 oldLeaf,
|
||||
uint256 newLeaf,
|
||||
uint256[] calldata siblingNodes
|
||||
)
|
||||
internal
|
||||
returns(uint256 imt_root)
|
||||
{
|
||||
imt_root = imt._update(oldLeaf, newLeaf, siblingNodes);
|
||||
}
|
||||
|
||||
/**
|
||||
* @notice Removes a commitment from the specified Merkle tree.
|
||||
* @dev Uses sibling nodes to prove the commitment's position before removal.
|
||||
* @param imt The Merkle tree data structure.
|
||||
* @param oldLeaf The commitment to remove.
|
||||
* @param siblingNodes An array of sibling nodes for generating a valid proof.
|
||||
* @return imt_root The new Merkle tree root after removal.
|
||||
*/
|
||||
function _removeCommitment(
|
||||
LeanIMTData storage imt,
|
||||
uint256 oldLeaf,
|
||||
uint256[] calldata siblingNodes
|
||||
)
|
||||
internal
|
||||
returns(uint256 imt_root)
|
||||
{
|
||||
imt_root = imt._remove(oldLeaf, siblingNodes);
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user