From fd29aedd6109b9ac5af39930e09e38a49a6d0b25 Mon Sep 17 00:00:00 2001 From: Seth Date: Wed, 7 Feb 2024 23:05:54 +0800 Subject: [PATCH 1/3] refactor: internal mappings (cherry picked from commit 5450b980a52394b5f8e88beb88e13cc785ed8167) --- src/BaseDocumentStore.sol | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/BaseDocumentStore.sol b/src/BaseDocumentStore.sol index 8541e42..5bf1e3a 100644 --- a/src/BaseDocumentStore.sol +++ b/src/BaseDocumentStore.sol @@ -19,12 +19,12 @@ abstract contract BaseDocumentStore is Initializable, IDocumentStore { /** * @notice A mapping of the document hash to the block number that was issued */ - mapping(bytes32 => uint256) public documentIssued; + mapping(bytes32 => uint256) internal documentIssued; /** * @notice A mapping of the hash of the claim being revoked to the revocation block number */ - mapping(bytes32 => uint256) public documentRevoked; + mapping(bytes32 => uint256) internal documentRevoked; /** * @notice Initialises the contract with a name From c11092bca610e7b1c2eed60c555e9d0c27e288ee Mon Sep 17 00:00:00 2001 From: Seth Date: Thu, 8 Feb 2024 13:18:00 +0800 Subject: [PATCH 2/3] refactor: streamline interface (cherry picked from commit 58ed6c25d65c407da82a9c79f29db69946c59aa0) --- src/BaseDocumentStore.sol | 8 ++-- src/DocumentStore.sol | 80 +++++++++++++++++-------------- src/interfaces/IDocumentStore.sol | 21 ++++++++ 3 files changed, 69 insertions(+), 40 deletions(-) diff --git a/src/BaseDocumentStore.sol b/src/BaseDocumentStore.sol index 5bf1e3a..302b50d 100644 --- a/src/BaseDocumentStore.sol +++ b/src/BaseDocumentStore.sol @@ -38,7 +38,7 @@ abstract contract BaseDocumentStore is Initializable, IDocumentStore { * @notice Issues a document * @param document The hash of the document to issue */ - function _issue(bytes32 document) internal { + function _issue(bytes32 document) internal virtual { documentIssued[document] = block.number; } @@ -47,7 +47,7 @@ abstract contract BaseDocumentStore is Initializable, IDocumentStore { * @param document The hash of the document to check * @return A boolean indicating whether the document has been issued */ - function _isIssued(bytes32 document) internal view returns (bool) { + function _isIssued(bytes32 document) internal view virtual returns (bool) { return (documentIssued[document] != 0); } @@ -55,7 +55,7 @@ abstract contract BaseDocumentStore is Initializable, IDocumentStore { * @notice Revokes a document * @param document The hash of the document to revoke */ - function _revoke(bytes32 document) internal { + function _revoke(bytes32 document) internal virtual { documentRevoked[document] = block.number; } @@ -64,7 +64,7 @@ abstract contract BaseDocumentStore is Initializable, IDocumentStore { * @param document The hash of the document to check * @return A boolean indicating whether the document has been revoked */ - function _isRevoked(bytes32 document) internal view returns (bool) { + function _isRevoked(bytes32 document) internal view virtual returns (bool) { return documentRevoked[document] != 0; } } diff --git a/src/DocumentStore.sol b/src/DocumentStore.sol index 7f3fb75..ae6fb6d 100644 --- a/src/DocumentStore.sol +++ b/src/DocumentStore.sol @@ -15,21 +15,21 @@ contract DocumentStore is DocumentStoreAccessControl, BaseDocumentStore { using MerkleProof for bytes32[]; /** - * @notice Initialises the contract with a name and owner + * @notice Initialises the contract with a name and initial admin * @param _name The name of the contract - * @param owner The owner of the contract + * @param initAdmin The initial admin of the contract */ - constructor(string memory _name, address owner) { - initialize(_name, owner); + constructor(string memory _name, address initAdmin) { + initialize(_name, initAdmin); } /** * @notice Internally initialises the contract with a name and owner * @param _name The name of the contract - * @param owner The owner of the contract + * @param initAdmin The owner of the contract */ - function initialize(string memory _name, address owner) internal initializer { - __DocumentStoreAccessControl_init(owner); + function initialize(string memory _name, address initAdmin) internal initializer { + __DocumentStoreAccessControl_init(initAdmin); __BaseDocumentStore_init(_name); } @@ -37,41 +37,30 @@ contract DocumentStore is DocumentStoreAccessControl, BaseDocumentStore { * @notice Issues a document * @param documentRoot The hash of the document to issue */ - function issue(bytes32 documentRoot) public onlyRole(ISSUER_ROLE) { - if (isIssued(documentRoot)) { - revert DocumentExists(documentRoot); - } - + function issue(bytes32 documentRoot) external onlyRole(ISSUER_ROLE) { _issue(documentRoot); - - emit DocumentIssued(documentRoot); } /** * @notice Issues multiple documents * @param documentRoots The hashes of the documents to issue */ - function bulkIssue(bytes32[] memory documentRoots) public { + function bulkIssue(bytes32[] memory documentRoots) external onlyRole(ISSUER_ROLE) { for (uint256 i = 0; i < documentRoots.length; i++) { - issue(documentRoots[i]); + _issue(documentRoots[i]); } } + function revoke(bytes32 documentRoot, bytes32 document, bytes32[] memory proof) external onlyRole(REVOKER_ROLE) { + _revoke(documentRoot, document, proof); + } + /** * @notice Revokes a document * @param documentRoot The hash of the document to revoke */ - function revoke(bytes32 documentRoot) public onlyRole(REVOKER_ROLE) { - revoke(documentRoot, documentRoot, new bytes32[](0)); - } - - function revoke(bytes32 documentRoot, bytes32 document, bytes32[] memory proof) public onlyRole(REVOKER_ROLE) { - bool active = isActive(documentRoot, document, proof); - if (!active) { - revert InactiveDocument(documentRoot, document); - } - _revoke(document); - emit DocumentRevoked(documentRoot, document); + function revoke(bytes32 documentRoot) external onlyRole(REVOKER_ROLE) { + _revoke(documentRoot, documentRoot, new bytes32[](0)); } /** @@ -82,9 +71,9 @@ contract DocumentStore is DocumentStoreAccessControl, BaseDocumentStore { bytes32[] memory documentRoots, bytes32[] memory documents, bytes32[][] memory proofs - ) public onlyRole(REVOKER_ROLE) { + ) external onlyRole(REVOKER_ROLE) { for (uint256 i = 0; i < documentRoots.length; i++) { - revoke(documentRoots[i], documents[i], proofs[i]); + _revoke(documentRoots[i], documents[i], proofs[i]); } } @@ -114,13 +103,6 @@ contract DocumentStore is DocumentStoreAccessControl, BaseDocumentStore { return _isRevoked(documentRoot, document, proof); } - function _isRevoked(bytes32 documentRoot, bytes32 document, bytes32[] memory proof) internal view returns (bool) { - if (documentRoot == document && proof.length == 0) { - return _isRevoked(document); - } - return (_isRevoked(documentRoot) || _isRevoked(document)); - } - /** * @notice Checks if a document has been revoked * @param documentRoot The hash of the document to check @@ -137,6 +119,32 @@ contract DocumentStore is DocumentStoreAccessControl, BaseDocumentStore { return !_isRevoked(documentRoot, document, proof); } + function _issue(bytes32 documentRoot) internal override { + if (isIssued(documentRoot)) { + revert DocumentExists(documentRoot); + } + + BaseDocumentStore._issue(documentRoot); + + emit DocumentIssued(documentRoot); + } + + function _revoke(bytes32 documentRoot, bytes32 document, bytes32[] memory proof) internal { + bool active = isActive(documentRoot, document, proof); + if (!active) { + revert InactiveDocument(documentRoot, document); + } + _revoke(document); + emit DocumentRevoked(documentRoot, document); + } + + function _isRevoked(bytes32 documentRoot, bytes32 document, bytes32[] memory proof) internal view returns (bool) { + if (documentRoot == document && proof.length == 0) { + return _isRevoked(document); + } + return (_isRevoked(documentRoot) || _isRevoked(document)); + } + modifier onlyValidDocument( bytes32 documentRoot, bytes32 document, diff --git a/src/interfaces/IDocumentStore.sol b/src/interfaces/IDocumentStore.sol index 421bc40..2b8e9d4 100644 --- a/src/interfaces/IDocumentStore.sol +++ b/src/interfaces/IDocumentStore.sol @@ -3,8 +3,11 @@ pragma solidity >=0.8.23 <0.9.0; interface IDocumentStore { error InactiveDocument(bytes32 documentRoot, bytes32 document); + error DocumentExists(bytes32 document); + error ZeroDocument(); + error InvalidDocument(bytes32 documentRoot, bytes32 document); /** @@ -18,4 +21,22 @@ interface IDocumentStore { * @param document The hash of the revoked document */ event DocumentRevoked(bytes32 indexed documentRoot, bytes32 indexed document); + + function name() external view returns (string memory); + + function issue(bytes32 documentRoot) external; + + function revoke(bytes32 documentRoot) external; + + function revoke(bytes32 documentRoot, bytes32 document, bytes32[] memory proof) external; + + function isIssued(bytes32 documentRoot) external view returns (bool); + + function isIssued(bytes32 documentRoot, bytes32 document, bytes32[] memory proof) external view returns (bool); + + function isRevoked(bytes32 documentRoot) external view returns (bool); + + function isRevoked(bytes32 documentRoot, bytes32 document, bytes32[] memory proof) external view returns (bool); + + function isActive(bytes32 documentRoot, bytes32 document, bytes32[] memory proof) external view returns (bool); } From 8207855cc13df9a1e83685543734867e61451ee2 Mon Sep 17 00:00:00 2001 From: Seth Date: Sat, 10 Feb 2024 02:10:14 +0800 Subject: [PATCH 3/3] refactor: reorganise interfaces (cherry picked from commit f09639a32c15eed9d3ec4fa68497c54fd62aa5a0) --- src/BaseDocumentStore.sol | 152 ++++++++++++++++++--- src/DocumentStore.sol | 134 +----------------- src/interfaces/IDocumentStore.sol | 10 +- src/interfaces/IDocumentStoreBatchable.sol | 12 ++ test/DocumentStore.t.sol | 22 ++- 5 files changed, 170 insertions(+), 160 deletions(-) create mode 100644 src/interfaces/IDocumentStoreBatchable.sol diff --git a/src/BaseDocumentStore.sol b/src/BaseDocumentStore.sol index 302b50d..aaa644d 100644 --- a/src/BaseDocumentStore.sol +++ b/src/BaseDocumentStore.sol @@ -3,14 +3,24 @@ pragma solidity >=0.8.23 <0.9.0; import "@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol"; +import "@openzeppelin/contracts/utils/cryptography/MerkleProof.sol"; -import {IDocumentStore} from "./interfaces/IDocumentStore.sol"; +import "./interfaces/IDocumentStore.sol"; +import "./interfaces/IDocumentStoreBatchable.sol"; +import "./base/DocumentStoreAccessControl.sol"; /** * @title BaseDocumentStore * @notice A base contract for storing and revoking documents */ -abstract contract BaseDocumentStore is Initializable, IDocumentStore { +abstract contract BaseDocumentStore is + Initializable, + IDocumentStoreBatchable, + IDocumentStore, + DocumentStoreAccessControl +{ + using MerkleProof for bytes32[]; + /** * @notice The name of the contract */ @@ -30,41 +40,149 @@ abstract contract BaseDocumentStore is Initializable, IDocumentStore { * @notice Initialises the contract with a name * @param _name The name of the contract */ - function __BaseDocumentStore_init(string memory _name) internal onlyInitializing { + function __BaseDocumentStore_init(string memory _name, address initAdmin) internal onlyInitializing { + __DocumentStoreAccessControl_init(initAdmin); name = _name; } /** * @notice Issues a document - * @param document The hash of the document to issue + * @param documentRoot The hash of the document to issue */ - function _issue(bytes32 document) internal virtual { - documentIssued[document] = block.number; + function issue(bytes32 documentRoot) external onlyRole(ISSUER_ROLE) { + _issue(documentRoot); } /** - * @notice Checks if a document has been issued - * @param document The hash of the document to check - * @return A boolean indicating whether the document has been issued + * @notice Issues multiple documents + * @param documentRoots The hashes of the documents to issue */ - function _isIssued(bytes32 document) internal view virtual returns (bool) { - return (documentIssued[document] != 0); + function bulkIssue(bytes32[] memory documentRoots) external onlyRole(ISSUER_ROLE) { + for (uint256 i = 0; i < documentRoots.length; i++) { + _issue(documentRoots[i]); + } + } + + function revoke(bytes32 documentRoot, bytes32 document, bytes32[] memory proof) external onlyRole(REVOKER_ROLE) { + _revoke(documentRoot, document, proof); } /** * @notice Revokes a document - * @param document The hash of the document to revoke + * @param documentRoot The hash of the document to revoke */ - function _revoke(bytes32 document) internal virtual { - documentRevoked[document] = block.number; + function revoke(bytes32 documentRoot) external onlyRole(REVOKER_ROLE) { + _revoke(documentRoot, documentRoot, new bytes32[](0)); + } + + /** + * @notice Revokes documents in bulk + * @param documentRoots The hashes of the documents to revoke + */ + function bulkRevoke( + bytes32[] memory documentRoots, + bytes32[] memory documents, + bytes32[][] memory proofs + ) external onlyRole(REVOKER_ROLE) { + for (uint256 i = 0; i < documentRoots.length; i++) { + _revoke(documentRoots[i], documents[i], proofs[i]); + } + } + + function isIssued( + bytes32 documentRoot, + bytes32 document, + bytes32[] memory proof + ) public view onlyValidDocument(documentRoot, document, proof) returns (bool) { + if (documentRoot == document && proof.length == 0) { + return documentIssued[document] != 0; + } + return documentIssued[documentRoot] != 0; + } + + function isIssued(bytes32 documentRoot) public view returns (bool) { + return isIssued(documentRoot, documentRoot, new bytes32[](0)); + } + + function isRevoked( + bytes32 documentRoot, + bytes32 document, + bytes32[] memory proof + ) public view onlyValidDocument(documentRoot, document, proof) returns (bool) { + if (!isIssued(documentRoot, document, proof)) { + revert DocumentNotIssued(documentRoot, document); + } + return _isRevoked(documentRoot, document, proof); } /** * @notice Checks if a document has been revoked - * @param document The hash of the document to check + * @param documentRoot The hash of the document to check * @return A boolean indicating whether the document has been revoked */ - function _isRevoked(bytes32 document) internal view virtual returns (bool) { - return documentRevoked[document] != 0; + function isRevoked(bytes32 documentRoot) public view returns (bool) { + return isRevoked(documentRoot, documentRoot, new bytes32[](0)); + } + + function isActive(bytes32 documentRoot, bytes32 document, bytes32[] memory proof) public view returns (bool) { + if (!isIssued(documentRoot, document, proof)) { + revert DocumentNotIssued(documentRoot, document); + } + return !_isRevoked(documentRoot, document, proof); + } + + function isActive(bytes32 documentRoot) public view returns (bool) { + return isActive(documentRoot, documentRoot, new bytes32[](0)); + } + + function supportsInterface(bytes4 interfaceId) public view virtual override returns (bool) { + return + interfaceId == type(IDocumentStore).interfaceId || + interfaceId == type(IDocumentStoreBatchable).interfaceId || + super.supportsInterface(interfaceId); + } + + /** + * @notice Issues a document + * @param documentRoot The hash of the document to issue + */ + function _issue(bytes32 documentRoot) internal { + if (isIssued(documentRoot)) { + revert DocumentExists(documentRoot); + } + + documentIssued[documentRoot] = block.number; + + emit DocumentIssued(documentRoot); + } + + function _revoke(bytes32 documentRoot, bytes32 document, bytes32[] memory proof) internal { + bool active = isActive(documentRoot, document, proof); + if (!active) { + revert InactiveDocument(documentRoot, document); + } + documentRevoked[document] = block.number; + emit DocumentRevoked(documentRoot, document); + } + + function _isRevoked(bytes32 documentRoot, bytes32 document, bytes32[] memory proof) internal view returns (bool) { + if (documentRoot == document && proof.length == 0) { + return documentRevoked[document] != 0; + } + return documentRevoked[documentRoot] != 0 || documentRevoked[document] != 0; + } + + modifier onlyValidDocument( + bytes32 documentRoot, + bytes32 document, + bytes32[] memory proof + ) { + if (document == 0x0 || documentRoot == 0x0) { + revert ZeroDocument(); + } + if (!proof.verify(documentRoot, document)) { + revert InvalidDocument(documentRoot, document); + } + _; } } diff --git a/src/DocumentStore.sol b/src/DocumentStore.sol index ae6fb6d..449ba41 100644 --- a/src/DocumentStore.sol +++ b/src/DocumentStore.sol @@ -6,14 +6,13 @@ import "@openzeppelin/contracts/utils/cryptography/MerkleProof.sol"; import "./BaseDocumentStore.sol"; import "./base/DocumentStoreAccessControl.sol"; +import "./interfaces/IDocumentStoreBatchable.sol"; /** * @title DocumentStore * @notice A contract for storing and revoking documents with access control */ -contract DocumentStore is DocumentStoreAccessControl, BaseDocumentStore { - using MerkleProof for bytes32[]; - +contract DocumentStore is BaseDocumentStore { /** * @notice Initialises the contract with a name and initial admin * @param _name The name of the contract @@ -29,133 +28,6 @@ contract DocumentStore is DocumentStoreAccessControl, BaseDocumentStore { * @param initAdmin The owner of the contract */ function initialize(string memory _name, address initAdmin) internal initializer { - __DocumentStoreAccessControl_init(initAdmin); - __BaseDocumentStore_init(_name); - } - - /** - * @notice Issues a document - * @param documentRoot The hash of the document to issue - */ - function issue(bytes32 documentRoot) external onlyRole(ISSUER_ROLE) { - _issue(documentRoot); - } - - /** - * @notice Issues multiple documents - * @param documentRoots The hashes of the documents to issue - */ - function bulkIssue(bytes32[] memory documentRoots) external onlyRole(ISSUER_ROLE) { - for (uint256 i = 0; i < documentRoots.length; i++) { - _issue(documentRoots[i]); - } - } - - function revoke(bytes32 documentRoot, bytes32 document, bytes32[] memory proof) external onlyRole(REVOKER_ROLE) { - _revoke(documentRoot, document, proof); - } - - /** - * @notice Revokes a document - * @param documentRoot The hash of the document to revoke - */ - function revoke(bytes32 documentRoot) external onlyRole(REVOKER_ROLE) { - _revoke(documentRoot, documentRoot, new bytes32[](0)); - } - - /** - * @notice Revokes documents in bulk - * @param documentRoots The hashes of the documents to revoke - */ - function bulkRevoke( - bytes32[] memory documentRoots, - bytes32[] memory documents, - bytes32[][] memory proofs - ) external onlyRole(REVOKER_ROLE) { - for (uint256 i = 0; i < documentRoots.length; i++) { - _revoke(documentRoots[i], documents[i], proofs[i]); - } - } - - function isIssued( - bytes32 documentRoot, - bytes32 document, - bytes32[] memory proof - ) public view onlyValidDocument(documentRoot, document, proof) returns (bool) { - if (documentRoot == document && proof.length == 0) { - return _isIssued(document); - } - return _isIssued(documentRoot); - } - - function isIssued(bytes32 documentRoot) public view returns (bool) { - return isIssued(documentRoot, documentRoot, new bytes32[](0)); - } - - function isRevoked( - bytes32 documentRoot, - bytes32 document, - bytes32[] memory proof - ) public view onlyValidDocument(documentRoot, document, proof) returns (bool) { - if (!isIssued(documentRoot, document, proof)) { - revert InvalidDocument(documentRoot, document); - } - return _isRevoked(documentRoot, document, proof); - } - - /** - * @notice Checks if a document has been revoked - * @param documentRoot The hash of the document to check - * @return A boolean indicating whether the document has been revoked - */ - function isRevoked(bytes32 documentRoot) public view returns (bool) { - return isRevoked(documentRoot, documentRoot, new bytes32[](0)); - } - - function isActive(bytes32 documentRoot, bytes32 document, bytes32[] memory proof) public view returns (bool) { - if (!isIssued(documentRoot, document, proof)) { - revert InvalidDocument(documentRoot, document); - } - return !_isRevoked(documentRoot, document, proof); - } - - function _issue(bytes32 documentRoot) internal override { - if (isIssued(documentRoot)) { - revert DocumentExists(documentRoot); - } - - BaseDocumentStore._issue(documentRoot); - - emit DocumentIssued(documentRoot); - } - - function _revoke(bytes32 documentRoot, bytes32 document, bytes32[] memory proof) internal { - bool active = isActive(documentRoot, document, proof); - if (!active) { - revert InactiveDocument(documentRoot, document); - } - _revoke(document); - emit DocumentRevoked(documentRoot, document); - } - - function _isRevoked(bytes32 documentRoot, bytes32 document, bytes32[] memory proof) internal view returns (bool) { - if (documentRoot == document && proof.length == 0) { - return _isRevoked(document); - } - return (_isRevoked(documentRoot) || _isRevoked(document)); - } - - modifier onlyValidDocument( - bytes32 documentRoot, - bytes32 document, - bytes32[] memory proof - ) { - if (document == 0x0 || documentRoot == 0x0) { - revert ZeroDocument(); - } - if (!proof.verify(documentRoot, document)) { - revert InvalidDocument(documentRoot, document); - } - _; + __BaseDocumentStore_init(_name, initAdmin); } } diff --git a/src/interfaces/IDocumentStore.sol b/src/interfaces/IDocumentStore.sol index 2b8e9d4..d2a0e69 100644 --- a/src/interfaces/IDocumentStore.sol +++ b/src/interfaces/IDocumentStore.sol @@ -10,6 +10,8 @@ interface IDocumentStore { error InvalidDocument(bytes32 documentRoot, bytes32 document); + error DocumentNotIssued(bytes32 documentRoot, bytes32 document); + /** * @notice Emitted when a document is issued * @param document The hash of the issued document @@ -28,15 +30,9 @@ interface IDocumentStore { function revoke(bytes32 documentRoot) external; - function revoke(bytes32 documentRoot, bytes32 document, bytes32[] memory proof) external; - function isIssued(bytes32 documentRoot) external view returns (bool); - function isIssued(bytes32 documentRoot, bytes32 document, bytes32[] memory proof) external view returns (bool); - function isRevoked(bytes32 documentRoot) external view returns (bool); - function isRevoked(bytes32 documentRoot, bytes32 document, bytes32[] memory proof) external view returns (bool); - - function isActive(bytes32 documentRoot, bytes32 document, bytes32[] memory proof) external view returns (bool); + function isActive(bytes32 documentRoot) external view returns (bool); } diff --git a/src/interfaces/IDocumentStoreBatchable.sol b/src/interfaces/IDocumentStoreBatchable.sol new file mode 100644 index 0000000..9dacfd8 --- /dev/null +++ b/src/interfaces/IDocumentStoreBatchable.sol @@ -0,0 +1,12 @@ +// SPDX-License-Identifier: Apache-2.0 +pragma solidity >=0.8.23 <0.9.0; + +interface IDocumentStoreBatchable { + function revoke(bytes32 documentRoot, bytes32 document, bytes32[] memory proof) external; + + function isIssued(bytes32 documentRoot, bytes32 document, bytes32[] memory proof) external view returns (bool); + + function isRevoked(bytes32 documentRoot, bytes32 document, bytes32[] memory proof) external view returns (bool); + + function isActive(bytes32 documentRoot, bytes32 document, bytes32[] memory proof) external view returns (bool); +} diff --git a/test/DocumentStore.t.sol b/test/DocumentStore.t.sol index a1fdaf4..059f8fd 100644 --- a/test/DocumentStore.t.sol +++ b/test/DocumentStore.t.sol @@ -300,7 +300,7 @@ contract DocumentStore_revokeRoot_Test is DocumentStoreWithFakeDocuments_Base { function testRevokeRootNonIssuedRootRevert(bytes32 nonIssuedRoot) public { vm.assume(nonIssuedRoot != docRoot && nonIssuedRoot != bytes32(0)); - vm.expectRevert(abi.encodeWithSelector(IDocumentStore.InvalidDocument.selector, nonIssuedRoot, nonIssuedRoot)); + vm.expectRevert(abi.encodeWithSelector(IDocumentStore.DocumentNotIssued.selector, nonIssuedRoot, nonIssuedRoot)); vm.prank(revoker); documentStore.revoke(nonIssuedRoot); @@ -404,7 +404,7 @@ contract DocumentStore_revoke_Test is DocumentStoreWithFakeDocuments_Base { function testRevokeNonIssuedDocumentRevert(bytes32 nonIssuedRoot) public { vm.assume(nonIssuedRoot != docRoot && nonIssuedRoot != bytes32(0)); - vm.expectRevert(abi.encodeWithSelector(IDocumentStore.InvalidDocument.selector, nonIssuedRoot, nonIssuedRoot)); + vm.expectRevert(abi.encodeWithSelector(IDocumentStore.DocumentNotIssued.selector, nonIssuedRoot, nonIssuedRoot)); vm.prank(revoker); documentStore.revoke(nonIssuedRoot); @@ -583,7 +583,7 @@ contract DocumentStore_isRootRevoked is DocumentStoreWithFakeDocuments_Base { function testIsRootRevokedWithNotIssuedRootRevert(bytes32 notIssuedRoot) public { vm.assume(notIssuedRoot != docRoot && notIssuedRoot != bytes32(0)); - vm.expectRevert(abi.encodeWithSelector(IDocumentStore.InvalidDocument.selector, notIssuedRoot, notIssuedRoot)); + vm.expectRevert(abi.encodeWithSelector(IDocumentStore.DocumentNotIssued.selector, notIssuedRoot, notIssuedRoot)); assertFalse(documentStore.isRevoked(notIssuedRoot)); } @@ -630,8 +630,20 @@ contract DocumentStore_isActive_Test is DocumentStoreWithFakeDocuments_Base { function testIsActiveWithNotIssuedDocumentRevert(bytes32 notIssuedDoc) public { vm.assume(notIssuedDoc != docRoot && notIssuedDoc != bytes32(0)); - vm.expectRevert(abi.encodeWithSelector(IDocumentStore.InvalidDocument.selector, docRoot, notIssuedDoc)); + vm.expectRevert(abi.encodeWithSelector(IDocumentStore.DocumentNotIssued.selector, notIssuedDoc, notIssuedDoc)); + + documentStore.isActive(notIssuedDoc, notIssuedDoc, new bytes32[](0)); + } + + function testIsActiveWithNotIssuedRootRevert() public { + bytes32 notIssuedRoot = 0xb841229d504c5c9bcb8132078db8c4a483825ad811078144c6f9aec84213d798; + bytes32 notIssuedDoc = 0xd56c26db0fde817dcd82269d0f9a3f50ea256ee0c870e43c3ec2ebdd655e3f37; + + bytes32[] memory proofs = new bytes32[](1); + proofs[0] = 0x9800b3feae3c44fe4263f6cbb2d8dd529c26c3a1c3ca7208a30cfa5efbc362e7; + + vm.expectRevert(abi.encodeWithSelector(IDocumentStore.DocumentNotIssued.selector, notIssuedRoot, notIssuedDoc)); - documentStore.isActive(docRoot, notIssuedDoc, proofs[0]); + documentStore.isActive(notIssuedRoot, notIssuedDoc, proofs); } }