Skip to content

Commit

Permalink
feat(contracts): add standard way to call external verifiers and aggr…
Browse files Browse the repository at this point in the history
…egate their logic
  • Loading branch information
0xjei committed Jan 14, 2025
1 parent 3851bbc commit 0bd434c
Show file tree
Hide file tree
Showing 22 changed files with 454 additions and 345 deletions.
15 changes: 9 additions & 6 deletions packages/contracts/contracts/src/AdvancedChecker.sol
Original file line number Diff line number Diff line change
Expand Up @@ -2,19 +2,22 @@
pragma solidity ^0.8.20;

import {IAdvancedChecker, Check, CheckStatus} from "./interfaces/IAdvancedChecker.sol";
import {Checker} from "./Checker.sol";

/// @title AdvancedChecker.
/// @notice Multi-phase validation checker with pre, main, and post checks.
/// @dev Base contract for implementing complex validation logic with configurable check phases.
abstract contract AdvancedChecker is IAdvancedChecker {
abstract contract AdvancedChecker is IAdvancedChecker, Checker {
constructor(address[] memory _verifiers) Checker(_verifiers) {}

/// @notice Entry point for validation checks.
/// @param subject Address to validate.
/// @param evidence Validation data.
/// @param checkType Type of check (PRE, MAIN, POST).
/// @return checked Validation result.
function check(
address subject,
bytes memory evidence,
bytes[] calldata evidence,
Check checkType
) external view override returns (bool checked) {
return _check(subject, evidence, checkType);
Expand All @@ -26,7 +29,7 @@ abstract contract AdvancedChecker is IAdvancedChecker {
/// @param evidence Validation data.
/// @param checkType Check type to perform.
/// @return checked Validation result.
function _check(address subject, bytes memory evidence, Check checkType) internal view returns (bool checked) {
function _check(address subject, bytes[] calldata evidence, Check checkType) internal view returns (bool checked) {
if (checkType == Check.PRE) {
return _checkPre(subject, evidence);
}
Expand All @@ -43,19 +46,19 @@ abstract contract AdvancedChecker is IAdvancedChecker {
/// @param subject Address to validate.
/// @param evidence Validation data.
/// @return checked Validation result.
function _checkPre(address subject, bytes memory evidence) internal view virtual returns (bool checked) {}
function _checkPre(address subject, bytes[] calldata evidence) internal view virtual returns (bool checked) {}

/// @notice Main validation implementation.
/// @dev Override to implement main check logic.
/// @param subject Address to validate.
/// @param evidence Validation data.
/// @return checked Validation result.
function _checkMain(address subject, bytes memory evidence) internal view virtual returns (bool checked) {}
function _checkMain(address subject, bytes[] calldata evidence) internal view virtual returns (bool checked) {}

/// @notice Post-condition validation implementation.
/// @dev Override to implement post-check logic.
/// @param subject Address to validate.
/// @param evidence Validation data.
/// @return checked Validation result.
function _checkPost(address subject, bytes memory evidence) internal view virtual returns (bool checked) {}
function _checkPost(address subject, bytes[] calldata evidence) internal view virtual returns (bool checked) {}
}
4 changes: 2 additions & 2 deletions packages/contracts/contracts/src/AdvancedPolicy.sol
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,7 @@ abstract contract AdvancedPolicy is IAdvancedPolicy, Policy {
/// @param subject Address to validate.
/// @param evidence Validation data.
/// @param checkType Type of check (PRE, MAIN, POST).
function enforce(address subject, bytes calldata evidence, Check checkType) external override onlyTarget {
function enforce(address subject, bytes[] calldata evidence, Check checkType) external override onlyTarget {
_enforce(subject, evidence, checkType);
}

Expand All @@ -59,7 +59,7 @@ abstract contract AdvancedPolicy is IAdvancedPolicy, Policy {
/// @custom:throws PreCheckNotEnforced If PRE check is required but not done.
/// @custom:throws MainCheckNotEnforced If MAIN check is required but not done.
/// @custom:throws MainCheckAlreadyEnforced If multiple MAIN checks not allowed.
function _enforce(address subject, bytes calldata evidence, Check checkType) internal {
function _enforce(address subject, bytes[] calldata evidence, Check checkType) internal {
if (!ADVANCED_CHECKER.check(subject, evidence, checkType)) {
revert UnsuccessfulCheck();
}
Expand Down
9 changes: 6 additions & 3 deletions packages/contracts/contracts/src/BaseChecker.sol
Original file line number Diff line number Diff line change
Expand Up @@ -2,18 +2,21 @@
pragma solidity ^0.8.20;

import {IBaseChecker} from "./interfaces/IBaseChecker.sol";
import {Checker} from "./Checker.sol";

/// @title BaseChecker
/// @notice Abstract base contract for implementing validation checks.
/// @dev Provides a standardized interface for implementing custom validation logic
/// through the internal _check method.
abstract contract BaseChecker is IBaseChecker {
abstract contract BaseChecker is Checker, IBaseChecker {
constructor(address[] memory _verifiers) Checker(_verifiers) {}

/// @notice Validates evidence for a given subject address.
/// @dev External view function that delegates to internal _check implementation.
/// @param subject Address to validate.
/// @param evidence Custom validation data.
/// @return checked Boolean indicating if the check passed.
function check(address subject, bytes memory evidence) external view override returns (bool checked) {
function check(address subject, bytes[] calldata evidence) external view override returns (bool checked) {
return _check(subject, evidence);
}

Expand All @@ -22,5 +25,5 @@ abstract contract BaseChecker is IBaseChecker {
/// @param subject Address to validate.
/// @param evidence Custom validation data.
/// @return checked Boolean indicating if the check passed.
function _check(address subject, bytes memory evidence) internal view virtual returns (bool checked) {}
function _check(address subject, bytes[] calldata evidence) internal view virtual returns (bool checked) {}
}
4 changes: 2 additions & 2 deletions packages/contracts/contracts/src/BasePolicy.sol
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@ abstract contract BasePolicy is Policy, IBasePolicy {
/// @custom:throws AlreadyEnforced if check was previously enforced.
/// @custom:throws UnsuccessfulCheck if the check fails.
/// @custom:emits Enforced when check succeeds.
function enforce(address subject, bytes calldata evidence) external override onlyTarget {
function enforce(address subject, bytes[] calldata evidence) external override onlyTarget {
_enforce(subject, evidence);
}

Expand All @@ -45,7 +45,7 @@ abstract contract BasePolicy is Policy, IBasePolicy {
/// @param evidence Additional data required for verification.
/// @custom:throws AlreadyEnforced if already enforced for this subject.
/// @custom:throws UnsuccessfulCheck if BASE_CHECKER.check returns false.
function _enforce(address subject, bytes calldata evidence) internal {
function _enforce(address subject, bytes[] memory evidence) internal {
bool checked = BASE_CHECKER.check(subject, evidence);

if (enforced[msg.sender][subject]) revert AlreadyEnforced();
Expand Down
38 changes: 38 additions & 0 deletions packages/contracts/contracts/src/Checker.sol
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.20;

import {IChecker} from "./interfaces/IChecker.sol";

/// @title Checker
/// @notice Abstract base contract for implementing attribute verification logic.
/// @dev Provides infrastructure to orchestrate third-party verifiers for single checks.
abstract contract Checker is IChecker {
/// @notice Array of third-party contract addresses used for verification.
/// @dev Can include existing and already deployed Checkers, NFTs, MACI polls, and/or any other contract
/// that provides evidence verification. These contracts should already be deployed and operational.
address[] internal verifiers;

/// @notice Initializes the Checker with an optional list of third-party verification contracts.
/// @param _verifiers Array of addresses for existing verification contracts.
/// @dev Each address should point to a deployed contract that will be consulted during verification.
/// This array can remain empty if there's no reliance on external verifiers.
constructor(address[] memory _verifiers) {
verifiers = _verifiers;
}

/// @notice Retrieves the list of third-party verifiers' addresses.
/// @return Array of addresses for the necessary verification contracts.
function getVerifiers() internal view returns (address[] memory) {
return verifiers;
}

/// @notice Retrieves the verifier address at a specific index.
/// @param index The index of the verifier in the array.
/// @return The address of the verifier at the specified index.
/// @custom:throws VerifierNotFound if no address have been specified at given index.
function getVerifierAtIndex(uint256 index) internal view returns (address) {
if (index >= verifiers.length) revert VerifierNotFound();

return verifiers[index];
}
}
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.20;

import {IChecker} from "./IChecker.sol";

/// @title Check.
/// @notice Defines validation phases in the AdvancedChecker system.
/// @custom:values PRE - Pre-condition validation.
Expand All @@ -26,11 +28,11 @@ struct CheckStatus {
/// @title IAdvancedChecker.
/// @notice Defines multi-phase validation system interface.
/// @dev Implement this for custom validation logic with pre/main/post checks.
interface IAdvancedChecker {
interface IAdvancedChecker is IChecker {
/// @notice Validates subject against specified check type.
/// @param subject Address to validate.
/// @param evidence Validation data.
/// @param checkType Check phase to execute.
/// @return checked True if validation passes.
function check(address subject, bytes calldata evidence, Check checkType) external view returns (bool checked);
function check(address subject, bytes[] calldata evidence, Check checkType) external view returns (bool checked);
}
Original file line number Diff line number Diff line change
Expand Up @@ -27,12 +27,12 @@ interface IAdvancedPolicy is IPolicy {
/// @param target Protected contract address.
/// @param evidence Validation data.
/// @param checkType Type of check performed.
event Enforced(address indexed subject, address indexed target, bytes evidence, Check checkType);
event Enforced(address indexed subject, address indexed target, bytes[] evidence, Check checkType);

/// @notice Enforces validation check on subject.
/// @dev Delegates to appropriate check method based on checkType.
/// @param subject Address to validate.
/// @param evidence Validation data.
/// @param checkType Check phase to execute.
function enforce(address subject, bytes calldata evidence, Check checkType) external;
function enforce(address subject, bytes[] calldata evidence, Check checkType) external;
}
6 changes: 4 additions & 2 deletions packages/contracts/contracts/src/interfaces/IBaseChecker.sol
Original file line number Diff line number Diff line change
@@ -1,12 +1,14 @@
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.20;

import {IChecker} from "./IChecker.sol";

/// @title IBaseChecker.
/// @notice Defines base validation functionality.
interface IBaseChecker {
interface IBaseChecker is IChecker {
/// @notice Validates subject against evidence.
/// @param subject Address to validate.
/// @param evidence Validation data.
/// @return checked True if validation passes.
function check(address subject, bytes calldata evidence) external view returns (bool checked);
function check(address subject, bytes[] calldata evidence) external view returns (bool checked);
}
4 changes: 2 additions & 2 deletions packages/contracts/contracts/src/interfaces/IBasePolicy.sol
Original file line number Diff line number Diff line change
Expand Up @@ -10,10 +10,10 @@ interface IBasePolicy is IPolicy {
/// @param subject Address that passed validation.
/// @param target Protected contract address.
/// @param evidence Validation data.
event Enforced(address indexed subject, address indexed target, bytes evidence);
event Enforced(address indexed subject, address indexed target, bytes[] evidence);

/// @notice Enforces validation check on subject.
/// @param subject Address to validate.
/// @param evidence Validation data.
function enforce(address subject, bytes calldata evidence) external;
function enforce(address subject, bytes[] calldata evidence) external;
}
9 changes: 9 additions & 0 deletions packages/contracts/contracts/src/interfaces/IChecker.sol
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.20;

/// @title IChecker
/// @notice Core checker interface for attribute verification functionalities.
interface IChecker {
/// @notice Core error conditions.
error VerifierNotFound();
}
Loading

0 comments on commit 0bd434c

Please sign in to comment.