From 0bd434c320f711b41eabbc1f412461635e3f6aac Mon Sep 17 00:00:00 2001 From: 0xjei Date: Tue, 14 Jan 2025 19:15:57 +0100 Subject: [PATCH] feat(contracts): add standard way to call external verifiers and aggregate their logic --- .../contracts/src/AdvancedChecker.sol | 15 +- .../contracts/src/AdvancedPolicy.sol | 4 +- .../contracts/contracts/src/BaseChecker.sol | 9 +- .../contracts/contracts/src/BasePolicy.sol | 4 +- packages/contracts/contracts/src/Checker.sol | 38 +++ .../src/interfaces/IAdvancedChecker.sol | 6 +- .../src/interfaces/IAdvancedPolicy.sol | 4 +- .../contracts/src/interfaces/IBaseChecker.sol | 6 +- .../contracts/src/interfaces/IBasePolicy.sol | 4 +- .../contracts/src/interfaces/IChecker.sol | 9 + .../contracts/src/test/Advanced.t.sol | 244 +++++++++-------- .../contracts/contracts/src/test/Base.t.sol | 71 +++-- .../test/advanced/AdvancedERC721Checker.sol | 21 +- .../src/test/advanced/AdvancedVoting.sol | 15 +- .../src/test/base/BaseERC721Checker.sol | 10 +- .../contracts/src/test/base/BaseVoting.sol | 5 +- .../wrappers/AdvancedERC721CheckerHarness.sol | 15 +- .../wrappers/AdvancedERC721PolicyHarness.sol | 2 +- .../wrappers/BaseERC721CheckerHarness.sol | 6 +- .../test/wrappers/BaseERC721PolicyHarness.sol | 2 +- packages/contracts/test/Advanced.test.ts | 246 +++++++++--------- packages/contracts/test/Base.test.ts | 63 +++-- 22 files changed, 454 insertions(+), 345 deletions(-) create mode 100644 packages/contracts/contracts/src/Checker.sol create mode 100644 packages/contracts/contracts/src/interfaces/IChecker.sol diff --git a/packages/contracts/contracts/src/AdvancedChecker.sol b/packages/contracts/contracts/src/AdvancedChecker.sol index 2e59e5b..922b245 100644 --- a/packages/contracts/contracts/src/AdvancedChecker.sol +++ b/packages/contracts/contracts/src/AdvancedChecker.sol @@ -2,11 +2,14 @@ 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. @@ -14,7 +17,7 @@ abstract contract AdvancedChecker is IAdvancedChecker { /// @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); @@ -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); } @@ -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) {} } diff --git a/packages/contracts/contracts/src/AdvancedPolicy.sol b/packages/contracts/contracts/src/AdvancedPolicy.sol index d1a9d2f..3d8ccde 100644 --- a/packages/contracts/contracts/src/AdvancedPolicy.sol +++ b/packages/contracts/contracts/src/AdvancedPolicy.sol @@ -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); } @@ -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(); } diff --git a/packages/contracts/contracts/src/BaseChecker.sol b/packages/contracts/contracts/src/BaseChecker.sol index 5f2319b..bbb106b 100644 --- a/packages/contracts/contracts/src/BaseChecker.sol +++ b/packages/contracts/contracts/src/BaseChecker.sol @@ -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); } @@ -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) {} } diff --git a/packages/contracts/contracts/src/BasePolicy.sol b/packages/contracts/contracts/src/BasePolicy.sol index 6de4251..c9e9c5d 100644 --- a/packages/contracts/contracts/src/BasePolicy.sol +++ b/packages/contracts/contracts/src/BasePolicy.sol @@ -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); } @@ -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(); diff --git a/packages/contracts/contracts/src/Checker.sol b/packages/contracts/contracts/src/Checker.sol new file mode 100644 index 0000000..d149fd6 --- /dev/null +++ b/packages/contracts/contracts/src/Checker.sol @@ -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]; + } +} diff --git a/packages/contracts/contracts/src/interfaces/IAdvancedChecker.sol b/packages/contracts/contracts/src/interfaces/IAdvancedChecker.sol index 89b27f9..67d27e1 100644 --- a/packages/contracts/contracts/src/interfaces/IAdvancedChecker.sol +++ b/packages/contracts/contracts/src/interfaces/IAdvancedChecker.sol @@ -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. @@ -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); } diff --git a/packages/contracts/contracts/src/interfaces/IAdvancedPolicy.sol b/packages/contracts/contracts/src/interfaces/IAdvancedPolicy.sol index fe544fd..d9f719d 100644 --- a/packages/contracts/contracts/src/interfaces/IAdvancedPolicy.sol +++ b/packages/contracts/contracts/src/interfaces/IAdvancedPolicy.sol @@ -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; } diff --git a/packages/contracts/contracts/src/interfaces/IBaseChecker.sol b/packages/contracts/contracts/src/interfaces/IBaseChecker.sol index 489ce06..d2f923d 100644 --- a/packages/contracts/contracts/src/interfaces/IBaseChecker.sol +++ b/packages/contracts/contracts/src/interfaces/IBaseChecker.sol @@ -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); } diff --git a/packages/contracts/contracts/src/interfaces/IBasePolicy.sol b/packages/contracts/contracts/src/interfaces/IBasePolicy.sol index a7fbe8f..faef64e 100644 --- a/packages/contracts/contracts/src/interfaces/IBasePolicy.sol +++ b/packages/contracts/contracts/src/interfaces/IBasePolicy.sol @@ -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; } diff --git a/packages/contracts/contracts/src/interfaces/IChecker.sol b/packages/contracts/contracts/src/interfaces/IChecker.sol new file mode 100644 index 0000000..3b1b847 --- /dev/null +++ b/packages/contracts/contracts/src/interfaces/IChecker.sol @@ -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(); +} diff --git a/packages/contracts/contracts/src/test/Advanced.t.sol b/packages/contracts/contracts/src/test/Advanced.t.sol index 931dbd8..78902a0 100644 --- a/packages/contracts/contracts/src/test/Advanced.t.sol +++ b/packages/contracts/contracts/src/test/Advanced.t.sol @@ -24,12 +24,22 @@ contract AdvancedChecker is Test { address public subject = vm.addr(0x3); address public notOwner = vm.addr(0x4); + address[] internal verifiers; + bytes[] public evidence = new bytes[](1); + bytes[] public wrongEvidence = new bytes[](1); + function setUp() public virtual { vm.startPrank(deployer); nft = new NFT(); - checker = new AdvancedERC721Checker(nft, 1, 0, 10); - checkerHarness = new AdvancedERC721CheckerHarness(nft, 1, 0, 10); + verifiers = new address[](1); + verifiers[0] = address(nft); + + checker = new AdvancedERC721Checker(verifiers, 1, 0, 10); + checkerHarness = new AdvancedERC721CheckerHarness(verifiers, 1, 0, 10); + + evidence[0] = abi.encode(0); + wrongEvidence[0] = abi.encode(1); vm.stopPrank(); } @@ -38,7 +48,7 @@ contract AdvancedChecker is Test { vm.startPrank(target); vm.expectRevert(abi.encodeWithSelector(IERC721Errors.ERC721NonexistentToken.selector, uint256(0))); - checker.check(subject, abi.encode(0), Check.PRE); + checker.check(subject, evidence, Check.PRE); vm.stopPrank(); } @@ -48,7 +58,7 @@ contract AdvancedChecker is Test { nft.mint(subject); - assert(!checker.check(notOwner, abi.encode(0), Check.PRE)); + assert(!checker.check(notOwner, evidence, Check.PRE)); vm.stopPrank(); } @@ -58,7 +68,7 @@ contract AdvancedChecker is Test { nft.mint(subject); - assert(checker.check(subject, abi.encode(0), Check.PRE)); + assert(checker.check(subject, evidence, Check.PRE)); vm.stopPrank(); } @@ -68,7 +78,7 @@ contract AdvancedChecker is Test { nft.mint(subject); - assert(!checker.check(notOwner, abi.encode(0), Check.MAIN)); + assert(!checker.check(notOwner, evidence, Check.MAIN)); vm.stopPrank(); } @@ -78,7 +88,7 @@ contract AdvancedChecker is Test { nft.mint(subject); - assert(checker.check(subject, abi.encode(0), Check.MAIN)); + assert(checker.check(subject, evidence, Check.MAIN)); vm.stopPrank(); } @@ -87,7 +97,7 @@ contract AdvancedChecker is Test { vm.startPrank(target); vm.expectRevert(abi.encodeWithSelector(IERC721Errors.ERC721NonexistentToken.selector, uint256(1))); - checker.check(subject, abi.encode(1), Check.POST); + checker.check(subject, wrongEvidence, Check.POST); vm.stopPrank(); } @@ -97,7 +107,7 @@ contract AdvancedChecker is Test { nft.mint(subject); - assert(!checker.check(notOwner, abi.encode(0), Check.POST)); + assert(!checker.check(notOwner, evidence, Check.POST)); vm.stopPrank(); } @@ -107,7 +117,7 @@ contract AdvancedChecker is Test { nft.mint(subject); - assert(checker.check(subject, abi.encode(0), Check.POST)); + assert(checker.check(subject, evidence, Check.POST)); vm.stopPrank(); } @@ -116,7 +126,7 @@ contract AdvancedChecker is Test { vm.startPrank(target); vm.expectRevert(abi.encodeWithSelector(IERC721Errors.ERC721NonexistentToken.selector, uint256(0))); - checkerHarness.exposed__check(subject, abi.encode(0), Check.PRE); + checkerHarness.exposed__check(subject, evidence, Check.PRE); vm.stopPrank(); } @@ -126,7 +136,7 @@ contract AdvancedChecker is Test { nft.mint(subject); - assert(!checkerHarness.exposed__check(notOwner, abi.encode(0), Check.PRE)); + assert(!checkerHarness.exposed__check(notOwner, evidence, Check.PRE)); vm.stopPrank(); } @@ -136,7 +146,7 @@ contract AdvancedChecker is Test { nft.mint(subject); - assert(checkerHarness.exposed__check(subject, abi.encode(0), Check.PRE)); + assert(checkerHarness.exposed__check(subject, evidence, Check.PRE)); vm.stopPrank(); } @@ -146,7 +156,7 @@ contract AdvancedChecker is Test { nft.mint(subject); - assert(!checkerHarness.exposed__check(notOwner, abi.encode(0), Check.MAIN)); + assert(!checkerHarness.exposed__check(notOwner, evidence, Check.MAIN)); vm.stopPrank(); } @@ -156,7 +166,7 @@ contract AdvancedChecker is Test { nft.mint(subject); - assert(checkerHarness.exposed__check(subject, abi.encode(0), Check.MAIN)); + assert(checkerHarness.exposed__check(subject, evidence, Check.MAIN)); vm.stopPrank(); } @@ -165,7 +175,7 @@ contract AdvancedChecker is Test { vm.startPrank(target); vm.expectRevert(abi.encodeWithSelector(IERC721Errors.ERC721NonexistentToken.selector, uint256(1))); - checkerHarness.exposed__check(subject, abi.encode(1), Check.POST); + checkerHarness.exposed__check(subject, wrongEvidence, Check.POST); vm.stopPrank(); } @@ -175,7 +185,7 @@ contract AdvancedChecker is Test { nft.mint(subject); - assert(!checkerHarness.exposed__check(notOwner, abi.encode(0), Check.POST)); + assert(!checkerHarness.exposed__check(notOwner, evidence, Check.POST)); vm.stopPrank(); } @@ -185,7 +195,7 @@ contract AdvancedChecker is Test { nft.mint(subject); - assert(checkerHarness.exposed__check(subject, abi.encode(0), Check.POST)); + assert(checkerHarness.exposed__check(subject, evidence, Check.POST)); vm.stopPrank(); } @@ -194,7 +204,7 @@ contract AdvancedChecker is Test { vm.startPrank(target); vm.expectRevert(abi.encodeWithSelector(IERC721Errors.ERC721NonexistentToken.selector, uint256(1))); - checkerHarness.exposed__checkPre(subject, abi.encode(1)); + checkerHarness.exposed__checkPre(subject, wrongEvidence); vm.stopPrank(); } @@ -204,7 +214,7 @@ contract AdvancedChecker is Test { nft.mint(subject); - assert(!checkerHarness.exposed__checkPre(notOwner, abi.encode(0))); + assert(!checkerHarness.exposed__checkPre(notOwner, evidence)); vm.stopPrank(); } @@ -214,7 +224,7 @@ contract AdvancedChecker is Test { nft.mint(subject); - assert(checkerHarness.exposed__checkPre(subject, abi.encode(0))); + assert(checkerHarness.exposed__checkPre(subject, evidence)); vm.stopPrank(); } @@ -224,7 +234,7 @@ contract AdvancedChecker is Test { nft.mint(subject); - assert(!checkerHarness.exposed__checkMain(notOwner, abi.encode(0))); + assert(!checkerHarness.exposed__checkMain(notOwner, evidence)); vm.stopPrank(); } @@ -234,7 +244,7 @@ contract AdvancedChecker is Test { nft.mint(subject); - assert(checkerHarness.exposed__checkMain(subject, abi.encode(0))); + assert(checkerHarness.exposed__checkMain(subject, evidence)); vm.stopPrank(); } @@ -243,7 +253,7 @@ contract AdvancedChecker is Test { vm.startPrank(target); vm.expectRevert(abi.encodeWithSelector(IERC721Errors.ERC721NonexistentToken.selector, uint256(1))); - checkerHarness.exposed__checkPost(subject, abi.encode(1)); + checkerHarness.exposed__checkPost(subject, wrongEvidence); vm.stopPrank(); } @@ -253,7 +263,7 @@ contract AdvancedChecker is Test { nft.mint(subject); - assert(!checkerHarness.exposed__checkPost(notOwner, abi.encode(0))); + assert(!checkerHarness.exposed__checkPost(notOwner, evidence)); vm.stopPrank(); } @@ -263,7 +273,7 @@ contract AdvancedChecker is Test { nft.mint(subject); - assert(checkerHarness.exposed__checkPost(subject, abi.encode(0))); + assert(checkerHarness.exposed__checkPost(subject, evidence)); vm.stopPrank(); } @@ -271,7 +281,7 @@ contract AdvancedChecker is Test { contract AdvancedPolicy is Test { event TargetSet(address indexed target); - event Enforced(address indexed subject, address indexed target, bytes evidence, Check checkType); + event Enforced(address indexed subject, address indexed target, bytes[] evidence, Check checkType); NFT internal nft; AdvancedERC721Checker internal checker; @@ -286,17 +296,27 @@ contract AdvancedPolicy is Test { address public subject = vm.addr(0x3); address public notOwner = vm.addr(0x4); + address[] internal verifiers; + bytes[] public evidence = new bytes[](1); + bytes[] public wrongEvidence = new bytes[](1); + function setUp() public virtual { vm.startPrank(deployer); nft = new NFT(); - checker = new AdvancedERC721Checker(nft, 1, 0, 10); - checkerSkipped = new AdvancedERC721Checker(nft, 1, 0, 10); + verifiers = new address[](1); + verifiers[0] = address(nft); + + checker = new AdvancedERC721Checker(verifiers, 1, 0, 10); + checkerSkipped = new AdvancedERC721Checker(verifiers, 1, 0, 10); policy = new AdvancedERC721Policy(checker, false, false, true); policyHarness = new AdvancedERC721PolicyHarness(checker, false, false, true); policySkipped = new AdvancedERC721Policy(checkerSkipped, true, true, false); policyHarnessSkipped = new AdvancedERC721PolicyHarness(checkerSkipped, true, true, false); + evidence[0] = abi.encode(0); + wrongEvidence[0] = abi.encode(1); + vm.stopPrank(); } @@ -354,7 +374,7 @@ contract AdvancedPolicy is Test { vm.startPrank(subject); vm.expectRevert(abi.encodeWithSelector(IPolicy.TargetOnly.selector)); - policy.enforce(subject, abi.encode(0x0), Check.PRE); + policy.enforce(subject, evidence, Check.PRE); vm.stopPrank(); } @@ -369,7 +389,7 @@ contract AdvancedPolicy is Test { vm.startPrank(target); vm.expectRevert(abi.encodeWithSelector(IERC721Errors.ERC721NonexistentToken.selector, uint256(0))); - policy.enforce(subject, abi.encode(0x0), Check.PRE); + policy.enforce(subject, evidence, Check.PRE); vm.stopPrank(); } @@ -385,7 +405,7 @@ contract AdvancedPolicy is Test { vm.startPrank(target); vm.expectRevert(abi.encodeWithSelector(IAdvancedPolicy.CannotPreCheckWhenSkipped.selector)); - policySkipped.enforce(subject, abi.encode(0x0), Check.PRE); + policySkipped.enforce(subject, evidence, Check.PRE); vm.stopPrank(); } @@ -401,7 +421,7 @@ contract AdvancedPolicy is Test { vm.startPrank(target); vm.expectRevert(abi.encodeWithSelector(IPolicy.UnsuccessfulCheck.selector)); - policy.enforce(notOwner, abi.encode(0x0), Check.PRE); + policy.enforce(notOwner, evidence, Check.PRE); vm.stopPrank(); } @@ -417,9 +437,9 @@ contract AdvancedPolicy is Test { vm.startPrank(target); vm.expectEmit(true, true, true, true); - emit Enforced(subject, target, abi.encode(0x0), Check.PRE); + emit Enforced(subject, target, evidence, Check.PRE); - policy.enforce(subject, abi.encode(0x0), Check.PRE); + policy.enforce(subject, evidence, Check.PRE); vm.stopPrank(); } @@ -434,10 +454,10 @@ contract AdvancedPolicy is Test { vm.startPrank(target); - policy.enforce(subject, abi.encode(0x0), Check.PRE); + policy.enforce(subject, evidence, Check.PRE); vm.expectRevert(abi.encodeWithSelector(IPolicy.AlreadyEnforced.selector)); - policy.enforce(subject, abi.encode(0x0), Check.PRE); + policy.enforce(subject, evidence, Check.PRE); vm.stopPrank(); } @@ -452,7 +472,7 @@ contract AdvancedPolicy is Test { vm.startPrank(subject); vm.expectRevert(abi.encodeWithSelector(IPolicy.TargetOnly.selector)); - policy.enforce(subject, abi.encode(0x0), Check.MAIN); + policy.enforce(subject, evidence, Check.MAIN); vm.stopPrank(); } @@ -467,7 +487,7 @@ contract AdvancedPolicy is Test { vm.startPrank(target); vm.expectRevert(abi.encodeWithSelector(IPolicy.UnsuccessfulCheck.selector)); - policy.enforce(subject, abi.encode(0x0), Check.MAIN); + policy.enforce(subject, evidence, Check.MAIN); vm.stopPrank(); } @@ -483,7 +503,7 @@ contract AdvancedPolicy is Test { vm.startPrank(target); vm.expectRevert(abi.encodeWithSelector(IAdvancedPolicy.PreCheckNotEnforced.selector)); - policy.enforce(subject, abi.encode(0x0), Check.MAIN); + policy.enforce(subject, evidence, Check.MAIN); vm.stopPrank(); } @@ -498,12 +518,12 @@ contract AdvancedPolicy is Test { vm.startPrank(target); - policy.enforce(subject, abi.encode(0x0), Check.PRE); + policy.enforce(subject, evidence, Check.PRE); vm.expectEmit(true, true, true, true); - emit Enforced(subject, target, abi.encode(0x0), Check.MAIN); + emit Enforced(subject, target, evidence, Check.MAIN); - policy.enforce(subject, abi.encode(0x0), Check.MAIN); + policy.enforce(subject, evidence, Check.MAIN); vm.stopPrank(); } @@ -518,17 +538,17 @@ contract AdvancedPolicy is Test { vm.startPrank(target); - policy.enforce(subject, abi.encode(0x0), Check.PRE); + policy.enforce(subject, evidence, Check.PRE); vm.expectEmit(true, true, true, true); - emit Enforced(subject, target, abi.encode(0x0), Check.MAIN); + emit Enforced(subject, target, evidence, Check.MAIN); - policy.enforce(subject, abi.encode(0x0), Check.MAIN); + policy.enforce(subject, evidence, Check.MAIN); vm.expectEmit(true, true, true, true); - emit Enforced(subject, target, abi.encode(0x0), Check.MAIN); + emit Enforced(subject, target, evidence, Check.MAIN); - policy.enforce(subject, abi.encode(0x0), Check.MAIN); + policy.enforce(subject, evidence, Check.MAIN); vm.stopPrank(); } @@ -543,10 +563,10 @@ contract AdvancedPolicy is Test { vm.startPrank(target); - policySkipped.enforce(subject, abi.encode(0x0), Check.MAIN); + policySkipped.enforce(subject, evidence, Check.MAIN); vm.expectRevert(abi.encodeWithSelector(IAdvancedPolicy.MainCheckAlreadyEnforced.selector)); - policySkipped.enforce(subject, abi.encode(0x0), Check.MAIN); + policySkipped.enforce(subject, evidence, Check.MAIN); vm.stopPrank(); } @@ -560,10 +580,10 @@ contract AdvancedPolicy is Test { vm.stopPrank(); vm.startPrank(target); - policy.enforce(subject, abi.encode(0x0), Check.PRE); + policy.enforce(subject, evidence, Check.PRE); vm.expectRevert(abi.encodeWithSelector(IAdvancedPolicy.MainCheckNotEnforced.selector)); - policy.enforce(subject, abi.encode(0x0), Check.POST); + policy.enforce(subject, evidence, Check.POST); vm.stopPrank(); } @@ -578,7 +598,7 @@ contract AdvancedPolicy is Test { vm.startPrank(subject); vm.expectRevert(abi.encodeWithSelector(IPolicy.TargetOnly.selector)); - policy.enforce(subject, abi.encode(0x0), Check.POST); + policy.enforce(subject, evidence, Check.POST); vm.stopPrank(); } @@ -592,11 +612,11 @@ contract AdvancedPolicy is Test { vm.stopPrank(); vm.startPrank(target); - policy.enforce(subject, abi.encode(0x0), Check.PRE); - policy.enforce(subject, abi.encode(0x0), Check.MAIN); + policy.enforce(subject, evidence, Check.PRE); + policy.enforce(subject, evidence, Check.MAIN); vm.expectRevert(abi.encodeWithSelector(IERC721Errors.ERC721NonexistentToken.selector, uint256(1))); - policy.enforce(subject, abi.encode(0x1), Check.POST); + policy.enforce(subject, wrongEvidence, Check.POST); vm.stopPrank(); } @@ -611,10 +631,10 @@ contract AdvancedPolicy is Test { vm.startPrank(target); - policySkipped.enforce(subject, abi.encode(0x0), Check.MAIN); + policySkipped.enforce(subject, evidence, Check.MAIN); vm.expectRevert(abi.encodeWithSelector(IAdvancedPolicy.CannotPostCheckWhenSkipped.selector)); - policySkipped.enforce(subject, abi.encode(0x0), Check.POST); + policySkipped.enforce(subject, evidence, Check.POST); vm.stopPrank(); } @@ -629,11 +649,11 @@ contract AdvancedPolicy is Test { vm.startPrank(target); - policy.enforce(subject, abi.encode(0x0), Check.PRE); - policy.enforce(subject, abi.encode(0x0), Check.MAIN); + policy.enforce(subject, evidence, Check.PRE); + policy.enforce(subject, evidence, Check.MAIN); vm.expectRevert(abi.encodeWithSelector(IPolicy.UnsuccessfulCheck.selector)); - policy.enforce(notOwner, abi.encode(0x0), Check.POST); + policy.enforce(notOwner, evidence, Check.POST); vm.stopPrank(); } @@ -648,13 +668,13 @@ contract AdvancedPolicy is Test { vm.startPrank(target); - policy.enforce(subject, abi.encode(0x0), Check.PRE); - policy.enforce(subject, abi.encode(0x0), Check.MAIN); + policy.enforce(subject, evidence, Check.PRE); + policy.enforce(subject, evidence, Check.MAIN); vm.expectEmit(true, true, true, true); - emit Enforced(subject, target, abi.encode(0x0), Check.POST); + emit Enforced(subject, target, evidence, Check.POST); - policy.enforce(subject, abi.encode(0x0), Check.POST); + policy.enforce(subject, evidence, Check.POST); vm.stopPrank(); } @@ -669,12 +689,12 @@ contract AdvancedPolicy is Test { vm.startPrank(target); - policy.enforce(subject, abi.encode(0x0), Check.PRE); - policy.enforce(subject, abi.encode(0x0), Check.MAIN); - policy.enforce(subject, abi.encode(0x0), Check.POST); + policy.enforce(subject, evidence, Check.PRE); + policy.enforce(subject, evidence, Check.MAIN); + policy.enforce(subject, evidence, Check.POST); vm.expectRevert(abi.encodeWithSelector(IPolicy.AlreadyEnforced.selector)); - policy.enforce(subject, abi.encode(0x0), Check.POST); + policy.enforce(subject, evidence, Check.POST); vm.stopPrank(); } @@ -689,7 +709,7 @@ contract AdvancedPolicy is Test { vm.startPrank(subject); vm.expectRevert(abi.encodeWithSelector(IPolicy.TargetOnly.selector)); - policyHarness.exposed__enforce(subject, abi.encode(0x0), Check.PRE); + policyHarness.exposed__enforce(subject, evidence, Check.PRE); vm.stopPrank(); } @@ -704,7 +724,7 @@ contract AdvancedPolicy is Test { vm.startPrank(target); vm.expectRevert(abi.encodeWithSelector(IERC721Errors.ERC721NonexistentToken.selector, uint256(0))); - policyHarness.exposed__enforce(subject, abi.encode(0x0), Check.PRE); + policyHarness.exposed__enforce(subject, evidence, Check.PRE); vm.stopPrank(); } @@ -720,7 +740,7 @@ contract AdvancedPolicy is Test { vm.startPrank(target); vm.expectRevert(abi.encodeWithSelector(IAdvancedPolicy.CannotPreCheckWhenSkipped.selector)); - policyHarnessSkipped.exposed__enforce(subject, abi.encode(0x0), Check.PRE); + policyHarnessSkipped.exposed__enforce(subject, evidence, Check.PRE); vm.stopPrank(); } @@ -736,7 +756,7 @@ contract AdvancedPolicy is Test { vm.startPrank(target); vm.expectRevert(abi.encodeWithSelector(IPolicy.UnsuccessfulCheck.selector)); - policyHarness.exposed__enforce(notOwner, abi.encode(0x0), Check.PRE); + policyHarness.exposed__enforce(notOwner, evidence, Check.PRE); vm.stopPrank(); } @@ -752,9 +772,9 @@ contract AdvancedPolicy is Test { vm.startPrank(target); vm.expectEmit(true, true, true, true); - emit Enforced(subject, target, abi.encode(0x0), Check.PRE); + emit Enforced(subject, target, evidence, Check.PRE); - policyHarness.exposed__enforce(subject, abi.encode(0x0), Check.PRE); + policyHarness.exposed__enforce(subject, evidence, Check.PRE); vm.stopPrank(); } @@ -769,10 +789,10 @@ contract AdvancedPolicy is Test { vm.startPrank(target); - policyHarness.exposed__enforce(subject, abi.encode(0x0), Check.PRE); + policyHarness.exposed__enforce(subject, evidence, Check.PRE); vm.expectRevert(abi.encodeWithSelector(IPolicy.AlreadyEnforced.selector)); - policyHarness.exposed__enforce(subject, abi.encode(0x0), Check.PRE); + policyHarness.exposed__enforce(subject, evidence, Check.PRE); vm.stopPrank(); } @@ -787,7 +807,7 @@ contract AdvancedPolicy is Test { vm.startPrank(subject); vm.expectRevert(abi.encodeWithSelector(IPolicy.TargetOnly.selector)); - policyHarness.exposed__enforce(subject, abi.encode(0x0), Check.MAIN); + policyHarness.exposed__enforce(subject, evidence, Check.MAIN); vm.stopPrank(); } @@ -802,7 +822,7 @@ contract AdvancedPolicy is Test { vm.startPrank(target); vm.expectRevert(abi.encodeWithSelector(IPolicy.UnsuccessfulCheck.selector)); - policyHarness.exposed__enforce(subject, abi.encode(0x0), Check.MAIN); + policyHarness.exposed__enforce(subject, evidence, Check.MAIN); vm.stopPrank(); } @@ -818,7 +838,7 @@ contract AdvancedPolicy is Test { vm.startPrank(target); vm.expectRevert(abi.encodeWithSelector(IAdvancedPolicy.PreCheckNotEnforced.selector)); - policyHarness.exposed__enforce(subject, abi.encode(0x0), Check.MAIN); + policyHarness.exposed__enforce(subject, evidence, Check.MAIN); vm.stopPrank(); } @@ -833,12 +853,12 @@ contract AdvancedPolicy is Test { vm.startPrank(target); - policyHarness.exposed__enforce(subject, abi.encode(0x0), Check.PRE); + policyHarness.exposed__enforce(subject, evidence, Check.PRE); vm.expectEmit(true, true, true, true); - emit Enforced(subject, target, abi.encode(0x0), Check.MAIN); + emit Enforced(subject, target, evidence, Check.MAIN); - policyHarness.exposed__enforce(subject, abi.encode(0x0), Check.MAIN); + policyHarness.exposed__enforce(subject, evidence, Check.MAIN); vm.stopPrank(); } @@ -853,17 +873,17 @@ contract AdvancedPolicy is Test { vm.startPrank(target); - policyHarness.exposed__enforce(subject, abi.encode(0x0), Check.PRE); + policyHarness.exposed__enforce(subject, evidence, Check.PRE); vm.expectEmit(true, true, true, true); - emit Enforced(subject, target, abi.encode(0x0), Check.MAIN); + emit Enforced(subject, target, evidence, Check.MAIN); - policyHarness.exposed__enforce(subject, abi.encode(0x0), Check.MAIN); + policyHarness.exposed__enforce(subject, evidence, Check.MAIN); vm.expectEmit(true, true, true, true); - emit Enforced(subject, target, abi.encode(0x0), Check.MAIN); + emit Enforced(subject, target, evidence, Check.MAIN); - policyHarness.exposed__enforce(subject, abi.encode(0x0), Check.MAIN); + policyHarness.exposed__enforce(subject, evidence, Check.MAIN); vm.stopPrank(); } @@ -878,10 +898,10 @@ contract AdvancedPolicy is Test { vm.startPrank(target); - policyHarnessSkipped.exposed__enforce(subject, abi.encode(0x0), Check.MAIN); + policyHarnessSkipped.exposed__enforce(subject, evidence, Check.MAIN); vm.expectRevert(abi.encodeWithSelector(IAdvancedPolicy.MainCheckAlreadyEnforced.selector)); - policyHarnessSkipped.exposed__enforce(subject, abi.encode(0x0), Check.MAIN); + policyHarnessSkipped.exposed__enforce(subject, evidence, Check.MAIN); vm.stopPrank(); } @@ -895,10 +915,10 @@ contract AdvancedPolicy is Test { vm.stopPrank(); vm.startPrank(target); - policyHarness.exposed__enforce(subject, abi.encode(0x0), Check.PRE); + policyHarness.exposed__enforce(subject, evidence, Check.PRE); vm.expectRevert(abi.encodeWithSelector(IAdvancedPolicy.MainCheckNotEnforced.selector)); - policyHarness.exposed__enforce(subject, abi.encode(0x0), Check.POST); + policyHarness.exposed__enforce(subject, evidence, Check.POST); vm.stopPrank(); } @@ -913,7 +933,7 @@ contract AdvancedPolicy is Test { vm.startPrank(subject); vm.expectRevert(abi.encodeWithSelector(IPolicy.TargetOnly.selector)); - policyHarness.exposed__enforce(subject, abi.encode(0x0), Check.POST); + policyHarness.exposed__enforce(subject, evidence, Check.POST); vm.stopPrank(); } @@ -927,11 +947,11 @@ contract AdvancedPolicy is Test { vm.stopPrank(); vm.startPrank(target); - policyHarness.exposed__enforce(subject, abi.encode(0x0), Check.PRE); - policyHarness.exposed__enforce(subject, abi.encode(0x0), Check.MAIN); + policyHarness.exposed__enforce(subject, evidence, Check.PRE); + policyHarness.exposed__enforce(subject, evidence, Check.MAIN); vm.expectRevert(abi.encodeWithSelector(IERC721Errors.ERC721NonexistentToken.selector, uint256(1))); - policyHarness.exposed__enforce(subject, abi.encode(0x1), Check.POST); + policyHarness.exposed__enforce(subject, wrongEvidence, Check.POST); vm.stopPrank(); } @@ -946,10 +966,10 @@ contract AdvancedPolicy is Test { vm.startPrank(target); - policyHarnessSkipped.exposed__enforce(subject, abi.encode(0x0), Check.MAIN); + policyHarnessSkipped.exposed__enforce(subject, evidence, Check.MAIN); vm.expectRevert(abi.encodeWithSelector(IAdvancedPolicy.CannotPostCheckWhenSkipped.selector)); - policyHarnessSkipped.exposed__enforce(subject, abi.encode(0x0), Check.POST); + policyHarnessSkipped.exposed__enforce(subject, evidence, Check.POST); vm.stopPrank(); } @@ -964,11 +984,11 @@ contract AdvancedPolicy is Test { vm.startPrank(target); - policyHarness.exposed__enforce(subject, abi.encode(0x0), Check.PRE); - policyHarness.exposed__enforce(subject, abi.encode(0x0), Check.MAIN); + policyHarness.exposed__enforce(subject, evidence, Check.PRE); + policyHarness.exposed__enforce(subject, evidence, Check.MAIN); vm.expectRevert(abi.encodeWithSelector(IPolicy.UnsuccessfulCheck.selector)); - policyHarness.exposed__enforce(notOwner, abi.encode(0x0), Check.POST); + policyHarness.exposed__enforce(notOwner, evidence, Check.POST); vm.stopPrank(); } @@ -983,13 +1003,13 @@ contract AdvancedPolicy is Test { vm.startPrank(target); - policyHarness.exposed__enforce(subject, abi.encode(0x0), Check.PRE); - policyHarness.exposed__enforce(subject, abi.encode(0x0), Check.MAIN); + policyHarness.exposed__enforce(subject, evidence, Check.PRE); + policyHarness.exposed__enforce(subject, evidence, Check.MAIN); vm.expectEmit(true, true, true, true); - emit Enforced(subject, target, abi.encode(0x0), Check.POST); + emit Enforced(subject, target, evidence, Check.POST); - policyHarness.exposed__enforce(subject, abi.encode(0x0), Check.POST); + policyHarness.exposed__enforce(subject, evidence, Check.POST); vm.stopPrank(); } @@ -1004,12 +1024,12 @@ contract AdvancedPolicy is Test { vm.startPrank(target); - policyHarness.exposed__enforce(subject, abi.encode(0x0), Check.PRE); - policyHarness.exposed__enforce(subject, abi.encode(0x0), Check.MAIN); - policyHarness.exposed__enforce(subject, abi.encode(0x0), Check.POST); + policyHarness.exposed__enforce(subject, evidence, Check.PRE); + policyHarness.exposed__enforce(subject, evidence, Check.MAIN); + policyHarness.exposed__enforce(subject, evidence, Check.POST); vm.expectRevert(abi.encodeWithSelector(IPolicy.AlreadyEnforced.selector)); - policyHarness.exposed__enforce(subject, abi.encode(0x0), Check.POST); + policyHarness.exposed__enforce(subject, evidence, Check.POST); vm.stopPrank(); } @@ -1024,6 +1044,7 @@ contract Voting is Test { AdvancedERC721Checker internal checker; AdvancedERC721Policy internal policy; AdvancedVoting internal voting; + address[] internal verifiers; address public deployer = vm.addr(0x1); address public subject = vm.addr(0x2); @@ -1033,7 +1054,10 @@ contract Voting is Test { vm.startPrank(deployer); nft = new NFT(); - checker = new AdvancedERC721Checker(nft, 1, 0, 10); + verifiers = new address[](1); + verifiers[0] = address(nft); + + checker = new AdvancedERC721Checker(verifiers, 1, 0, 10); policy = new AdvancedERC721Policy(checker, false, false, true); voting = new AdvancedVoting(policy); diff --git a/packages/contracts/contracts/src/test/Base.t.sol b/packages/contracts/contracts/src/test/Base.t.sol index ab40814..eef8978 100644 --- a/packages/contracts/contracts/src/test/Base.t.sol +++ b/packages/contracts/contracts/src/test/Base.t.sol @@ -22,12 +22,20 @@ contract BaseChecker is Test { address public subject = vm.addr(0x3); address public notOwner = vm.addr(0x4); + address[] internal verifiers; + bytes[] public evidence = new bytes[](1); + function setUp() public virtual { vm.startPrank(deployer); nft = new NFT(); - checker = new BaseERC721Checker(nft); - checkerHarness = new BaseERC721CheckerHarness(nft); + verifiers = new address[](1); + verifiers[0] = address(nft); + + checker = new BaseERC721Checker(verifiers); + checkerHarness = new BaseERC721CheckerHarness(verifiers); + + evidence[0] = abi.encode(0); vm.stopPrank(); } @@ -36,7 +44,7 @@ contract BaseChecker is Test { vm.startPrank(target); vm.expectRevert(abi.encodeWithSelector(IERC721Errors.ERC721NonexistentToken.selector, uint256(0))); - checkerHarness.exposed__check(subject, abi.encode(0)); + checkerHarness.exposed__check(subject, evidence); vm.stopPrank(); } @@ -46,7 +54,7 @@ contract BaseChecker is Test { nft.mint(subject); - assert(!checkerHarness.exposed__check(notOwner, abi.encode(0))); + assert(!checkerHarness.exposed__check(notOwner, evidence)); vm.stopPrank(); } @@ -56,7 +64,7 @@ contract BaseChecker is Test { nft.mint(subject); - assert(checkerHarness.exposed__check(subject, abi.encode(0))); + assert(checkerHarness.exposed__check(subject, evidence)); vm.stopPrank(); } @@ -65,7 +73,7 @@ contract BaseChecker is Test { vm.startPrank(target); vm.expectRevert(abi.encodeWithSelector(IERC721Errors.ERC721NonexistentToken.selector, uint256(0))); - checker.check(subject, abi.encode(0)); + checker.check(subject, evidence); vm.stopPrank(); } @@ -75,7 +83,7 @@ contract BaseChecker is Test { nft.mint(subject); - assert(!checker.check(notOwner, abi.encode(0))); + assert(!checker.check(notOwner, evidence)); vm.stopPrank(); } @@ -85,7 +93,7 @@ contract BaseChecker is Test { nft.mint(subject); - assert(checker.check(subject, abi.encode(0))); + assert(checker.check(subject, evidence)); vm.stopPrank(); } @@ -93,7 +101,7 @@ contract BaseChecker is Test { contract BasePolicy is Test { event TargetSet(address indexed target); - event Enforced(address indexed subject, address indexed target, bytes evidence); + event Enforced(address indexed subject, address indexed target, bytes[] evidence); NFT internal nft; BaseERC721Checker internal checker; @@ -105,14 +113,22 @@ contract BasePolicy is Test { address public subject = vm.addr(0x3); address public notOwner = vm.addr(0x4); + address[] internal verifiers; + bytes[] public evidence = new bytes[](1); + function setUp() public virtual { vm.startPrank(deployer); nft = new NFT(); - checker = new BaseERC721Checker(nft); + verifiers = new address[](1); + verifiers[0] = address(nft); + + checker = new BaseERC721Checker(verifiers); policy = new BaseERC721Policy(checker); policyHarness = new BaseERC721PolicyHarness(checker); + evidence[0] = abi.encode(0); + vm.stopPrank(); } @@ -180,7 +196,7 @@ contract BasePolicy is Test { vm.startPrank(subject); vm.expectRevert(abi.encodeWithSelector(IPolicy.TargetOnly.selector)); - policy.enforce(subject, abi.encode(0x0)); + policy.enforce(subject, evidence); vm.stopPrank(); } @@ -195,7 +211,7 @@ contract BasePolicy is Test { vm.startPrank(target); vm.expectRevert(abi.encodeWithSelector(IERC721Errors.ERC721NonexistentToken.selector, uint256(0))); - policy.enforce(subject, abi.encode(0x0)); + policy.enforce(subject, evidence); vm.stopPrank(); } @@ -211,7 +227,7 @@ contract BasePolicy is Test { vm.startPrank(target); vm.expectRevert(abi.encodeWithSelector(IPolicy.UnsuccessfulCheck.selector)); - policy.enforce(notOwner, abi.encode(0x0)); + policy.enforce(notOwner, evidence); vm.stopPrank(); } @@ -227,9 +243,9 @@ contract BasePolicy is Test { vm.startPrank(target); vm.expectEmit(true, true, true, true); - emit Enforced(subject, target, abi.encode(0x0)); + emit Enforced(subject, target, evidence); - policy.enforce(subject, abi.encode(0x0)); + policy.enforce(subject, evidence); vm.stopPrank(); } @@ -244,10 +260,10 @@ contract BasePolicy is Test { vm.startPrank(target); - policy.enforce(subject, abi.encode(0x0)); + policy.enforce(subject, evidence); vm.expectRevert(abi.encodeWithSelector(IPolicy.AlreadyEnforced.selector)); - policy.enforce(subject, abi.encode(0x0)); + policy.enforce(subject, evidence); vm.stopPrank(); } @@ -262,7 +278,7 @@ contract BasePolicy is Test { vm.startPrank(subject); vm.expectRevert(abi.encodeWithSelector(IPolicy.TargetOnly.selector)); - policyHarness.exposed__enforce(subject, abi.encode(0x0)); + policyHarness.exposed__enforce(subject, evidence); vm.stopPrank(); } @@ -277,7 +293,7 @@ contract BasePolicy is Test { vm.startPrank(target); vm.expectRevert(abi.encodeWithSelector(IERC721Errors.ERC721NonexistentToken.selector, uint256(0))); - policyHarness.exposed__enforce(subject, abi.encode(0x0)); + policyHarness.exposed__enforce(subject, evidence); vm.stopPrank(); } @@ -293,7 +309,7 @@ contract BasePolicy is Test { vm.startPrank(target); vm.expectRevert(abi.encodeWithSelector(IPolicy.UnsuccessfulCheck.selector)); - policyHarness.exposed__enforce(notOwner, abi.encode(0x0)); + policyHarness.exposed__enforce(notOwner, evidence); vm.stopPrank(); } @@ -309,9 +325,9 @@ contract BasePolicy is Test { vm.startPrank(target); vm.expectEmit(true, true, true, true); - emit Enforced(subject, target, abi.encode(0x0)); + emit Enforced(subject, target, evidence); - policyHarness.exposed__enforce(subject, abi.encode(0x0)); + policyHarness.exposed__enforce(subject, evidence); vm.stopPrank(); } @@ -326,10 +342,10 @@ contract BasePolicy is Test { vm.startPrank(target); - policyHarness.exposed__enforce(subject, abi.encode(0x0)); + policyHarness.exposed__enforce(subject, evidence); vm.expectRevert(abi.encodeWithSelector(IPolicy.AlreadyEnforced.selector)); - policyHarness.exposed__enforce(subject, abi.encode(0x0)); + policyHarness.exposed__enforce(subject, evidence); vm.stopPrank(); } @@ -348,11 +364,16 @@ contract Voting is Test { address public subject = vm.addr(0x2); address public notOwner = vm.addr(0x3); + address[] internal verifiers; + function setUp() public virtual { vm.startPrank(deployer); nft = new NFT(); - checker = new BaseERC721Checker(nft); + verifiers = new address[](1); + verifiers[0] = address(nft); + + checker = new BaseERC721Checker(verifiers); policy = new BaseERC721Policy(checker); voting = new BaseVoting(policy); diff --git a/packages/contracts/contracts/src/test/advanced/AdvancedERC721Checker.sol b/packages/contracts/contracts/src/test/advanced/AdvancedERC721Checker.sol index f8dcbc2..309959f 100644 --- a/packages/contracts/contracts/src/test/advanced/AdvancedERC721Checker.sol +++ b/packages/contracts/contracts/src/test/advanced/AdvancedERC721Checker.sol @@ -15,12 +15,17 @@ contract AdvancedERC721Checker is AdvancedChecker { uint256 public immutable MAX_TOKEN_ID; /// @notice Initializes checker with validation parameters. - /// @param _nft ERC721 contract address. + /// @param _verifiers Array of addresses for existing verification contracts. /// @param _minBalance Required token balance. /// @param _minTokenId Minimum valid token ID. /// @param _maxTokenId Maximum valid token ID. - constructor(IERC721 _nft, uint256 _minBalance, uint256 _minTokenId, uint256 _maxTokenId) { - NFT = _nft; + constructor( + address[] memory _verifiers, + uint256 _minBalance, + uint256 _minTokenId, + uint256 _maxTokenId + ) AdvancedChecker(_verifiers) { + NFT = IERC721(getVerifierAtIndex(0)); MIN_BALANCE = _minBalance; MIN_TOKEN_ID = _minTokenId; MAX_TOKEN_ID = _maxTokenId; @@ -30,9 +35,9 @@ contract AdvancedERC721Checker is AdvancedChecker { /// @param subject Address to validate. /// @param evidence Encoded tokenId. /// @return Token ownership status. - function _checkPre(address subject, bytes memory evidence) internal view override returns (bool) { + function _checkPre(address subject, bytes[] calldata evidence) internal view override returns (bool) { super._checkPre(subject, evidence); - uint256 tokenId = abi.decode(evidence, (uint256)); + uint256 tokenId = abi.decode(evidence[0], (uint256)); return NFT.ownerOf(tokenId) == subject; } @@ -40,7 +45,7 @@ contract AdvancedERC721Checker is AdvancedChecker { /// @param subject Address to validate. /// @param evidence Unused parameter. /// @return Balance threshold status. - function _checkMain(address subject, bytes memory evidence) internal view override returns (bool) { + function _checkMain(address subject, bytes[] calldata evidence) internal view override returns (bool) { super._checkMain(subject, evidence); return NFT.balanceOf(subject) >= MIN_BALANCE; } @@ -49,9 +54,9 @@ contract AdvancedERC721Checker is AdvancedChecker { /// @param subject Address to validate. /// @param evidence Encoded tokenId. /// @return Token range validation status. - function _checkPost(address subject, bytes memory evidence) internal view override returns (bool) { + function _checkPost(address subject, bytes[] calldata evidence) internal view override returns (bool) { super._checkPost(subject, evidence); - uint256 tokenId = abi.decode(evidence, (uint256)); + uint256 tokenId = abi.decode(evidence[0], (uint256)); return tokenId >= MIN_TOKEN_ID && tokenId <= MAX_TOKEN_ID && NFT.ownerOf(tokenId) == subject; } } diff --git a/packages/contracts/contracts/src/test/advanced/AdvancedVoting.sol b/packages/contracts/contracts/src/test/advanced/AdvancedVoting.sol index ab0d468..c182f0c 100644 --- a/packages/contracts/contracts/src/test/advanced/AdvancedVoting.sol +++ b/packages/contracts/contracts/src/test/advanced/AdvancedVoting.sol @@ -43,10 +43,11 @@ contract AdvancedVoting { /// @custom:emits Registered on successful registration. function register(uint256 tokenId) external { // Encode token ID for policy verification. - bytes memory evidence = abi.encode(tokenId); + bytes[] memory _evidence = new bytes[](1); + _evidence[0] = abi.encode(tokenId); // Verify NFT ownership through policy's PRE check. - POLICY.enforce(msg.sender, evidence, Check.PRE); + POLICY.enforce(msg.sender, _evidence, Check.PRE); emit Registered(msg.sender); } @@ -66,8 +67,9 @@ contract AdvancedVoting { if (option >= 2) revert InvalidOption(); // Verify voting power through policy's MAIN check. - bytes memory evidence = abi.encode(option); - POLICY.enforce(msg.sender, evidence, Check.MAIN); + bytes[] memory _evidence = new bytes[](1); + _evidence[0] = abi.encode(option); + POLICY.enforce(msg.sender, _evidence, Check.MAIN); // Increment vote count safely. unchecked { @@ -94,8 +96,9 @@ contract AdvancedVoting { if (post) revert AlreadyClaimed(); // Verify reward eligibility through policy's POST check. - bytes memory evidence = abi.encode(rewardId); - POLICY.enforce(msg.sender, evidence, Check.POST); + bytes[] memory _evidence = new bytes[](1); + _evidence[0] = abi.encode(rewardId); + POLICY.enforce(msg.sender, _evidence, Check.POST); emit RewardClaimed(msg.sender, rewardId); } diff --git a/packages/contracts/contracts/src/test/base/BaseERC721Checker.sol b/packages/contracts/contracts/src/test/base/BaseERC721Checker.sol index 7ed5ae1..b8cc57d 100644 --- a/packages/contracts/contracts/src/test/base/BaseERC721Checker.sol +++ b/packages/contracts/contracts/src/test/base/BaseERC721Checker.sol @@ -12,18 +12,18 @@ contract BaseERC721Checker is BaseChecker { IERC721 public immutable NFT; /// @notice Initializes with ERC721 contract. - /// @param _nft ERC721 contract address. - constructor(IERC721 _nft) { - NFT = IERC721(_nft); + /// @param _verifiers Array of addresses for existing verification contracts. + constructor(address[] memory _verifiers) BaseChecker(_verifiers) { + NFT = IERC721(getVerifierAtIndex(0)); } /// @notice Validates token ownership. /// @param subject Address to check. /// @param evidence Encoded tokenId. /// @return True if subject owns token. - function _check(address subject, bytes memory evidence) internal view override returns (bool) { + function _check(address subject, bytes[] calldata evidence) internal view override returns (bool) { super._check(subject, evidence); - uint256 tokenId = abi.decode(evidence, (uint256)); + uint256 tokenId = abi.decode(evidence[0], (uint256)); return NFT.ownerOf(tokenId) == subject; } } diff --git a/packages/contracts/contracts/src/test/base/BaseVoting.sol b/packages/contracts/contracts/src/test/base/BaseVoting.sol index 369d27e..4f37794 100644 --- a/packages/contracts/contracts/src/test/base/BaseVoting.sol +++ b/packages/contracts/contracts/src/test/base/BaseVoting.sol @@ -39,10 +39,11 @@ contract BaseVoting { /// @custom:emits Registered on successful registration. function register(uint256 tokenId) external { // Encode token ID for policy verification. - bytes memory evidence = abi.encode(tokenId); + bytes[] memory _evidence = new bytes[](1); + _evidence[0] = abi.encode(tokenId); // Verify NFT ownership. - POLICY.enforce(msg.sender, evidence); + POLICY.enforce(msg.sender, _evidence); emit Registered(msg.sender); } diff --git a/packages/contracts/contracts/src/test/wrappers/AdvancedERC721CheckerHarness.sol b/packages/contracts/contracts/src/test/wrappers/AdvancedERC721CheckerHarness.sol index 63471ab..1d0511d 100644 --- a/packages/contracts/contracts/src/test/wrappers/AdvancedERC721CheckerHarness.sol +++ b/packages/contracts/contracts/src/test/wrappers/AdvancedERC721CheckerHarness.sol @@ -2,7 +2,6 @@ pragma solidity ^0.8.20; import {AdvancedERC721Checker} from "../advanced/AdvancedERC721Checker.sol"; -import {IERC721} from "@openzeppelin/contracts/token/ERC721/IERC721.sol"; import {Check} from "../../interfaces/IAdvancedChecker.sol"; /// @title AdvancedERC721CheckerHarness. @@ -10,23 +9,23 @@ import {Check} from "../../interfaces/IAdvancedChecker.sol"; /// @dev Inherits AdvancedERC721Checker and exposes protected methods for testing. contract AdvancedERC721CheckerHarness is AdvancedERC721Checker { /// @notice Initializes test harness with checker configuration. - /// @param _nft ERC721 contract to validate. + /// @param _verifiers Array of addresses for existing verification contracts. /// @param _minBalance Minimum token balance required. /// @param _minTokenId Minimum valid token ID. /// @param _maxTokenId Maximum valid token ID. constructor( - IERC721 _nft, + address[] memory _verifiers, uint256 _minBalance, uint256 _minTokenId, uint256 _maxTokenId - ) AdvancedERC721Checker(_nft, _minBalance, _minTokenId, _maxTokenId) {} + ) AdvancedERC721Checker(_verifiers, _minBalance, _minTokenId, _maxTokenId) {} /// @notice Test exposure for _check method. /// @param subject Address to validate. /// @param evidence Validation data. /// @param checkType Type of check to perform. /// @return Validation result. - function exposed__check(address subject, bytes calldata evidence, Check checkType) public view returns (bool) { + function exposed__check(address subject, bytes[] calldata evidence, Check checkType) public view returns (bool) { return _check(subject, evidence, checkType); } @@ -34,7 +33,7 @@ contract AdvancedERC721CheckerHarness is AdvancedERC721Checker { /// @param subject Address to validate. /// @param evidence Validation data. /// @return Pre-check validation result. - function exposed__checkPre(address subject, bytes calldata evidence) public view returns (bool) { + function exposed__checkPre(address subject, bytes[] calldata evidence) public view returns (bool) { return _checkPre(subject, evidence); } @@ -42,7 +41,7 @@ contract AdvancedERC721CheckerHarness is AdvancedERC721Checker { /// @param subject Address to validate. /// @param evidence Validation data. /// @return Main validation result. - function exposed__checkMain(address subject, bytes calldata evidence) public view returns (bool) { + function exposed__checkMain(address subject, bytes[] calldata evidence) public view returns (bool) { return _checkMain(subject, evidence); } @@ -50,7 +49,7 @@ contract AdvancedERC721CheckerHarness is AdvancedERC721Checker { /// @param subject Address to validate. /// @param evidence Validation data. /// @return Post-check validation result. - function exposed__checkPost(address subject, bytes calldata evidence) public view returns (bool) { + function exposed__checkPost(address subject, bytes[] calldata evidence) public view returns (bool) { return _checkPost(subject, evidence); } } diff --git a/packages/contracts/contracts/src/test/wrappers/AdvancedERC721PolicyHarness.sol b/packages/contracts/contracts/src/test/wrappers/AdvancedERC721PolicyHarness.sol index 070fb07..46a1518 100644 --- a/packages/contracts/contracts/src/test/wrappers/AdvancedERC721PolicyHarness.sol +++ b/packages/contracts/contracts/src/test/wrappers/AdvancedERC721PolicyHarness.sol @@ -20,7 +20,7 @@ contract AdvancedERC721PolicyHarness is AdvancedERC721Policy { /// @param subject Address to validate. /// @param evidence Validation data. /// @param checkType Check type to enforce. - function exposed__enforce(address subject, bytes calldata evidence, Check checkType) public onlyTarget { + function exposed__enforce(address subject, bytes[] calldata evidence, Check checkType) public onlyTarget { _enforce(subject, evidence, checkType); } } diff --git a/packages/contracts/contracts/src/test/wrappers/BaseERC721CheckerHarness.sol b/packages/contracts/contracts/src/test/wrappers/BaseERC721CheckerHarness.sol index c070d68..d97448d 100644 --- a/packages/contracts/contracts/src/test/wrappers/BaseERC721CheckerHarness.sol +++ b/packages/contracts/contracts/src/test/wrappers/BaseERC721CheckerHarness.sol @@ -2,19 +2,19 @@ pragma solidity ^0.8.20; import {BaseERC721Checker} from "../base/BaseERC721Checker.sol"; -import {IERC721} from "@openzeppelin/contracts/token/ERC721/IERC721.sol"; /// @title BaseERC721CheckerHarness. /// @notice Test harness for BaseERC721Checker internal methods. contract BaseERC721CheckerHarness is BaseERC721Checker { /// @notice Initializes test harness with NFT contract. - constructor(IERC721 _nft) BaseERC721Checker(_nft) {} + /// @param _verifiers Array of addresses for existing verification contracts. + constructor(address[] memory _verifiers) BaseERC721Checker(_verifiers) {} /// @notice Test exposure for _check method. /// @param subject Address to validate. /// @param evidence Validation data. /// @return Validation result. - function exposed__check(address subject, bytes calldata evidence) public view returns (bool) { + function exposed__check(address subject, bytes[] calldata evidence) public view returns (bool) { return _check(subject, evidence); } } diff --git a/packages/contracts/contracts/src/test/wrappers/BaseERC721PolicyHarness.sol b/packages/contracts/contracts/src/test/wrappers/BaseERC721PolicyHarness.sol index a2d7077..26c047b 100644 --- a/packages/contracts/contracts/src/test/wrappers/BaseERC721PolicyHarness.sol +++ b/packages/contracts/contracts/src/test/wrappers/BaseERC721PolicyHarness.sol @@ -13,7 +13,7 @@ contract BaseERC721PolicyHarness is BaseERC721Policy { /// @notice Test exposure for _enforce method. /// @param subject Address to validate. /// @param evidence Validation data. - function exposed__enforce(address subject, bytes calldata evidence) public onlyTarget { + function exposed__enforce(address subject, bytes[] calldata evidence) public onlyTarget { _enforce(subject, evidence); } } diff --git a/packages/contracts/test/Advanced.test.ts b/packages/contracts/test/Advanced.test.ts index 46d6c04..55c816b 100644 --- a/packages/contracts/test/Advanced.test.ts +++ b/packages/contracts/test/Advanced.test.ts @@ -34,7 +34,7 @@ describe("Advanced", () => { const nft: NFT = await NFTFactory.deploy() const checker: AdvancedERC721Checker = await AdvancedERC721CheckerFactory.connect(deployer).deploy( - await nft.getAddress(), + [await nft.getAddress()], 1, 0, 10 @@ -42,7 +42,7 @@ describe("Advanced", () => { const checkerHarness: AdvancedERC721CheckerHarness = await AdvancedERC721CheckerHarnessFactory.connect( deployer - ).deploy(await nft.getAddress(), 1, 0, 10) + ).deploy([await nft.getAddress()], 1, 0, 10) // mint 0 for subject. await nft.connect(deployer).mint(subjectAddress) @@ -80,7 +80,7 @@ describe("Advanced", () => { await loadFixture(deployAdvancedCheckerFixture) await expect( - checker.connect(target).check(subjectAddress, invalidNFTId, 0) + checker.connect(target).check(subjectAddress, [invalidNFTId], 0) ).to.be.revertedWithCustomError(nft, "ERC721NonexistentToken") }) @@ -88,14 +88,14 @@ describe("Advanced", () => { const { checker, target, notOwnerAddress, validNFTId } = await loadFixture(deployAdvancedCheckerFixture) - expect(await checker.connect(target).check(notOwnerAddress, validNFTId, 0)).to.be.equal(false) + expect(await checker.connect(target).check(notOwnerAddress, [validNFTId], 0)).to.be.equal(false) }) it("succeeds when valid", async () => { const { checker, target, subjectAddress, validNFTId } = await loadFixture(deployAdvancedCheckerFixture) - expect(await checker.connect(target).check(subjectAddress, validNFTId, 0)).to.be.equal(true) + expect(await checker.connect(target).check(subjectAddress, [validNFTId], 0)).to.be.equal(true) }) }) describe("main check", () => { @@ -103,14 +103,14 @@ describe("Advanced", () => { const { checker, target, notOwnerAddress, validNFTId } = await loadFixture(deployAdvancedCheckerFixture) - expect(await checker.connect(target).check(notOwnerAddress, validNFTId, 1)).to.be.equal(false) + expect(await checker.connect(target).check(notOwnerAddress, [validNFTId], 1)).to.be.equal(false) }) it("succeeds when balance sufficient", async () => { const { checker, target, subjectAddress, validNFTId } = await loadFixture(deployAdvancedCheckerFixture) - expect(await checker.connect(target).check(subjectAddress, validNFTId, 1)).to.be.equal(true) + expect(await checker.connect(target).check(subjectAddress, [validNFTId], 1)).to.be.equal(true) }) }) describe("post check", () => { @@ -119,7 +119,7 @@ describe("Advanced", () => { await loadFixture(deployAdvancedCheckerFixture) await expect( - checker.connect(target).check(subjectAddress, invalidNFTId, 2) + checker.connect(target).check(subjectAddress, [invalidNFTId], 2) ).to.be.revertedWithCustomError(nft, "ERC721NonexistentToken") }) @@ -127,14 +127,14 @@ describe("Advanced", () => { const { checker, target, notOwnerAddress, validNFTId } = await loadFixture(deployAdvancedCheckerFixture) - expect(await checker.connect(target).check(notOwnerAddress, validNFTId, 2)).to.be.equal(false) + expect(await checker.connect(target).check(notOwnerAddress, [validNFTId], 2)).to.be.equal(false) }) it("succeeds when in valid range", async () => { const { checker, target, subjectAddress, validNFTId } = await loadFixture(deployAdvancedCheckerFixture) - expect(await checker.connect(target).check(subjectAddress, validNFTId, 2)).to.be.equal(true) + expect(await checker.connect(target).check(subjectAddress, [validNFTId], 2)).to.be.equal(true) }) }) }) @@ -146,7 +146,7 @@ describe("Advanced", () => { await loadFixture(deployAdvancedCheckerFixture) await expect( - checkerHarness.connect(target).exposed__check(subjectAddress, invalidNFTId, 0) + checkerHarness.connect(target).exposed__check(subjectAddress, [invalidNFTId], 0) ).to.be.revertedWithCustomError(nft, "ERC721NonexistentToken") }) @@ -155,7 +155,7 @@ describe("Advanced", () => { await loadFixture(deployAdvancedCheckerFixture) expect( - await checkerHarness.connect(target).exposed__check(notOwnerAddress, validNFTId, 0) + await checkerHarness.connect(target).exposed__check(notOwnerAddress, [validNFTId], 0) ).to.be.equal(false) }) @@ -164,7 +164,7 @@ describe("Advanced", () => { await loadFixture(deployAdvancedCheckerFixture) expect( - await checkerHarness.connect(target).exposed__check(subjectAddress, validNFTId, 0) + await checkerHarness.connect(target).exposed__check(subjectAddress, [validNFTId], 0) ).to.be.equal(true) }) }) @@ -174,7 +174,7 @@ describe("Advanced", () => { await loadFixture(deployAdvancedCheckerFixture) expect( - await checkerHarness.connect(target).exposed__check(notOwnerAddress, validNFTId, 1) + await checkerHarness.connect(target).exposed__check(notOwnerAddress, [validNFTId], 1) ).to.be.equal(false) }) @@ -183,7 +183,7 @@ describe("Advanced", () => { await loadFixture(deployAdvancedCheckerFixture) expect( - await checkerHarness.connect(target).exposed__check(subjectAddress, validNFTId, 1) + await checkerHarness.connect(target).exposed__check(subjectAddress, [validNFTId], 1) ).to.be.equal(true) }) }) @@ -193,7 +193,7 @@ describe("Advanced", () => { await loadFixture(deployAdvancedCheckerFixture) await expect( - checkerHarness.connect(target).exposed__check(subjectAddress, invalidNFTId, 2) + checkerHarness.connect(target).exposed__check(subjectAddress, [invalidNFTId], 2) ).to.be.revertedWithCustomError(nft, "ERC721NonexistentToken") }) @@ -202,7 +202,7 @@ describe("Advanced", () => { await loadFixture(deployAdvancedCheckerFixture) expect( - await checkerHarness.connect(target).exposed__check(notOwnerAddress, validNFTId, 2) + await checkerHarness.connect(target).exposed__check(notOwnerAddress, [validNFTId], 2) ).to.be.equal(false) }) @@ -211,7 +211,7 @@ describe("Advanced", () => { await loadFixture(deployAdvancedCheckerFixture) expect( - await checkerHarness.connect(target).exposed__check(subjectAddress, validNFTId, 2) + await checkerHarness.connect(target).exposed__check(subjectAddress, [validNFTId], 2) ).to.be.equal(true) }) }) @@ -223,7 +223,7 @@ describe("Advanced", () => { await loadFixture(deployAdvancedCheckerFixture) await expect( - checkerHarness.connect(target).exposed__checkPre(subjectAddress, invalidNFTId) + checkerHarness.connect(target).exposed__checkPre(subjectAddress, [invalidNFTId]) ).to.be.revertedWithCustomError(nft, "ERC721NonexistentToken") }) @@ -231,18 +231,18 @@ describe("Advanced", () => { const { checkerHarness, target, notOwnerAddress, validNFTId } = await loadFixture(deployAdvancedCheckerFixture) - expect(await checkerHarness.connect(target).exposed__checkPre(notOwnerAddress, validNFTId)).to.be.equal( - false - ) + expect( + await checkerHarness.connect(target).exposed__checkPre(notOwnerAddress, [validNFTId]) + ).to.be.equal(false) }) it("succeeds when valid", async () => { const { checkerHarness, target, subjectAddress, validNFTId } = await loadFixture(deployAdvancedCheckerFixture) - expect(await checkerHarness.connect(target).exposed__checkPre(subjectAddress, validNFTId)).to.be.equal( - true - ) + expect( + await checkerHarness.connect(target).exposed__checkPre(subjectAddress, [validNFTId]) + ).to.be.equal(true) }) }) @@ -252,7 +252,7 @@ describe("Advanced", () => { await loadFixture(deployAdvancedCheckerFixture) expect( - await checkerHarness.connect(target).exposed__checkMain(notOwnerAddress, validNFTId) + await checkerHarness.connect(target).exposed__checkMain(notOwnerAddress, [validNFTId]) ).to.be.equal(false) }) @@ -260,9 +260,9 @@ describe("Advanced", () => { const { checkerHarness, target, subjectAddress, validNFTId } = await loadFixture(deployAdvancedCheckerFixture) - expect(await checkerHarness.connect(target).exposed__checkMain(subjectAddress, validNFTId)).to.be.equal( - true - ) + expect( + await checkerHarness.connect(target).exposed__checkMain(subjectAddress, [validNFTId]) + ).to.be.equal(true) }) }) @@ -272,7 +272,7 @@ describe("Advanced", () => { await loadFixture(deployAdvancedCheckerFixture) await expect( - checkerHarness.connect(target).exposed__checkPost(subjectAddress, invalidNFTId) + checkerHarness.connect(target).exposed__checkPost(subjectAddress, [invalidNFTId]) ).to.be.revertedWithCustomError(nft, "ERC721NonexistentToken") }) @@ -281,7 +281,7 @@ describe("Advanced", () => { await loadFixture(deployAdvancedCheckerFixture) expect( - await checkerHarness.connect(target).exposed__checkPost(notOwnerAddress, validNFTId) + await checkerHarness.connect(target).exposed__checkPost(notOwnerAddress, [validNFTId]) ).to.be.equal(false) }) @@ -289,9 +289,9 @@ describe("Advanced", () => { const { checkerHarness, target, subjectAddress, validNFTId } = await loadFixture(deployAdvancedCheckerFixture) - expect(await checkerHarness.connect(target).exposed__checkPost(subjectAddress, validNFTId)).to.be.equal( - true - ) + expect( + await checkerHarness.connect(target).exposed__checkPost(subjectAddress, [validNFTId]) + ).to.be.equal(true) }) }) }) @@ -314,7 +314,7 @@ describe("Advanced", () => { const iERC721Errors: IERC721Errors = await ethers.getContractAt("IERC721Errors", await nft.getAddress()) const checker: AdvancedERC721Checker = await AdvancedERC721CheckerFactory.connect(deployer).deploy( - await nft.getAddress(), + [await nft.getAddress()], 1, 0, 10 @@ -322,7 +322,7 @@ describe("Advanced", () => { const checkerSkippedPrePostNoMultMain: AdvancedERC721Checker = await AdvancedERC721CheckerFactory.connect( deployer - ).deploy(await nft.getAddress(), 1, 0, 10) + ).deploy([await nft.getAddress()], 1, 0, 10) const policy: AdvancedERC721Policy = await AdvancedERC721PolicyFactory.connect(deployer).deploy( await checker.getAddress(), @@ -441,7 +441,7 @@ describe("Advanced", () => { await policy.setTarget(await target.getAddress()) await expect( - policy.connect(subject).enforce(subjectAddress, ZeroHash, 0) + policy.connect(subject).enforce(subjectAddress, [ZeroHash], 0) ).to.be.revertedWithCustomError(policy, "TargetOnly") }) @@ -452,7 +452,7 @@ describe("Advanced", () => { await policy.setTarget(await target.getAddress()) await expect( - policy.connect(target).enforce(subjectAddress, invalidEncodedNFTId, 0) + policy.connect(target).enforce(subjectAddress, [invalidEncodedNFTId], 0) ).to.be.revertedWithCustomError(iERC721Errors, "ERC721NonexistentToken") }) @@ -463,7 +463,7 @@ describe("Advanced", () => { await policySkipped.setTarget(await target.getAddress()) await expect( - policySkipped.connect(target).enforce(subjectAddress, validEncodedNFTId, 0) + policySkipped.connect(target).enforce(subjectAddress, [validEncodedNFTId], 0) ).to.be.revertedWithCustomError(policySkipped, "CannotPreCheckWhenSkipped") }) @@ -474,7 +474,7 @@ describe("Advanced", () => { await policy.setTarget(await target.getAddress()) expect( - policy.connect(target).enforce(notOwnerAddress, validEncodedNFTId, 0) + policy.connect(target).enforce(notOwnerAddress, [validEncodedNFTId], 0) ).to.be.revertedWithCustomError(policy, "UnsuccessfulCheck") }) @@ -485,7 +485,7 @@ describe("Advanced", () => { await policy.setTarget(targetAddress) - const tx = await policy.connect(target).enforce(subjectAddress, validEncodedNFTId, 0) + const tx = await policy.connect(target).enforce(subjectAddress, [validEncodedNFTId], 0) const receipt = await tx.wait() const event = AdvancedERC721PolicyFactory.interface.parseLog( receipt?.logs[0] as unknown as { topics: string[]; data: string } @@ -501,7 +501,7 @@ describe("Advanced", () => { expect(receipt?.status).to.eq(1) expect(event.args.subject).to.eq(subjectAddress) expect(event.args.target).to.eq(targetAddress) - expect(event.args.evidence).to.eq(validEncodedNFTId) + expect(event.args.evidence[0]).to.eq(validEncodedNFTId) expect(event.args.checkType).to.eq(0) expect((await policy.enforced(targetAddress, subjectAddress))[0]).to.be.equal(true) }) @@ -512,10 +512,10 @@ describe("Advanced", () => { await policy.setTarget(await target.getAddress()) - await policy.connect(target).enforce(subjectAddress, validEncodedNFTId, 0) + await policy.connect(target).enforce(subjectAddress, [validEncodedNFTId], 0) await expect( - policy.connect(target).enforce(subjectAddress, validEncodedNFTId, 0) + policy.connect(target).enforce(subjectAddress, [validEncodedNFTId], 0) ).to.be.revertedWithCustomError(policy, "AlreadyEnforced") }) }) @@ -528,7 +528,7 @@ describe("Advanced", () => { await policy.setTarget(await target.getAddress()) expect( - policy.connect(target).enforce(subjectAddress, validEncodedNFTId, 1) + policy.connect(target).enforce(subjectAddress, [validEncodedNFTId], 1) ).to.be.revertedWithCustomError(policy, "PreCheckNotEnforced") }) @@ -537,10 +537,10 @@ describe("Advanced", () => { await loadFixture(deployAdvancedPolicyFixture) await policy.setTarget(await target.getAddress()) - await policy.connect(target).enforce(subjectAddress, validEncodedNFTId, 0) + await policy.connect(target).enforce(subjectAddress, [validEncodedNFTId], 0) expect( - policy.connect(target).enforce(notOwnerAddress, validEncodedNFTId, 1) + policy.connect(target).enforce(notOwnerAddress, [validEncodedNFTId], 1) ).to.be.revertedWithCustomError(policy, "UnsuccessfulCheck") }) @@ -550,9 +550,9 @@ describe("Advanced", () => { const targetAddress = await target.getAddress() await policy.setTarget(await target.getAddress()) - await policy.connect(target).enforce(subjectAddress, validEncodedNFTId, 0) + await policy.connect(target).enforce(subjectAddress, [validEncodedNFTId], 0) - const tx = await policy.connect(target).enforce(subjectAddress, validEncodedNFTId, 1) + const tx = await policy.connect(target).enforce(subjectAddress, [validEncodedNFTId], 1) const receipt = await tx.wait() const event = AdvancedERC721PolicyFactory.interface.parseLog( receipt?.logs[0] as unknown as { topics: string[]; data: string } @@ -568,7 +568,7 @@ describe("Advanced", () => { expect(receipt?.status).to.eq(1) expect(event.args.subject).to.eq(subjectAddress) expect(event.args.target).to.eq(targetAddress) - expect(event.args.evidence).to.eq(validEncodedNFTId) + expect(event.args.evidence[0]).to.eq(validEncodedNFTId) expect(event.args.checkType).to.eq(1) expect((await policy.enforced(targetAddress, subjectAddress))[1]).to.be.equal(1) }) @@ -579,10 +579,10 @@ describe("Advanced", () => { const targetAddress = await target.getAddress() await policy.setTarget(targetAddress) - await policy.connect(target).enforce(subjectAddress, validEncodedNFTId, 0) - await policy.connect(target).enforce(subjectAddress, validEncodedNFTId, 1) + await policy.connect(target).enforce(subjectAddress, [validEncodedNFTId], 0) + await policy.connect(target).enforce(subjectAddress, [validEncodedNFTId], 1) - const tx = await policy.connect(target).enforce(subjectAddress, validEncodedNFTId, 1) + const tx = await policy.connect(target).enforce(subjectAddress, [validEncodedNFTId], 1) const receipt = await tx.wait() const event = AdvancedERC721PolicyFactory.interface.parseLog( receipt?.logs[0] as unknown as { topics: string[]; data: string } @@ -598,7 +598,7 @@ describe("Advanced", () => { expect(receipt?.status).to.eq(1) expect(event.args.subject).to.eq(subjectAddress) expect(event.args.target).to.eq(targetAddress) - expect(event.args.evidence).to.eq(validEncodedNFTId) + expect(event.args.evidence[0]).to.eq(validEncodedNFTId) expect(event.args.checkType).to.eq(1) expect((await policy.enforced(targetAddress, subjectAddress))[1]).to.be.equal(2) }) @@ -608,10 +608,10 @@ describe("Advanced", () => { await loadFixture(deployAdvancedPolicyFixture) await policySkipped.setTarget(await target.getAddress()) - await policySkipped.connect(target).enforce(subjectAddress, validEncodedNFTId, 1) + await policySkipped.connect(target).enforce(subjectAddress, [validEncodedNFTId], 1) expect( - policySkipped.connect(target).enforce(notOwnerAddress, validEncodedNFTId, 1) + policySkipped.connect(target).enforce(notOwnerAddress, [validEncodedNFTId], 1) ).to.be.revertedWithCustomError(policySkipped, "MainCheckAlreadyEnforced") }) }) @@ -624,13 +624,13 @@ describe("Advanced", () => { await policy.setTarget(await target.getAddress()) expect( - policy.connect(target).enforce(subjectAddress, validEncodedNFTId, 2) + policy.connect(target).enforce(subjectAddress, [validEncodedNFTId], 2) ).to.be.revertedWithCustomError(policy, "PreCheckNotEnforced") - await policy.connect(target).enforce(subjectAddress, validEncodedNFTId, 0) + await policy.connect(target).enforce(subjectAddress, [validEncodedNFTId], 0) expect( - policy.connect(target).enforce(subjectAddress, validEncodedNFTId, 2) + policy.connect(target).enforce(subjectAddress, [validEncodedNFTId], 2) ).to.be.revertedWithCustomError(policy, "MainCheckNotEnforced") }) @@ -639,11 +639,11 @@ describe("Advanced", () => { await loadFixture(deployAdvancedPolicyFixture) await policy.setTarget(await target.getAddress()) - await policy.connect(target).enforce(subjectAddress, validEncodedNFTId, 0) - await policy.connect(target).enforce(subjectAddress, validEncodedNFTId, 1) + await policy.connect(target).enforce(subjectAddress, [validEncodedNFTId], 0) + await policy.connect(target).enforce(subjectAddress, [validEncodedNFTId], 1) await expect( - policy.connect(subject).enforce(subjectAddress, ZeroHash, 2) + policy.connect(subject).enforce(subjectAddress, [ZeroHash], 2) ).to.be.revertedWithCustomError(policy, "TargetOnly") }) @@ -652,11 +652,11 @@ describe("Advanced", () => { await loadFixture(deployAdvancedPolicyFixture) await policy.setTarget(await target.getAddress()) - await policy.connect(target).enforce(subjectAddress, validEncodedNFTId, 0) - await policy.connect(target).enforce(subjectAddress, validEncodedNFTId, 1) + await policy.connect(target).enforce(subjectAddress, [validEncodedNFTId], 0) + await policy.connect(target).enforce(subjectAddress, [validEncodedNFTId], 1) await expect( - policy.connect(target).enforce(subjectAddress, invalidEncodedNFTId, 2) + policy.connect(target).enforce(subjectAddress, [invalidEncodedNFTId], 2) ).to.be.revertedWithCustomError(iERC721Errors, "ERC721NonexistentToken") }) @@ -665,10 +665,10 @@ describe("Advanced", () => { await loadFixture(deployAdvancedPolicyFixture) await policySkipped.setTarget(await target.getAddress()) - await policySkipped.connect(target).enforce(subjectAddress, validEncodedNFTId, 1) + await policySkipped.connect(target).enforce(subjectAddress, [validEncodedNFTId], 1) await expect( - policySkipped.connect(target).enforce(subjectAddress, validEncodedNFTId, 2) + policySkipped.connect(target).enforce(subjectAddress, [validEncodedNFTId], 2) ).to.be.revertedWithCustomError(policySkipped, "CannotPostCheckWhenSkipped") }) @@ -677,11 +677,11 @@ describe("Advanced", () => { await loadFixture(deployAdvancedPolicyFixture) await policy.setTarget(await target.getAddress()) - await policy.connect(target).enforce(subjectAddress, validEncodedNFTId, 0) - await policy.connect(target).enforce(subjectAddress, validEncodedNFTId, 1) + await policy.connect(target).enforce(subjectAddress, [validEncodedNFTId], 0) + await policy.connect(target).enforce(subjectAddress, [validEncodedNFTId], 1) expect( - policy.connect(target).enforce(notOwnerAddress, validEncodedNFTId, 2) + policy.connect(target).enforce(notOwnerAddress, [validEncodedNFTId], 2) ).to.be.revertedWithCustomError(policy, "UnsuccessfulCheck") }) @@ -691,10 +691,10 @@ describe("Advanced", () => { const targetAddress = await target.getAddress() await policy.setTarget(targetAddress) - await policy.connect(target).enforce(subjectAddress, validEncodedNFTId, 0) - await policy.connect(target).enforce(subjectAddress, validEncodedNFTId, 1) + await policy.connect(target).enforce(subjectAddress, [validEncodedNFTId], 0) + await policy.connect(target).enforce(subjectAddress, [validEncodedNFTId], 1) - const tx = await policy.connect(target).enforce(subjectAddress, validEncodedNFTId, 2) + const tx = await policy.connect(target).enforce(subjectAddress, [validEncodedNFTId], 2) const receipt = await tx.wait() const event = AdvancedERC721PolicyFactory.interface.parseLog( receipt?.logs[0] as unknown as { topics: string[]; data: string } @@ -710,7 +710,7 @@ describe("Advanced", () => { expect(receipt?.status).to.eq(1) expect(event.args.subject).to.eq(subjectAddress) expect(event.args.target).to.eq(targetAddress) - expect(event.args.evidence).to.eq(validEncodedNFTId) + expect(event.args.evidence[0]).to.eq(validEncodedNFTId) expect(event.args.checkType).to.eq(2) expect((await policy.enforced(targetAddress, subjectAddress))[2]).to.be.equal(true) }) @@ -720,12 +720,12 @@ describe("Advanced", () => { await loadFixture(deployAdvancedPolicyFixture) await policy.setTarget(await target.getAddress()) - await policy.connect(target).enforce(subjectAddress, validEncodedNFTId, 0) - await policy.connect(target).enforce(subjectAddress, validEncodedNFTId, 1) - await policy.connect(target).enforce(subjectAddress, validEncodedNFTId, 2) + await policy.connect(target).enforce(subjectAddress, [validEncodedNFTId], 0) + await policy.connect(target).enforce(subjectAddress, [validEncodedNFTId], 1) + await policy.connect(target).enforce(subjectAddress, [validEncodedNFTId], 2) await expect( - policy.connect(target).enforce(subjectAddress, validEncodedNFTId, 2) + policy.connect(target).enforce(subjectAddress, [validEncodedNFTId], 2) ).to.be.revertedWithCustomError(policy, "AlreadyEnforced") }) }) @@ -740,7 +740,7 @@ describe("Advanced", () => { await policyHarness.setTarget(await target.getAddress()) await expect( - policyHarness.connect(subject).exposed__enforce(subjectAddress, ZeroHash, 0) + policyHarness.connect(subject).exposed__enforce(subjectAddress, [ZeroHash], 0) ).to.be.revertedWithCustomError(policyHarness, "TargetOnly") }) @@ -751,7 +751,7 @@ describe("Advanced", () => { await policyHarness.setTarget(await target.getAddress()) await expect( - policyHarness.connect(target).exposed__enforce(subjectAddress, invalidEncodedNFTId, 0) + policyHarness.connect(target).exposed__enforce(subjectAddress, [invalidEncodedNFTId], 0) ).to.be.revertedWithCustomError(iERC721Errors, "ERC721NonexistentToken") }) @@ -762,7 +762,7 @@ describe("Advanced", () => { await policyHarnessSkipped.setTarget(await target.getAddress()) await expect( - policyHarnessSkipped.connect(target).exposed__enforce(subjectAddress, validEncodedNFTId, 0) + policyHarnessSkipped.connect(target).exposed__enforce(subjectAddress, [validEncodedNFTId], 0) ).to.be.revertedWithCustomError(policyHarnessSkipped, "CannotPreCheckWhenSkipped") }) @@ -773,7 +773,7 @@ describe("Advanced", () => { await policyHarness.setTarget(await target.getAddress()) expect( - policyHarness.connect(target).exposed__enforce(notOwnerAddress, validEncodedNFTId, 0) + policyHarness.connect(target).exposed__enforce(notOwnerAddress, [validEncodedNFTId], 0) ).to.be.revertedWithCustomError(policyHarness, "UnsuccessfulCheck") }) @@ -786,7 +786,7 @@ describe("Advanced", () => { const tx = await policyHarness .connect(target) - .exposed__enforce(subjectAddress, validEncodedNFTId, 0) + .exposed__enforce(subjectAddress, [validEncodedNFTId], 0) const receipt = await tx.wait() const event = AdvancedERC721PolicyFactory.interface.parseLog( receipt?.logs[0] as unknown as { topics: string[]; data: string } @@ -801,7 +801,7 @@ describe("Advanced", () => { expect(receipt?.status).to.eq(1) expect(event.args.subject).to.eq(subjectAddress) expect(event.args.target).to.eq(targetAddress) - expect(event.args.evidence).to.eq(validEncodedNFTId) + expect(event.args.evidence[0]).to.eq(validEncodedNFTId) expect((await policyHarness.enforced(targetAddress, subjectAddress))[0]).to.be.equal(true) }) @@ -811,10 +811,10 @@ describe("Advanced", () => { await policyHarness.setTarget(await target.getAddress()) - await policyHarness.connect(target).exposed__enforce(subjectAddress, validEncodedNFTId, 0) + await policyHarness.connect(target).exposed__enforce(subjectAddress, [validEncodedNFTId], 0) await expect( - policyHarness.connect(target).enforce(subjectAddress, validEncodedNFTId, 0) + policyHarness.connect(target).enforce(subjectAddress, [validEncodedNFTId], 0) ).to.be.revertedWithCustomError(policyHarness, "AlreadyEnforced") }) }) @@ -827,7 +827,7 @@ describe("Advanced", () => { await policyHarness.setTarget(await target.getAddress()) expect( - policyHarness.connect(target).exposed__enforce(subjectAddress, validEncodedNFTId, 1) + policyHarness.connect(target).exposed__enforce(subjectAddress, [validEncodedNFTId], 1) ).to.be.revertedWithCustomError(policyHarness, "PreCheckNotEnforced") }) @@ -836,10 +836,10 @@ describe("Advanced", () => { await loadFixture(deployAdvancedPolicyFixture) await policyHarness.setTarget(await target.getAddress()) - await policyHarness.connect(target).exposed__enforce(subjectAddress, validEncodedNFTId, 0) + await policyHarness.connect(target).exposed__enforce(subjectAddress, [validEncodedNFTId], 0) expect( - policyHarness.connect(target).exposed__enforce(notOwnerAddress, validEncodedNFTId, 1) + policyHarness.connect(target).exposed__enforce(notOwnerAddress, [validEncodedNFTId], 1) ).to.be.revertedWithCustomError(policyHarness, "UnsuccessfulCheck") }) @@ -849,11 +849,11 @@ describe("Advanced", () => { const targetAddress = await target.getAddress() await policyHarness.setTarget(await target.getAddress()) - await policyHarness.connect(target).exposed__enforce(subjectAddress, validEncodedNFTId, 0) + await policyHarness.connect(target).exposed__enforce(subjectAddress, [validEncodedNFTId], 0) const tx = await policyHarness .connect(target) - .exposed__enforce(subjectAddress, validEncodedNFTId, 1) + .exposed__enforce(subjectAddress, [validEncodedNFTId], 1) const receipt = await tx.wait() const event = AdvancedERC721PolicyFactory.interface.parseLog( receipt?.logs[0] as unknown as { topics: string[]; data: string } @@ -868,7 +868,7 @@ describe("Advanced", () => { expect(receipt?.status).to.eq(1) expect(event.args.subject).to.eq(subjectAddress) expect(event.args.target).to.eq(targetAddress) - expect(event.args.evidence).to.eq(validEncodedNFTId) + expect(event.args.evidence[0]).to.eq(validEncodedNFTId) expect((await policyHarness.enforced(targetAddress, subjectAddress))[1]).to.be.equal(1) }) @@ -878,12 +878,12 @@ describe("Advanced", () => { const targetAddress = await target.getAddress() await policyHarness.setTarget(targetAddress) - await policyHarness.connect(target).exposed__enforce(subjectAddress, validEncodedNFTId, 0) - await policyHarness.connect(target).exposed__enforce(subjectAddress, validEncodedNFTId, 1) + await policyHarness.connect(target).exposed__enforce(subjectAddress, [validEncodedNFTId], 0) + await policyHarness.connect(target).exposed__enforce(subjectAddress, [validEncodedNFTId], 1) const tx = await policyHarness .connect(target) - .exposed__enforce(subjectAddress, validEncodedNFTId, 1) + .exposed__enforce(subjectAddress, [validEncodedNFTId], 1) const receipt = await tx.wait() const event = AdvancedERC721PolicyFactory.interface.parseLog( receipt?.logs[0] as unknown as { topics: string[]; data: string } @@ -898,7 +898,7 @@ describe("Advanced", () => { expect(receipt?.status).to.eq(1) expect(event.args.subject).to.eq(subjectAddress) expect(event.args.target).to.eq(targetAddress) - expect(event.args.evidence).to.eq(validEncodedNFTId) + expect(event.args.evidence[0]).to.eq(validEncodedNFTId) expect((await policyHarness.enforced(targetAddress, subjectAddress))[1]).to.be.equal(2) }) @@ -907,13 +907,13 @@ describe("Advanced", () => { await loadFixture(deployAdvancedPolicyFixture) await policyHarnessSkipped.setTarget(await target.getAddress()) - await policyHarnessSkipped.connect(target).exposed__enforce(subjectAddress, validEncodedNFTId, 1) + await policyHarnessSkipped.connect(target).exposed__enforce(subjectAddress, [validEncodedNFTId], 1) expect( - policyHarnessSkipped.connect(target).exposed__enforce(notOwnerAddress, validEncodedNFTId, 1) + policyHarnessSkipped.connect(target).exposed__enforce(notOwnerAddress, [validEncodedNFTId], 1) ).to.be.revertedWithCustomError(policyHarnessSkipped, "MainCheckAlreadyEnforced") expect( - policyHarnessSkipped.connect(target).exposed__enforce(subjectAddress, validEncodedNFTId, 1) + policyHarnessSkipped.connect(target).exposed__enforce(subjectAddress, [validEncodedNFTId], 1) ).to.be.revertedWithCustomError(policyHarnessSkipped, "MainCheckAlreadyEnforced") }) }) @@ -926,13 +926,13 @@ describe("Advanced", () => { await policyHarness.setTarget(await target.getAddress()) expect( - policyHarness.connect(target).exposed__enforce(subjectAddress, validEncodedNFTId, 2) + policyHarness.connect(target).exposed__enforce(subjectAddress, [validEncodedNFTId], 2) ).to.be.revertedWithCustomError(policyHarness, "PreCheckNotEnforced") - await policyHarness.connect(target).exposed__enforce(subjectAddress, validEncodedNFTId, 0) + await policyHarness.connect(target).exposed__enforce(subjectAddress, [validEncodedNFTId], 0) expect( - policyHarness.connect(target).exposed__enforce(subjectAddress, validEncodedNFTId, 2) + policyHarness.connect(target).exposed__enforce(subjectAddress, [validEncodedNFTId], 2) ).to.be.revertedWithCustomError(policyHarness, "MainCheckNotEnforced") }) @@ -941,11 +941,11 @@ describe("Advanced", () => { await loadFixture(deployAdvancedPolicyFixture) await policyHarness.setTarget(await target.getAddress()) - await policyHarness.connect(target).exposed__enforce(subjectAddress, validEncodedNFTId, 0) - await policyHarness.connect(target).exposed__enforce(subjectAddress, validEncodedNFTId, 1) + await policyHarness.connect(target).exposed__enforce(subjectAddress, [validEncodedNFTId], 0) + await policyHarness.connect(target).exposed__enforce(subjectAddress, [validEncodedNFTId], 1) await expect( - policyHarness.connect(subject).exposed__enforce(subjectAddress, ZeroHash, 2) + policyHarness.connect(subject).exposed__enforce(subjectAddress, [ZeroHash], 2) ).to.be.revertedWithCustomError(policyHarness, "TargetOnly") }) @@ -960,11 +960,11 @@ describe("Advanced", () => { } = await loadFixture(deployAdvancedPolicyFixture) await policyHarness.setTarget(await target.getAddress()) - await policyHarness.connect(target).exposed__enforce(subjectAddress, validEncodedNFTId, 0) - await policyHarness.connect(target).exposed__enforce(subjectAddress, validEncodedNFTId, 1) + await policyHarness.connect(target).exposed__enforce(subjectAddress, [validEncodedNFTId], 0) + await policyHarness.connect(target).exposed__enforce(subjectAddress, [validEncodedNFTId], 1) await expect( - policyHarness.connect(target).exposed__enforce(subjectAddress, invalidEncodedNFTId, 2) + policyHarness.connect(target).exposed__enforce(subjectAddress, [invalidEncodedNFTId], 2) ).to.be.revertedWithCustomError(iERC721Errors, "ERC721NonexistentToken") }) @@ -973,10 +973,10 @@ describe("Advanced", () => { await loadFixture(deployAdvancedPolicyFixture) await policyHarnessSkipped.setTarget(await target.getAddress()) - await policyHarnessSkipped.connect(target).exposed__enforce(subjectAddress, validEncodedNFTId, 1) + await policyHarnessSkipped.connect(target).exposed__enforce(subjectAddress, [validEncodedNFTId], 1) await expect( - policyHarnessSkipped.connect(target).exposed__enforce(subjectAddress, validEncodedNFTId, 2) + policyHarnessSkipped.connect(target).exposed__enforce(subjectAddress, [validEncodedNFTId], 2) ).to.be.revertedWithCustomError(policyHarnessSkipped, "CannotPostCheckWhenSkipped") }) @@ -985,11 +985,11 @@ describe("Advanced", () => { await loadFixture(deployAdvancedPolicyFixture) await policyHarness.setTarget(await target.getAddress()) - await policyHarness.connect(target).exposed__enforce(subjectAddress, validEncodedNFTId, 0) - await policyHarness.connect(target).exposed__enforce(subjectAddress, validEncodedNFTId, 1) + await policyHarness.connect(target).exposed__enforce(subjectAddress, [validEncodedNFTId], 0) + await policyHarness.connect(target).exposed__enforce(subjectAddress, [validEncodedNFTId], 1) expect( - policyHarness.connect(target).exposed__enforce(notOwnerAddress, validEncodedNFTId, 2) + policyHarness.connect(target).exposed__enforce(notOwnerAddress, [validEncodedNFTId], 2) ).to.be.revertedWithCustomError(policyHarness, "UnsuccessfulCheck") }) @@ -999,12 +999,12 @@ describe("Advanced", () => { const targetAddress = await target.getAddress() await policyHarness.setTarget(targetAddress) - await policyHarness.connect(target).exposed__enforce(subjectAddress, validEncodedNFTId, 0) - await policyHarness.connect(target).exposed__enforce(subjectAddress, validEncodedNFTId, 1) + await policyHarness.connect(target).exposed__enforce(subjectAddress, [validEncodedNFTId], 0) + await policyHarness.connect(target).exposed__enforce(subjectAddress, [validEncodedNFTId], 1) const tx = await policyHarness .connect(target) - .exposed__enforce(subjectAddress, validEncodedNFTId, 2) + .exposed__enforce(subjectAddress, [validEncodedNFTId], 2) const receipt = await tx.wait() const event = AdvancedERC721PolicyFactory.interface.parseLog( receipt?.logs[0] as unknown as { topics: string[]; data: string } @@ -1019,7 +1019,7 @@ describe("Advanced", () => { expect(receipt?.status).to.eq(1) expect(event.args.subject).to.eq(subjectAddress) expect(event.args.target).to.eq(targetAddress) - expect(event.args.evidence).to.eq(validEncodedNFTId) + expect(event.args.evidence[0]).to.eq(validEncodedNFTId) expect((await policyHarness.enforced(targetAddress, subjectAddress))[2]).to.be.equal(true) }) @@ -1028,12 +1028,12 @@ describe("Advanced", () => { await loadFixture(deployAdvancedPolicyFixture) await policyHarness.setTarget(await target.getAddress()) - await policyHarness.connect(target).exposed__enforce(subjectAddress, validEncodedNFTId, 0) - await policyHarness.connect(target).exposed__enforce(subjectAddress, validEncodedNFTId, 1) - await policyHarness.connect(target).exposed__enforce(subjectAddress, validEncodedNFTId, 2) + await policyHarness.connect(target).exposed__enforce(subjectAddress, [validEncodedNFTId], 0) + await policyHarness.connect(target).exposed__enforce(subjectAddress, [validEncodedNFTId], 1) + await policyHarness.connect(target).exposed__enforce(subjectAddress, [validEncodedNFTId], 2) await expect( - policyHarness.connect(target).exposed__enforce(subjectAddress, validEncodedNFTId, 2) + policyHarness.connect(target).exposed__enforce(subjectAddress, [validEncodedNFTId], 2) ).to.be.revertedWithCustomError(policyHarness, "AlreadyEnforced") }) }) @@ -1057,7 +1057,7 @@ describe("Advanced", () => { const iERC721Errors: IERC721Errors = await ethers.getContractAt("IERC721Errors", await nft.getAddress()) const checker: AdvancedERC721Checker = await AdvancedERC721CheckerFactory.connect(deployer).deploy( - await nft.getAddress(), + [await nft.getAddress()], 1, 0, 10 @@ -1384,7 +1384,7 @@ describe("Advanced", () => { const nft: NFT = await NFTFactory.deploy() const checker: AdvancedERC721Checker = await AdvancedERC721CheckerFactory.connect(deployer).deploy( - await nft.getAddress(), + [await nft.getAddress()], 1, 0, 20 diff --git a/packages/contracts/test/Base.test.ts b/packages/contracts/test/Base.test.ts index bcf7cb3..53143e7 100644 --- a/packages/contracts/test/Base.test.ts +++ b/packages/contracts/test/Base.test.ts @@ -32,12 +32,12 @@ describe("Base", () => { await ethers.getContractFactory("BaseERC721CheckerHarness") const nft: NFT = await NFTFactory.deploy() - const checker: BaseERC721Checker = await BaseERC721CheckerFactory.connect(deployer).deploy( + const checker: BaseERC721Checker = await BaseERC721CheckerFactory.connect(deployer).deploy([ await nft.getAddress() - ) + ]) const checkerHarness: BaseERC721CheckerHarness = await BaseERC721CheckerHarnessFactory.connect( deployer - ).deploy(await nft.getAddress()) + ).deploy([await nft.getAddress()]) // mint 0 for subject. await nft.connect(deployer).mint(subjectAddress) @@ -71,22 +71,21 @@ describe("Base", () => { const { nft, checker, target, subjectAddress, invalidNFTId } = await loadFixture(deployBaseCheckerFixture) - await expect(checker.connect(target).check(subjectAddress, invalidNFTId)).to.be.revertedWithCustomError( - nft, - "ERC721NonexistentToken" - ) + await expect( + checker.connect(target).check(subjectAddress, [invalidNFTId]) + ).to.be.revertedWithCustomError(nft, "ERC721NonexistentToken") }) it("returns false when subject not owner", async () => { const { checker, target, notOwnerAddress, validNFTId } = await loadFixture(deployBaseCheckerFixture) - expect(await checker.connect(target).check(notOwnerAddress, validNFTId)).to.be.equal(false) + expect(await checker.connect(target).check(notOwnerAddress, [validNFTId])).to.be.equal(false) }) it("succeeds when valid", async () => { const { checker, target, subjectAddress, validNFTId } = await loadFixture(deployBaseCheckerFixture) - expect(await checker.connect(target).check(subjectAddress, validNFTId)).to.be.equal(true) + expect(await checker.connect(target).check(subjectAddress, [validNFTId])).to.be.equal(true) }) }) @@ -96,7 +95,7 @@ describe("Base", () => { await loadFixture(deployBaseCheckerFixture) await expect( - checkerHarness.connect(target).exposed__check(subjectAddress, invalidNFTId) + checkerHarness.connect(target).exposed__check(subjectAddress, [invalidNFTId]) ).to.be.revertedWithCustomError(nft, "ERC721NonexistentToken") }) @@ -104,7 +103,7 @@ describe("Base", () => { const { checkerHarness, target, notOwnerAddress, validNFTId } = await loadFixture(deployBaseCheckerFixture) - expect(await checkerHarness.connect(target).exposed__check(notOwnerAddress, validNFTId)).to.be.equal( + expect(await checkerHarness.connect(target).exposed__check(notOwnerAddress, [validNFTId])).to.be.equal( false ) }) @@ -113,7 +112,7 @@ describe("Base", () => { const { checkerHarness, target, subjectAddress, validNFTId } = await loadFixture(deployBaseCheckerFixture) - expect(await checkerHarness.connect(target).exposed__check(subjectAddress, validNFTId)).to.be.equal( + expect(await checkerHarness.connect(target).exposed__check(subjectAddress, [validNFTId])).to.be.equal( true ) }) @@ -137,9 +136,9 @@ describe("Base", () => { const nft: NFT = await NFTFactory.deploy() const iERC721Errors: IERC721Errors = await ethers.getContractAt("IERC721Errors", await nft.getAddress()) - const checker: BaseERC721Checker = await BaseERC721CheckerFactory.connect(deployer).deploy( + const checker: BaseERC721Checker = await BaseERC721CheckerFactory.connect(deployer).deploy([ await nft.getAddress() - ) + ]) const policy: BaseERC721Policy = await BaseERC721PolicyFactory.connect(deployer).deploy( await checker.getAddress() ) @@ -240,7 +239,7 @@ describe("Base", () => { await policy.setTarget(await target.getAddress()) - await expect(policy.connect(subject).enforce(subjectAddress, ZeroHash)).to.be.revertedWithCustomError( + await expect(policy.connect(subject).enforce(subjectAddress, [ZeroHash])).to.be.revertedWithCustomError( policy, "TargetOnly" ) @@ -253,7 +252,7 @@ describe("Base", () => { await policy.setTarget(await target.getAddress()) await expect( - policy.connect(target).enforce(subjectAddress, invalidEncodedNFTId) + policy.connect(target).enforce(subjectAddress, [invalidEncodedNFTId]) ).to.be.revertedWithCustomError(iERC721Errors, "ERC721NonexistentToken") }) @@ -264,7 +263,7 @@ describe("Base", () => { await policy.setTarget(await target.getAddress()) expect( - policy.connect(target).enforce(notOwnerAddress, validEncodedNFTId) + policy.connect(target).enforce(notOwnerAddress, [validEncodedNFTId]) ).to.be.revertedWithCustomError(policy, "UnsuccessfulCheck") }) @@ -275,7 +274,7 @@ describe("Base", () => { await policy.setTarget(await target.getAddress()) - const tx = await policy.connect(target).enforce(subjectAddress, validEncodedNFTId) + const tx = await policy.connect(target).enforce(subjectAddress, [validEncodedNFTId]) const receipt = await tx.wait() const event = BaseERC721PolicyFactory.interface.parseLog( receipt?.logs[0] as unknown as { topics: string[]; data: string } @@ -290,7 +289,7 @@ describe("Base", () => { expect(receipt?.status).to.eq(1) expect(event.args.subject).to.eq(subjectAddress) expect(event.args.target).to.eq(targetAddress) - expect(event.args.evidence).to.eq(validEncodedNFTId) + expect(event.args.evidence[0]).to.eq(validEncodedNFTId) expect(await policy.enforced(targetAddress, subjectAddress)).to.be.equal(true) }) @@ -299,10 +298,10 @@ describe("Base", () => { await policy.setTarget(await target.getAddress()) - await policy.connect(target).enforce(subjectAddress, validEncodedNFTId) + await policy.connect(target).enforce(subjectAddress, [validEncodedNFTId]) await expect( - policy.connect(target).enforce(subjectAddress, validEncodedNFTId) + policy.connect(target).enforce(subjectAddress, [validEncodedNFTId]) ).to.be.revertedWithCustomError(policy, "AlreadyEnforced") }) }) @@ -314,7 +313,7 @@ describe("Base", () => { await policyHarness.setTarget(await target.getAddress()) await expect( - policyHarness.connect(subject).exposed__enforce(subjectAddress, ZeroHash) + policyHarness.connect(subject).exposed__enforce(subjectAddress, [ZeroHash]) ).to.be.revertedWithCustomError(policyHarness, "TargetOnly") }) @@ -325,7 +324,7 @@ describe("Base", () => { await policyHarness.setTarget(await target.getAddress()) await expect( - policyHarness.connect(target).exposed__enforce(subjectAddress, invalidEncodedNFTId) + policyHarness.connect(target).exposed__enforce(subjectAddress, [invalidEncodedNFTId]) ).to.be.revertedWithCustomError(iERC721Errors, "ERC721NonexistentToken") }) @@ -336,7 +335,7 @@ describe("Base", () => { await policyHarness.setTarget(await target.getAddress()) expect( - policyHarness.connect(target).exposed__enforce(notOwnerAddress, validEncodedNFTId) + policyHarness.connect(target).exposed__enforce(notOwnerAddress, [validEncodedNFTId]) ).to.be.revertedWithCustomError(policyHarness, "UnsuccessfulCheck") }) @@ -347,7 +346,7 @@ describe("Base", () => { await policyHarness.setTarget(await target.getAddress()) - const tx = await policyHarness.connect(target).exposed__enforce(subjectAddress, validEncodedNFTId) + const tx = await policyHarness.connect(target).exposed__enforce(subjectAddress, [validEncodedNFTId]) const receipt = await tx.wait() const event = BaseERC721PolicyFactory.interface.parseLog( receipt?.logs[0] as unknown as { topics: string[]; data: string } @@ -362,7 +361,7 @@ describe("Base", () => { expect(receipt?.status).to.eq(1) expect(event.args.subject).to.eq(subjectAddress) expect(event.args.target).to.eq(targetAddress) - expect(event.args.evidence).to.eq(validEncodedNFTId) + expect(event.args.evidence[0]).to.eq(validEncodedNFTId) expect(await policyHarness.enforced(targetAddress, subjectAddress)).to.be.equal(true) }) @@ -372,10 +371,10 @@ describe("Base", () => { await policyHarness.setTarget(await target.getAddress()) - await policyHarness.connect(target).exposed__enforce(subjectAddress, validEncodedNFTId) + await policyHarness.connect(target).exposed__enforce(subjectAddress, [validEncodedNFTId]) await expect( - policyHarness.connect(target).enforce(subjectAddress, validEncodedNFTId) + policyHarness.connect(target).enforce(subjectAddress, [validEncodedNFTId]) ).to.be.revertedWithCustomError(policyHarness, "AlreadyEnforced") }) }) @@ -397,9 +396,9 @@ describe("Base", () => { const nft: NFT = await NFTFactory.deploy() const iERC721Errors: IERC721Errors = await ethers.getContractAt("IERC721Errors", await nft.getAddress()) - const checker: BaseERC721Checker = await BaseERC721CheckerFactory.connect(deployer).deploy( + const checker: BaseERC721Checker = await BaseERC721CheckerFactory.connect(deployer).deploy([ await nft.getAddress() - ) + ]) const policy: BaseERC721Policy = await BaseERC721PolicyFactory.connect(deployer).deploy( await checker.getAddress() ) @@ -586,9 +585,9 @@ describe("Base", () => { const nft: NFT = await NFTFactory.deploy() - const checker: BaseERC721Checker = await BaseERC721CheckerFactory.connect(deployer).deploy( + const checker: BaseERC721Checker = await BaseERC721CheckerFactory.connect(deployer).deploy([ await nft.getAddress() - ) + ]) const policy: BaseERC721Policy = await BaseERC721PolicyFactory.connect(deployer).deploy( await checker.getAddress() )