Skip to content

Commit

Permalink
add deletion circuit tests
Browse files Browse the repository at this point in the history
failing atm
  • Loading branch information
dcbuild3r committed Sep 5, 2023
1 parent a889d2e commit 8f40fc8
Show file tree
Hide file tree
Showing 13 changed files with 624 additions and 133 deletions.
63 changes: 63 additions & 0 deletions src/test/data/TestDeletionParams.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
{
"inputHash": "0xfe7bd6158c7603ed86cef4dbe90a417fe7c16e94a730ae75ff0135837c6f4dd1",
"deletionIndices": [0, 2, 4],
"preRoot": "0x218676b10b4d8c25fce789f3b13f2b3e49497ce0b20f57bacd7dfda85c0b6ac2",
"postRoot": "0x7c453712267d1cca763c6da89bb632bd85bf9d8b48ef71bd0b7595f81357edb",
"identityCommitments": ["0x1", "0x3", "0x5"],
"merkleProofs": [
[
"0x2",
"0x20a3af0435914ccd84b806164531b0cd36e37d4efb93efab76913a93e1f30996",
"0x176cf35331147314efef56ab615fe64b748584a01d362fa17297672192d5ecd",
"0x18f43331537ee2af2e3d758d50f72106467c6eea50371dd528d57eb2b856d238",
"0x7f9d837cb17b0d36320ffe93ba52345f1b728571a568265caac97559dbc952a",
"0x2b94cf5e8746b3f5c9631f4c5df32907a699c58c94b2ad4d7b5cec1639183f55",
"0x2dee93c5a666459646ea7d22cca9e1bcfed71e6951b953611d11dda32ea09d78",
"0x78295e5a22b84e982cf601eb639597b8b0515a88cb5ac7fa8a4aabe3c87349d",
"0x2fa5e5f18f6027a6501bec864564472a616b2e274a41211a444cbe3a99f3cc61",
"0xe884376d0d8fd21ecb780389e941f66e45e7acce3e228ab3e2156a614fcd747",
"0x1b7201da72494f1e28717ad1a52eb469f95892f957713533de6175e5da190af2",
"0x1f8d8822725e36385200c0b201249819a6e6e1e4650808b5bebc6bface7d7636",
"0x2c5d82f66c914bafb9701589ba8cfcfb6162b0a12acf88a8d0879a0471b5f85a",
"0x14c54148a0940bb820957f5adf3fa1134ef5c4aaa113f4646458f270e0bfbfd0",
"0x190d33b12f986f961e10c0ee44d8b9af11be25588cad89d416118e4bf4ebe80c",
"0x22f98aa9ce704152ac17354914ad73ed1167ae6596af510aa5b3649325e06c92"
],
[
"0x4",
"0x65e2c6cc08a36c4a943286bc91c216054a1981eb4f7570f67394ef8937a21b8",
"0x176cf35331147314efef56ab615fe64b748584a01d362fa17297672192d5ecd",
"0x18f43331537ee2af2e3d758d50f72106467c6eea50371dd528d57eb2b856d238",
"0x7f9d837cb17b0d36320ffe93ba52345f1b728571a568265caac97559dbc952a",
"0x2b94cf5e8746b3f5c9631f4c5df32907a699c58c94b2ad4d7b5cec1639183f55",
"0x2dee93c5a666459646ea7d22cca9e1bcfed71e6951b953611d11dda32ea09d78",
"0x78295e5a22b84e982cf601eb639597b8b0515a88cb5ac7fa8a4aabe3c87349d",
"0x2fa5e5f18f6027a6501bec864564472a616b2e274a41211a444cbe3a99f3cc61",
"0xe884376d0d8fd21ecb780389e941f66e45e7acce3e228ab3e2156a614fcd747",
"0x1b7201da72494f1e28717ad1a52eb469f95892f957713533de6175e5da190af2",
"0x1f8d8822725e36385200c0b201249819a6e6e1e4650808b5bebc6bface7d7636",
"0x2c5d82f66c914bafb9701589ba8cfcfb6162b0a12acf88a8d0879a0471b5f85a",
"0x14c54148a0940bb820957f5adf3fa1134ef5c4aaa113f4646458f270e0bfbfd0",
"0x190d33b12f986f961e10c0ee44d8b9af11be25588cad89d416118e4bf4ebe80c",
"0x22f98aa9ce704152ac17354914ad73ed1167ae6596af510aa5b3649325e06c92"
],
[
"0x6",
"0x2098f5fb9e239eab3ceac3f27b81e481dc3124d55ffed523a839ee8446b64864",
"0x1ebadf14eecbfe79f7ac75d3b6c688b8630fb675fcf24ab20e2a08381998266f",
"0x18f43331537ee2af2e3d758d50f72106467c6eea50371dd528d57eb2b856d238",
"0x7f9d837cb17b0d36320ffe93ba52345f1b728571a568265caac97559dbc952a",
"0x2b94cf5e8746b3f5c9631f4c5df32907a699c58c94b2ad4d7b5cec1639183f55",
"0x2dee93c5a666459646ea7d22cca9e1bcfed71e6951b953611d11dda32ea09d78",
"0x78295e5a22b84e982cf601eb639597b8b0515a88cb5ac7fa8a4aabe3c87349d",
"0x2fa5e5f18f6027a6501bec864564472a616b2e274a41211a444cbe3a99f3cc61",
"0xe884376d0d8fd21ecb780389e941f66e45e7acce3e228ab3e2156a614fcd747",
"0x1b7201da72494f1e28717ad1a52eb469f95892f957713533de6175e5da190af2",
"0x1f8d8822725e36385200c0b201249819a6e6e1e4650808b5bebc6bface7d7636",
"0x2c5d82f66c914bafb9701589ba8cfcfb6162b0a12acf88a8d0879a0471b5f85a",
"0x14c54148a0940bb820957f5adf3fa1134ef5c4aaa113f4646458f270e0bfbfd0",
"0x190d33b12f986f961e10c0ee44d8b9af11be25588cad89d416118e4bf4ebe80c",
"0x22f98aa9ce704152ac17354914ad73ed1167ae6596af510aa5b3649325e06c92"
]
]
}
File renamed without changes.
47 changes: 36 additions & 11 deletions src/test/identity-manager/WorldIDIdentityManagerCalculation.t.sol
Original file line number Diff line number Diff line change
Expand Up @@ -18,9 +18,9 @@ contract WorldIDIdentityManagerCalculation is WorldIDIdentityManagerTest {
// Setup
bytes memory callData = abi.encodeCall(
ManagerImplV1.calculateIdentityRegistrationInputHash,
(startIndex, preRoot, postRoot, identityCommitments)
(startIndex, insertionPreRoot, insertionPostRoot, identityCommitments)
);
bytes memory returnData = abi.encode(inputHash);
bytes memory returnData = abi.encode(insertionInputHash);

// Test
assertCallSucceedsOn(identityManagerAddress, callData, returnData);
Expand All @@ -33,14 +33,39 @@ contract WorldIDIdentityManagerCalculation is WorldIDIdentityManagerTest {

// Test
managerImpl.calculateIdentityRegistrationInputHash(
startIndex, preRoot, postRoot, identityCommitments
startIndex, insertionPreRoot, insertionPostRoot, identityCommitments
);
}

/// @notice Tests whether it is possible to correctly calculate the `inputHash` to the merkle
/// tree verifier.
function testCalculateIdentityDeletionInputHashFromParametersOnKnownInput() public {
// Setup
bytes memory callData = abi.encodeCall(
ManagerImpl.calculateIdentityDeletionInputHash,
(deletionIndices, insertionPreRoot, insertionPostRoot)
);
bytes memory returnData = abi.encode(deletionInputHash);

// Test
assertCallSucceedsOn(identityManagerAddress, callData, returnData);
}

/// @notice Checks that the input hash can only be calculated if behind the proxy.
function testCannotCalculateIdentityDeletionInputHashIfNotViaProxy() public {
// Setup
vm.expectRevert("Function must be called through delegatecall");

// Test
managerImpl.calculateIdentityDeletionInputHash(
deletionIndices, insertionPreRoot, insertionPostRoot
);
}

/// @notice Check whether it's possible to caculate the identity update input hash.
function testCanCalculateIdentityUpdateInputHash(
uint256 preRoot,
uint256 postRoot,
uint256 insertionPreRoot,
uint256 insertionPostRoot,
uint32 startIndex1,
uint32 startIndex2,
uint256 oldIdent1,
Expand All @@ -63,8 +88,8 @@ contract WorldIDIdentityManagerCalculation is WorldIDIdentityManagerTest {

bytes32 expectedResult = keccak256(
abi.encodePacked(
preRoot,
postRoot,
insertionPreRoot,
insertionPostRoot,
uint256(startIndex1),
uint256(startIndex2),
oldIdent1,
Expand All @@ -75,7 +100,7 @@ contract WorldIDIdentityManagerCalculation is WorldIDIdentityManagerTest {
);
bytes memory callData = abi.encodeCall(
ManagerImplV1.calculateIdentityUpdateInputHash,
(preRoot, postRoot, leafIndices, oldIdents, newIdents)
(insertionPreRoot, insertionPostRoot, leafIndices, oldIdents, newIdents)
);
bytes memory expectedReturn = abi.encode(expectedResult);

Expand All @@ -86,8 +111,8 @@ contract WorldIDIdentityManagerCalculation is WorldIDIdentityManagerTest {
/// @notice Ensures that the identity update hash can only be calculated when called via the
/// proxy.
function testCannotCalculateIdentityUpdateHashIfNotViaProxy(
uint256 preRoot,
uint256 postRoot,
uint256 insertionPreRoot,
uint256 insertionPostRoot,
uint32[] memory leafIndices,
uint256[] memory oldIdents,
uint256[] memory newIdents
Expand All @@ -97,7 +122,7 @@ contract WorldIDIdentityManagerCalculation is WorldIDIdentityManagerTest {

// Test
managerImpl.calculateIdentityUpdateInputHash(
preRoot, postRoot, leafIndices, oldIdents, newIdents
insertionPreRoot, insertionPostRoot, leafIndices, oldIdents, newIdents
);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -113,7 +113,7 @@ contract WorldIDIdentityManagerDataQuery is WorldIDIdentityManagerTest {
bytes memory queryCallData = abi.encodeCall(ManagerImplV1.queryRoot, (newPreRoot));
bytes memory returnData =
abi.encode(ManagerImplV1.RootInfo(newPreRoot, uint128(originalTimestamp), false));
vm.warp(originalTimestamp + 2 hours); // Force preRoot to expire
vm.warp(originalTimestamp + 2 hours); // Force insertionPreRoot to expire

// Test
assertCallSucceedsOn(identityManagerAddress, queryCallData, returnData);
Expand Down Expand Up @@ -176,7 +176,7 @@ contract WorldIDIdentityManagerDataQuery is WorldIDIdentityManagerTest {
vm.assume(SemaphoreTreeDepthValidator.validate(actualTreeDepth));
makeNewIdentityManager(
actualTreeDepth,
preRoot,
insertionPreRoot,
defaultInsertVerifiers,
defaultDeletionVerifiers,
defaultUpdateVerifiers,
Expand Down
151 changes: 83 additions & 68 deletions src/test/identity-manager/WorldIDIdentityManagerIdentityDeletion.t.sol
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ import {WorldIDIdentityManagerTest} from "./WorldIDIdentityManagerTest.sol";
import {ITreeVerifier} from "../../interfaces/ITreeVerifier.sol";
import {SimpleVerifier, SimpleVerify} from "../mock/SimpleVerifier.sol";
import {TypeConverter as TC} from "../utils/TypeConverter.sol";
import {Verifier as TreeVerifier} from "../mock/TreeVerifier.sol";
import {Verifier as TreeVerifier} from "../mock/DeletionTreeVerifier.sol";
import {VerifierLookupTable} from "../../data/VerifierLookupTable.sol";

import {WorldIDIdentityManager as IdentityManager} from "../../WorldIDIdentityManager.sol";
Expand All @@ -24,37 +24,49 @@ contract WorldIDIdentityManagerIdentityDeletion is WorldIDIdentityManagerTest {

/// Taken from WorldIDIdentityManagerImplV1.sol
event TreeChanged(
uint256 indexed preRoot, ManagerImpl.TreeChange indexed kind, uint256 indexed postRoot
uint256 indexed deletionPreRoot,
ManagerImpl.TreeChange indexed kind,
uint256 indexed deletionPostRoot
);

// /// @notice Checks that the proof validates properly with the correct inputs.
// function testDeleteIdentitiesWithCorrectInputsFromKnown() public {
// // Setup
// ITreeVerifier actualVerifier = new TreeVerifier();
// (VerifierLookupTable insertVerifiers, VerifierLookupTable deletionVerifiers, VerifierLookupTable updateVerifiers) =
// makeVerifierLookupTables(TC.makeDynArray([40]));
// deletionVerifiers.addVerifier(identityCommitmentsSize, actualVerifier);
// makeNewIdentityManager(
// treeDepth, preRoot, insertVerifiers, deletionVerifiers, updateVerifiers, semaphoreVerifier
// );
// bytes memory deleteCallData = abi.encodeCall(
// ManagerImpl.deleteIdentities,
// (proof, preRoot, deletionIndices, postRoot)
// );
// bytes memory latestRootCallData = abi.encodeCall(ManagerImplV1.latestRoot, ());
// bytes memory queryRootCallData = abi.encodeCall(ManagerImplV1.queryRoot, (postRoot));

// // Test
// assertCallSucceedsOn(identityManagerAddress, deleteCallData);
// assertCallSucceedsOn(identityManagerAddress, latestRootCallData, abi.encode(postRoot));
// assertCallSucceedsOn(
// identityManagerAddress,
// queryRootCallData,
// abi.encode(ManagerImplV1.RootInfo(postRoot, 0, true))
// );
// }

/// @notice Checks that the proof validates properly with correct inputs.
/// @notice Checks that the deletionProof validates properly with the correct inputs.
function testDeleteIdentitiesWithCorrectInputsFromKnown() public {
// Setup
ITreeVerifier actualVerifier = new TreeVerifier();
(
VerifierLookupTable insertVerifiers,
VerifierLookupTable deletionVerifiers,
VerifierLookupTable updateVerifiers
) = makeVerifierLookupTables(TC.makeDynArray([40]));
deletionVerifiers.addVerifier(identityCommitmentsSize, actualVerifier);
makeNewIdentityManager(
treeDepth,
deletionPreRoot,
insertVerifiers,
deletionVerifiers,
updateVerifiers,
semaphoreVerifier
);
bytes memory deleteCallData = abi.encodeCall(
ManagerImpl.deleteIdentities,
(deletionProof, deletionPreRoot, deletionIndices, deletionPostRoot)
);
bytes memory latestRootCallData = abi.encodeCall(ManagerImplV1.latestRoot, ());
bytes memory queryRootCallData = abi.encodeCall(ManagerImplV1.queryRoot, (deletionPostRoot));

// Test
assertCallSucceedsOn(identityManagerAddress, deleteCallData);
assertCallSucceedsOn(
identityManagerAddress, latestRootCallData, abi.encode(deletionPostRoot)
);
assertCallSucceedsOn(
identityManagerAddress,
queryRootCallData,
abi.encode(ManagerImplV1.RootInfo(deletionPostRoot, 0, true))
);
}

/// @notice Checks that the deletionProof validates properly with correct inputs.
function testDeleteIdentitiesWithCorrectInputs(
uint128[8] memory prf,
uint128 newPreRoot,
Expand Down Expand Up @@ -183,7 +195,7 @@ contract WorldIDIdentityManagerIdentityDeletion is WorldIDIdentityManagerTest {
assertCallFailsOn(identityManagerAddress, callData, errorData);
}

/// @notice Checks that it reverts if the provided proof is incorrect for the public inputs.
/// @notice Checks that it reverts if the provided deletionProof is incorrect for the public inputs.
function testCannotDeleteIdentitiesWithIncorrectInputs(
uint128[8] memory prf,
uint128 newPreRoot,
Expand Down Expand Up @@ -217,45 +229,46 @@ contract WorldIDIdentityManagerIdentityDeletion is WorldIDIdentityManagerTest {
// Test
assertCallFailsOn(identityManagerAddress, callData, expectedError);
}
//
//
// /// @notice Checks that it reverts if the provided post root is incorrect.
// function testCannotRegisterIdentitiesIfPostRootIncorrect(uint256 newPostRoot) public {
// // Setup
// vm.assume(newPostRoot != postRoot && newPostRoot < SNARK_SCALAR_FIELD);
// managerImpl = new ManagerImpl();
// managerImplAddress = address(managerImpl);
// ITreeVerifier actualVerifier = new TreeVerifier();
// (VerifierLookupTable insertVerifiers, VerifierLookupTable deletionVerifiers, VerifierLookupTable updateVerifiers) =
// makeVerifierLookupTables(TC.makeDynArray([70]));
// insertVerifiers.addVerifier(identityCommitmentsSize, actualVerifier);
//
// bytes memory callData = abi.encodeCall(
// ManagerImplV1.initialize,
// (treeDepth, preRoot, insertVerifiers, deletionVerifiers, updateVerifiers, semaphoreVerifier)
// );
//
// identityManager = new IdentityManager(managerImplAddress, callData);
// identityManagerAddress = address(identityManager);
// bytes memory registerCallData = abi.encodeCall(
// ManagerImplV1.registerIdentities,
// (proof, preRoot, startIndex, identityCommitments, newPostRoot)
// );
// bytes memory expectedError =
// abi.encodeWithSelector(ManagerImplV1.ProofValidationFailure.selector);
//
// // Test
// assertCallFailsOn(identityManagerAddress, registerCallData, expectedError);
// }
//

/// @notice Checks that it reverts if the provided post root is incorrect.
function testCannotDeleteIdentitiesIfPostRootIncorrect(uint256 newPostRoot) public {
// Setup
vm.assume(newPostRoot != deletionPostRoot && newPostRoot < SNARK_SCALAR_FIELD);
ITreeVerifier actualVerifier = new TreeVerifier();
(
VerifierLookupTable insertVerifiers,
VerifierLookupTable deletionVerifiers,
VerifierLookupTable updateVerifiers
) = makeVerifierLookupTables(TC.makeDynArray([40]));
deletionVerifiers.addVerifier(identityCommitmentsSize, actualVerifier);
makeNewIdentityManager(
treeDepth,
deletionPreRoot,
insertVerifiers,
deletionVerifiers,
updateVerifiers,
semaphoreVerifier
);

bytes memory deletionCallData = abi.encodeCall(
ManagerImpl.deleteIdentities,
(deletionProof, deletionPreRoot, deletionIndices, newPostRoot)
);
bytes memory expectedError =
abi.encodeWithSelector(ManagerImplV1.ProofValidationFailure.selector);

// Test
assertCallFailsOn(identityManagerAddress, deletionCallData, expectedError);
}

/// @notice Tests that it reverts if an attempt is made to delete identities as an address
/// that is not the identity operator address.
function testCannotDeleteIdentitiesAsNonIdentityOperator(address nonOperator) public {
// Setup
vm.assume(nonOperator != address(this) && nonOperator != address(0x0));
bytes memory callData = abi.encodeCall(
ManagerImpl.deleteIdentities, (proof, preRoot, deletionIndices, postRoot)
ManagerImpl.deleteIdentities,
(deletionProof, deletionPreRoot, deletionIndices, deletionPostRoot)
);
bytes memory errorData =
abi.encodeWithSelector(ManagerImplV1.Unauthorized.selector, nonOperator);
Expand Down Expand Up @@ -284,7 +297,8 @@ contract WorldIDIdentityManagerIdentityDeletion is WorldIDIdentityManagerTest {
semaphoreVerifier
);
bytes memory callData = abi.encodeCall(
ManagerImpl.deleteIdentities, (proof, actualRoot, deletionIndices, postRoot)
ManagerImpl.deleteIdentities,
(deletionProof, actualRoot, deletionIndices, deletionPostRoot)
);
bytes memory expectedError = abi.encodeWithSelector(
ManagerImplV1.NotLatestRoot.selector, actualRoot, uint256(currentPreRoot)
Expand All @@ -300,7 +314,8 @@ contract WorldIDIdentityManagerIdentityDeletion is WorldIDIdentityManagerTest {
// Setup
uint256 newPreRoot = SNARK_SCALAR_FIELD + i;
bytes memory callData = abi.encodeCall(
ManagerImpl.deleteIdentities, (proof, newPreRoot, deletionIndices, postRoot)
ManagerImpl.deleteIdentities,
(deletionProof, newPreRoot, deletionIndices, deletionPostRoot)
);
bytes memory expectedError = abi.encodeWithSelector(
ManagerImplV1.UnreducedElement.selector,
Expand All @@ -312,13 +327,13 @@ contract WorldIDIdentityManagerIdentityDeletion is WorldIDIdentityManagerTest {
assertCallFailsOn(identityManagerAddress, callData, expectedError);
}

/// @notice Tests that it reverts if an attempt is made to delete identities with a postRoot
/// @notice Tests that it reverts if an attempt is made to delete identities with a deletionPostRoot
/// that is not in reduced form.
function testCannotDeleteIdentitiesWithUnreducedPostRoot(uint128 i) public {
// Setup
uint256 newPostRoot = SNARK_SCALAR_FIELD + i;
bytes memory callData = abi.encodeCall(
ManagerImpl.deleteIdentities, (proof, initialRoot, deletionIndices, newPostRoot)
ManagerImpl.deleteIdentities, (deletionProof, initialRoot, deletionIndices, newPostRoot)
);
bytes memory expectedError = abi.encodeWithSelector(
ManagerImplV1.UnreducedElement.selector,
Expand All @@ -338,6 +353,6 @@ contract WorldIDIdentityManagerIdentityDeletion is WorldIDIdentityManagerTest {
vm.prank(expectedOwner);

// Test
managerImpl.deleteIdentities(proof, initialRoot, deletionIndices, postRoot);
managerImpl.deleteIdentities(deletionProof, initialRoot, deletionIndices, deletionPostRoot);
}
}
Loading

0 comments on commit 8f40fc8

Please sign in to comment.